Boost 中的 stacktrace 库提供了堆栈跟踪功能。堆栈跟踪又分了好几个子模块,其中最常用的两个模块是:

模块

作用

basic

使用编译器的功能提供最基本的堆栈跟踪功能

addr2line

使用 addr2line 将函数地址翻译成函数名

boost 使用 addr2line 的方式是 fork 子进程,然后在子进程中翻译函数地址。这会导致创建很多子进程。

要使用这两个模块,对 CMake 的方法为:

target_link_libraries(project PRIVATE Boost::stacktrace_basic Boost::stacktrace_addr2line)
target_compile_definitions(project PRIVATE BOOST_STACKTRACE_USE_ADDR2LINE)

打印堆栈

打印堆栈是最简单的使用方式,具体而言,调用:

std::cerr.clear();
std::cerr << boost::stacktrace::stacktrace() << std::endl;

导出堆栈

当程序发生崩溃时,打印堆栈的方式可能无法正常使用。更安全的方式是:

  1. 当程序崩溃时将堆栈信息保存到文件中

  2. 下次启动时读取堆栈信息


std::string kDumpFilePath = "./backtrace.dump";

void setup_backtrace() {
    ::signal(SIGABRT, handle_signal);
    ::signal(SIGSEGV, handle_signal);
}

void handle_signal(int signum) {
    ::signal(signum, SIG_DFL);
    boost::stacktrace::safe_dump_to(kDumpFilePath.c_str());
    std::cerr << boost::stacktrace::stacktrace() << std::endl;
    ::raise(SIGABRT);
}

void print_and_delete_dump_file() {
    if(!boost::filesystem::exists(kDumpFilePath)) return;

    std::ifstream ifs(kDumpFilePath);
    auto          st = boost::stacktrace::stacktrace::from_dump(ifs);
    spdlog::info("上一次崩溃信息:");
    std::cerr.clear();
    std::cerr << st << std::endl;
    ifs.close();
    fflush(stderr);

    boost::filesystem::remove(kDumpFilePath);
}
Last moify: 2022-12-04 15:11:33
Build time:2025-07-18 09:41:42
Powered By asphinx