获取Core时函数栈的方法

在Linux服务开发过程中,经常会遇到各种问题,其中一种快速高效解决问题的策略就是:当服务处理异常时,操作系统自动产生Core文件,通过GDB调试工具分析Core文件,还原异常发生时服务的函数栈调用层次,继而快速的分析出导致异常发生的逻辑代码。Core文件,本质就是服务发生异常时的内存映像,如果服务占用的内存空间非常大,尤其是在64位操作系统下,例如占用20G的内存,写入磁盘Core文件的耗时会比较久,或者服务频繁异常导致写入数量非常大的Core文件,占用非常大的磁盘空间。以上两种情况显然不适合产生Core文件,所以这里介绍一种获取Core发生的函数栈调用情况的方法。


主要原理为:注册段错误的信号处理函数,在信号处理函数中,通过backtrace来获取当前服务的函数栈调用情况。


示例代码如下(test_core.c):

#include 
#include 
#include 
#include 

void Dump()
{
        void    *DumpArray[25];
        int     Size =  backtrace(DumpArray, 25);
        char **symbols = backtrace_symbols(DumpArray, Size);
        for(int i = 0; i < Size; i++)
        {
                printf("i:%d %s\n",i, symbols[i]);
        }
}

void SEGVHandler(int)
{
   Dump();
   printf("Line:%s\n",__LINE__);
   abort();
}

int main(){

        signal(SIGSEGV,SEGVHandler);
        signal(SIGFPE,SEGVHandler);
        *(char *)1 =1 ;

        return 0;
}

编译选项为:  g++ -g -rdynamic  test_core.c (rdynamic选项的详解可以参见: http://lenky.info/archives/2013/01/13/2190)

执行结果为:

获取Core时函数栈的方法_第1张图片


观察执行结果可以发现,很遗憾打印出来的函数栈未能清楚的标记出现问题的代码的行号,但是我们观察到存在出现问题时的代码地址,为此我们可以通过一个命令将地址转换为出现问题的代码行号:

 addr2line 0x4009aa -e ./a.out -f   
main
/root/testbasic/test_core.c:27

至此,我们获取到出现问题时的函数代码行号。


你可能感兴趣的:(Linux,C/C++基础)