第2章 调试前的必知必会
Hack #4 获取进程的Coredump
启用内核转储
ulimit -c unlimited //开启coredump,不限制coredump文件的大小。
ulimit -c 1073741824 //设置coredump文件的上限是1G
利用gdb调试Coredump文件:
gdb -c core_file_name ./exe_file
将Coredump文件放在固定的位置
默认是放在当前目录,Coredump保存位置的完整路径可以通过sysctl变量kernel.core_pattern设置。设置示例如下:
# cat /etc/sysctl.conf
kernel.core_pattern = /var/core/%t-%e-%p-%c.core
kernel.core_uses_pid = 0
#sysctl -p
就会将Coredump文件生成在/var/core下面。
上述core_pattern格式如下:
生成coredump的时刻-进程名-PID-内核Coredump最大大小.core
gdb的使用
设置断点
断点命令break可以简写为b。
break/b 断点
格式: 示例
break 函数名 b iseq_compile
break 行号 b 45
break 文件名 :行号 b compile.c:25
break 文件名 :函数名 b compile.c:get_name
break +偏移量 b +3 //现在暂停位置往后3行
break -偏移量 b -3
break *地址 b *0x08116fd6 //地址0x08116fd6设置断点
设置好的断点可以通过info break确认。
运行
用run命令开始运行。不加参数只执行run,就会执行到设置了断点的位置后暂停运行,可以简写为r。
显示栈帧
backtrace命令可以在遇到断点而暂停执行时显示栈帧。该命令简写为bt。此外,backtrace的别名还有where和info stack(简写为info s)。
backtrace //显示所有栈帧
backtrace N //只显示开头N个栈帧
backtrace -N //只显示最后N个栈帧
backtrace full
backtrace full N
backtrace full -N
不仅显示backtrace,还要显示局部变量。N与前述意思相同,表示开头N个(或最后N个)栈帧。
显示变量
print命令可以显示变量。print可以简写为p。
格式:
print 变量
显示寄存器
info registers可以显示寄存器,简写为info reg。
在寄存器名之前添加$,即可显示各个寄存器的内容。
p $eax
显示时可以使用以下格式,
p/格式 变量
显示寄存器可使用的格式
格式 说明
x 显示为十六进制数
d 显示为十进制数
u 显示为无符号十进制数
o 显示为八进制数
t 显示为二进制数,t的由来是two
a 地址
c 显示为字符(ASCII)
f 浮点小数
s 显示为字符串
(gdb) p/c $eax
$7 = 97 'a' //十进制数的97为ASCII字符的'a'。
单步执行
执行源码中一行的命令为next(简写为n)。执行时如果遇到函数调用,可能想执行到函数内部,此时可以使用step(简写为s)命令。
继续运行
调试时,可以使用continue(简写为c)命令继续运行程序。
监视点
大型软件或大量使用指针的程序中,很难弄清变量在什么地方被改变
第3章