发生异常时gcc arm打印回溯

时间:2016-07-25 10:40:55

标签: c gcc arm g++

如何在抛出异常时打印完整的回溯? 我有以下测试程序来提升异常并打印回溯:

#include <iostream>
#include <iostream> 
#include <exception>
#include <cstdlib>
#include <execinfo.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>


void do_backtrace(int signo);

const struct catchSignals_t{
  int signo;
  const char *name;
} catchSignals[] = {
        { SIGSEGV, "SIGSEGV" },
        { SIGILL,  "SIGILL"  },
        { SIGFPE,  "SIGFPE"  },
        { SIGABRT, "SIGABRT" },
        { SIGBUS,  "SIGBUS"  },
        { SIGUSR2, "SIGUSR2" }
};


bool regHandlers() {
    bool result = true;

    for (auto i: catchSignals) {
        result = result && (signal(i.signo, do_backtrace) != SIG_ERR);

        if (!result)
            std::cerr <<  "Failed to install signal:" << i.name;
    }

    return result;
};


void do_backtrace(int signo) {
    std::cerr << "Received signal " << signo << std::endl;
    void * array[50];
    int size = backtrace(array, 50);

    std::cerr << " backtrace returned " << size << " frames\n\n";


    char ** messages = backtrace_symbols(array, size);

    for (int i = 0; i < size && messages != NULL; ++i) {
        std::cerr << "[bt]: (" << i << ") " << messages[i] << std::endl;
    }
    std::cerr << std::endl;

    free(messages);
//    abort();

    exit(0);

}

void on_terminate() {
    std::cout << "on_terminate called" << std::endl;

    static bool tried_throw = false;

    try {
        // try once to re-throw currently active exception
        if (!tried_throw++) throw;
    }
    catch (const std::exception &e) {
        std::cerr << __FUNCTION__ << " caught unhandled exception. what(): "
                  << e.what() << std::endl;
    }
    catch (...) {
        std::cerr << __FUNCTION__ << " caught unknown/unhandled exception." 
                  << std::endl;
    }

    do_backtrace(6);
}

namespace {
    static const bool SET_TERMINATE = std::set_terminate(on_terminate);
}

void foo() 
{

    kill(getpid(), SIGABRT);

    abort();
//    throw 20;
}


int main() {
    regHandlers();


    foo();
    return 1;
}

在x86主机PC上,它打印完全回溯,我可以转换地址以找出抛出异常的位置,但在目标臂上,这是完全不同的输出。看起来像:

on_terminate backtrace returned 3 frames

[bt]: (0) ./a.out() [0x8a2c]
[bt]: (1) /usr/lib/libstdc++.so.6(+0x4a1e8) [0xb6ecf1e8]
[bt]: (2) /usr/lib/libstdc++.so.6(_ZSt9terminatev+0x1c) [0xb6ecf210]

Aborted (core dumped)

这个问题不仅仅是异常,这可以通过信号处理程序看到 - 回溯也没有完整,我无法找到它上升的位置。

已更新!

构建命令:

arm-buildroot-linux-gnueabi-g++ --std=c++11 -funwind-tables -mapcs-frame -rdynamic main.cc -o test

在代码中使用abort()时,回溯如下:

Received signal 6
 backtrace returned 3 frames

[bt]: (0) ./test(_Z12do_backtracei+0x50) [0x8df8]
[bt]: (1) /lib/libc.so.6(__default_sa_restorer_v2+0) [0xb6c90dc0]
[bt]: (2) /lib/libc.so.6(gsignal+0x38) [0xb6c8fb58]

从这个回溯中,无法说出代码崩溃的位置(使用abort()的地方)。

在代码中使用kill(getpid(),SIGABRT) - 后跟跟踪并且看起来没问题:

Received signal 6
 backtrace returned 6 frames

[bt]: (0) ./test(_Z12do_backtracei+0x50) [0x8e58]
[bt]: (1) /lib/libc.so.6(__default_sa_restorer_v2+0) [0xb6c61dc0]
[bt]: (2) /lib/libc.so.6(kill+0xc) [0xb6c60e3c]
[bt]: (3) ./test(_Z3foov+0x20) [0x90e4]
[bt]: (4) ./test(main+0x14) [0x90fc]
[bt]: (5) /lib/libc.so.6(__libc_start_main+0x114) [0xb6c4aff4]

0 个答案:

没有答案