注意: 这里是讲gdb的高级技巧。如果没有接触过gdb,请自行搜索相关教程。
gdb是一个功能极其强大的命令行调试器。其实,除了我们常用的 file b s n q disp p
等命令,也有很多高级技巧。虽然有的功能是为系统级调试提供的,但还是有方便之处。
接下来,我将介绍一些高级技巧,希望可以帮助大家。
(温馨提醒:多用help命令!请提前用 -g
参数编译)
backtrace(简写为bt)可以让你查看栈帧信息。这对调试递归的函数很有帮助。
配套命令:
up/down [num]
往栈顶/栈底移动num帧。num默认为1。
frame [num]
切换到第num帧。frame简写为f。
commands(简写为comm)可以在触发某个(或多个)断点的时候运行指定gdb命令。
用法:commands [断点编号1] [断点编号2] ...
之后,它会让你逐行输入要指定的gdb命令。
效果吗...在到你指定的断点时,他都会逐行运行你之前输入的命令。
顺便提一句,怎么查看断点编号?运行 info b
即可。
输出类似这样:(num是编号)
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000000129e in pre() at UVA10140 Prime Distance.cpp:12
2 breakpoint keep y 0x00000000000012c7 in pre() at UVA10140 Prime Distance.cpp:13
3 breakpoint keep y 0x00000000000012de in pre() at UVA10140 Prime Distance.cpp:14
用法:ignore [断点编号] [num]
。ignore可缩写为ig。
效果:在前num次触发指定断点时都不停止(即到了第num+1次触发断点才停下)
这在调一些循环结构的代码时比较有用。
用法:condition [断点编号] [条件]
。condition可缩写为cond。
效果:触发断点时,只有指定的条件为真时才停下。
什么?断点还有类型?这里介绍下:
rbreak [正则表达式]
。说明一下rbreak。举个例子,我程序里有两个函数,dfs1与dfs2。如果我运行 rbreak dfs*
,由于dfs1与dfs2均匹配,所以这两个函数均会被加上断点。
用法:print/[format] [变量1] [变量2] ...
当然,如果是display命令,则要换成display/[format] [变量1] [变量2] ...
其中,format是一个小写字母,指定打印变量值的格式。
format字母 | 对应格式 |
---|---|
x | 按十六进制格式显示变量 |
d | 按十进制格式显示变量 |
u | 按十六进制格式显示无符号整型 |
o | 按八进制格式显示变量 |
t | 按二进制格式显示变量 |
a | 按十六进制格式显示变量 |
c | 按字符格式显示变量 |
f | 按浮点数格式显示变量 |
比如说,调试状压DP的程序时,就可以 p/t [变量名]
来以二进制形式查看变量了。disp同理。
其实断点是可以保存的!比如说,我临时要重启一下,又不想丢失当前调试的断点信息。那么,我们可以将当前的断点信息保存到一个文件里,到时候再导入。
用法:save breakpoints [文件名]
效果:将当前所有的断点信息保存到一个指定的文件里。
有人有疑问了,怎么导入断点信息呢?那就是source命令!
用法:source [文件名]
效果:从指定的文件里导入断点信息。
用法:call [调用语句]
效果:调用指定函数。
比如说,我的程序有一个min函数,我就可以通过 call min(a,b)
来获取变量a、b的最小值了。
用法:无参数。
效果:继续运行,直到当前函数返回。
其实,断点还有一种特殊的类型——watchpoint。(简写为wa——似乎不太吉祥)
用法:watch/rwatch/awatch [变量名]
作用:监视指定变量。
有时候,我们要复现某个bug,这个时候,我们可以创建一个快照,即checkpoint。
命令:checkpoint
(可简写为ch)
用法:无参数。
效果:创建一个快照,包含当前调试的所有信息。同时会输出这个checkpoint的信息,就像这样:
checkpoint 1: fork returned pid 25776.
其中,数字1便是这个checkpoint的编号。
那么,如何回滚到以前的快照呢?那就是restart命令啦!
用法:restart [checkpoint编号]
效果:回退到指定checkpoint的快照。
用法:jump [num]
作用:强制使跳转至第num行。(中间的行都跳过了)
注意,这个不能跨函数跳转,否则会出错。
用法:return [argu]
作用:强制使当前函数退出,并返回argu值。(如果该函数本来就没有返回值,则argu可以省略)
蒟蒻写博客不易,恳请大佬点个赞!
原文:https://www.cnblogs.com/acceptedzhs/p/12562880.html