测试代码
#include <stdio.h>
int add_range(int low, int high) {
int i, sum;
for (i = low; i <= high; ++i) {
sum += i;
}
return sum;
}
int main (int argc, char *argv[]) {
int result[100];
result[0] = add_range(1, 10);
result[1] = add_range(1, 100);
printf("result[0] = %d\nresult[1] = %d\n", result[0], result[1]);
return 0;
}
测试过程
在执行上面的代码时,我们发现,测试的结果并不是我们想要的。
都知道从1加到10应该是55, 从1加到100应该是5050,那为什么测试结果是这样的呢?
1)查看源码
①可以使用
list 行号
命令(缩写为l)来列出源码内容,比如list 1
从第一行开始列出源码
②可以使用list 函数名
命令来列出函数的内容,比如list func
2)开始调试
①使用
start
命令开始执行程序
②使用next命令(缩写n)让程序中的语句一条一条地执行,不进入调用的函数
这样,我们仍然看不出来哪里错了,因为错误不在main函数中,而是在调用的add_range函数中
③重来,这一次使用命令
step
(缩写为s),进入调用的函数中
在函数中,有几种查看状态的方法
a. 使用命令backtrace
(缩写为bt)来查看函数调用的帧栈,
可以看到,当前的函数是被main函数调用的,main传进来的参数是low = 1, high = 10,
main的栈帧编号为1,add_range的栈帧编号为0。
b. 使用命令info
(缩写为i)来查看局部变量的信息,info还可以查看比如断点、函数等内容
好的,现在你看到了,局部变量并没有被初始化,找到错误原因了吧
假如我接下来想继续跟踪,就应该继续使用命令
step
,然后使用命令
由于发生了错误,再往下跟踪就没有意义了,于是使用finish
命令让程序一直运行到从当前函数返回为止
可以看到,使用finish以后,函数返回了32822,但并没有将返回值赋给result[0],
继续使用命令step
,完成赋值
3)在gdb中修改错误,继续调试
上面,我们已经找到了错误,是局部变量没有初始化导致的,
但我们并不想浪费这次调试机会,退出gdb再去修改源码然后再编译运行,而且也不确定找到的错误是不是对的
这样,我们可以在gdb中马上把错误改正过来,看看还有没有别的bug
可以看到,在进入调用函数后,将可见的变量sum设为0,输出的结果即为正确的55了
4)退出gdb环境
使用命令
quit
或者直接ctrl+D
去修改源码令sum = 0,编译运行即可
Tips:
假如在函数add_range中想查看别的函数的局部变量的值,
可以使用frame命令(缩写为f),选择想查看的函数栈帧编号,然后再使用info命令查看局部变量