gdb入门实例1——单步执行和跟踪函数调用分析实战

测试代码

#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,然后使用命令print(缩写为p)打印变量信息
在这里插入图片描述
由于发生了错误,再往下跟踪就没有意义了,于是使用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命令查看局部变量
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/CSDN_dzh/article/details/84644049
今日推荐