We have a library that deals with many aspects of error reporting. I have been tasked to port this library to Linux. When running though my little test suite, one of the tests failed. A simplified version of the test appears below.
// Compiler: 4.1.1 20070105 RedHat 4.1.1-52
// Output: Terminate called after throwing an instance of 'int' abort
#include <iostream>
#include <csignal>
using namespace std;
void catch_signal(int signalNumber)
{
signal(SIGINT, SIG_DFL);
throw(signalNumber);
}
int test_signal()
{
signal(SIGINT, catch_signal);
try
{
raise(SIGINT);
}
catch (int &z)
{
cerr << "Caught exception: " << z << endl;
}
return 0;
}
int main()
{
try
{
test_signal();
}
catch (int &z)
{
cerr << "Caught unexpected exception: " << z << endl;
}
return 0;
}
My expectation is that the Caught exception: message will be displayed. What actually happens is that the program terminates as no catch handler appears to be present for the thrown int.
There are a few questions on SO that seem related. I found a number of Google pages that were related. The 'wisdom' seems to boil down to.
The code works as expected on our AIX/TRU64/MSVC compiler/environments. It fails in our Linux environment.
EDIT: Possibly related - Throwing C++ exceptions from a hardware exception handler. Why does -fnon-call-exceptions not behave as expected?
Signals are totally different than C++ exceptions. You can't use a C++ try/catch block to handle a signal. Specifically, signals are a POSIX concept, not a C++ language concept. Signals are delivered asynchronously to your application by the kernel, whereas C++ exceptions are synchronous events defined by the C++ standard.
You are quite limited in what you can do portably in a POSIX signal handler. A common strategy is to have a global flag of type sig_atomic_t
which will be set to 1 in the signal handler, and then possibly longjmp
to the appropriate execution path.
See here for help writing proper signal handlers.