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

~QQuickContainer() Crash when calling QQmlIncubator::abort

    XMLWordPrintable

Details

    • 47b4037cc (dev), a2de295be (6.6), 8ec96b617 (tqtc/lts-6.5)

    Description

      When aborting incubation using QQmlIncubator, QQuickContainer references an already deleted item. Backtrace:

      QQuickContainerPrivate::itemAt(int) const (@QQuickContainerPrivate::itemAt(int) const:9)
      QQuickContainerPrivate::cleanup() (@QQuickContainerPrivate::cleanup():23)
      QQuickContainer::~QQuickContainer() (@QQuickContainer::~QQuickContainer():12)
      ___lldb_unnamed_symbol8599 (@___lldb_unnamed_symbol8599:17)
      QQmlObjectCreator::clear() (@QQmlObjectCreator::clear():110)
      QQmlIncubatorPrivate::clear() (@QQmlIncubatorPrivate::clear():104)
      QQmlIncubator::clear() (@QQmlIncubator::clear():30)
      QQmlIncubatorPrivate::clear() (@QQmlIncubatorPrivate::clear():122)
      QQmlIncubator::clear() (@QQmlIncubator::clear():30)
      X::abortIncubation(X*)
      ...
      

      Sample QML file that causes the crash.

      import QtQuick
      import QtQuick.Layouts
      import QtQuick.Controls
      
      Item {
          Repeater {
              model: 100 // Repeat so the panel doesn't incubate immediately - we need to abort while it's still loading.
              TabBar {
                  id: bar
                  width: parent.width
                  TabButton {
                      text: qsTr("Home")
                  }
                  TabButton {
                      text: qsTr("Discover")
                  }
                  TabButton {
                      text: qsTr("Activity")
                  }
              }
          }
      }
      

      Test harness code:

      #include <QFile>
      #include <QGuiApplication>
      #include <QQmlComponent>
      #include <QQmlEngine>
      #include <QQmlIncubator>
      #include <QTimer>
      #include <iostream>
      
      void testIncubation(QQmlIncubationController& controller)
      {
          for (int i = 0; i < 1000; i++) {
              QQmlIncubator incubator;
              QQmlComponent component(controller.engine(), QUrl("qrc:/main.qml"));
              if (component.isError()) {
                  for (const auto& error : component.errors()) {
                      std::cerr << error.toString().toStdString() << std::endl;
                  }
                  exit(-1);
              }
              component.create(incubator);
              controller.incubateFor(i);
              if (controller.incubatingObjectCount() == 0) {
                  std::cout << "We've incubated for " << i << " and the component is fully loaded now." << std::endl;
                  break;
              }
      
              incubator.clear();
          }
      }
      
      int main(int argc, char* argv[])
      {
          QGuiApplication app(argc, argv);
          QQmlEngine engine;
          QQmlIncubationController controller;
          engine.setIncubationController(&controller);
          QTimer::singleShot(1, [&]() {
              testIncubation(controller);
              app.exit(0);
          });
      
          return app.exec();
      }
      

      Attachments

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

        Activity

          People

            smd Jan Arve
            jhuels20 Joshua Huels
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes