所以我的C++程序剛剛崩潰了,我得到的錯誤是:攔截C++異常
terminate called after throwing an instance of 'std::length_error'
what(): basic_string::_S_create
Aborted
現在,我最近添加到我的代碼是一個SIGSEGV處理程序,所以如果它是分段錯誤,它會繼續打印堆棧跟蹤。
我該如何着手爲C++中的未捕獲(或更多不可捕獲)異常做退出處理程序?
所以我的C++程序剛剛崩潰了,我得到的錯誤是:攔截C++異常
terminate called after throwing an instance of 'std::length_error'
what(): basic_string::_S_create
Aborted
現在,我最近添加到我的代碼是一個SIGSEGV處理程序,所以如果它是分段錯誤,它會繼續打印堆棧跟蹤。
我該如何着手爲C++中的未捕獲(或更多不可捕獲)異常做退出處理程序?
使用set_terminate功能,設定終止處理函數:
一個終止處理函數是 功能自動調用的時候, 異常處理過程必須 放棄了一些原因。 發生在處理程序無法找到時 針對拋出的異常或某些 其他異常情況 使無法繼續 處理過程。
只要把try
- catch(...)
在您的程序的級別。事情是這樣的:
try {
doStuff();
} catch(std::exception& e) {
//handle std::exception-derived exceptions
} catch(...) {
//handle all other exceptions
}
您可以安裝自己的終止處理程序set_terminate。
您可以通過catch-all子句捕獲所有C++異常catch (...) {}
。
通過@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);
}
啊,謝謝。它能夠訪問異常來自何處的堆棧跟蹤嗎?我想我很快會發現.. – kamziro 2010-11-22 12:27:40
@kamziro:您可能會在調試器中看到堆棧跟蹤,但我認爲沒有辦法從代碼中獲取堆棧跟蹤。 – vitaut 2010-11-22 12:35:47
嗯,它的工作原理,我只是重用我的SIGSEGV處理程序,它使用backtrace和addr2line(linux)將事情轉換爲格式良好的堆棧跟蹤。 – kamziro 2010-11-22 12:37:56