backtrace_symbols() with both -static and -rdynamic
Asked Answered
T

2

11

Looking at this question and this question I can see that for backtrace_symbols() to work, one must compile with the -rdynamic flag.

I've tried it into a test program and it works, but I'm writing a program that is also compiled with -static and this page says that backtrace_symbols() doesn't work when -static is passed to the compiler/linker.

Is there any quick workaround to this or I'll never have a human-readable backtrace function in my statically linked program?

Tsarina answered 9/11, 2012 at 12:9 Comment(0)
T
10

The answer was already at hand: it was in the same page I linked in the question. At the end, I successfully used libunwind.

#include <libunwind.h>
#include <stdio.h>

void do_backtrace()
{
    unw_cursor_t    cursor;
    unw_context_t   context;

    unw_getcontext(&context);
    unw_init_local(&cursor, &context);

    while (unw_step(&cursor) > 0)
    {
        unw_word_t  offset, pc;
        char        fname[64];

        unw_get_reg(&cursor, UNW_REG_IP, &pc);

        fname[0] = '\0';
        (void) unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);

        printf ("%p : (%s+0x%x) [%p]\n", pc, fname, offset, pc);
    }
}

int main()
{
 do_backtrace();
 return 0;
}

I was getting linking errors because I was (again) forgotting to place linker options at the end of the command line. I really don't understand why g++/gcc don't issue at least a warning when ignoring command line options. The correct command line to compile is (-g isn't needed):

g++ -static unwind.cpp -o unwind -lunwind -lunwind-x86
Tsarina answered 13/11, 2012 at 12:58 Comment(0)
P
3

If you absolutely have to compile your program as static, you can still use backtrace() to find out addresses of the functions and then find function names by parsing debug information, using libdwarf, for example.

But it isn't a simple task, so I'd suggest to use -rdynamic flag.

Purlin answered 9/11, 2012 at 14:19 Comment(4)
Yes, -static is mandatory in my program. I also tried with libunwind but my example programs don't link both on Ubuntu 12.04 x86 and x86_64. I'm always getting linking errors such as: undefined reference to _Ux86_init_local undefined reference to _Ux86_get_reg undefined reference to _Ux86_get_proc_name undefined reference to _Ux86_step both with binary Ubuntu libunwind and latest self-compiled libunwind downloaded from here.Tsarina
@Tsarina I have mentioned libdwarf, not the libunwind. I had no problems linking with libunwindPurlin
I'll try libdwarf as soon as possible. I was just mentioning libunwind because it could be another interesting alternative without any special requirement. What architecture/distribution did you use whan you successfully linked to libunwind?Tsarina
@Tsarina I am using OpenSUSE 10.x-12.x on X86 but I don't think it really matters as you can compile libdwarf on your platform. You would also need to link to libelf to be able to process ELF binary.Purlin

© 2022 - 2024 — McMap. All rights reserved.