GDB调试
加入调试选项:gcc main.c -o main -Wall -g
启动调试器:gdb main
(--silent
静默模式)
GDB常用的调试指令表:
调试指令 | 作用 |
---|---|
break xxx | 在源代码指定的某一行设置断点,其中 xxx 用于指定具体打断点的位置。 |
run | 执行被调试的程序,会自动在第一个断点处暂停执行,后面可以加argv参数 |
continue | 当程序在某一断点处停止运行后,使用该指令可以继续执行,直至遇到下一个断点或者程序结束。 |
next | 执行下一条语句,不会进入函数调用 |
step | 执行下一条语句,会进入函数调用 |
print xxx | 打印指定变量的值,其中 xxx 指的就是某一变量名。 |
list | 显示源程序代码的内容,包括各行代码所在的行号。 |
quit | 终止调试 |
backtrace | 查看函数调用信息(堆栈) |
frame | 查看栈帧 |
display | 跟踪查看某个变量 |
info breakpoints | 查看所有断点 |
break
以指令地址作为断点:
b *0x400f0c
layout
layout src
显示源代码
layout asm
显示汇编代码。在汇编代码下执行单条指令:si
layout split
显示源代码和汇编窗口
layout regs
显示源代码/汇编和寄存器窗口
info
info frame
显示栈帧, abbreviation: i f
info register
显示寄存器, abbreviation: i reg
info breakpoint
显示断点信息。abbreviation: i break
delete
删除断点:delete 1
, abbreviation: d 1
finish
结束当前函数调用,返回函数调用点
watch
监控某个变量或者表达式的值,通过值的变化情况判断程序的执行过程是否存在Bug
syntax: watch var
例如上面的程序,通过wa $rax
,每当rax中被写入一次随机值时,都会触发一次中断
x
x为examine的缩写,用于查看指定内存单元或寄存器的数据
x/<n/f/u> <addr>
n:是正整数,表示需要显示的内存单元的个数,即从当前地址向后显示n个内存单元的内容,
一个内存单元的大小由第三个参数u定义。
f:表示addr指向的内存内容的输出格式,s对应输出字符串,此处需特别注意输出整型数据的格式:
x 按十六进制格式显示变量.
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
u:就是指以多少个字节作为一个内存单元-unit,默认为4。u还可以用被一些字符表示:
如b=1 byte, h=2 bytes,w=4 bytes,g=8 bytes.
<addr>:表示内存地址。
查看 %rsi
指向的内存的32个字符数据:
(gdb) x/32c $rsi
0x402400: 66 'B' 111 'o' 114 'r' 100 'd' 101 'e' 114 'r' 32 ' ' 114 'r'
0x402408: 101 'e' 108 'l' 97 'a' 116 't' 105 'i' 111 'o' 110 'n' 115 's'
0x402410: 32 ' ' 119 'w' 105 'i' 116 't' 104 'h' 32 ' ' 67 'C' 97 'a'
0x402418: 110 'n' 97 'a' 100 'd' 97 'a' 32 ' ' 104 'h' 97 'a' 118 'v'
查看和修改某一寄存器的值
(gdb) i registers eax //abbreviation: i reg eax
eax 0xf7dd9f60 -136470688
(gdb) p $eax
$1 = -136470688
(gdb) set var $eax=6
将结果输出重定向到文件
(gdb) set logging file <file_name>
(gdb) set logging enabled on
(gdb) x/32c $rsi
(gdb) set logging enabled off
或者:
gdb | tee log_file
指定被调试程序的参数
(gdb) run args