1、开始调试
- 调试尚未执行的可执行文件program
gdb <program>
设置断点到main
R
- 调试正在运行的程序
两种方法:
- 在UNIX下用ps查看正在运行的程序的PID(进程ID),然后用gdb <program> PID格式挂接正在运行的程序。
- 先用gdb <program>关联上源代码,并进行gdb,在gdb中用attach命令来挂接进程的PID。并用detach来取消挂接的进程。
来自 <https://markrepo.github.io/tools/2018/06/22/gdb/>
2、设置断点
B 函数名
B *地址
删除断点delete
用法:delete [breakpoints num] [range...]
delete可删除单个断点,也可删除一个断点的集合,这个集合用连续的断点号来描述。
例如:
delete 5
delete 1-10
文件行号打断点:b [file:]linenum
e.g. b main.c:7
3、调试汇编
x/ni $pc 显示当前pc,向下n行
Disassemble 函数名,显示该函数的反汇编
Stepi(si):单步指令运行
4、查看内存
gdb中使用“x”命令来打印内存的值,格式为“x/nfu addr”。含义为以f格式打印从addr开始的n个长度单元为u的内存值。参数具体含义如下:
a)n:输出单元的个数。
b)f:是输出格式。比如x是以16进制形式输出,o是以8进制形式输出,等等。
c)u:标明一个单元的长度。b是一个byte,h是两个byte(halfword),w是四个byte(word),g是八个byte(giant word)。
以上面程序为例:
(1) 以16进制格式打印数组前a16个byte的值:
(gdb) x/16xb a
0x7fffffffe4a0: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
0x7fffffffe4a8: 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
5、修改变量
P 变量名=xxx
Set var 变量名=xxx var修饰符告诉gdb这是代码中的符号,不是gdb中的
6、修改寄存器
Set &寄存器名 = xxx
7、查看变量、寄存器
查看变量:p/x 变量名,查看数组p/x 数组名 / p/x *指针@len
查看寄存器:查看单个寄存器p/x $<寄存器名>、 查看所有寄存器info registers
8、自动显示
每单步一次,就自动显示设置好的内容
Display[/x、i、s……] 变量、寄存器等。(i表示显示输出机器指令码,也就是反汇编)
Info display 显示所有已设置的需要自动显示的内容
Delete display 删除设置的自动显示
Disable/enable display 不删除,只是不显示
9、设置gdb变量
Set $变量名 = 初始值
接着可以使用该变量进行运算,并用在表达式种
10、强制条转、调用 jump 地址、jump 文件行号;call <函数名>
相关链接:
《100个gdb小技巧》
来自 <https://wizardforcel.gitbooks.io/100-gdb-tips/content/index.html>
Use of Debuggers A Brief Introduction to GDB, including its use within emacs
来自 <http://faculty.kutztown.edu/spiegel/Debugging/DebugPrimer.htm>