本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
gdb调试不同于界面化的调试,虽然命令非常简单,但上手比较有难度。对于从没使用过gdb的人来说,可以考虑装一个Python插件(gef),当然也可以不装,只是为了方便显示调试信息而已。会使用gdb的可以直接跳到后面阅读(附有gdb操作命令)
插件安装步骤
-
以普通用户身份, 进入用户目录 cd ~
-
安装gef插件(必须gdb7.7以上)
wget -q -O- github.com/hugsy/gef/r… | sh
1.编译程序
-
将程序编译为可以被gdb调试的版本(-g 为程序加上符号表) gcc -g program.c -o program
-
查看符号表
readelf -s program
2.启动GDB
-
gdb有多种启动方式
1.本地普通启动 gdb <program> 2.attach到某个进程启动 gdb attach <PID> 3.使用本地core文件启动 gdb <program> core 4.远程启动 gdb server 0.0.0.0:1234 /path/to/file
3.基础命令
| 命令简写 | 命令全拼 | 含义 |
|---|---|---|
| l | list | 显示程序 |
| b | break | 设置断点 |
| c | continue | 到下一个断点 |
| n | next | 下一行(不进入函数内部) |
| s | step | 下一行(进入函数内部) |
| u | until | 完成当前循环体 |
| f | finish | 完成当前函数 |
| p/f | 打印 | |
| x/nfu | examine | 查看内存 |
| bt | backtrace | 函数调用堆栈 |
| - | set args | 设置函数参数 |
| - | set listsize | 设置每次显示行数 |
| i b | info breakpoints | 显示断点信息 |
| i f | info frame | 显示栈内信息 |
| i r | info registers | 显示寄存器信息 |
| i lo | info locals | 显示局部变量信息 |
| q | quit | 退出 |
| - | shell | 使用shell命令 |
命令使用技巧
-
设置函数参数
set args 20 -
设置GDB信息显示窗口的行数
set listsize 20 -
条件断点的设置
b 20 if (i>5) -
修改内存
p i=20 -
打印具体长度的值
p iNumber@20 -
操作断点
disable 1 enable 1 delete 1 -
设置观察点-观察的内存发生改变(硬件断点)
watch 0x0000 -
设置捕捉点
catch event event可以是以下: 1.throw 抛出一个C++的异常 catch throw 2.catch 捕捉一个C++的异常 catch catch 3.exec 调用系统调用exec时停止 catch exec 4.fork 调用系统调用fork时停止 catch fork 5.load/load libname 载入动态链接库时 catch load / catch load libname 6.unload -
x命令的参数(查看内存)
x/n,f,u n 是一个正整数,表示显示内存的长度 f 表示显示的格式(与print一致) u 表示从当前地址往后请求的字节数(GDB默认为4byte)
源代码中搜索
-
全部搜索
reverse-search <regexp> -
向前搜索
forward-search <regexp> -
搜索(内存搜索)
search <regexp>