玩转gdb调试工具(下)

[复制链接]
查看787 | 回复8 | 2023-9-8 12:58:25 | 显示全部楼层 |阅读模式

在GDB系列一二部分中记录了断点调试常用的一些命令。本部分将对之前的命令进行一次综合应用。

断点调试

通过在程序的适当位置打断点,观察程序执行至该位置时某些变量(或表达式)的值,进而不断缩小导致程序出现异常或 Bug 的语句的搜索范围,并最终找到,整个过程就称为断点调试。

值得一提的是,整个断点调试的过程,除了要借助 break、watch 或者 catch 命令以外,还要借助其它一些命令,例如在前面章节中,我们已经使用过的 print 命令(查看变量的值)、continue 命令(使程序继续执行)等。

GDB断点调试常用命令

命令(缩写) 功 能
run(r) 启动或者重启一个程序。
list(l) 显示带有行号的源码。
continue(c) 让暂停的程序继续运行。
next(n) 单步调试程序,即手动控制代码一行一行地执行。
step(s) 如果有调用函数,进入调用的函数内部;否则,和 next 命令的功能一样。
until(u) until location(u location) 当你厌倦了在一个循环体内单步跟踪时,单纯使用 until 命令,可以运行程序直到退出循环体。 until n 命令中,n 为某一行代码的行号,该命令会使程序运行至第 n 行代码处停止。
finish(fi) 结束当前正在执行的函数,并在跳出函数后暂停程序的执行。
return(return) 结束当前调用函数并返回指定值,到上一层函数调用处停止程序执行。
jump(j) 使程序从当前要执行的代码处,直接跳转到指定位置处继续执行后续的代码。
print(p) 打印指定变量的值。
quit(q) 退出 GDB 调试器。

finish命令和return命令

实际调试时,在某个函数中调试一段时间后,可能不需要再一步步执行到函数返回处,希望直接执行完当前函数,这时可以使用 finish 命令。与 finish 命令类似的还有 return 命令,它们都可以结束当前执行的函数。

finish 命令和 return 命令的区别是,finish 命令会执行函数到正常退出;而 return 命令是立即结束执行当前函数并返回,也就是说,如果当前函数还有剩余的代码未执行完毕,也不会执行了。除此之外,return 命令还有一个功能,即可以指定该函数的返回值。

Reading symbols from main.out...
(gdb) list    <---- 浏览当前程序
2   int print(int num){
3       int ret = num * num;
4       return ret;
5   }
6   int myfunc(int num){
7       int i = 1;
8       int sum = 0;
9       while(i <= num){
10          sum += print(i);
11          i++;
12      }
13      return sum;
14  }
15  int main(){
16      int num =0;
17      scanf("%d", &num);
18      int result = myfunc(num);
19      printf("%d", result);
20      return 0;
21  }
(gdb) break 16    <---- 在16行处设置一个普通断点
Breakpoint 1 at 0x119b: file main.c, line 16.
(gdb) run    <---- 开始运行程序
Starting program: /root/c/c.biancheng.com/gdb_demo/main.out 

Breakpoint 1, main () at main.c:16
16      int num =0;
(gdb) next    <---- 单步调试
17      scanf("%d", &num);
(gdb) next
5         <---- 相应scanf,输入5
18      int result = myfunc(num);
(gdb) step    <---- 进入myfunc函数
myfunc (num=5) at main.c:7
7       int i = 1;
(gdb) print num
$1 = 5
(gdb) next
8       int sum = 0;
(gdb) next
9       while(i <= num){
(gdb) step    <---- 这里使用step和next是一个效果
10          sum += print(i);
(gdb) next
11          i++;
(gdb) next
9       while(i <= num){
(gdb) next
10          sum += print(i);
(gdb) next
11          i++;
(gdb) next
9       while(i <= num){
(gdb) next
10          sum += print(i);
(gdb) next
11          i++;
(gdb) next
9       while(i <= num){
(gdb) finish    <---- 不想一步一步调了,直接使用finish,使整个循环结束
Run till exit from #0  myfunc (num=5) at main.c:9
0x00005555555551c4 in main () at main.c:18
18      int result = myfunc(num);
Value returned is $2 = 55
(gdb) print result
$3 = 0    <---- 有意思的地方,循环结束之后,赋值语句没有立刻执行
(gdb) next    <---- 单步调试一下
19      printf("%d", result);
(gdb) print result
$4 = 55    <---- myfunc函数返回了
(gdb) quit
A debugging session is active.

    Inferior 1 [process 143555] will be killed.

Quit anyway? (y or n) y

以上就是一个基本的断掉调试过程了!

回复

使用道具 举报

可乐klelee | 2023-9-8 12:59:58 | 显示全部楼层
GDB工具收尾!
回复 支持 反对

使用道具 举报

ai_mcu | 2023-9-8 13:06:59 | 显示全部楼层
写的很细,优秀
明天总会更好
回复 支持 反对

使用道具 举报

CHENQIGUANG1998 | 2023-9-8 13:53:22 | 显示全部楼层
打卡学习
回复

使用道具 举报

爱笑 | 2023-9-8 14:05:45 | 显示全部楼层
可乐大佬啥时候以这个效率来几篇小安派的
用心做好保姆工作
回复 支持 反对

使用道具 举报

jkernet | 2023-9-8 19:34:15 来自手机 | 显示全部楼层
高质量
回复

使用道具 举报

可乐klelee | 2023-9-8 20:19:35 | 显示全部楼层
爱笑 发表于 2023-9-8 14:05
可乐大佬啥时候以这个效率来几篇小安派的

可乐大佬关我可乐菜鸟什么事
回复 支持 反对

使用道具 举报

开发板 | 2023-9-9 19:45:19 | 显示全部楼层
优秀!
回复

使用道具 举报

iiv | 2023-9-13 20:26:08 | 显示全部楼层
支持!
回复

使用道具 举报

iiv | 2023-9-16 19:20:06 | 显示全部楼层
mark一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则