Intercepting c++ exceptions
So my c++ program just crashed, and the error I got was:
terminate called after throwing an instance of 'std::length_error'
what(): basi开发者_开发问答c_string::_S_create
Aborted
Now, what I've added recently to my code is a SIGSEGV handler, so if it was a segmentation fault, it would proceed to print the stack trace.
How do I go about making an exit handler for uncaught (or more like uncatchable) exceptions in c++?
Use set_terminate function which sets the terminate handler function:
A terminate handler function is a function automatically called when the exception handling process has to be abandoned for some reason. This happens when a handler cannot be found for a thrown exception, or for some other exceptional circumstance that makes impossible to continue the handling process.
Adding to the answer by @vitaut, if you are using C++11 you can check for and get the current exception within the handler specified by std::set_terminate
.
According to Daniel Krügler who refers to the standard quoted below, there is an implicit exception handler active during the call to std::terminate
, which means that we can use std::current_exception
to both check whether there is an active exception and also examine it.
The C++11 standard working draft N3242, section 15.3.7 (emphasis mine):
A handler is considered active when initialization is complete for the formal parameter (if any) of the catch clause. [ Note: The stack will have been unwound at that point. — end note ] Also, an implicit handler is considered active when std::terminate() or std::unexpected() is entered due to a throw. A handler is no longer considered active when the catch clause exits or when std::unexpected() exits after being entered due to a throw.
Stealing from Andrzej's C++ blog, here is an example of how this can be done:
[[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 );
}
Just put try
-catch(...)
at the to level of your program. Something like this:
try {
doStuff();
} catch( std::exception& e ) {
//handle std::exception-derived exceptions
} catch(...) {
//handle all other exceptions
}
You can install your own terminate handler with set_terminate.
You can catch all C++ exceptions with a catch-all clause catch (...) {}
.
精彩评论