GDB使用技巧
一、常用GDB指令
l 或 list 或 l 行号 可以显示代码
回车表示重复上一次命令
break 或 b 表示设置断点 后跟行号 或 函数入口名
info break 查看断点信息
run 或 r 运行程序
next 或 n 单条语句执行
continue 或 c 继续运行程序
print 或 p 表示打印指定变量值 后跟变量
bt 查看函数堆栈
finish 退出函数
shell 命令 后跟指令执行shell
make 命令 等同于 shell make 参数
q 退出gdb
二、启动GDB方法
1、gdb {程序名}
2、gdb {程序名} core
3、gdb {程序名} {PID}
三、运行时配置
1、set args [] 来指定运行时参数
2、path [] 可设置运行时参数
3、show path 查看运行路径
4、set/show env[ironment] varname[=] 查看或设置变量的值
5、cd和pwd 同shell
6、可以使用 > 重定向输出
四、断点的使用
1、可以直接跟[文件名] [函数名/行数] if [条件]
2、直接break 表示停在下一行
3、break +/-行数 可以表示当前行号与偏移
4、Break *地址
5、info [break]points [n] n表示断点号
五、观察点的使用
1、watch <exp> 表达式有变化时,停住程序。
2、rwatch <exp> 表达式被读时,停住程序。
3、awatch <exp> 表达式被读写时,停住程序。
4、info watch[points] 查看所有观察点
六、捕捉点的使用
1、catch <throw|catch|exec|fork|vfork|load|unload> 发生事件时,停住程序。
2、tcatch <throw|catch|exec|fork|vfork|load|unload> 只设置一次捕捉点,程序结束后消失。
七、维护停止点
1、直接使用clear,并非像手册中的,清除所有停止点,而是清除当前行的停止点。
2、clear 跟行号、函数名等,delete,enable,disenable是跟断点号。
3、condition <断点号> <停止条件表达式> 修改指定断点的中断条件。
4、ignore <断点号> <忽略中断次数> 设置忽略若干次中断后停止。
5、commands [断点号] 如果无断点号,则寻找上一个断点位置,清除也是这个命令。
command_Lists 清除则留空
end commands前可以跟break设置断点
八、恢复及单步调试
1、continue/c/fg [继续断点数] 继续程序执行并忽略后面若干个断点
2、set step-mode on 打开这个模式,可以在程序没有debug信息时,单步继续。
3、step/next [指令数] 单步跟踪,经过若干个代码。
4、finish 执行完当前函数,并返回函数信息(行号,文件名,函数名,返回值),无法返回main函数。
5、until 或 u 类似在循环中使用continue,这点和完全手册上说的不太一样,我实验是无法跳出循环,和c一样效果,继续循环。
6、stepi/si nexti/ni 单步执行一条机械指令。单步时一般使用display/i $pc ,其中/i是显示格式,i是汇编,$pc是gdb内部变量,表示程序机械码的地址,类似寄存器SI。设置display后,可以用info display来查看,一样可以d display 编号 来删除。
九、信号处理
1、产生信号:signal <信号名>
2、捕获信号:handle <信号名> <处理方式|[no]stop|[no]print|[no]pass|[no]ignore> 也可以使用info查询
十、线程与栈信息
1、break <代码行号> thread <线程号> if [条件] 其中线程号使用info threads查询
2、backtrace、b [n]打印当前函数栈的所有信息,n表示上/下n层栈信息。如果当前栈不是想要查看的,可以使用frame / f [栈层编号]来切换。
3、使用info frame/f 来查询栈的详细信息。使用info args打印当前函数的参数信息,使用info locals打印局部变量,使用info catch打印出捕获的异常。
十一、源代码信息
1、list <funcname|linenum|+-line|+|,last|first,last> 可以查看指定项源代码信息
2、set/show listsize [size_t] 设置或显示 一次显示代码的行数
3、搜索代码其中:forward-search/search <正则表达式>是沿代码往下搜索,reverse-search是沿代码往上搜索。此与手册中说明不符合。
4、关于源文件目录,可以使用show directories来查看,其中包括2个GDB变量:$cdir与$cwd,使用p打印这两个变量值都为void,此处有疑问。清楚目录直接使用directory,设置目录使用dir/directory <源码目录>
5、disassemble <函数名>用于查看指定函数的汇编。
6、info line <函数|行号> 用来查询指定行或函数在运行时的内存地址start、end。
十二、查看运行时数据
1、[p]rint /<输出格式> <exp> 其中exp为表达式:(1)文件|函数::变量名 (2)*首地址@长度 (3){类型名} <内存地址|&变量> 可以查看不同类型解析出来的内容
2、可以通过 show/set print [array|elements|null-stop|pretty|union|object|static-members|vtbl] <on/off>
3、使用$1、2、3、4……可以表示历史记录的变量和内容。
4、环境变量一定要用set $[变量名]=<值>来操作。不可以直接等于。第一次set相当于定义变量。值可以是程序中变量、地址、结构体等。
5、show convenience 表示查看所有环境变量的值。
6、info [all-]registers <regName> 可以查看所有或指定的寄存器名称。print $<寄存器> 也可以访问指定寄存器名称。
7、print <变量名>=<变量值> 可以给变量赋值。同样可以用set [var] <变量名>=<变量值>。同样的效果,为了和系统变量区分,最好加var表示你修改的是程序中的变量。
十三、流程控制
1、jump <文件名:行号|+行号|地址> jump不会修改程序栈中信息,因此跳转出函数时可能报错。不过跳转时会给出提示,是否跨出跳转。
2、可以使用set $pc=<跳转地址> 来控制流程跳转到指定地址。
3、return <expr> 取消该函数的执行并返回expr的值作为返回值。
4、使用call <函数名>来调用函数。也可以使用print通过求表达式的值来求函数的值,并储存在$n变量中去。
十四、杂项
1、set/show language设置/显示当前的语言 set language会显示支持的语言集合。
2、info frame 第三行 也可以显示该层的语言
3、info source 显示当前文档的语言