调试工具_gdb使用教程

news/2024/12/29 9:35:08/

目录

一. 环境介绍

二. gdb指令

1. 启动调试

2. 退出调试

3. 查看代码 

4. 运行程序

 5. 打断点

6. 查看断点

7.  删除断点

8.  逐过程调试

9. 逐语句调试

10.  查看变量

11. 常显示变量(监视)

12. 取消常显示变量

13. 运行到指定行

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

15. 执行到下一个断点

16. 关闭断点

17. 开启断点

18. 不同文件中打断点

19. 查看局部变量

20. 修改变量的值

21. 查看函数的调用堆栈


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 + 可执行程序文件名

[lxy@hecs-165234 test9]$ gdb test_debug 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/lxy/test/test9/test_debug...done.
(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_64
(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 /lib64/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 = 4195472
(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 = 4195472
(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 里面常用的命令,我们下期见~ 


http://www.ppmy.cn/news/826813.html

相关文章

2022年低压电工考试试题模拟考试平台操作

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2022低压电工考试题是低压电工题库上机考试练习题&#xff01;2022年低压电工考试试题模拟考试平台操作依据低压电工考前押题。低压电工练习题通过安全生产模拟考试一点通模拟在线真实考试。 1、【单选题】( )仪表由固…

2021年中式面点师(高级)报名考试及中式面点师(高级)模拟试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 中式面点师&#xff08;高级&#xff09;报名考试根据新中式面点师&#xff08;高级&#xff09;考试大纲要求&#xff0c;安全生产模拟考试一点通将中式面点师&#xff08;高级&#xff09;模拟考试试题进行汇编&…

397种生活小窍门

397种生活小窍门 吸收别人的经验 类别&#xff1a;生活 | 浏览(39) | 2008-5-23 14:54:07 | 关闭广告 1 、巧用牙膏 6:若有小面积皮肤损伤或烧伤、烫伤&#xff0c;抹上少许牙膏&#xff0c;可立即止血止痛&#xff0c;也可防止感染&#xff0c;疗效颇佳。 2 、巧除纱窗…

尚硅谷Docker实战教程-笔记12【高级篇,Docker-compose容器编排】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【基础篇&#xff0c;Docker理念简介、官网介绍、平台入门图解、平台架构图解】…

小常识

1吹风机对着标签吹&#xff0c;等吹到标签的胶热了&#xff0c;就可以很容易的把标签撕下来了 2喝茶以后&#xff0c;杯子里面留下难看的茶渍&#xff0c;用牙膏洗茶渍&#xff0c;非常干净 3刚刚被蚊子咬完的时候涂上肥皂就不会痒了&#xff0c;我一直这么做 4旅行带衣服如…

日常生活小常识100条

生活中的小事情往往能带给我们意想不到的效果,相信每个人都能有用。 1 、巧用牙膏:若有小面积皮肤损伤或烧伤、烫伤&#xff0c;抹上少许牙膏&#xff0c;可立即止血止痛&#xff0c;也可防止感染&#xff0c;疗效颇佳。 2 、巧除纱窗油腻:可将洗衣粉、吸烟剩下的烟头一起放在水…

LeetCode20.有效的括号

20.有效的括号 文章目录 20.有效的括号一、题目二、题解算法思路具体实现算法分析 一些拓展1、栈数据结构的应用2、括号匹配问题的其他解法3、括号匹配问题的变种&#xff1a; 一、题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的…

电脑快捷键【Crtl】

1.CtrlX 剪切 2.CtrlZ 全选 3.CtrlC 复制 4.CtrlV 粘贴 5.CtrlZ 撤回 6.CtrlR 刷新当前页面 7.CtrlF5 强制刷新 9.CtrlEsc 打开开始界面 1…