If we receive a signal, we re-register ALL previous signal handlers.

This fixes the case when we pass signal to previously registered
handler, and it needs to transform the signal into different one.

Still problematic: What if the signal handler we replaced does not
terminate the application? We can end up in a weird state and loop
forever.

Possible solution: Deregister our signal handlers, CALL the previous
signal handler explicitly and if control returns, abort. This would
however complicate our code quite a bit, as we would have to parse the
sigaction we delegate to, decide whether to use signal handler or signal
action, etc...
This commit is contained in:
Martin Hořeňovský 2017-01-14 15:21:44 +01:00
parent 7c8b93eac3
commit ffc4a9dc14

View File

@ -118,10 +118,10 @@ namespace Catch {
SignalDefs &def = signalDefs[i]; SignalDefs &def = signalDefs[i];
if (sig == def.id) { if (sig == def.id) {
name = def.name; name = def.name;
sigaction(def.id, &oldSigActions[i], CATCH_NULL);
break; break;
} }
} }
reset();
reportFatal(name, -sig); reportFatal(name, -sig);
raise( sig ); raise( sig );
} }
@ -146,7 +146,7 @@ namespace Catch {
~FatalConditionHandler() { ~FatalConditionHandler() {
reset(); reset();
} }
void reset() { static void reset() {
if( isSet ) { if( isSet ) {
// Set signals back to previous values -- hopefully nobody overwrote them in the meantime // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {