gdb牛刀小试
gdb牛刀小试
写在前面
最近时间很多,我在努力做MIT6.S081这门课的Lab,但是经常会遇到一些让我难以理解并且无从入手的bug,因此愈加萌发了学习gdb的想法。也试着去看gdb的官方文档,但是那个pdf足足有将近900页,总感觉这样看书对于一个新手不是高效的学习方法(当然对于已经使用过一段时间gdb的程序员来说,平时抽点时间细水长流地去看官方文档肯定是很棒的),因此想要找一个好点的教程,带我入门gdb,于是翻到了大佬写的教程(真的很古早,2003年,我当时看到发表时间人懵了)。本文一是想记录一下自己的学习过程,二也是想做个教程上的翻新(可能教程太早,gdb也发生了一些变化)。
测试代码
1 |
|
gdb调试
- 首先编译代码生成可执行文件(一定要加-g参数,这样才能把调试信息加到可执行文件中)
1 | cc -g tst.c -o tst |
- 然后启动gdb($后为bash命令)
1 | ubuntu@VM-0-14-ubuntu:~/learn_gdb$gdb |
- 之后会跳出一大段关于gdb的描述,并问你是否继续,继续就输入c,退出就输入q
- 进入我们想要调试的文件,注意是可执行文件,所以不需要带上文件后缀类型名(gdb后为输入的命令)
1 | (gdb) file tst |
- 输入l命令查看源代码(一次默认显示10行,想看更多就按回车)
1 | (gdb) l |
设置断点(设置两个断点,第一个设置在第16行,第二个设置在函数func的入口处)
1
2(gdb) break 16
Breakpoint 1 at 0x1187: file tst.c, line 16.1
2(gdb) break func
Breakpoint 2 at 0x1149: file tst.c, line 4.查看断点的信息
1
2
3
4(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001187 in main at tst.c:16
2 breakpoint keep y 0x0000000000001149 in func at tst.c:4运行代码(r为run的缩写)
1
2
3
4
5(gdb) r
Starting program: /home/ubuntu/learn_gdb/tst
Breakpoint 1, main () at tst.c:16
16 int j=0;执行单条语句(n为next的缩写)
1
2
3
4
5
6(gdb) n
17 j = 1;
(gdb) n
18 j = 2;
(gdb) n
19 j = 3;继续运行程序(c为continue的缩写),这时发现程序运行到了第二个断点处
1
2
3
4
5(gdb) c
Continuing.
Breakpoint 2, func (n=21845) at tst.c:4
4 {继续单步执行程序
1
2
3
4
5
6(gdb) n
5 int sum = 0, i;
(gdb) n
6 for (i = 0; i < n; i++)
(gdb) n
8 sum += i;打印一些变量的信息(p为print的缩写)
1
2
3
4(gdb) p i
$1 = 0
(gdb) p sum
$2 = 0继续单步执行程序
1
2
3
4(gdb) n
6 for (i = 0; i < n; i++)
(gdb) n
8 sum += i;再查看一下变量的信息
1
2
3
4(gdb) p i
$3 = 1
(gdb) p sum
$4 = 0查看函数栈
1
2
3(gdb) bt
#0 func (n=250) at tst.c:8
#1 0x00005555555551e9 in main () at tst.c:28退出当前的函数(也就是func函数)
1
2
3
4
5(gdb) finish
Run till exit from #0 func (n=250) at tst.c:8
0x00005555555551e9 in main () at tst.c:28
28 printf("result[1-250] = %d /n", func(250));
Value returned is $5 = 31125继续运行程序(可以发现程序正常退出了)
1
2
3(gdb) c
Continuing.
result[1-100] = 5050 /nresult[1-250] = 31125 /n[Inferior 1 (process 2973774) exited normally]退出gdb调试
1
(gdb) q
一些疑问以及自己的解答
- break断点的设置是断在一个语句的之前还是之后的?(比如break 16,这个第16行的语句是执行了没有呢?)
Answer:break断点的设置是断在一个语句之前的。也就是说第16行语句是没有执行的(可以通过print相关的变量验证)。
参考
- 本文标题:gdb牛刀小试
- 本文作者:mufiye
- 创建时间:2021-11-21 12:53:00
- 本文链接:http://mufiye.github.io/2021/11/21/gdb牛刀小试/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
评论