Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt GUI Recover from a SIGSEGV
Forum Updated to NodeBB v4.3 + New Features

Qt GUI Recover from a SIGSEGV

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 4 Posters 631 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    anshah
    wrote on last edited by anshah
    #1

    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;
    }
    
    JonBJ 1 Reply Last reply
    0
    • A anshah

      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;
      }
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @anshah
      Why are trying to do such a thing in the first place? Catching and continuing safely after, say, SIGSEGV is fraught at best.

      You may want to Google for trap sigsegv and read through the various articles (e.g. stackoverflow) where people discuss this.

      Meanwhile: I'm not sure for the exact reason of your continuing problem. However, if you do trap a signal you are only allowed to do very limited things indeed inside the handler. In yours you choose to call QCoreApplication::exit/quit(). These are likely to invoke complex code, and wouldn't surprise me at all if there are problems in what it calls.

      If you really want to try this, I would arrange (somehow) that the handler only does something very simple like setting a flag. And then exit the handler. Then have caller inspect the flag and have it call the QCoreApplication methods. But I agree this may be difficult to achieve, once you trap a signal when you exit the handler you are allowing code to continue from the point where it got the signal, and if it does that goodness knows what it will then try to do next.

      So again: why do you expect/want to try to trap such a signal?

      Pablo J. RoginaP 1 Reply Last reply
      3
      • gde23G Offline
        gde23G Offline
        gde23
        wrote on last edited by
        #3

        In the signal handler you are only allowed to do really basic things (see here what you can do).
        So as JonB already pointed out QCoreApllication probably is not from that category.
        Besides not working it is also really dangerous to try such things because the program is at a state where is has undefined behavior so more or less anything could happen.

        Now the constructive part: What I would do is make a second application or script, that just loops around and checks if your application is still running and if not then starts it.

        1 Reply Last reply
        5
        • JonBJ JonB

          @anshah
          Why are trying to do such a thing in the first place? Catching and continuing safely after, say, SIGSEGV is fraught at best.

          You may want to Google for trap sigsegv and read through the various articles (e.g. stackoverflow) where people discuss this.

          Meanwhile: I'm not sure for the exact reason of your continuing problem. However, if you do trap a signal you are only allowed to do very limited things indeed inside the handler. In yours you choose to call QCoreApplication::exit/quit(). These are likely to invoke complex code, and wouldn't surprise me at all if there are problems in what it calls.

          If you really want to try this, I would arrange (somehow) that the handler only does something very simple like setting a flag. And then exit the handler. Then have caller inspect the flag and have it call the QCoreApplication methods. But I agree this may be difficult to achieve, once you trap a signal when you exit the handler you are allowing code to continue from the point where it got the signal, and if it does that goodness knows what it will then try to do next.

          So again: why do you expect/want to try to trap such a signal?

          Pablo J. RoginaP Offline
          Pablo J. RoginaP Offline
          Pablo J. Rogina
          wrote on last edited by
          #4

          @anshah as suggested by @gde23 you may want to rely on some other application/script/service to watchdog for your Qt app and restart it just in case.

          You may want to look at this example using systemd

          Upvote the answer(s) that helped you solve the issue
          Use "Topic Tools" button to mark your post as Solved
          Add screenshots via postimage.org
          Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved