所以我的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