如何在C++中修复回溯行号错误

Jas*_*eng 3 c++ macos backtrace debug-symbols

我想在跟踪程序捕获异常的一些信息时遇到问题.

我使用了以下功能:

extern "C" void log_backtrace()
{   
    // Dump the callstack
    int callstack[128];
    int  frames = backtrace((void**) callstack, 128);
    char** strs = backtrace_symbols((void**) callstack, frames);

    for (int i = 1; i < frames; ++i)
    {
        char functionSymbol[64*1024];
        char moduleName    [64*1024];
        int  offset        = 0;
        sscanf(strs[i], "%*d %s %*s %s %*s %d", &moduleName, &functionSymbol, &offset);
        int addr = callstack[i];
        int   validCppName;
        char* functionName = abi::__cxa_demangle(functionSymbol, NULL, 0,
                                             &validCppName);
        if (validCppName == 0)
            printf(   "\t%8.8x — %s + %d\t\t(%s)\n", addr, functionName, offset, moduleName);
        else
            printf(   "\t%8.8x — %s + %d\t\t(%s)\n", addr, functionSymbol, offset, moduleName);
        if (functionName)
            free(functionName);
    }
    free(strs);
}
Run Code Online (Sandbox Code Playgroud)

输出是这样的:

20:48:44 [ERROR]tcp_client::connect() failed. error:Connection refused
00000001 — latte::Log::out_error(std::string const&) + 151      (valhalla)
001a6637 — latte::tcp_client::connect(boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> const&) + 307       (valhalla)
00000001 — valhalla::hall::start() + 388        (valhalla)
00204803 — main + 388       (valhalla)
00000001 — start + 52       (valhalla)
00143ae4 — 0x0 + 1      (???)
Run Code Online (Sandbox Code Playgroud)

所有信息(名称空间,类名和方法名称)都很好.但唯一的问题是行号是错误的.

如何修复回溯中的行号?

Fle*_*exo 12

它们不是行号,而是函数开头的偏移量.有一个名为addr2linebinutils 的工具,可以将地址转换为给定调试符号的行号.你可以在你的程序中调用它(pipe()+ fork()+ exec()),或者查看它用来执行此操作的库.

在我的Linux系统上,addr2line 内部使用libbfd.从我所看到的情况来看,它并没有很好的记录,但是从addr2line源代码中可以很容易地看到它.