2012-08-23 89 views
1

我一直在使用建立在我的腳本backstrace_symbolsC++不能解碼回溯

void handler(int sig) { 
    void *array[20]; 
    size_t size; 
    char **strings; 
    size_t i; 

    size = backtrace(array, 20); 
    strings = backtrace_symbols(array,size); 

    tracelog.open("/var/log/safesquid/safesquid/debug/trace.log", ios::app); 
    tracelog << sig << endl; 
    for (i=0; i<size; i++) 
     tracelog << strings[i] << endl; 

    free(strings); 

    exit(1); 
} 

在主函數,它使用

signal(SIGSEGV, handler); 

回溯把它稱爲:

11 
/opt/scripts/cplusconnector(_Z7handleri+0x2b) [0x40233b] 
/lib64/libc.so.6(+0x32920) [0x7fe7b503c920] 
/lib64/libc.so.6(+0x131b5f) [0x7fe7b513bb5f] 
/opt/scripts/cplusconnector(main+0x163) [0x4035c3] 
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7fe7b5028cdd] 
/opt/scripts/cplusconnector() [0x402199] 
11 
/opt/scripts/cplusconnector(_Z7handleri+0x2b) [0x40233b] 
/lib64/libc.so.6(+0x32920) [0x7fd9db71a920] 
/lib64/libc.so.6(+0x131b5f) [0x7fd9db819b5f] 
/opt/scripts/cplusconnector(main+0x163) [0x4035c3] 
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7fd9db706cdd] 
/opt/scripts/cplusconnector() [0x402199] 

[[email protected] dev]# addr2line -e test-unstrippped 0x402199 0x7f1999f16cdd 0x4035c3 
??:0 
??:0 
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/basic_string.h:975 

問題出在哪裏,爲什麼運行程序結果在segmentation fault

更新:

有人使用這些選項

編譯
g++ cplusconnector-k.cpp -g -rdynamic -O2 -I/usr/include/mysql -L/usr/lib/mysql -lmysqlcppconn -o test `mysql_config --cflags --libs` 

更新:

我刪除了優化,並試圖解決使用add2line從回溯象徵,它指向代碼中的這一行..

/opt/webcache/scripts/cplusconnector(_Z7handleri+0x25) [0x401d49] 
/lib64/libc.so.6(+0x32920) [0x7f6ad974b920] 
/lib64/libc.so.6(+0x131b5f) [0x7f6ad984ab5f] 
/usr/lib64/libstdc++.so.6(_ZNSsaSEPKc+0x1c) [0x7f6ad9dcd12c] 
/opt/webcache/scripts/cplusconnector(main+0x12b) [0x4027ae] 
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7f6ad9737cdd] 
/opt/webcache/scripts/cplusconnector() [0x401c69] 


[[email protected] dev]# addr2line -e test 0x401d49 0x7f6ad974b920 0x7f6ad984ab5f 0x7f6ad9dcd12c 0x4027ae 0x7f6ad9737cdd 0x401c69 
/usr/local/dev/cplusconnector-k.cpp:42 
??:0 
??:0 
??:0 
/usr/local/dev/cplusconnector-k.cpp:138 
??:0 
??:0 

線:42是主要功能之外,是全球:

ofstream httplog; 

線:138的主要功能是內:

if (std::string::npos != host.find(string("1.0.0.1"))){ 
      return 0; 
     } 

任何想法?

+2

如果你用調試符號(給GCC的'-g'命令行選項),那麼你應該在回溯中看到文件名和行號。這會告訴你哪一行'main'調用了正在崩潰的庫函數。在調試器下運行代碼(例如''gdb'),或啓用核心轉儲('ulimit -c unlimited')並在調試器('gdb my_program core')中檢查結果,可能會提供更多信息,例如當時的變量值。 –

+1

我已經嘗試gdb,並且還使用-g標誌編譯它,當從命令行運行時,應用程序不提供段錯誤..並且gdb是乾淨的,只有當代理運行此腳本時,纔會發出段錯誤... – krisdigitx

+1

@ krisdigitx:另外,確保你正在調試的程序沒有優化編譯('-O0'),否則函數內聯和其他代碼轉換可能會使回溯無用。 –

回答

2

要調試您的程序,您可以啓用core傾銷(使用系統調用setrlimit(2),通常通過ulimit bash內建)。然後,用程序和核心轉儲運行gdb

至於爲什麼backtrace_symbols給你這樣的名字,這是因爲name mangling。另見this

也考慮使用Ian Taylor的libbacktrace(集成到GCC的最新版本中,例如GCC 6及更高版本)。與-g(也許還喜歡-O一些優化標誌)

+1

我已經嘗試gdb,並使用-g標誌編譯它,當從命令行運行時,應用程序不會給出段錯誤.and gdb是乾淨的,只有當代理運行此腳本時,纔會發生段錯誤... – krisdigitx

2

我看到的確有很好的理由使用免費()

對於名字改編使用abi::__cxa_demangle編譯代碼。

+0

' backtrace_symbols'返回一個'malloc'ed數組,所以'free'是在這裏使用的正確的東西。 –

+0

@MikeSeymour是的,我似乎已經遲了幾秒,似乎太遲了 – sji

1

backtrace()不能從信號處理程序調用。

有一個可從信號處理程序調用的(短)方法列表。 我也懶得現在谷歌雖然