您的位置:首页 > 其它

使用GDB调试程序

2016-03-06 10:02 351 查看
工作中用的操作系统主要是linux,在与其他应用进行联调适配以及对客户进行支持的过程中,总会有各种各样的问题。所以调试程序来进行问题的分析定位就成了工作中必备的技能之一,linux下C以及C++程序最常用的调试工具就是GDB了。我的示例代码如下:

#include <stdio.h>
int add_range(int low, int high)
{
int i, sum;
for (i = low; i <= high; i++)
sum = sum + i;
return sum;
}
int main(void)
{
int add_range(int a,int b);
int result[2];
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;
}


要想用GDB调试程序,再进行编译的时候我们需将调试信息加到可执行文件当中。在用gcc进行编译的时候可以使用-g参数来实现这一点。

gcc -g test.c -o test


编译完成之后,执行二进制文件,发现结果和预期不符,此时我们就需要分析问题产生在什么地方。启动GDB调试程序,在当前目录下执行命令:

gdb test


可以看到



gdb里面有很多命令可供使用,具体可以参考/article/4630400.html

使用start启动程序,程序会启动在main函数的第一行等待命令,可以使用info locals命令查看当前函数内所开辟的局部变量的值:



然后我们进行下一条命令的执行,可以使用next命令或者step命令,区别为:next命令会一直执行程序的下一个动作或语句,执行step命令后,如果下个语句有函数,则进入到函数当中,我们使用step命令,如下:



可以看到进入到了add_range当中,然后我们使用n命令执行下一个动作,然后查看局部变量的值,就已经发生了变化:



此时使用bt命令查看当前函数调用桢栈的所有信息:



可以看到当前函数的调用信息:add_range()->main()

因为add_range函数会一直循环,使用n命令费时费力,可以使用finish命令结束当期那函数的执行,并且返回值,使用info locals命令查看此时main函数里的局部变量值:



发现此时result的第一个元素并没有进行相应的赋值,可见finish只是结束当前函数的调用,并且返回值,并不进行赋值,使用next或者step命令执行下一步动作进行赋值。

执行完第二个add_range函数后,我们此时再看main()里局部变量的值,:



此时我们可以看到,执行完第二个函数之后,错误结果就产生了。错误的步骤应该发生在第二个add_range()里,此时我们重新调试一下该程序,进入到第二个add_range()里,查看程序刚开始执行是局部变量的值:



可以看到,add_range函数在执行的时候,局部变量值为i = 11和sum = 55,并不是1和0。所以问题原因就找到了,因为在add_range()里,并没有给局部变量i和sum初始化,所以函数在进行调用的时候其值为栈内随机的一个值,第一个函数执行完释放后第二个函数又在相应的栈内引用了i和sum,所以造成了这种情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: