0

I want to be able to recover from a Segmentation Fault in MyApplication by catching the SIGSEGV and restarting QApplication. So for testing purposes I'm injecting a segmentation fault in my code.

The issue is that the signal handler that catches the SIGSEGV is getting a non-stop stream of SIGSEGVs. At first I thought it was the while loop in my main but it still happens even though I comment out the while loop. So my questions are simple: Is it even possible to recover from a Segmentation Fault in Qt? Why am I getting rolling SIGSEGVs non-stop?

#include <QApplication>
#include <QDebug>
#include "MyApplication.h"

#include <initializer_list>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

#define RESTART_CODE 1000

void catchUnixSignals(std::initializer_list<int> quitSignals)
{
    auto handler = [](int sig) -> void
    {
        if (sig == SIGSEGV)
        {
            QCoreApplication::exit(RESTART_CODE);
        }
        else
        {
            QCoreApplication::quit();
        }
    };

    sigset_t blocking_mask;
    sigemptyset(&blocking_mask);
    for (auto sig : quitSignals)
        sigaddset(&blocking_mask, sig);

    struct sigaction sa;
    sa.sa_handler = handler;
    sa.sa_mask    = blocking_mask;
    sa.sa_flags   = 0;

    for (auto sig : quitSignals)
        sigaction(sig, &sa, nullptr);
}

int main(int argc, char *argv[])
{
    catchUnixSignals({SIGSEGV, SIGQUIT, SIGINT, SIGTERM, SIGHUP, SIGKILL});

    int i = 0;
    do
    {
        QApplication app(argc, argv);

        MyApp myapp;
        MyApp.start();

        app.exec();

        if (app.exec() != RESTART_CODE) break;
    } while(1);

    return 0;
}
anshah
  • 105
  • 9
  • [This post](https://stackoverflow.com/questions/8401689/best-practices-for-recovering-from-a-segmentation-fault) might prove useful. Also note that there is very little you can do from within a signal handler so `QCoreApplication::exit` etc. is almost certainly *not* going to work. – G.M. Sep 10 '20 at 09:06

1 Answers1

0

This does not directly answers your question, but is another way to achieve similar behavior.

To recover from a segmentation fault, an option is to use a watchdog, i.e. another independent process that checks the status of your main software and restarts it when needed.

  1. When you start your software, you create another process that runs a 2nd software, the watchdog. Ensure to start it in "detached" mode to avoid that it gets closed if your main software crashes.
  2. In the watchdog, frequently call "tasklist" on Windows or "ps" or "top" on Linux and parse the output to check whether your software is still running. OR, use a UDP or TCP port to communicate between the main software and the watchdog, to tell the watchdog that the main software is still running well.
  3. In the watchdog, if the main software is no longer running, restart the main software process (also in detached).
  4. CAUTION: You need to manage the case where the main software is exited correctly. In that case the main software should either kill the watchdog itself when exiting normally (calling "kill" on the pid), or send it a message so that the watchdog exits as well.
Alexandre
  • 498
  • 2
  • 8