Why is my terminate handler never invoked? - c++

I have read that one can call std::set_terminate() to use own function as global exception handler, which catches all unhandled exceptions.
Simplified code of my program:
#include <exception>
#include <stdexcept>
#include <iostream>
void my_terminate_handler()
{
std::cerr << "Terminate handler" << std::endl;
std::cin.get();
std::abort();
}
int main()
{
std::set_terminate(my_terminate_handler);
int i = 1;
i--;
std::cout << 1/i << std::endl;
return 0;
}
Why my_terminate_handler() never invoked? Both in VC++ 2013, 2015 RC and gcc++-4.8.

The terminate handler will be called if the program calls terminate. This can happen for various reasons - including an uncaught exception - but division by zero isn't one of those reasons. That gives undefined behaviour; typically, it raises a signal (not a C++ exception), and you'd need to install a signal handler, not a terminate handler, to catch that.

Because there is no uncaught exception in your code. Add one and it gets executed:
#include <exception>
#include <stdexcept>
#include <iostream>
void my_terminate_handler()
{
std::cerr << "Terminate handler" << std::endl;
}
int main()
{
std::set_terminate(my_terminate_handler);
throw "cake";
}

Related

C++ thrown exception message not shown when running app from Windows CMD

If I run a simple app
#include <stdexcept>
int main() {
throw std::runtime_error("Hello World!");
}
with Windows CMD, the error message is not shown. How can I fix it?
Let's take a look at what throw does in C++ from the official Microsoft Docs.
In the C++ exception mechanism, control moves from the throw statement to the first catch statement that can handle the thrown type.
Note that this means throw does not actually output anything on its own — you'd have to catch it first, then output something. Also note that this means the throw will have to be surrounded by try if you want to do anything with the exception other than terminate the program (which throwing the exception will do on its own).
See below for an example of how to use throw properly.
#include <stdexcept>
#include <cstdio>
int main() {
try {
throw std::runtime_error("Hello World!");
} catch (const std::exception& e) {
puts(e.what());
}
}
The only thing guaranteed to happen when an exception escapes main is that the program stops.
To print the message of an exception you have to catch it and print the message
#include <stdexcept>
#include <cstdio>
int main()
{
try {
throw std::runtime_exception("Hello World!");
} catch (const std::exception& e) {
std::puts(e.what());
}
}

gsl::fail_fast not found in the namespace

In this simple use of C++ contracts, I get the error: no type named 'fail_fast' in namespace 'gsl'. Will try block throw the fast_fail exception or some other exception?
#define GSL_THROW_ON_CONTRACT_VIOLATION
#include <gsl/gsl>
#include <iostream>
int main(void)
{
try {
Expects(false);
}
catch(const gsl::fail_fast &e) {
std::cout << "exception: " << e.what() << '\n';
}
}
GSL_THROW_ON_CONTRACT_VIOLATION and gsl::fast_fail were removed from the Microsoft GSL starting with release v3.0.0. All contract violations result in a call to std::terminate unless you are building in kernel mode for MSVC where it invokes __fastfail.
Header file gsl_assert.h only defines gsl::fail_fast exception with GSL_THROW_ON_CONTRACT_VIOLATION defined. So it compiles now? – Serve Laurijssen
There was a period of time where gsl::fast_fail was defined only when GSL_THROW_ON_CONTRACT_VIOLATION was defined, however that was identified in #267 and subsequently fixed in #268.

Why do unhandled exceptions cause a segmentation fault?

Here is a minimum example:
[joel#maison various] (master *)$ cat throw.cpp
#include <iostream>
int main(int argc, char* argv[])
{
throw("pouet pouet");
}
[joel#maison various] (master *)$ ./a.out
terminate called after throwing an instance of 'char const*'
Aborted (core dumped)
Reading the docs, it seems like the default terminate handler is abort(). I couldn't find anything about triggering a segfault in the abort man page.
Throwing an exception and not handling it calls abort() which raises SIGABRT.
You can verify it with the following
#include <iostream>
#include <stdexcept>
#include <signal.h>
extern "C" void handle_sigabrt(int)
{
std::cout << "Handling and then returning (exiting)" << std::endl;
}
int main()
{
signal(SIGABRT, &handle_sigabrt);
throw("pouet pouet");
}
Demo

Exception Handling - set_unexpected() not able to call

#include "iostream"
#include "conio.h"
#include "exception"
#include "cstdlib"
using namespace std;
void myunexpected ()
{
cerr << "unexpected called\n";
throw 0; // throws int (in exception-specification)
}
void myfunction () throw (int)
{
throw 'x'; // throws char (not in exception-specification)
}
int main (void)
{
set_unexpected (myunexpected);
try
{
myfunction();
}
catch (int) { cerr << "caught int\n"; }
catch (...) { cerr << "caught other exception (non-compliant compiler?)\n"; }
getch();
return 0;
}
Output(When executed on Visual studio 2008):
caught other exception (non-compliant compiler?)
But, I was expecting the output to be:
unexpected called
caught int
NOTE: I executed this program on Visual Studio 2008.
Yes, as per the Standard the output should be[#1]:
unexpected called
caught int
gcc gives accurate result.
Note that, MSVC is notoriously buggy w.r.t handling exception specifications. Exception specifications are considered a failed experiment.
AFAIK, MSVC does not implement exception specifications, except for the empty ones (throw()/nothrow)
C++03 Standard:
[#1] 15.5.2 The unexpected() function [except.unexpected]
The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a new exception which is allowed by the exception specification which previously was violated, then the search for another handler will continue at the call of the function whose exception specification was violated....

set_terminate function is not working for me

I have the following code taken from cplusplus.com:
// set_terminate example
#include <iostream>
#include <exception>
#include <cstdlib>
using namespace std;
void myterminate () {
cout << "terminate handler called\n";
abort(); // forces abnormal termination
}
int main (void) {
set_terminate (myterminate);
throw 0; // unhandled exception: calls terminate handler
return 0;
}
As there is unhandled exception in the code, it needs to call myterminate() function which is set as terminate handler and supposed to override the default terminate handler.
The program is crashing but not calling myterminate(). I am using Visual C++ 2008 Express Edition.
What's the issue with the code?
One possibility - if you are running the program inside VC++ debugger, the debugger catches unhandled exceptions and it might not return control back to the running program to run myterminate. Try to run your program outside Visual C++.