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. Catching segfault

Catching segfault

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 5 Posters 3.2k Views
  • 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.
  • N Offline
    N Offline
    Nulik
    wrote on last edited by
    #1

    Hi,
    I want to provide an option to the user, to report App crash. The front end is in QML and from there C++ classes are being called.

    I installed a signal handler to catch SIGSEGV:
    ///main.cpp:

    void signal_handler(int signum) {
        signal(SIGSEGV, SIG_DFL);
        signal(SIGFPE, SIG_DFL);
        aewm_obj.show_fault(signum);
    }
    int main(int argc, char *argv[])
    {
       ....
        signal(SIGSEGV, signal_handler);
        signal(SIGFPE, signal_handler);
        ....
       QGuiApplication app(argc, argv);
       qml_engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
       ....
    }
    

    The show_fault function() should get the stack trace, and send signal to QML where the user will confirm sending of the crash report, something like this:

    void aewm::show_fault(int signum) {
        QString failure_description;
        failure_description=get_stack_trace();
        emit app_fault(signum,failure_description);
    }
    

    However this code seems to be producing another SEGFAULT which is a real SEGFAULT, not a test. Why is this happening? I am generating a test SEGFAULT with this code;

    void aewm::crash_app() {
        char *null_pointer=nullptr;
    
        *null_pointer='A';
    }
    

    The problem is, I can't even debug this with GDB since GDB has its own signal hander and it catches my test SIGSEGV.

    JonBJ 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Do I understand correctly that you are trying to access your gui while your application is crashing ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      N 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Do I understand correctly that you are trying to access your gui while your application is crashing ?

        N Offline
        N Offline
        Nulik
        wrote on last edited by Nulik
        #3

        @SGaist

        yes, If a crash occurs (and I don't know where this is going to happen, within the GUI or, maybe Qt Network classes) I want to send the control to the QML where the user is going to confirm sending the crash report, and Exit the App after that.

        1 Reply Last reply
        0
        • N Nulik

          Hi,
          I want to provide an option to the user, to report App crash. The front end is in QML and from there C++ classes are being called.

          I installed a signal handler to catch SIGSEGV:
          ///main.cpp:

          void signal_handler(int signum) {
              signal(SIGSEGV, SIG_DFL);
              signal(SIGFPE, SIG_DFL);
              aewm_obj.show_fault(signum);
          }
          int main(int argc, char *argv[])
          {
             ....
              signal(SIGSEGV, signal_handler);
              signal(SIGFPE, signal_handler);
              ....
             QGuiApplication app(argc, argv);
             qml_engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
             ....
          }
          

          The show_fault function() should get the stack trace, and send signal to QML where the user will confirm sending of the crash report, something like this:

          void aewm::show_fault(int signum) {
              QString failure_description;
              failure_description=get_stack_trace();
              emit app_fault(signum,failure_description);
          }
          

          However this code seems to be producing another SEGFAULT which is a real SEGFAULT, not a test. Why is this happening? I am generating a test SEGFAULT with this code;

          void aewm::crash_app() {
              char *null_pointer=nullptr;
          
              *null_pointer='A';
          }
          

          The problem is, I can't even debug this with GDB since GDB has its own signal hander and it catches my test SIGSEGV.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Nulik

          The problem is, I can't even debug this with GDB since GDB has its own signal hander and it catches my test SIGSEGV

          GDB allows you to catch/ignore/pass on signals as you choose. Can't you just continue, or perhaps handle SIGSEGV nostop?

          N 1 Reply Last reply
          1
          • JonBJ JonB

            @Nulik

            The problem is, I can't even debug this with GDB since GDB has its own signal hander and it catches my test SIGSEGV

            GDB allows you to catch/ignore/pass on signals as you choose. Can't you just continue, or perhaps handle SIGSEGV nostop?

            N Offline
            N Offline
            Nulik
            wrote on last edited by Nulik
            #5

            @JonB said in Catching segfault:

            GDB allows you to catch/ignore/pass on signals as you choose. Can't you just continue, or perhaps handle SIGSEGV nostop?

            Thanks! Actually, my code works if I send SIGSEGV or SIGFPE from the console using kill -SEGV [PID] , but if I simulate a SIGSEGV by assigning some value to null pointer I can't recover from this.

            Is there a way to send control to QML's main event loop from the signal handler? Or how should one recover from SIGSEGV ? (i.e. abort current execution path and return back to main event loop)

            N 1 Reply Last reply
            0
            • N Nulik

              @JonB said in Catching segfault:

              GDB allows you to catch/ignore/pass on signals as you choose. Can't you just continue, or perhaps handle SIGSEGV nostop?

              Thanks! Actually, my code works if I send SIGSEGV or SIGFPE from the console using kill -SEGV [PID] , but if I simulate a SIGSEGV by assigning some value to null pointer I can't recover from this.

              Is there a way to send control to QML's main event loop from the signal handler? Or how should one recover from SIGSEGV ? (i.e. abort current execution path and return back to main event loop)

              N Offline
              N Offline
              Nulik
              wrote on last edited by Nulik
              #6

              or, maybe I should load another version "main.qml" containing only the Dialog with crash report and 'Send' button? (from the signal handler once it has received the SIGSEGV) I would need to initialize all the variables involved in this , because a SIGSEGV can corrupt memory. Any ideas on how to implement the 'crash report' feature will be greatly appreciated

              N 1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                You have several examples given in the Wikipedia Crash reporter article.

                Breakpad comes to mind when going cross-platform. KDE's Dr Konqi might also be available on other platforms.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • N Nulik

                  or, maybe I should load another version "main.qml" containing only the Dialog with crash report and 'Send' button? (from the signal handler once it has received the SIGSEGV) I would need to initialize all the variables involved in this , because a SIGSEGV can corrupt memory. Any ideas on how to implement the 'crash report' feature will be greatly appreciated

                  N Offline
                  N Offline
                  Nulik
                  wrote on last edited by
                  #8

                  my problem is, that when signal handler exits, the code that caused the SIGSEGV is executed again, and again, in a loop. Hopefully I am clearing the signal handler inside the signal handler itself and it doesn't loop many times, but I that's why I am catching this SIGSEGV twice.

                  1 Reply Last reply
                  0
                  • N Offline
                    N Offline
                    Nulik
                    wrote on last edited by
                    #9

                    I have almost solved it, but for some reason QCoreApplication::exit() doesn't exits the main event loop and I cant reload a new main.qml file.

                    Here is the description of the problem on StackOverflow: https://stackoverflow.com/questions/55699851/how-to-reload-main-qml-file

                    1 Reply Last reply
                    0
                    • W Offline
                      W Offline
                      wrosecrans
                      wrote on last edited by
                      #10

                      Once a segmentation fault has happened, you know you have a memory bug, and the whole process basically has to be assumed to be trashed. Accomplishing anything useful within it at that point is misguided. In general, you can only present the user with a crash handler by having a simple parent process monitoring the child process the user actually interacts with, and then the parent process can detect when the child process has died and present some sort of crash reporter UI if needed.

                      kshegunovK 1 Reply Last reply
                      1
                      • W wrosecrans

                        Once a segmentation fault has happened, you know you have a memory bug, and the whole process basically has to be assumed to be trashed. Accomplishing anything useful within it at that point is misguided. In general, you can only present the user with a crash handler by having a simple parent process monitoring the child process the user actually interacts with, and then the parent process can detect when the child process has died and present some sort of crash reporter UI if needed.

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by kshegunov
                        #11

                        @wrosecrans said in Catching segfault:

                        and the whole process basically has to be assumed to be trashed. Accomplishing anything useful within it at that point is misguided.

                        I disagree. There are specific cases where you must handle the signal. Moreover you may have foreign code that generated the segfault (for example if you load plugins, and the user-programmer made an error), then it can be beneficial to respond to the signal appropriately and do a graceful shutdown, as much as this is possible.

                        Read and abide by the Qt Code of Conduct

                        W 1 Reply Last reply
                        2
                        • kshegunovK kshegunov

                          @wrosecrans said in Catching segfault:

                          and the whole process basically has to be assumed to be trashed. Accomplishing anything useful within it at that point is misguided.

                          I disagree. There are specific cases where you must handle the signal. Moreover you may have foreign code that generated the segfault (for example if you load plugins, and the user-programmer made an error), then it can be beneficial to respond to the signal appropriately and do a graceful shutdown, as much as this is possible.

                          W Offline
                          W Offline
                          wrosecrans
                          wrote on last edited by
                          #12

                          @kshegunov Once the plugin has triggered a segfault, you know longer have any guarantee that anything in your address space is correct, so it's generally safest to just die rather than risk executing code that could do wildly incorrect things. Every bit that the signal handler uses to decide how to safely shut down is suspect at that point.

                          1 Reply Last reply
                          0

                          • Login

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