2012-11-09 10 views
10

Patrząc na this question i this question Widzę, że dla backtrace_symbols() do pracy, należy skompilować z flagą -rdynamic.backtrace_symbols() z zarówno -static i -rdynamic

Próbowałem go do programu testowego i to działa, ale piszę program, który jest również skompilowany z -static i this page mówi, że backtrace_symbols() nie działa, gdy -static jest przekazywane do kompilator/linker.

Czy jest to szybkie obejście tego problemu, czy też nigdy nie będę posiadał czytelnej dla człowieka funkcji śledzenia w moim statycznie powiązanym programie?

Odpowiedz

8

Odpowiedź była już pod ręką: była w the same page I linked in the question. Na koniec z powodzeniem użyłem 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; 
} 

Otrzymałem linki błędów, ponieważ byłem (ponownie) zapomniałem umieścić opcje linkera na końcu wiersza poleceń. Naprawdę nie rozumiem, dlaczego g++/gcc nie wydaje co najmniej ostrzeżenia po zignorowaniu opcji wiersza poleceń. Poprawny wiersz poleceń do kompilacji jest (-g nie jest potrzebny):

g++ -static unwind.cpp -o unwind -lunwind -lunwind-x86 
3

Jeśli koniecznie musisz skompilować program jako statyczny, możesz nadal używać backtrace(), aby znaleźć adresy funkcji, a następnie znaleźć nazwy funkcji, analizując informacje debugowania, używając na przykład libdwarf.

Ale to nie jest proste zadanie, więc proponuję użyć flagi -rdynamic.

+0

Tak, '-static' jest obowiązkowe w moim programie. Próbowałem również z 'libunwind' ale moje przykładowe programy nie łączą się zarówno w Ubuntu 12.04 x86 jak i x86_64. Ja zawsze otrzymuję błędy łączące takie jak: 'nieokreślonej odniesieniu do _Ux86_init_local' ' niezdefiniowanej odniesienie do _Ux86_get_reg' 'niezdefiniowanej odniesienie do _Ux86_get_proc_name' ' niezdefiniowanej odniesienie do _Ux86_step' zarówno z binarnym libunwind Ubuntu i ostatni self-kompilowane libunwind pobranych od [tutaj] (http://download.savannah.gnu.org/releases/libunwind/). – Avio

+0

@Avio Wspomniałem 'libdwarf', a nie' libunwind'. Nie miałem żadnych problemów z linkami do 'libunwind'a – qrdl

+0

Spróbuję' libdwarf' jak najszybciej. Właśnie wspomniałem o "libunwind", ponieważ może to być kolejna interesująca alternatywa bez specjalnych wymagań. Jaką architekturę/dystrybucję używasz, z powodzeniem połączoną z 'libunwind'? – Avio