注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

^_^ china.ygw的博客

软件开发/c/c++/数据库/开源/linux/windows/安全/网络...

 
 
 

日志

 
 
 
 

linux环境实现C/C++程序崩溃退出时打印栈信息  

2013-07-17 23:03:03|  分类: c/c++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

        可以说,只要是开发人员,没有人愿意看到运行好好的程序突然莫名其妙发生崩溃。那种感觉,真的让人很绝望,很不爽!
        但是不爽归不爽,很多时候,程序还是时不时的崩溃,从而导致一系列不好的影响。出现这种情况时,往往很难查找到问题,除非再熟读整个代码N遍,并且各个环节的流程都是非常清楚。但是实际上,很困难。
        好在linux系统提供了信号注册函数和程序自身栈信息获取函数,可以在程序启动时注册可能导致程序崩溃的一系列信号,然后在对应的处理函数中获取自身栈信息,为问题的查找和解决提供了快速途径。
        首先,可以通过signal函数注册如下可能导致程序崩溃的信号:

signal(SIGPIPE, _signal_handler);    // SIGPIPE,管道破裂。
signal(SIGSEGV, _signal_handler);    // SIGSEGV,非法内存访问
signal(SIGFPE, _signal_handler);       // SIGFPE,数学相关的异常,如被0除,浮点溢出,等等
signal(SIGABRT, _signal_handler);     // SIGABRT,由调用abort函数产生,进程非正常退出


        当发现如上信号时,程序自动调用_signal_handler函数进行处理,该函数原型如下:

void _signal_handler(IN int signo)
{
    _backtrace(signo);
    exit(0);
}

        其中,signo就是对应的信号量。_backtrace就是实现程序自身栈信息的打印,主要处理如下:

    void *pTrace[256];
    char **ppszMsg = NULL;
    size_t uTraceSize = 0;
    static const char szSigMsg[][256] = {
        "Received SIGSEGV",
        "Received SIGPIPE",
        "Received SIGFPE",
        "Received SIGABRT"};

do {

        if (0 == (uTraceSize = backtrace(pTrace, sizeof(pTrace) / sizeof(void *)))) {
            break;
        }
        if (NULL == (ppszMsg = backtrace_symbols(pTrace, uTraceSize))) {
            break;
        }

        printf("%s. call stack:\n", szSigMsg[eid]);
        for (size_t i = 0; i < uTraceSize; ++i) {
              printf("%s\n", ppszMsg[i]);
        }
    } while (0);

    if (NULL != ppszMsg) {
        free(ppszMsg);
        ppszMsg = NULL;
    }

        注意,上述代码中的eid就是signo,当然,此处需要自定义的signo,以便与szSigMsg数组对应的信号描述对应上。
        另外,以上处理只支持C/C++程序。
  评论这张
 
阅读(3783)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018