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

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

    XMLWordPrintable

Details

    • 1bcf85bd3 (dev), cdc63b1cb (6.6)

    Description

      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?

      Attachments

        Issue Links

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

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes