您好,欢迎来到伴沃教育。
搜索
您的当前位置:首页调试工具_gdb使用教程

调试工具_gdb使用教程

来源:伴沃教育


GDB(GNU调试器)是一个功能强大的调试工具,提供了很多命令用于调试程序。下面我们来看一下如何使用gdb调试。

一. 环境介绍

我们要知道我们的程序有两种,一种是release 还有一种是 debug 版本的,我们的调试只有咋 debug 版本下才可以调试,我们只需要在编译的时候在后面加 -g 选项就是添加调试信息,也就是debug 版本。

二. gdb指令

下面我们就来看一下我们的 gdb 的指令

测试程序:

#include<stdio.h>


int addToToop(int top)
{
  int ret = 0;
  for(int i = 1; i <= top; ++i)
    ret += i;

  return ret;
}


int main()
{
  printf("开始调试\n");
  int sum = 20;
  int ret =  addToToop(sum);
  printf("%d\n", ret);
  printf("结束调试\n");
  return 0;
}

1. 启动调试

指令:gdb + 可执行程序文件名

 如果变成上面这样那么就以及成功了

2. 退出调试

指令:quit / q

(gdb) quit
[lxy@hecs-165234 test9]$ 
 


(gdb) q
[lxy@hecs-165234 test9]$ 

3. 查看代码 

指令:list / l  (后面也可以加 数字 表示查看该行和上下行的部分代码)

(gdb) l
10    
11      return ret;
12    }
13    
14    
15    
16    
17    int main()
18    {
19      printf("开始调试\n");
(gdb) l 0
1    #include<stdio.h>
2    
3    
4    
5    int addToToop(int top)
6    {
7      int ret = 0;
8      for(int i = 1; i <= top; ++i)
9        ret += i;
10    
(gdb) 

gdb 会记住上一次的指令,所以我们在查看的时候我们可以 l 0 然后之一回车

指令: l + 函数名(显示函数代码)

(gdb) l addToToop
1    #include<stdio.h>
2    
3    
4    
5    int addToToop(int top)
6    {
7      int ret = 0;
8      for(int i = 1; i <= top; ++i)
9        ret += i;
10    
(gdb) 
11      return ret;
12    }
13    
14    
15    
16    
17    int main()
18    {
19      printf("开始调试\n");
20      int sum = 20;
(gdb) 

4. 运行程序

指令:run / r

(gdb) r
Starting program: /home/lxy/test/test9/test_debug 
开始调试
210
结束调试
[Inferior 1 (process 7520) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_
(gdb) 

 5. 打断点

指令:break / b 后面 + 行号

(gdb) break 21
Breakpoint 1 at 0x4005c4: file test.c, line 21.
(gdb) b 22
Breakpoint 2 at 0x4005d1: file test.c, line 22.
(gdb) 

6. 查看断点

指令:info  breakpoints / info b / i b

(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
2       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
2       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
2       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
(gdb) 

 断点信息查看介绍:

  • NUM:断点编号
  • Type:断点类型
  • Disp:....
  • Enb:断点是否有效(可以将断点设置为无效)
  • 后面的就不做介绍了

7.  删除断点

指令:delete / d + 断点编号

(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
2       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
(gdb) delete 1
(gdb) i b
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
(gdb) d 2
(gdb) i b
No breakpoints or watchpoints.
(gdb) 

8.  逐过程调试

指令:next / n

我们先将断点打到 20 行的位置,然后我们开始逐语句调试

(gdb) b 20
Breakpoint 3 at 0x4005bd: file test.c, line 20.
(gdb) r
Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 3, main () at test.c:20
20      int sum = 20;
(gdb) n
21      int ret =  addToToop(sum);
(gdb) n
22      printf("%d\n", ret);
(gdb) n
210
23      printf("结束调试\n");
(gdb) n
结束调试
24      return 0;
(gdb) n
25    }
(gdb) n
0x00007ffff7a2f555 in __libc_start_main () from /lib/libc.so.6
(gdb) n

9. 逐语句调试

指令:step / s

我们还是在 20 行的位置打断点,然后我们逐语句调试,我们会进入到函数里面

(gdb) r
Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 3, main () at test.c:20
20      int sum = 20;
(gdb) s
21      int ret =  addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7      int ret = 0;
(gdb) s
8      for(int i = 1; i <= top; ++i)
(gdb) s
9        ret += i;
(gdb) 

10.  查看变量

指令:print / p + 变量名

Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 3, main () at test.c:20
20      int sum = 20;
(gdb) print sum
$4 = 0
(gdb) n
21      int ret =  addToToop(sum);
(gdb) print sum
$5 = 20
(gdb) p sum
$6 = 20
(gdb) 

11. 常显示变量(监视)

指令:display + 变量名

我们将断点打到 21 行(函数所在行),然后我们 s 进入函数, 我们 display 查看变量 i 

Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 4, main () at test.c:21
21      int ret =  addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7      int ret = 0;
(gdb) n
8      for(int i = 1; i <= top; ++i)
(gdb) display i
1: i = 41972
(gdb) n
9        ret += i;
1: i = 1
(gdb) n
8      for(int i = 1; i <= top; ++i)
1: i = 1
(gdb) n
9        ret += i;
1: i = 2
(gdb) 

我们的常显示变量的前面还有一个数字,这个就是常显示变量的 编号 

12. 取消常显示变量

指令:undisplay + 常显示变量的编号

还是根据上面的 显示 i 变量,然后我们取消显示 i 变量 

1: i = 2
(gdb) undisplay 1
(gdb) 

13. 运行到指定行

这次我们在进入到 函数中去 然后我们使用指令到指定行

指令:until + 行号

开始调试

Breakpoint 4, main () at test.c:21
21      int ret =  addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7      int ret = 0;
(gdb) s
8      for(int i = 1; i <= top; ++i)
(gdb) until 11
addToToop (top=20) at test.c:11
11      return ret;
(gdb) 
 

14. 执行完当前函数的剩余部分

我们继续到 该函数中去

指令:finish(执行完当前函数剩余的所有代码,并且在下一个函数执行前一行停止)

(gdb) run
Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 4, main () at test.c:21
21      int ret =  addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7      int ret = 0;
(gdb) s
8      for(int i = 1; i <= top; ++i)
(gdb) finish
Run till exit from #0  addToToop (top=20) at test.c:8
0x00000000004005ce in main () at test.c:21
21      int ret =  addToToop(sum);
Value returned is $8 = 210
(gdb) 

15. 执行到下一个断点

我们多打几个断点 20 21 22 ,然后我们 continue

指令:continue

(gdb) i b
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
    breakpoint already hit 1 time
(gdb) b 20
Breakpoint 5 at 0x4005bd: file test.c, line 20.
(gdb) b 22
Breakpoint 6 at 0x4005d1: file test.c, line 22.
(gdb) i b
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
    breakpoint already hit 1 time
5       breakpoint     keep y   0x00000000004005bd in main at test.c:20
6       breakpoint     keep y   0x00000000004005d1 in main at test.c:22

断点打好了


(gdb) run
Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 5, main () at test.c:20
20      int sum = 20;
(gdb) continue
Continuing.

Breakpoint 4, main () at test.c:21
21      int ret =  addToToop(sum);
(gdb) continue
Continuing.

Breakpoint 6, main () at test.c:22
22      printf("%d\n", ret);
(gdb) continue
Continuing.
210
结束调试
[Inferior 1 (process 7634) exited normally]
(gdb) 

16. 关闭断点

指令:disable + 断点编号

我们现在有 20 21 22 三个断点,我们现在关闭掉 21 我们 i b 查看一下

(gdb) i b
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
    breakpoint already hit 1 time
5       breakpoint     keep y   0x00000000004005bd in main at test.c:20
    breakpoint already hit 1 time
6       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
    breakpoint already hit 1 time
(gdb) disable 4
(gdb) i b
Num     Type           Disp Enb Address            What
4       breakpoint     keep n   0x00000000004005c4 in main at test.c:21
    breakpoint already hit 1 time
5       breakpoint     keep y   0x00000000004005bd in main at test.c:20
    breakpoint already hit 1 time
6       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
    breakpoint already hit 1 time
(gdb) 

17. 开启断点

指令:enable + 断点编号

(gdb) i b
Num     Type           Disp Enb Address            What
4       breakpoint     keep n   0x00000000004005c4 in main at test.c:21
    breakpoint already hit 1 time
5       breakpoint     keep y   0x00000000004005bd in main at test.c:20
    breakpoint already hit 1 time
6       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
    breakpoint already hit 1 time
(gdb) enable 4
(gdb) i b
Num     Type           Disp Enb Address            What
4       breakpoint     keep y   0x00000000004005c4 in main at test.c:21
    breakpoint already hit 1 time
5       breakpoint     keep y   0x00000000004005bd in main at test.c:20
    breakpoint already hit 1 time
6       breakpoint     keep y   0x00000000004005d1 in main at test.c:22
    breakpoint already hit 1 time
(gdb) 

18. 不同文件中打断点

指令:break / b + 文件名 + :+ 行号

这里就不做演示了....(没有多个文件)

19. 查看局部变量

指令:info locals / i locals

我们打断点到 22 行,然后我们查看主函数里面的变量

(gdb) run
Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 7, main () at test.c:22
22      printf("%d\n", ret);
(gdb) info locals
sum = 20
ret = 210
(gdb) i locals
sum = 20
ret = 210
(gdb) 

20. 修改变量的值

指令:set var + (变量名 = 值)

我们到 21 行里面的函数里面,然后直接修改i的值为200,然后查看 i 的值

(gdb) run 
Starting program: /home/lxy/test/test9/test_debug 
开始调试

Breakpoint 8, main () at test.c:21
21      int ret =  addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7      int ret = 0;
(gdb) s
8      for(int i = 1; i <= top; ++i)
(gdb) p i
$13 = 41972
(gdb) set var i = 200
(gdb) p i
$14 = 200
(gdb) 

21. 查看函数的调用堆栈

指令:bt

我们先到 mian 函数里面查看调用堆栈,然后在进入到我们自己写的函数的里面继续查看调用堆栈,然后我们在 finish 结束掉我们自己的函数,然后查看调用堆栈

(gdb) run 
Starting program: /home/lxy/test/test9/test_debug 

Breakpoint 9, main () at test.c:19
19      printf("开始调试\n");
(gdb) bt
#0  main () at test.c:19
(gdb) s
开始调试
20      int sum = 20;
(gdb) s
21      int ret =  addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7      int ret = 0;
(gdb) s
8      for(int i = 1; i <= top; ++i)
(gdb) bt
#0  addToToop (top=20) at test.c:8
#1  0x00000000004005ce in main () at test.c:21

(gdb) s
9        ret += i;
(gdb) finish
Run till exit from #0  addToToop (top=20) at test.c:9
0x00000000004005ce in main () at test.c:21
21      int ret =  addToToop(sum);
Value returned is $15 = 210
(gdb) bt
#0  0x00000000004005ce in main () at test.c:21
(gdb) 

上面的就是 gdb 里面常用的命令,我们下期见~ 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- bangwoyixia.com 版权所有 湘ICP备2023022004号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务