gdb
很好用.
以下是一些常见的生成调试文件的方式:
g++
/gcc
/clang
:编译时增加-g
选项即可。cmake
:编译时输入cmake -DCMAKE_BUILD_TYPE=Debug .
,这一步指定了构建类型为调试类型,实质上改变的是 build 文件结构。makefile
:CXXFLAGS += -g
。
使用gdb
:#
有了生成的调试文件,我们就可以使用 gdb
对我们的文件进行调试。这里先对 gdb
的基本运行方式做简单的介绍:
gdb
是一个调试工具(CI),功能很强大,可以实现各种各样的调试,并且允许自己编写简单的调试脚本。一般安装了 gcc
都会自带一个 gdb
,和 gcc
处在同一个 bin 文件夹下。
在终端中输入 gdb
以进入 gdb
调试工具内部。
要想使用 gdb
对调试文件进行调试,可以有以下方式:
- 在打开
gdb
的时候,将调试文件路径作为参数传给gdb
,此时会自动将调试文件路径添加到gdb
的目标文件表中。 - 打开
gdb
之后,可以使用file
命令添加待测试文件,这里可以使用相对路径或者是绝对路径,相对路径是相对于你在什么位置打开的gdb
而言的,例如你在D:\
中打开了gdb
,那么.\vscode\
就是D:\vscode\
。- 注意,多次使用
file
,会将之前的指定文件覆盖为新的指定文件。
- 注意,多次使用
以下是一些常见的gdb命令(“()”内为缩写):
run
:运行当前已绑定的目标文件。break
(b
)Line
:在第Line
行添加一个断点。相应的,使用clear
line
删除掉第line
行的断点;- 还可以使用
break
function_name
来为函数添加断点,这样在该函数被调用的时候可以暂停。
- 还可以使用
step
(s
):单步调试,并且进入函数等。next
(n
):一次性执行到下一行代码。continue
:执行到下一次断点触发。exit
:退出gdb
。kill
:终止当前正在调试的程序。backtrace
(bt
):显示调用栈;info
:显示信息,根据参数不同显示不同信息info locals
:显示当前函数的局部变量和值;info args
:显示当前函数的参数及其值;info functions
:列出当前文件中定义的所有函数;
list
(l
):显示当前执行点周围的源代码(上下几行);
除了以上简单命令,gdb为我们还提供了其他很有用的命令,推荐大家阅读文档进行学习。
创建自己的命令:#
gdb允许你使用简单的脚本语言将一些重复的调试操作抽象化成为本地命令,若这些命令是在gdb运行时编写的,那么他们在gdb退出后即无法使用,需要重新编写,以下是一个简单的例子:
1 | (gdb) define repeat |
这里使用 define
命令抽象化了一个允许任意次数 continue
的操作 repeat
。可以看到,在 gdb
脚本中,set
用来声明变量,$
开头表示这是一个变量,在使用这个变量的时候也要这样使用,arg0
是一个保留的变量名称,这个变量是在调用 repeat
时给入的,例如以下调用:
1 | (gdb) repeat 3 |
将会设置 arg0
为 3 。
如果 define
的过程中打错了字,只能重复 end
然后重新输入。不过我们有另外一个更重要的解决方案,那就是,**gdb
可以运行已经编写好的脚本文件!**
这是一个非常强大的功能,很多重复性的工作不再需要人来完成,而是交由机器代行。这就是生产力的飞跃, 我们接下来就来看看具体的操作。
- 脚本文件的创建:这很简单,只需要将后缀保留为
.gdb
即可。我们在其中可以编写任意脚本。 - 脚本文件的运行:未启动
gdb
时,使用gdb -x script.gdb
运行脚本文件(脚本文件内部可以添加一行file exec.exe
来加载一个可执行文件作为调试对象);启动gdb
时,使用source path_to_your_script.gdb
来运行脚本文件。这里的参数都是文件路径。