2013-03-07 51 views
1

我想使用backtrace和backtrace_symbols結果打印出我捕獲SIGSEGV信號後代碼崩潰的位置。我明確地從一個工作者線程觸發。我用選項-rdynamic編譯了我的靜態鏈接多線程C++程序,並且我期待backtrace_symbols會返回一個堆棧跟蹤來告訴我發生崩潰的位置,但下面的結果並不是我所期望的,MyApplicationService不是一種方法,但只是可執行文件的名稱,我不明白爲什麼。回溯結果沒有顯示崩潰位置

2013-03-07 15:13:18.119986598 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZNK5boost4_mfi3mf2IvN18my_app__service_lib14service_runnerERKNS_6system10error_codeEiEclEPS3_S7_i+0x74) [0xcd69fa] 
    2013-03-07 15:13:18.119988126 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost3_bi5list3INS0_5valueIPN18my_app__service_lib14service_runnerEEENS_3argILi1EEENS7_ILi2EEEEclINS_4_mfi3mf2IvS4_RKNS_6system10error_codeEiEENS0_5list2ISH_RKiEEEEvNS0_4typeIvEERT_RT0_i+0x7c) [0xcd6848] 
    2013-03-07 15:13:18.119989192 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost3_bi6bind_tIvNS_4_mfi3mf2IvN18my_app__service_lib14service_runnerERKNS_6system10error_codeEiEENS0_5list3INS0_5valueIPS5_EENS_3argILi1EEENSF_ILi2EEEEEEclIS7_iEEvRKT_RKT0_+0x4c) [0xcd6690] 
    2013-03-07 15:13:18.119990120 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost4asio6detail7binder2INS_3_bi6bind_tIvNS_4_mfi3mf2IvN18my_app__service_lib14service_runnerERKNS_6system10error_codeEiEENS3_5list3INS3_5valueIPS8_EENS_3argILi1EEENSI_ILi2EEEEEEESA_iEclEv+0x2b) [0xcd6597] 
    2013-03-07 15:13:18.119991031 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost4asio19asio_handler_invokeINS0_6detail7binder2INS_3_bi6bind_tIvNS_4_mfi3mf2IvN18my_app__service_lib14service_runnerERKNS_6system10error_codeEiEENS4_5list3INS4_5valueIPS9_EENS_3argILi1EEENSJ_ILi2EEEEEEESB_iEEEEvT_z+0x62) [0xcd64b0] 
    2013-03-07 15:13:18.119992105 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN33boost_asio_handler_invoke_helpers6invokeIN5boost4asio6detail7binder2INS1_3_bi6bind_tIvNS1_4_mfi3mf2IvN18my_app__service_lib14service_runnerERKNS1_6system10error_codeEiEENS5_5list3INS5_5valueIPSA_EENS1_3argILi1EEENSK_ILi2EEEEEEESC_iEESO_EEvRT_RT0_+0x64) [0xcd636c] 
    2013-03-07 15:13:18.119993000 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost4asio6detail14signal_handlerINS_3_bi6bind_tIvNS_4_mfi3mf2IvN18my_app__service_lib14service_runnerERKNS_6system10error_codeEiEENS3_5list3INS3_5valueIPS8_EENS_3argILi1EEENSI_ILi2EEEEEEEE11do_completeEPNS1_15task_io_serviceEPNS1_25task_io_service_operationESC_m+0xb9) [0xcd605d] 
    2013-03-07 15:13:18.119993884 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost4asio6detail25task_io_service_operation8completeERNS1_15task_io_serviceERKNS_6system10error_codeEm+0x32) [0xccceac] 
    2013-03-07 15:13:18.119994819 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost4asio6detail15task_io_service10do_run_oneERNS1_11scoped_lockINS1_11posix_mutexEEERNS2_11thread_infoERKNS_6system10error_codeE+0x1a1) [0xccf4a5] 
    2013-03-07 15:13:18.119995795 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost4asio6detail15task_io_service3runERNS_6system10error_codeE+0x137) [0xcceffd] 
    2013-03-07 15:13:18.119996845 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN5boost4asio10io_service3runEv+0x2f) [0xccf823] 
    2013-03-07 15:13:18.119997845 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(_ZN18my_app__service_lib14service_runner3runEv+0x97) [0xccbb65] 
    2013-03-07 15:13:18.119998914 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService(main+0x4cc) [0xcc4608] 
    2013-03-07 15:13:18.119999767 [7f2279bbe720] INFO service_runner - /lib64/libc.so.6(__libc_start_main+0xfd) [0x3f0f01ecdd] 
    2013-03-07 15:13:18.120000694 [7f2279bbe720] INFO service_runner - ../Debug/MyApplicationService() [0xcc4059] 

