C ++获取“ Segmentation Fault” Linux x64的文件名和行号

|                                                                                                                       
已邀请:
汤米(Tommie)因解决这个问题而值得赞扬。 通过使用来自
<execinfo.h>
的某种标准standard0ѭ实用程序,我从GDB分离了他的答案。
static void dumpstack(void){
    static void *backbuf[ 50 ];
    int levels;

    levels = backtrace( backbuf, 50 );
    backtrace_symbols_fd( backbuf, levels, STDERR_FILENO );

    return;
}
您可以尝试打开文件并写入而不是
STDERR_FILENO
,但是在崩溃的过程中,我会避​​免如此繁重的操作。 在我的系统上,输出如下所示:
Shadow:code dkrauss$ ./dumpy 
0   dumpy                               0x0000000100000d81 dumpstack + 25
1   dumpy                               0x0000000100000d18 signal_handler + 47
2   libSystem.B.dylib                   0x00007fff86b1766a _sigtramp + 26
3   ???                                 0x0000000000000000 0x0 + 0
4   dumpy                               0x0000000100000a18 start + 52
FATAL: Segmentation Fault
因此,它不提供文件名+行号,但提供函数名+代码偏移量,您可以轻松地对其进行翻译。     
嗯...您可以尝试通过这种方式...
struct sigaction g_sigact;

void panic(const char *fmt, ...){
    char buf[PANICBUF_LEN];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, \"%s\\n\", buf);
    exit(-1);
}
void init_signals(void){
    g_sigact.sa_handler = signal_handler;
    sigemptyset(&g_sigact.sa_mask);
    g_sigact.sa_flags = 0;
    sigaction(SIGINT, &g_sigact, (struct sigaction *)NULL);

    sigaddset(&g_sigact.sa_mask, SIGSEGV);
    sigaction(SIGSEGV, &g_sigact, (struct sigaction *)NULL);

    sigaddset(&g_sigact.sa_mask, SIGBUS);
    sigaction(SIGBUS, &g_sigact, (struct sigaction *)NULL);

    sigaddset(&g_sigact.sa_mask, SIGQUIT);
    sigaction(SIGQUIT, &g_sigact, (struct sigaction *)NULL);

    sigaddset(&g_sigact.sa_mask, SIGHUP);
    sigaction(SIGHUP, &g_sigact, (struct sigaction *)NULL);

    sigaddset(&g_sigact.sa_mask, SIGKILL);
    sigaction(SIGKILL, &g_sigact, (struct sigaction *)NULL);
}

static void signal_handler(int sig){
    if (sig == SIGHUP) g_keepRunning = 0;
    if (sig == SIGSEGV || sig == SIGBUS){
        dumpstack();
        panic(\"FATAL: %s Fault\\n\", (sig == SIGSEGV) ? \"Segmentation\" : ((sig == SIGBUS) ? \"Bus\" : \"Unknown\"));
    }
    if ((sig == SIGQUIT || (sig == SIGKILL) || (sig == SIGINT)) ;
}

static void dumpstack(void){
    /* Got this routine from http://www.whitefang.com/unix/faq_toc.html
    ** Section 6.5. Modified to redirect to file to prevent clutter
    */
    char dbx[160];
    sprintf(dbx, \"echo -ne \'detach\\n\' | gdb --eval-command=where --pid=%d > %d.dump\", getpid(), getpid());
    system(dbx);
    return;
}
当捕获到分段错误时,将调用
dumpstack
并打印最新的堆栈跟踪信息,直到出现分段错误并重定向到具有过程的数字pid的文件为止。     
为什么您完全不想运行gdb?如果使用它,您可以很容易地检测到段错误的位置。     

要回复问题请先登录注册