Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix backtrace line number error in C++

I got a problem while wants to trace some information on program catches exceptions.

I used the function below:

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);
}

And the output is like this:

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      (???)

All the information (the namespaces, class names and the method names) are good. But the only problem is the line numbers are wrong.

How can I fix the line numbers in the backtrace?

like image 208
Jason Cheng Avatar asked Oct 28 '25 10:10

Jason Cheng


1 Answers

They're not line numbers, but offsets from the start of the function. There's a tool called addr2line which is shipped with binutils that can convert addresses into line numbers given debug symbols. You could either call this from within your program (pipe()+fork()+exec()), or look at the library it uses to do this.

On my Linux system addr2line uses libbfd internally for this. It's not terribly well documented though from what I've seen, but it's reasonably easy to see by example from the addr2line source.

like image 52
Flexo Avatar answered Oct 29 '25 23:10

Flexo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!