2010-11-22 122 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); 
}