2010-11-22 120 views
3

所以我的C++程序剛剛崩潰了,我得到的錯誤是:攔截C++異常

terminate called after throwing an instance of 'std::length_error' 
    what(): basic_string::_S_create 
Aborted 

現在,我最近添加到我的代碼是一個SIGSEGV處理程序,所以如果它是分段錯誤,它會繼續打印堆棧跟蹤。

我該如何着手爲C++中的未捕獲(或更多不可捕獲)異常做退出處理程序?

回答

5

使用set_terminate功能,設定終止處理函數:

一個終止處理函數是 功能自動調用的時候, 異常處理過程必須 放棄了一些原因。 發生在處理程序無法找到時 針對拋出的異常或某些 其他異常情況 使無法繼續 處理過程。

+0

啊,謝謝。它能夠訪問異常來自何處的堆棧跟蹤嗎?我想我很快會發現.. – kamziro 2010-11-22 12:27:40

+0

@kamziro:您可能會在調試器中看到堆棧跟蹤,但我認爲沒有辦法從代碼中獲取堆棧跟蹤。 – vitaut 2010-11-22 12:35:47

+0

嗯,它的工作原理,我只是重用我的SIGSEGV處理程序,它使用backtrace和addr2line(linux)將事情轉換爲格式良好的堆棧跟蹤。 – kamziro 2010-11-22 12:37:56

0

只要把try - catch(...)在您的程序的級別。事情是這樣的:

try { 
    doStuff(); 
} catch(std::exception& e) { 
    //handle std::exception-derived exceptions 
} catch(...) { 
    //handle all other exceptions 
}  
0

您可以安裝自己的終止處理程序set_terminate

您可以通過catch-all子句捕獲所有C++異常catch (...) {}

1

通過@vitaut添加到答案中,如果您使用的是C++ 11,則可以檢查並獲取std::set_terminate指定的處理程序中的當前異常。

According to Daniel Krügler誰指的是下面引用的標準,有呼叫std::terminate,這意味着我們可以使用std::current_exception既檢查是否存在有效的例外,同時檢查它在一個隱含的異常處理程序活躍。

的C++ 11標準working draft N3242,部分15.3.7(強調礦):

甲處理程序掣 的考慮當初始化完成的形式參數活性(如果有的話)條款。 [注意:此時堆棧將被解開。 - 結束註釋]而且,由於throw,當std :: terminate()或std :: unexpected()被輸入時,隱式處理程序 被視爲活動。當catch子句退出或當std :: unexpected()由於throw而輸入 後退出時,處理程序 不再被視爲活動。


Stealing from Andrzej's C++ blog,這裏是如何可以做到這一點的例子:

[[noreturn]] void onTerminate() noexcept 
{ 
    if(auto exc = std::current_exception()) { 
     // we have an exception 
     try{ 
      rethrow_exception(exc); // throw to recognize the type 
     } 
     catch(MyException const& exc) { 
      // additional action 
     } 
     catch(MyOtherException const& exc) { 
      // additional action 
     } 
     catch(std::exception const& exc) { 
      // additional action 
     } 
     catch(...) { 
      // additional action 
     } 
    } 

    std::_Exit(EXIT_FAILURE); 
}