Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-132121

Bad signal restoration cause infinite loop in FatalSignalHandler destructor

    XMLWordPrintable

Details

    • Linux/X11
    • 50d1a22e5 (dev), dcf09c0c6 (6.9), 240fe965a (6.8)

    Description

      I think i have found a possible bug in the destructor of the FatalSignalHandler class.

      As i understand the previous sigaction in not well restored in the destructor causing a possible infinite loop if the test emit SIGINT or SIGABRT since the second call to QTest::qExec.

      In the destructor of FatalSignalHandler::~FatalSignalHandler, the loop :

      for (size_t i = 0; i < fatalSignals.size(); ++i) {
          struct sigaction &act = oldActions()[i];
          if (act.sa_flags == 0 && act.sa_handler == SIG_DFL)
              continue; // Already the default
          if (sigaction(fatalSignals[i], nullptr, &action))
              continue; // Failed to query present handler
          if (isOurs(action))
              sigaction(fatalSignals[i], &act, nullptr);
      }

      should be changed to avoid my infinite loop by

      for (size_t i = 0; i < fatalSignals.size(); ++i) {
          struct sigaction &act = oldActions()[i];
          if (sigaction(fatalSignals[i], nullptr, &action))
              continue; // Failed to query present handler
          if (action.sa_flags == 0 && action.sa_handler == SIG_DFL)
              continue; // Already the default
          if (isOurs(action)){
              sigaction(fatalSignals[i], &act, nullptr);
          }
      }

      I think the problem was introduced by this commit in 6.3 : https://github.com/qt/qtbase/commit/29dd43d5ab18ec01df0d173e974d261afd16a311#diff-54b52494b19b90709dc482a4947c665c766a9e72fc00f25769dada130022de81R1905

      To reproduce the problem on Linux platform, create two simple but long test with :

      if(iRes == 0){
          Test1 tc(szDirTestFile);
          iRes = QTest::qExec(&tc);
      }
      
      if(iRes == 0){
          Test2 tc(szDirTestFile);
          iRes = QTest::qExec(&tc);
      }
      

      If you type use in the terminal CRTL+C to emit SIGINT during the Test2 you will have an infinite loop with message like this, but not if you kill on the Test1.

      Received signal 2 (SIGINT)
               test_test2 function time: 403ms, total time: 669ms
      Received signal 2 (SIGINT)
               test_test2 function time: 403ms, total time: 669ms
      Received signal 2 (SIGINT)
               test_test2 function time: 403ms, total time: 669ms
      Received signal 2 (SIGINT)
               test_test2 function time: 403ms, total time: 669ms

      I can confirm the bug is not present in 5.15.

      As workaround we can use -noscrashhandler in the QTest::qExec call.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            Unassigned Unassigned
            ebeuque Eric Beuque
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There is 1 open Gerrit change