一、gdb的一些基础命令
l:显示代码
l n:跳转到当前代码页的第n行的代码
l filename.c :n:跳转到filename.c文件的第n行代码
b 行号:加断点
info break:查看断点信息
delete 断点编号:删除断点
r,运行程序
n,单步执行
c,继续执行,遇到断点停止执行
p,打印
s,进入函数
finish,退出函数
q,退出gdb
二、调试示例
先写一个main.c程序,该程序用来循环输出从键盘输入的字符串,直到遇到"end"结束循环:


编译并运行main.c:

发现和我们的预期并不一样,在输入"end"之后并没有结束循环,通过Ctrl+c结束这个进程。
- 进入gdb,gdb去调试Release版本:

从上图可以看出目前并不可以进行调试,之所以能打出一些信息,是因为这些信息是gdb打印出来的,而main程序还没有执行,下面的这句话

告诉我们在main程序中没有找到合适的符号,也就是没有包含调试信息,所以这个时候是调试不了的。在输入l进行显示代码时,下面这句话

告诉我们没有调试的符号表示被导入。说明这时的main程序是有问题的,没有包含调试信息。输入q退出gdb。
- gdb去调试Debug版本:
(1)编译和跟踪
按照gcc -o main main.c -g去编译main.c生成可执行程序main,并用gdb去跟踪main程序:

这时我们可以通过
这句话看出gdb从main中读到了符号表。
(2)显示所编写的代码
通过gdb指令l显示代码

一次只能显示10行代码。
(3)设置断点
语法形式:break 行号,break可以简写为b
将断点加到第13行:

可以继续下断点:

查看加了哪些断点info break:

删除断点delete Num:
删除第2个断点:

(4)运行程序进行调试
输入run,可以简写为r,按回车:

当前程序执行到了13行停止。
输入n,让程序单步执行:

从上图可以看出输入了字符串"hello",然后程序运行到了17行的if语句。
这时,我们输入p buff来查看一些buff中的内容:

可以看到,当前buff中存放的是字符串"hello\n"。
继续输入n单步执行:

当前程序又执行到了13行。
我们继续单步执行,这次输入字符串"end",程序跳转到17行的if语句:

此时,我们再输入p buff来查看一些buff中的内容:

可以看到,当前buff中存放的是字符串"end\n",这和我们输入的字符串"end"并不相同。
因此,再继续执行时,程序依然会进入循环:

此时,我们就通过调试发现了代码中存在的问题。
- 退出gdb
输入q退出gdb,此时会提示如果要退出会杀死刚刚的main程序,是否要退出,输入y表示退出,按回车就退出gdb。

退出gdb之后,刚刚的main程序也就结束了:

- 通过调试结果修正代码
将strcmp()改为strncmp():

此时,我们再去编译main.c,执行main程序,结果如下:



















