2012-11-09 13 views
10

Guardando a this question e this question Posso vedere che per backtrace_symbols() funzionare, si deve compilare con il flag -rdynamic.backtrace_symbols() con entrambi -static e -rdynamic

ho provato in un programma di test e funziona, ma sto scrivendo un programma che è anche compilato con -static e this page dice che backtrace_symbols() non funziona quando -static viene passato al compilatore/linker.

C'è qualche soluzione rapida a questo oppure non avrò mai una funzione di lettura incrociata leggibile dall'uomo nel mio programma collegato in modo statico?

risposta

8

La risposta era già a portata di mano: era in the same page I linked in the question. Alla fine, ho usato con successo lo 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; 
} 

mi stavo collega errori perché ero (ancora una volta) forgotting di inserire opzioni del linker alla fine della riga di comando. Non capisco davvero perché g++/gcc non emetta almeno un avviso quando si ignorano le opzioni della riga di comando. La linea giusta di comando per la compilazione è (-g non è necessaria):

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

Se è assolutamente necessario compilare il programma come statico, è comunque possibile utilizzare backtrace() per trovare gli indirizzi delle funzioni e quindi trovare i nomi delle funzioni analizzando le informazioni di debug, ad esempio utilizzando libdwarf.

Ma non è un compito semplice, quindi suggerirei di usare il flag -rdynamic.

+0

Sì, '-static' è obbligatorio nel mio programma. Ho anche provato con 'libunwind' ma i miei programmi di esempio non si collegano sia su Ubuntu 12.04 x86 che x86_64. Sono sempre ottenere gli errori di collegamento come ad esempio: 'undefined reference to _Ux86_init_local' ' undefined reference to _Ux86_get_reg' 'undefined reference to _Ux86_get_proc_name' ' undefined reference to _Ux86_step' sia con binario libunwind Ubuntu e ultima auto-compilato libunwind scaricato da [qui] (http://download.savannah.gnu.org/releases/libunwind/). – Avio

+0

@ Avvio Ho menzionato 'libdwarf', non' libunwind'. Non ho avuto problemi nel collegamento con 'libunwind' – qrdl

+0

Proverò' libdwarf' il prima possibile. Stavo solo citando 'libunwind' perché potrebbe essere un'alternativa interessante senza alcun requisito speciale. Quale architettura/distribuzione hai usato quando hai collegato correttamente a 'libunwind'? – Avio