2012-11-09 79 views
10

看着this questionthis question我可以看到,要使用backtrace_symbols()工作,必須使用-rdynamic標誌進行編譯。backtrace_symbols()同時具有-static和-rdynamic

我已經試過它變成一個測試程序和它的作品,但我正在寫也編譯-staticthis page說,當-static傳遞到編譯器/連接backtrace_symbols()不工作的程序。

是否有任何快速解決方法,或者我永遠不會在我的靜態鏈接程序中有一個人類可讀的backtrace函數?

回答

8

答案已經在手邊:它在the same page I linked in the question。最後,我成功使用了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; 
} 

我得到鏈接錯誤,因爲我(再次)忘記將鏈接器選項放在命令行的末尾。我真的不明白爲什麼g++/gcc在忽略命令行選項時至少不會發出警告。正確的命令行編譯是(無需-g):

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

如果您絕對必須將程序編譯爲靜態,您仍然可以使用backtrace()來查找函數的地址,然後通過解析調試信息來找到函數名稱,例如使用libdwarf

但這不是一個簡單的任務,所以我建議使用-rdynamic標誌。

+0

是,'-static'是在我的計劃是強制性的。我也嘗試過'libunwind',但我的示例程序不會在Ubuntu 12.04 x86和x86_64上鍊接。我總是得到鏈接錯誤,例如:未定義的引用_Ux86_init_local 未定義的引用_Ux86_get_reg的 未定義的引用_Ux86_get_proc_name的 未定義引用_Ux86_step與二進制Ubuntu libunwind和最新的自編譯libunwind下載[這裏](http://download.savannah.gnu.org/releases/libunwind/)。 – Avio

+0

@Avio我提到'libdwarf',而不是'libunwind'。我沒有任何問題鏈接'libunwind' – qrdl

+0

我會盡快嘗試'libdwarf'。我只是提到'libunwind',因爲它可能是沒有任何特殊要求的另一個有趣的選擇。你成功鏈接到'libunwind'的時候使用過什麼架構/分佈? – Avio

相關問題