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

Crash if popping a StackView causes a nested event loop to run

XMLWordPrintable

    • 1bcf85bd3 (dev), cdc63b1cb (6.6)

      Code

      //cppobj.h
      class CppObj : public QObject
      {
          Q_OBJECT
          QML_ELEMENT
          QML_SINGLETON
      
      public:
          explicit CppObj(QObject* parent = nullptr) : QObject(parent) {}
      
          Q_INVOKABLE void spinNestedLoop()
          {
              qDebug("Spinning inner event loop...");
      
              QEventLoop innerLoop;
              QTimer::singleShot(2000, this, [&]{
                  innerLoop.quit();
              });
              innerLoop.exec(); // No nested loop ==> no crash
      
      /*
              // Same outcome if this is used instead of QEventLoop
              int i = 20;
              while (--i >= 0)
              {
                  QThread::msleep(100);
                  QCoreApplication::processEvents();
              }
      */
      
              qDebug("...done!");
          }
      };
      
      // main.qml
      import QtQuick 2.15
      import QtQuick.Controls 2.15
      import NestedEventsPopCrash 1.0
      
      ApplicationWindow {
          id: window
          width: 640
          height: 480
          visible: true
      
          header: Button {
              property bool timeToPush: stackView.depth <= 1
      
              text: timeToPush ? "Push" : "Pop"
              onClicked: {
                  if (timeToPush) {
                      stackView.push(otherComp)
                  } else {
                      console.log("Popping...")
                      let item = stackView.pop()
                      console.log("...Popped!")
                  }
              }
          }
      
          StackView {
              id: stackView
              anchors.fill: parent
              initialItem: Text {
                  text: "Click the 'Push' button"
                  onVisibleChanged: {
                      if (visible)
                          CppObj.spinNestedLoop()
                  }
              }
          }
      
          Component {
              id: otherComp
              Text {
                  text: "Click the 'Pop' button to crash"
                  Component.onDestruction: console.log(this, "says bye")
              }
          }
      }
      

       

      Steps to reproduce

      1. Run the attached example
      2. Click "Push"
      3. Click "Pop"

      After 2 seconds, a segfault should occur.

       

      Notes
      It looks like the crash occurs because the otherComp instance was deleted by stackView.pop() while the nested event loop is running.

       

      This looks very closely related to QTBUG-104608. However, I don't quite follow tvete's explanation for why the bug is invalid. The documentation doesn't say that deleting objects from a nested event loop is forbidden, does it?

        For Gerrit Dashboard: QTBUG-118525
        # Subject Branch Project Status CR V

            vhilshei Volker Hilsheimer
            skoh-qt Sze Howe Koh
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes