目录
一、其他调试代码的工具
二、GDB调试
1、调试准备
2、开始调试
3、调试命令
1.运行程序
2.退出gdb
3.传参
4.查看代码
5.设置或删除断点及相关操作
6.继续运行
7.运行中打印某些值及其类型
8.自动的打印某些值和信息及其相关操作
9.单步调试
10.设置变量的值
未完待续~~~。
一、其他调试代码的工具
1.strace 、lsof工具也可以调试。
二、GDB调试
1、调试准备
在使用gdb调试之前,我们需要在使用gcc编译的时候加上 -g选项, 如果你没有-g选项,运行的时候可以看到gdb提示你不能调试。同时对于多个文件,你都要加上-g
2、开始调试
假设我编译好的文件名为test, 使用gdb ./test 开启调试。我的文件树如下图所示:
3、调试命令
1.运行程序
我们使用(run or r or start)三个命令可以运行程序, r是run命令的缩写,这个命令就像你运行 ./test 可执行文件一样,顺便说一下这个test 与加了 -g选项的test 是不一样的。运行start命令,会使程序停止在 main函数入口。如下图:
我的makefile如下:
all:test
test.o:test.c
gcc -g $^ -c -o $@
sestack.o:sestack.c
gcc -g $^ -c -o $@
test:test.o sestack.o
gcc -g $^ -o $@
2.退出gdb
使用quit or q来退出gdb
3.传参
有时候,我们需要通过命令行去传参数,可以使用set args 参数1 参数2 参数3 ...来给程序传参数。
4.查看代码
你只能查看当前文件的代码, 如果需要查看其他文件的代码,则需切换到其他的文件。使用list or l 来查看当前文件的代码,你可以通过set listsize 20 来修改你每次需要显示的行数为20。如下图:
当前我在test
接下来我们切换到sestack.c,你可以看到我使用了list 、 list 行号、 list 函数名、 list 文件名:行号。
5.设置或删除断点及相关操作
有两种断点,一种是常规断点,一种是条件断点。使用break 行号or b 行号 来设置断点。
或者是使用他们在一个函数处设置断点。
常规断点的使用,如下图所示:
条件断点的使用如下图所示:
在设置完断点后我们可以通过info b 或者 i b来查看断点的信息。
我们可以通过delete or del or d + 断点的编号来删除断点。或者d num1-num4
我们还可以通过disable(dis) 或者 enable(ena) 来设置断点的有效和无效。(观察Enb这一行)
6.继续运行
使用continue or c来继续的向下运行。
7.运行中打印某些值及其类型
使用print or p 来打印我们想打印的值。同时我们还可以设置我们打印时的输出格式。如下表所示:
我们可以使用ptype 来打印某个变量的类型。
8.自动的打印某些值和信息及其相关操作
我们使用display可以来展示我们经常需要打印的值。我们也可以通过info display来展示我们需要自动打印的信息。
我们可以通过undisplay 编号 或者delete display 编号来删除, 当然这里可以展示不打印使用disable 不打印, 使用enable 来打印:
9.单步调试
我们可以用step or s来进行单步调试(s可以进入到函数体的内部),值得注意的时当我们使用单步调试进入一个函数的时候,我们必须使用finish 来跳出函数。
如果通过 s 单步调试进入到函数内部,想要跳出这个函数体, 可以执行 finish 命令。如果想要跳出函数体必须要保证函数体内不能有有效断点,否则无法跳出(待实践)。
我们也可以使用next or n来向下运行,但是next不会进入函数体内。
如果我们想跳出某个循环体 ,我们可以使用until ,但是要满足一下的条件:
- 要跳出的循环体内部不能有有效的断点
- 必须要在循环体的开始 / 结束行执行该命令
10.设置变量的值
有时候我们需要设置某个变量的值,来查看程序的行为。我们可以使用set val 变量名=值来设置某个变量的值。
可以看到我把s指针设置为null后报错了。