Is the following code
#include <stdexcept>
int main() {
throw std::runtime_error("foobar");
}
guaranteed to produce the following outout?
terminate called after throwing an instance of 'std::runtime_error'
what(): foobar
fish: Job 1, './a.out' terminated by signal SIGABRT (Abort)
Can I rely on this exact output on every compiler?
Can I rely on that what method will be called and error message will be printed will be printed?
No it is not guaranteed, it unspecified whether there is any message. From cppreference:
If an exception is thrown and not caught, including exceptions that escape the initial function of std::thread, the main function, and the constructor or destructor of any static or thread-local objects, then std::terminate is called. It is implementation-defined whether any stack unwinding takes place for uncaught exceptions.
The case that is relevant here is "exceptions that escape [...] the main function". The call to std::terminate is guaranteed though. And you can install a std::terminate_handler to print a custom message if you like.
Related
I have a non-void function which returns a value to be used as an input of a class constructor, but there is a possibility for that value not to be available, so I want to return the value in case of success or just terminate (std::terminate()) the application in case of failure before the function return.
Since std::terminate is called by the runtime according to https://en.cppreference.com/w/cpp/error/terminate, am I obliged to throw an exception and let the runtime decide whether the program is terminated or not?
What about the following warning I read in a simple test I just performed? "terminate called without an active exception"
Am I going in a stupid way?
Thanks for your insights in advance!
... I obliged to throw an exception and let the runtime decide whether the program is terminated or not?
It is up to you. If you want to be able for an exception to be caught somewhere up the call stack then you should throw an exception. In cases you want to terminate because there is no way to recover then calling std::terminate is fine. Just consider that if you throw an exception which is not caught then the program terminates anyhow, so you can choose to either catch it or not, while std::terminate terminates always.
The same page that you linked to, in your question, also has the following statement:
std::terminate() may also be called directly from the program.
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 ]
void myterminate ()
{
cout << "terminate handler called";
}
int main (void)
{
set_terminate (myterminate);
throw; // throwing an exception. So, terminate handler should be invoked
// as no one is handling this exception.
getch();
return 0;
}
But After executing this code, the output is:
terminate handler called + "Debug Error!" dialog box appears.
I am not sure why it is coming like this !!!! Please help.
Based on the MSDN documentation for set_terminate the new handler function must call exit() or abort() will be called:
The set_terminate function installs term_func as the function called by terminate. set_terminate is used with C++ exception handling and may be called at any point in your program before the exception is thrown. terminate calls abort by default. You can change this default by writing your own termination function and calling set_terminate with the name of your function as its argument. terminate calls the last function given as an argument to set_terminate. After performing any desired cleanup tasks, term_func should exit the program. If it does not exit (if it returns to its caller), abort is called.
For example:
void myterminate ()
{
cout << "terminate handler called";
exit(1);
}
According to the requirments of the standard, a function used as a terminate_handler must meet the following requirement (ISO/IEC 14882:2011 18.8.3.1):
Required behavior: A terminate_handler shall terminate execution of the program without returning
to the caller.
As your function doesn't meet this requirement you program has undefined behaviour. In order to see your custom diagnostic you should output a newline to std::cout (as this can be required on many platforms) and then terminate the program in some way, such as calling std::abort.
std::abort is used to signal an abnormal termination of the program so you can expect extra diagnostics to be reported to the user such as via the dialog box that you are seeing.
Note that using std::exit from a terminate handler is potentially dangerous as std::terminate might be called in response to an exceptional condition occurring in a function registered with std::atexit or std:: at_quick_exit. This would lead to a second attempt to call std::exit.
In summary, if you don't want an "abnormal" termination, you almost always need to catch exceptions that you throw.
You have to exit program in your terminate handler. Add the following line to the handler and it will work:
exit(-1);
What's the difference between those three, and how shall I end program in case of exception which I can't handle properly?
abort indicates "abnormal" end to the program, and raises the the POSIX signal SIGABRT, which means that any handler that you have registered for that signal will be invoked, although the program will still terminate afterwords in either case. Usually you would use abort in a C program to exit from an unexpected error case where the error is likely to be a bug in the program, rather than something like bad input or a network failure. For example, you might abort if a data structure was found to have a NULL pointer in it when that should logically never happen.
exit indicates a "normal" end to the program, although this may still indicate a failure (but not a bug). In other words, you might exit with an error code if the user gave input that could not be parsed, or a file could not be read. An exit code of 0 indicates success. exit also optionally calls handlers before it ends the program. These are registered with the atexit and on_exit functions.
std::terminate is what is automatically called in a C++ program when there is an unhandled exception. This is essentially the C++ equivalent to abort, assuming that you are reporting all your exceptional errors by means of throwing exceptions. This calls a handler that is set by the std::set_terminate function, which by default simply calls abort.
In C++, you usually want to avoid calling abort or exit on error, since you're better off throwing an exception and letting code further up the call stack decide whether or not ending the program is appropriate. Whether or not you use exit for success is a matter of circumstance - whether or not it makes sense to end the program somewhere other than the return statement in main.
std::terminate should be considered a last-ditch error reporting tool, even in C++. The problem with std::terminate is that the terminate handler does not have access to the exception that went unhandled, so there's no way to tell what it was. You're usually much better off wrapping the entirety of main in a try { } catch (std::exception& ex) { } block. At least then you can report more information about exceptions that derived from std::exception (although of course exceptions that do not derive from std::exception would still end up unhandled).
Wrapping the body of main in try { } catch(...) { } isn't much better than setting a terminate handler, because again you have no access to the exception in question. There is at least one benefit, though: whether stack unwinding is done when an exception goes completely uncaught is implementation defined, so if you need guaranteed stack unwinding, this would be a way to get that.
std::abort and std::exit (and more: std::_Exit, std::quick_exit) are just lower level functions. You use them to tell the program what you want it to do exactly: what destructors (and if) to call, what other clean-up functions to call, what value to return, etc.
std::terminate is a higher level abstraction: it is called (by either run-time or you) to indicate that an error in the program occurred and that for some reason it is not possible to handle by throwing an exception. The necessity for that typically occurs when error occurs in the exception mechanism itself, but you can use it any time when you do not want your program to continue beyond the given error. I compiled the full list of situations when std::terminate is called in my post. It is not specified what std::terminate does, because you are in control of it. You can configure the behavior by registering any functions. The limitations you have are that the function cannot return back to the error site and it cannot exit via an exception, but technically you can even start your message pump inside. For the list of useful things that you can do inside, see my other post.
In particular, note that std::terminate is considered an exception handler in contexts where std::terminate is called due to a thrown exception that could not be handled, and you can check what the exception was and inspect it by using C++11 using std::rethrow_exception and std::current_exception. It is all in my post.
quick_exit() !
If your program is multi-threaded, then calling exit() will most likely result in a crash because global/static std::thread objects will be attempted to destruct without exiting their threads.
If you want to return an error code and exit the program (more or less) normally, call quick_exit() in multi-threaded programs.
For abnormal termination (without a possibility for you to specify the error code), abort() or std::terminate() can be called.
Note: quick_exit() has not been supported by MSVC++ until version 2015 .
terminate() is automatically called
when an exception occurs that cannot
be handled. By default, terminate()
calls abort(). You can set a custom
handle with set_terminate() function.
abort() sends the SIGABRT signal.
exit() is not necessarily a bad
thing. It successfully exits the
application, and calls atexit()
functions in LIFO order. I don't
normally see this in C++
applications, however, I do see it in
many unix based applications where it
sends an exit code at the end.
Usually a exit(0) indicates a
successful run of the application.
terminate leaves you the possibility to register what will happen when it is called. Should be one of the other two.
exit is a normal exit allowing to specify an exit status. Handlers registered by at_exit() are run
abort is an abnormal exit. The only thing which is ran is the signal handler for SIGABRT.
My advice would be not to use any of them. Instead, catch the exceptions you can't handle in main() and simply return from there. This means that you are guaranteed that stack unwinding happens correctly and all destructors are called. In other words:
int main() {
try {
// your stuff
}
catch( ... ) {
return 1; // or whatever
}
}
I am not asking an unexpected exception, but an exception that is not captured.
Crashed? Or terminated?
According to §15.3/9:
If no matching handler is found in a program, the function terminate() is called; whether or not the stack is unwound before this call to terminate() is implementation-defined (15.5.1). Emphasis mine
What happens after that is up to your OS. In practice: a crash. (Or if you're in a debugger, "Hey, you didn't catch this.")
Typically terminate will call abort() which quits the process, possibly dumping a core, or if a debugger is attached, stops in the debugger so you can see what happened. If you don't catch the exception somewhere, the program cannot continue.