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?

Community
  • 1
  • 1
Avio
  • 2,700
  • 6
  • 30
  • 50

2 Answers2

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
Avio
  • 2,700
  • 6
  • 30
  • 50
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.

qrdl
  • 34,062
  • 14
  • 56
  • 86
  • 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](http://download.savannah.gnu.org/releases/libunwind/). – Avio Nov 09 '12 at 14:26
  • @Avio I have mentioned `libdwarf`, not the `libunwind`. I had no problems linking with `libunwind` – qrdl Nov 10 '12 at 06:05
  • 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`? – Avio Nov 10 '12 at 12:46
  • @Avio 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. – qrdl Nov 10 '12 at 14:48