2010-11-25 81 views
1

我試圖從程序中打印調用堆棧。不幸的是,調用glibc的backtrace()函數只能返回一個記錄 - 當前函數的地址。我正在研究sh4-linux,這可能會導致問題。我在x86架構上打印時沒有問題。sh4-linux的回溯函數返回一個函數

示例代碼:

#include <string> 
#include <iostream> 
#include <execinfo.h> 

const int maxCalls = 666; 

void baz() 
{ 
     void *buffer[ maxCalls ]; 
     int stackSize = backtrace(buffer, maxCalls); 

     char **symbols = backtrace_symbols(buffer, stackSize); 

     std::string str; 

     for(unsigned i = 0; i < stackSize; ++i) 
     { 
       str+= symbols[i]; 
     } 
     free(symbols); 
     std::cout << str<< std::endl; 
} 

void bar() 
{ 
     baz(); 
} 

void foo() 
{ 
     bar(); 
} 

int main(int argc, char **argv) 
{ 
     foo(); 
     return 0; 
} 

這是由編譯:

sh4-linux-g++ test.cpp -g -c -o test.o 
sh4-linux-g++ test.o -g -rdynamic -o test 

編輯:其實這個代碼工作正常。可能有一些編譯器標誌在實際項目中導致此行爲。

編譯器標誌是:-g -O0 -pipe -fpermissive -frtti -fno-exceptions -ffunction-sections

鏈接標誌:-lpthread -g -rdynamic -Wl,-gc-sections -Wl,--start-group {Files here} -Wl,--end-group --verbose -Xlinker -lm

EDIT2:我發現這標誌是原因:-fno-exceptions。誰能告訴我爲什麼?如果它可以修復而不跳過這個標誌?

EDIT3:好吧,沒關係。看來我實際上可以省略這個標誌。

回答

1

嘗試刪除「stackSize = 1;」

+0

好點;-)這個簡單的應用程序開始工作。但是,真正的應用程序仍然給我一條線回溯。任何想法哪個編譯器標誌可能會產生這種效果? – x13n 2010-11-29 08:33:46

0

編譯器可能會內聯這些函數。可以嘗試使用-O0選項重新編譯。

+0

沒有。 -O0默認使用。另外,當我明確傳遞該標誌時,二進制文件完全相同。 – x13n 2010-11-26 07:28:38

1

glibc需要補丁。看here

正如該補丁所述,使用回溯的用戶應用程序需要使用「-fexceptions」進行編譯。如果你想完整的符號解析地址,你也需要「-rdynamic」。