Search code examples
c++signalsexitresource-cleanup

How to destroy object created in main() after SIGSEGV


I would like to know if there is any trivial way of destroying an object that was created in main() after the application just crashed (or was interrupted, or some other. See the code:

#include <iostream>
#include <signal.h>
#include <stdlib.h>

class TestClass {
public:
    TestClass() { std::cerr << "Constructor" << std::endl; }
    ~TestClass() { std::cerr << "Destructor" << std::endl; }
};

void signal_handler(int signum) {
    std::cerr << "Signal caught " << signum << std::endl;
    exit(1);
}

int main() {

    TestClass a; 

    struct sigaction new_action, old_action;
    new_action.sa_handler = signal_handler;
    sigemptyset (&new_action.sa_mask);
    new_action.sa_flags = 0;

    sigaction (SIGSEGV, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
    {
        sigaction (SIGSEGV, &new_action, NULL);
    }
    // CRASH !!!
    int* p = 0; *p = 0;
}

So, I install a signal handler, which upon execution shall do some cleanup, and just exit afterwards. Obviously, it is a big application, so I'd like to call the destructor of my classes which have created temporary files (theoretically speaking).

It would be easy to allocate it dynamically and in the signal_handler just free it (in order to call the destructor), but that involves some extra work.

And also, it could be a global object, but I want to avoid the global initialization order issue ...


Solution

  • You could try to orchestrate an orderly shutdown on SIGSEGV. It's not without its pitfalls, but start here: Is it possible to terminate only the one thread on receiving a SIGSEGV?

    You could try to terminate the one offending thread in your signal handler, and set a global flag to say "We're screwed, time to shut down." Then in your main message loop, check the flag and break out if it's set.