GDB安装插件
下载链接: git clone https://github.com/gatieme/GdbPlugins.git ~/GdbPlugins
设置方法如下:
echo "source ~/GdbPlugins/peda/peda.py" > ~/.gdbinit
echo "source ~/GdbPlugins/gef/gef.py" > ~/.gdbinit
echo "source ~/GdbPlugins/gdbinit/gdbinit" > ~/.gdbinit
根据个人喜好选择自己喜欢的调试脚本
GDB的命令
启动方法
- 本地普通启动 gdb <program>
- 本地段错误文件启动 gdb <program> core
- attach方式启动 gdb <program> <PID>
- 远程启动 gdbserver 0.0.0.0:1234 /path/to/file
Linux程序发布流程
- 确定程序是否存在符号表
readelf -s test - 生成符号表
objcopy --only-keep-debug test test.symbol - 生成发布程序
objcopy --strip-debug test test-release - 使用符号表进行程序debug
gdb -q --symbol=test.symbol --exec=test-release
调试
基本命令
-
展示代码
list [文件名]:行数
-
设置代码区块长度
set listsize 长度
-
设置参数
set args 参数...
-
执行下一步
进入函数s(step) 不进入函数n(next) 跳出循环u(until) 跳到下一个断点c(continue) 快速结束函数f(finish)
-
查看变量类型
pt 变量名
-
查看变量的值
单个输出变量值:print 变量名 输出局部所有变量:info local print 输出格式 x 按十六进制格式显示变量。 d 按十进制格式显示变量。 u 按十六进制格式显示无符号整型。 o 按八进制格式显示变量。 t 按二进制格式显示变量。 a 按十六进制格式显示变量。p/a i c 按字符格式显示变量。p/c i f 按浮点数格式显示变量。 查看数组 p *array@len # 人为数组,查看内存中的连续对象 如果是静态数组,直接 p array
-
查看内存
x 地址 (例如:x &i) 输出十进制:x/d 地址 x命令的语法如下所示 x/n、f、u是可选的参数 x/s 输出字符串 n 是一个正整数,表示显示内存的长度,是从当前地址向后显示几个地址的内容。 f 表示显示的格式,跟print 的格式参数相同 u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。 n/f/u三个参数可以一起使用 例如: x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示三个单位,u表示按十六进制显示。
-
查看函数调用栈
bt
-
调核文件的时候,调栈
frame [num]
-
输出栈信息
info frame
-
使用shell命令
shell + 命令
-
修改变量值
print i=10
-
搜索源代码
局部搜索: 向后搜索:search <regexp> 向前搜素:forward-search <regexp> 全文搜索: reverse-search <regexp> 其中,<regexp>就是正则表达式,也可以是一个字符串的匹配模式
暂停调试
-
查看断点信息
info breakpoints
-
打断点
设置普通断点: break [文件名]:行数 或者 break 函数名 或者 break 地址 设置条件断点: break 行数 if 条件
-
设定观察点:在内存出现变动的是后,马上断下来
当值被写的时候: watch 变量 或者 watch 函数::变量 当值被读的时候: rwatch 变量 或者 rwatch 函数::变量 当值被写或被读的时候: awatch 变量 或者 awatch 函数::变量
-
设定捕捉点
catch <event> 当event发生时,停住程序。event可以是下面的内容: 1、throw 一个C++抛出的异常。(throw为关键字) 2、catch 一个C++捕捉到的异常。(catch为关键字) 3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用) 4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用) 5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用) 6、load 或 load <libname> 载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用) 7、unload 或 unload <libname> 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用) tcatch <event> 只设置一次捕捉点,当程序停住以后,应点被自动删除
-
断点失效
失效:disable 断点号 开启:enable 断点号 删除:delete 断点号
-
在断点处自动化执行命令
commands 断点号 . . . end 输入end结束输入命令
-
自动显示变量值
添加自动变量: display expr display /fmt expr display /fmt addr 例:读取数组 display /x *array@4 删除: undisplay nums
多进程调试
-
gdb跟踪模式
查看: show follow-fork-mode 设置: set follow-fork-mode [parent|child]
-
多线程执行模式
查看: show detach-on-fork 设置: set detach-on-fork [on|off] on: 只调试父进程或子进程的其中一个(根据follow-fork-mode来决定),这是默认的模式。 off: 父子进程都在gdb的控制之下,其中一个进程正常调试(根据follow-fork-mode来决定),另一个进程会被设置为暂停状态。
-
进入某进程
attach <PID>
-
查看当前运行在那个进程上
info inferiors
-
切换进程
inferior <进程在当前gdb的编号>
-
清除进程
remove-inferiors 编号
detach inferiors 编号
kill inferiors 编号
-
新添加进程(复制或者执行新程序)
add-inferiors [-copies n] [-exec executable]
多线程调试
-
查看线程
info threads
-
切换线程
thread <ID>
-
对线程执行的地方打断点
break file.c:<rownum> thread <all|num>
-
设置线程调试执行模式
查看: show scheduler-locking 设置: set scheduler-locking [off|on|step] off 不锁定任何线程,所有线程都执行,默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,只有当前线程会执行。