本文由上面博客地址各栏目总结而得,在这里感谢一下博主。

core dump: 对应程序由于各种异常或者bug导致在运行过程中,并且在满足一定条件下产生一个叫做core的文件。通常情况下,core文件会包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等。许多程序出错的时候会产生一个core文件,通过工具分析这个文件,我们可以定位到程序异常退出的时候对应的堆栈调用等信息。

说明:本文中,linux是安装在自己的虚拟机上,为了方便,直接使用的root权限,仅为示意。

在这里先介绍一个linux命令ulimit,就是user limit,意思是与用户相关的一些限制参数。ulimit -a显示各种限制参数

core dump调试_core dump调试

ulimit -c unlimited 用来设置生成core文件

core dump调试_core dump调试_02

调试程序代码:


#include<stdio.h>

int main()
{
int *p=NULL;
*p=0;

printf("bad\n");
return 0;
}


上述代码一看就有错误,但是在大型项目中,用肉眼就很难看了。下面说明一下linux下调试core dump方法。

先介绍2个linux命令。dmesg,一种程序,用于检测和控制内核缓冲。程序用来帮助用户了解系统的启动信息,可以获得出错堆栈地址。

addr2line,是一个可以将指令的地址和可执行映像转换成文件名,函数名或源代码的工具。这种功能将跟踪地址转换成更有意义的内容来说很有用。在调用addr2line工具时,要使用 -e选项来指定可执行映像,使用-f选项可以告诉工具输出函数名。


dmesg+addr2line调试:

core dump调试_core dump调试_03

dmesg用来找出错堆栈地址,addr2line将地址解析为代码行。上面显示代码出错行为第6行。


gdb调试:

core dump调试_core dump调试_04

gdb调试过程中,输入r,bt。r是运行a.out文件,bt查看堆栈情况。其实这里有一个小的不足,就是执行r后相当于重新运行了a.out文件。然而在实际开发中,有很多问题都是概率发生的,所以此方法不太实用。那gdb就不行了吗?答案时候NO,接着看。

上面的实验过程中,ulimit -c unlimied 在转换权限的时候忘用了,所以没有生成core.xxx文件,在用了之后会生成。

core dump调试_core dump调试_05

看,生成了core.xxxx文件。现在我们用gdb直接调试core.xxx文件,这样就无需重新run了,直接查看bt.。

输入:gdb a.out core.3945

core dump调试_core dump调试_06


strace+addr2line调试:

strace:用来跟踪进程执行时的系统调用和所接收的信号。实际上strace是一个集诊断,调试,统计与一体的工具。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。

strace -i可以定位core地址。

执行:strace -i a.out

core dump调试_core dump调试_07

然后接着执行addr2line命令,找出出错行。


总结:本人总结了3种core调试方法和一些linux下的调试命令。