這是我用來打印上述結果的代碼:

  void *trace[16]; 
      char **messages = (char **)NULL; 
      int i, trace_size = 0; 
      SERVICE_LOG_INFO << "Receive signal " << sig ;  
      trace_size = backtrace(trace, 16); 
      messages = backtrace_symbols(trace, trace_size); 
      LOG << "[bt] Execution path:" ; 
      for (i=1; i<trace_size; ++i) 
       LOG << messages[i]; 

其它信息:

OS: RHEL 6.3 
    compiler: gcc 4.4.6 
    compile option: -I/opt/rh/devtoolset-1.0/root/usr/include -I/opt/rh/devtoolset-1.0/root/usr/include/c++/4.7.0 -I/opt/rh/devtoolset-1.0/root/usr/include/c++/4.7.0/backward -I/opt/rh/devtoolset-1.0/root/usr/include/c++/4.7.0/x86_64-redhat-linux -I/opt/rh/devtoolset-1.0/root/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include -I/opt/boost_1_52_0 -I/opt/tbb41_20121003oss/include -I/opt/libev-4.11/include -I"Myapp/include" -O0 -g3 -rdynamic -Wall -c -fmessage-length=0 -std=c++11 -fno-strict-aliasing -MMD -MP -MF"src/service_runner.d" -MT"src/service_runner.d" -o "src/service_runner.o" "../src/service_runner.cpp" 
+1

你建立與調試信息?爲什麼不嘗試在調試器中運行它? – 2013-03-07 06:31:35

+0

是與-g3。我正在使用eclipse CDT – 2013-03-07 06:32:21

+0

我們需要更多信息,例如當你編譯和鏈接你的應用程序時,命令行看起來如何?您使用的編譯器和版本等。 – 2013-03-07 06:33:54

回答

1

編譯選項顯示-c,所以-rdynamic被傳遞給編譯步驟。你需要確保它使用鏈接的代碼。檢查是否是這種情況。

編輯:布賴恩,你現在在問題中添加了破損的符號,所以你現在想問一個不同的問題。請不要這樣做。

但因爲你做的事:你需要從backtrace_symbols分析每一行提取錯位象徵,它調用__cxa_demangle。策略是從字符串末尾搜索+,然後再從+後面搜索前括號(。向後搜索的原因是,前面的文件名也可能包含這些字符(不太可能,但可能)。如果您嘗試實施它並遇到問題,請致電請打開一個新問題

+0

謝謝丹尼爾。情況好轉。但是現在消息已經大量上漲了,但它仍然沒有指向它崩潰的地方。 +1 – 2013-03-07 07:22:31

+0

不客氣。我假設這個問題得到解答,請打開一個新的問題,如果你需要幫助(當然,在你的一些研究之後),這個問題只會集中在崩潰問題上。 – 2013-03-07 07:26:41

+1

你有你的符號*損壞*(查找「C++ mangling」)。你需要* demangle *他們。你可以在你的程序中使用它(參見'cxa_demangle()')或者使用外部工具('C++ filt')。 – 2013-03-07 08:15:13

1

終於搞定了一切。

解步驟: 1)在接頭選項添加-rdynamic。

2)使用此代碼來還原函數的字符串錯位:(代碼是從這個thread

  // skip first stack frame (points here) 
      for (int i = 0; i < trace_size && messages != NULL; ++i) 
      { 
       char *mangled_name = 0, *offset_begin = 0, *offset_end = 0; 

       // find parantheses and +address offset surrounding mangled name 
       for (char *p = messages[i]; *p; ++p) 
       { 
        if (*p == '(') 
        { 
         mangled_name = p; 
        } 
        else if (*p == '+') 
        { 
         offset_begin = p; 
        } 
        else if (*p == ')') 
        { 
         offset_end = p; 
         break; 
        } 
       } 

       // if the line could be processed, attempt to demangle the symbol 
       if (mangled_name && offset_begin && offset_end && 
        mangled_name < offset_begin) 
       { 
        *mangled_name++ = '\0'; 
        *offset_begin++ = '\0'; 
        *offset_end++ = '\0'; 

        int status; 
        char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status); 

        // if demangling is successful, output the demangled function name 
        if (status == 0) 
        { 
         std::cerr << "[bt]: (" << i << ") " << messages[i] << " : " 
            << real_name << "+" << offset_begin << offset_end 
            << std::endl; 

        } 
        // otherwise, output the mangled function name 
        else 
        { 
         std::cerr << "[bt]: (" << i << ") " << messages[i] << " : " 
            << mangled_name << "+" << offset_begin << offset_end 
            << std::endl; 
        } 
        free(real_name); 
       } 
       // otherwise, print the whole line 
       else 
       { 
        std::cerr << "[bt]: (" << i << ") " << messages[i] << std::endl; 
       } 
      } 
      std::cerr << std::endl;