linux下调试程序的神器
转储功能(core dump)
(1).开启转储功能
ulimit -c
//查看是否开启转储功能,返回不是0则已经开启,否则就是未开启。
ulimit -c unlimited //开启转储功能。
ulimit -c 1024 //设定转储文件的大小。
(2).设定转储文件生成地址
编辑/etc/sysctl.conf文件
kernel.core_pattern =
/var/core/%t-%e-%p.core
kernel.core_uses_pid = 1
文件保存,执行 sysctl
-p命令(需root权限)。注:此时执行一个会宕机的程序,会在/var/core/文件夹下面生成转储文件(如:1432378356-a.out-4821.core)。
core_pattern设定的就是文件保存目录和文件的名字格式。其中%t是转储时的unix时间戳,%e是当前执行的文件名,%p是crash进程的PID。
格式符号
%p 被转储进程的进程ID(PID)
%u 被转储进程的真是用户ID(UID)
%g 被转储进程的真是组(GID)
%s 引发转储的信号编号
%t 转储时间,unix时间戳(从1970年1月1日0时开始的秒数)
%h 主机名
%e 可执行文件的名称
%c 转储文件的大小上限(内核版本2.6.24+可用)
(3).转储文件的压缩
解决core文件过大问题,可在/etc/sysctl.conf文件的core_pattern中加入压缩脚本以及管道命令,可以对生成的转储文件进行压缩。在/etc/sysctl.conf文件中加入下列两行:
kernel.core_pattern = |
/usr/localsbin/zipsh %t %e %p
kernel.core_uses_pid = 1
保存文件,执行:sysctl -p命令。
编辑 /usr/local/sbin/zipsh文件
#!/bin/sh
exec gzip - >
/var/core/$1-$2-$3.core.gz
会在/var/core下生成压缩的转储文件。
调试基本信息查看(栈`变量`寄存器`内存)
(1).栈信息
简单处理:不管是操作转储文件还是用GDB设置断点进行调试,都可以输入(GDB)bt打印栈内容进行查看。一般的宕机BUG,看下宕机的位置,然后看下源代码基本就可以解决了。
复杂情况:简单的(GDB)bt还查不到问题,罗列常见一些对栈的操作:
(GDB) bt:显示所有栈帧。
(GDB) bt 10:显示前面10个栈帧。
(GDB) bt -10:显示后面10个栈帧。
(GDB) bt full:显示栈帧以及局部变量。
(GDB) bt full
10:显示前面10个栈帧以及局部变量。(没有源码情况下更useful)
(GDB) bt full -10:显示后面10个栈帧以及局部变量。
(GDB) frame
:进入指定的栈帧中,然后可以栈帧内容等信息。(源码放在core目录下关联查看更清晰)
(GDB) info frame
:可以查看指定栈帧的详细信息(函数参数、寄存器信息、先前栈的sp)。
(GDB) up:进入上层栈帧。
(GDB) down:进入下层栈帧。
(2).变量:调试BUG过程中查看变量
(GDB) p
(3).寄存器:调试查看到当前正在执行的指令的地址等。
(GDB) info reg:显示所有寄存器。可以简写为:i r。
查看具体的寄存器:i $ebx
(GDB) p $eax:显示eax寄存器内容。
(GDB) p/c
$eax:用字符显示eax寄存器内容,反斜杠后面的是显示格式,可使用的格式见下表:该表在显示内存内容的x命令中也是通用的。
格式 说明
x 显示为十六进制数
d 显示为十进制数
u 显示为无符号十进制数
o 显示为八进制数
t 显示为二进制数
a 显示为地址
c 显示为字符(ASCII)
f 显示为浮点小数
s 显示为字符串
i 显示为机器语言(仅显示内存x命令)
(4).内存:可以查看具体内存地址中的内容,如:目前执行的汇编指令,以及栈中内容等。
(GDB) x
$pc:显示程序指针指向位置的内容。
(GDB) x/i
$pc:显示程序当前位置的汇编指令。
(GDB) x/10i $pc:显示程序当前位置开始往后的10条汇编指令。
(GDB) disassem $pc:反汇编当前函数。简写为:disas
$pc。