您当前的位置: 首页 >  c++

Linux小百科

暂无认证

  • 0浏览

    0关注

    1185博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

如何在系统崩溃时从C++中获取函数调用栈信息?

Linux小百科 发布时间:2021-04-25 23:42:45 ,浏览量:0

这篇文章主要讲述在 Linux 和 Windows 这 2 个平台上,如何用C++ 来捕获函数调用栈里的信息。

如何在系统崩溃时从C++中获取函数调用栈信息?如何在系统崩溃时从C++中获取函数调用栈信息?

一、前言

程序在执行过程中 crash 是非常严重的问题,一般都应该在测试阶段排除掉这些问题,但是总会有漏网之鱼被带到 release 阶段。

因此,程序的日志系统需要侦测这种情况,在代码崩溃的时候获取函数调用栈信息,为 debug 提供有效的信息。

这篇文章的理论知识很少,直接分享 2 段代码:在 Linux 和 Windows 这 2 个平台上,如何用C++ 来捕获函数调用栈里的信息。

二、Linux 平台

1. 注册异常信号的处理函数 需要处理哪些异常信号

#include  
#include  
#include  
 
const std::map Signals = { 
    {SIGINT, "SIGINT"},     
    {SIGABRT, "SIGABRT"},  
    {SIGFPE, "SIGFPE"},    
    {SIGILL, "SIGILL"},   
    {SIGSEGV, "SIGSEGV"} 
    // 可以添加其他信号 
}; 

注册信号处理函数

struct sigaction action; 
sigemptyset(&action.sa_mask); 
action.sa_sigaction = &sigHandler; 
action.sa_flags = SA_SIGINFO;  
 
 for (const auto &sigPair : Signals) 
 { 
    if (sigaction(sigPair.first, &action, NULL) < 0) 
        fprintf(stderr, "Error: sigaction failed! \n"); 
 } 

2. 捕获异常,获取函数调用栈信息

void sigHandler(int signum, siginfo_t *info, void *ctx) 
{ 
    const size_t dump_size = 50; 
    void *array[dump_size]; 
    int size = backtrace(array, dump_size); 
    char **symbols = backtrace_symbols(array, size); 
    std::ostringstream oss; 
 
    for (int i = 0; i < size; ++i) 
    { 
        char *mangleName = 0; 
        char *offsetBegin = 0; 
        char *offsetEnd = 0; 
 
        for (char *p = symbols[i]; *p; ++p) 
        { 
            if ('(' == *p) 
            {    
                 mangleName = p; 
            }    
            else if ('+' == *p) 
            { 
                offsetBegin = p; 
            } 
            else if (')' == *p) 
            { 
                offsetEnd = p; 
                break; 
            } 
        } 
 
        if (mangleName && offsetBegin && offsetEnd && mangleName < offsetBegin) 
        { 
            *mangleName++ = '\0'; 
            *offsetBegin++ = '\0'; 
            *offsetEnd++ = '\0'; 
             
            int status; 
            char *realName = abi::__cxa_demangle(mangleName, 0, 0, &status); 
            if (0 == status) 
                oss             
关注
打赏
1665632672
查看更多评论
立即登录/注册

微信扫码登录

0.0426s