GDB 调试工具高级用法
解决core核心文件转出问题
ulimit -c #查看core文件的生成开关,若为0则关闭
ulimit -c unlimited #打开开关,只在当前shell生效
sudo sh -c 'echo "./%e.core.%p" > /proc/sys/kernel/core_pattern' #在当前目录下生成core文件,临时生效
启动GDB
gdb ./process #直接调试目标程序
gdb ./process core #调试转储文件
gdb <program> <PID> #调试服务程序
开始调试
栈回溯显示我们是如何到达失败点的,通常足够帮助我们确定常见的问题。
bt (backtrace的简写)常常是我在 gdb 中使用的第一条命令
gdb$ bt #栈回溯,有core文件的情况下
disas main #反汇编main函数,或者其它出错函数
i r #(info registers 的简写)打印寄存器值
start #开始调试,在main函数的第一条语句停下来 ; 等同于 break main
查看源代码
- list :简记为 l ,其作用就是列出程序的源代码,默认每次显示10行。
- list 行号:将显示当前文件以“行号”为中心的前后10行代码,如:list 12
- list 函数名:将显示“函数名”所在函数的源代码,如:list main
- list :不带参数,将接着上一次 list 命令的,输出下边的内容
设置断点
break 是设置断点,可简写为b
b n #在第n行源码处设置断点
b fn1 if a>b #条件断点设置
b func #在func()函数入口点设置断点
delete 断点号n #删除第n个断点
disable 断点号n #暂停第n个断点
enable 断点号n #开启第n个断点
clear 行号n #清除第n行的断点
info b #(info breakpoints)显示当前程序的断点设置情况
delete breakpoints #清除所有断点
交互命令
r #运行此程序 c #继续运行 next #单步步过 step #单步步入 until #一直运行程序,直到退出循环体 until+行号 #运行至某行,不仅仅用来跳出循环 finish #运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息 call 函数(参数) #调用程序中可见的函数,并传递“参数”,如:call gdb_test(55) q #退出
打印表达式
print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式
比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用
print a #将显示整数 a 的值 print name #将显示字符串 name 的值 p main #打印main函数内容和地址 p buffer #打印buffer内容 p &buffer #打印buffer地址
info f #这句也可以查到main函数地址,最后一行
- display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
- watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
- whatis :查询变量或函数
- info function: 查询函数
- 扩展info locals: 显示当前堆栈页的所有变量
回退
gdb 有一个超棒的功能叫回退
这里我可以逐行或逐条指令的回退。它通过播放我们记录的寄存器状态来工作
reverse-stepi #回退一条指令
用GDB查看内存
格式: x /nfu <addr>
x 是 examine 的缩写
n 表示要显示的内存单元的个数
f 表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。
u 表示一个地址单元的长度
b 表示单字节
h 表示双字节
w 表示四字节
g 表示八字节
Format letters are
o(octal), x(hex), d(decimal), u(unsigneddecimal)
t(binary), f(float), a(address), i(instruction), c(char) ands(string)
Size letters are
b(byte), h(halfword), w(word), g(giant, 8bytes)
举例
x/3uh buf
表示从内存地址buf读取内容 h 表示以双字节为一个单位 3 表示三个单位 u 表示按十六进制显示
详细例子:
(gdb) list
#include<stdio.h> int main() { char a[1]; a[0]='a'; unsigned long long md5=14126471717450151013; printf("%d/n",a[0]); return 0; }
(gdb) break 10 Breakpoint 1 at 0x8048372: file test.c, line 10. (gdb) run Starting program:/data/compiler/g_platform/bradenwu/md5/test.out Breakpoint 1, main () at test.c:10 10 return 0; (gdb) x/8xb md5 0x8837f465: Cannot access memory at address 0x8837f465 (gdb) x/8xb &md5 0xbfffefa0: 0x65 0xf4 0x37 0x88 0x2e 0x4f 0x0b 0xc4