I have seen many code examples where the unexpected() function handler (as set by set_unexpected) itself throws an exception.
What is the point of doing that? I thought unexpected() was the exception catcher of last resort. Who will catch the exception thrown by the unexpected() function handler?
Related
I'm currently following C++ core guidelines setting all destructors in my code to be noexcept. Some of my destructors may potentially throw exceptions - in that case I would like the program to crash and provide me with details on what caused the crash. Setting the noexcept specifier on the destructor will call std::terminate() which in turns invoke the default terminate_handler. The default terminate_handler will print the exception which was fired inside the destructor. This is great in the case in which the throwing destructor was not called while another exception was being thrown. In that case I would like the terminate_handler to print both exceptions so I can know what triggered the error handling path in the first place.
The problem is I can't seem to find a way in the standard library to get the uncaught exception. There's a std::current_exception() function which gets the exception being handled and std::uncaught_exceptions() which only gets the number of uncaught exception. I would like to get an std::exception_ptr or something to the uncaught exceptions. Is that possible?
See: https://www.danielseither.de/blog/2013/12/globally-handling-uncaught-exceptions-and-signals-in-c/
std::exception_ptr exptr = std::current_exception();
try {
std::rethrow_exception(exptr);
}
catch (std::exception &ex) {
std::fprintf(stderr, "Terminated due to exception: %s\n", ex.what());
}
I am calling a function which comes from a static library, it threw nlopt exception, so I used the following code to locate the exception.
try
{
reg_info("Before GP");
omp_set_num_threads(1);
GP predictor(train_in, train_out);
predictor.set_noise_lower_bound(1e-3);
reg_info("Before Train");
predictor.train();
reg_info("After Train");
reg_info("Before Predict");
predictor.predict(pred_in, pred_y, pred_s2);
reg_info("After Predict");
reg_info("After GP");
}
catch(...)
{
reg_info("Exception");
}
But I got the following output message:
Info : Before GP
Info : Before Train
terminate called after throwing an instance of 'nlopt::forced_stop'
what(): nlopt forced stop
It seems that the predictor.train(); threw the exception, but why didn't it caught by catch(...)? shouldn't it catch everything?
It looked at the source code of GP::train(), it did throw an nlopt::forced_stop() exception that is not properly caught, but still, I don't understand why the catch(...) didn't catch it successfully.
shouldn't it catch everything?
Only if the handler is reached. There are situations where an exception can not be caught and std::terminate is called instead.
[except.throw]/7 If the exception handling mechanism, after completing the initialization of the exception object but before
the activation of a handler for the exception, calls a function that exits via an exception, std::terminate
is called
[except.ctor]/1 As control passes from the point where an exception is thrown to a handler, destructors are invoked by a
process, specified in this section, called stack unwinding. If a destructor directly invoked by stack unwind-
ing exits with an exception, std::terminate is called (15.5.1). [ Note: Consequently, destructors should
generally catch exceptions and not let them propagate out of the destructor. — end note ]
The following code terminates abnormally as no object is explicitly thrown. What is thrown by throw statement in the following code?
int main()
{
try{
cout<<"try";
throw ;
}
catch(...){
cout<<"catch";
}
return 0;
}
throw without an argument should only be used inside a catch statement, to rethrow the caught exception object. You code tries to use it outside the catch statement - instead you should pick a type to throw, if in doubt it's not unreasonable to start with std::runtime_error. For more options, see here. You can also throw your own types, but it's usually a good idea to derive them from one of the Standard-library provided types so client code has a better chance at specifying appropriate handling for all logically similar errors, rather than having to catch and handle them separately and being constantly updated for each new possible error.
FWIW, the Standard says in 15.1/9:
If no exception is presently being handled, executing a throw-expression with no operand calls std::terminate().
So very explicitly, the answer to "What is thrown..." is that no throwing is done, and std::terminate is called instead.
So the question is: "What happens when I throw outside a catch block?" The answer to this can be found in its documentation:
Rethrows the currently handled exception. Abandons the execution of the current catch block and passes control to the next matching exception handler (but not to another catch clause after the same try block: its compound-statement is considered to have been 'exited'), reusing the existing exception object: no new objects are made. This form is only allowed when an exception is presently being handled (it calls std::terminate if used otherwise). The catch clause associated with a function-try-block must exit via rethrowing if used on a constructor.
Emphasize mine.
I'm having a problem with a tester that my application crashes in initialization. I added more logging and exception handling but it still crashes with the generic "this program has stopped working" message rather than triggering my error handling.
Given my main() looks like this and has catch(...) under what circumstances would this not be triggered?
try{
simed::CArmApp app(0, cmd);
for(bool done = false;!done;)
{
done = !app.frame();
}
} catch(const std::runtime_error &e){
handleApplicationError(e.what());
return -1;
} catch(...) {
handleApplicationError("Unknown Error");
return -999;
}
My code is calling into a library doing OpenGL rendering which is where I believe things are going wrong.
If a C++ catch(...) block is not catching errors maybe it is because of a Windows error.
On Windows there is a concept called Structured Exception Handling which is where the OS raises "exceptions" when bad things happen such as dereferencing a pointer that is invalid, dividing by zero etc. I say "exceptions" because these are not C++ exceptions; rather these are critical errors that Windows defines in a C-style fashion - this is because Win32 was written in C so C++ exceptions were not viable.
See also:
Difference between a C++ exception and Structured Exception
try-except Statement
Method of getting a stack trace from an EXCEPTION_POINTERS struct
Update based on comments
If you want both C++ exception handing and SEH perhaps you could try the following (untested) code:
__try
{
try
{
// Your code here...
}
catch (std::exception& e)
{
// C++ exception handling
}
}
__except(HandleStructuredException())
{
// SEH handling
}
If an exception is thrown by the destructor of an object that is destroyed as a result of the stack unwinding to handle a different exception, the program will exit, catch(...) or not.
So far I know, there can be at least two situations where catch(...) cannot actually catch
More than 1 unhandled Exception: when an exception is raised before a previously occurred exception is handled, then c++ can not handle it, and application will crash.
Throwing exception that is not in exception specification list: if any method throws an exception which is not in the exception specification list (in any) then unexpected will be called which calls abort.
Do you declare any global objects?
If you have any objects created outside your main loop, that could explain why it is not caught ( it is not in your try-catch ).
In the application I am writing, I make usage of exceptions for most of my error handling. I've not defined my own exception classes just yet, I merely did the following:
namespace Mage {
typedef std::exception Exception;
}
This way I won't have to change all of my code when I define my own type later which should use the same interface.
That said, any exception crashes my application. Taking the above definition in mind, why would this crash?
void Mage::Root::initialize(Mage::String& p_log) {
// initialize GLFW and GLEW.
if (!glfwInit()) {
throw new Mage::Exception("failed to initialize OpenGL");
return;
} else m_GLFWInitialized = true;
Whether I remove or keep 'new', it would still crash. Am I missing something? I've looked up tutorials but those don't get me any wiser.
I also catch the error right here:
try {
MAGE_ROOT.initialize(Mage::String("Mage.log"));
} catch (Mage::Exception& e) {
std::cerr << e.what() << std::endl;
}
The crash I'm getting is:
Debug Error!
Program: ...sual Studio 2010\Project\Mage3D\Binaries\Debug\Test.exe
R6010
- abort() has been called
(Press Retry to debug application)
The problem is that you are not catching your exception.
I wasn't aware you -have- to catch the exception (from the comments)
Yes, you have to. If you do not catch a thrown exception, std::terminate() will be called. This is the intended behavior: exceptions exist to prevent programmers from forgetting about error handling.
This said, I suggest:
throwing by value;
catching by reference
For instance:
void foo()
{
// ...
throw std::logic_error("Error!");
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Throw by value (std::logic_error derives from std::exception)
// ...
}
void bar()
{
try
{
// ...
foo();
// ...
}
catch (std::exception& e)
^^^^^^^^^^^^^^^
// Catch by reference
{
std::cout << e.what(); // For instance...
}
}
UPDATE:
With regards to the piece of code you posted, you are throwing a pointer and catching by reference. The handler won't match. And since there is no other matching handler, std::terminate() will be called.
Instead, you should throw your exception by value:
throw Mage::Exception("failed to initialize OpenGL");
And if the code you posted is indeed the one you are using, you will see that control is transferred to your handler.
Based on the error message, you're using Visual Studio (2010) for your project. Unless you wrap your throw in a try/catch block, it will "sail through the roof" and be "handled" by the C++ runtime, which means calling abort(). You probably want something like this higher in the call stack:
try
{
SomeFunctionThatUltimatelyThrows();
}
catch(Exception & e)
{
// .. handle error - log, resume, exit, whatever
}
Note also Scott Meyers advice to always catch exceptions by reference. The "exception": If you're using MFC CExceptions though, you want to catch by pointer and call the Delete method for self-destructing heap-based exceptions.
Based on your edit, you may have a mismatch between throwing "by pointer" and catching "by reference". If you've resolved that and are still not getting your catch block to execute, you could try debugging the abort() call by using the CRT SetAbortHandler to install your own abort function. This could simply chain into the existing one, but would give an opportunity to set a breakpoint and examine the call stack to see what is going wrong.
C++ try-catch-throw logic for dummies. Note that this does NOT cover RAII / stack-based allocation / destruction.
When you throw an exception, an exception is said to be "propagating". It propagates up the call stack until it finds the first handler that can handle it (so it's caught) or until it's reached the root of your call stack.
If it is caught, execution continues from the point the exception is caught. The exception is destructed at the end of the catch block.
If it finds the root, it calls std::unhandled_exception, which usually calls std::terminate, which usually calls abort(). In short, everything's dropped ASAP.
If you throw an exception while an exception is currently propagating, you would have two propagating at a time. Java and C# have cutesy ways of dealing with this, but this should never happen in the first place - there's no exception handler that is logically going to handle combinations of exceptions. Do not throw exceptions while one is currently propagating. This rule isn't too hard to hold even if you don't use std::uncaught_exception() which you shouldn't.
While unwinding the stack / propagating the exception all objects found on the stack are destructed. These destructors should never throw an exception - after all, when destroying an object "fails", what else are you going to do after the destructor to fix it?
Always throw by value, catch by reference. If you throw & catch by pointer, you will most likely leak something, which is impossible by reference. If you catch by value, you will slice off your derived exception types. Catch by reference.
At the root of your software, include a catch-all - catch(...). This doesn't allow you to find out what exactly you've caught, but at least you can crash safely. Do this also when the called code may throw "something" that you don't know.