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

Changing sourceComponent in Loader from item crashes application in debug Qt version

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • P2: Important
    • None
    • 5.2.1, 5.3.2, 5.4.2, 5.5.0
    • None
    • Mageia Linux Cauldron x86_64

    Description

      This program crashes due to failed assert:

      import QtQuick 2.2
      import QtQuick.Window 2.1
      import QtQuick.Controls 1.1
      
      Window {
          id: main
      
          property string text: "Test text"
      
          visible: true
      
          Loader {
              id: categoryLoader
      
              anchors.centerIn: parent
              sourceComponent: labelComponent
      
              Component {
                  id: labelComponent
      
                  Row {
                      spacing: 10
      
                      Label {
                          anchors.verticalCenter: parent.verticalCenter
                          text: main.text
                      }
      
                      Button {
                          anchors.verticalCenter: parent.verticalCenter
                          text: "Edit"
      
                          onClicked: categoryLoader.sourceComponent = editorComponent
                      }
                  }
              }
      
              Component {
                  id: editorComponent
      
                  TextField {
                      text: main.text
      
                      onEditingFinished: {
                          main.text = text
                          categoryLoader.sourceComponent = labelComponent
                      }
                  }
              }
          }
      }
      

      To reproduce, click on "Edit" button, change some text and press Enter.

      I cannot reproduce it with official Qt binaries, only if I compile Qt on my own and only if I configure Qt with -debug or -developer-build. With -release the program works fine.

      Stack trace:

      0	raise			0x7ffff54c8627	
      1	abort			0x7ffff54c9dba	
      2	qt_message_fatal	qlogging.cpp	1575	0x7ffff65c42f2	
      3	QMessageLogger::fatal	qlogging.cpp	777	0x7ffff65c0a5e	
      4	qt_assert	qglobal.cpp	2967	0x7ffff65b9cd6	
      5	QQuickItemPrivate::removeChild	qquickitem.cpp	2735	0x7ffff7a6f149	
      6	QQuickItem::setParentItem	qquickitem.cpp	2513	0x7ffff7a6e4f0	
      7	QQuickLoaderPrivate::clear	qquickloader.cpp	110	0x7ffff7b6a016	
      8	QQuickLoader::setSourceComponent	qquickloader.cpp	463	0x7ffff7b6a810	
      9	QQuickLoader::qt_static_metacall	moc_qquickloader_p.cpp	250	0x7ffff7b6c0b6	
      10	QQuickLoader::qt_metacall	moc_qquickloader_p.cpp	301	0x7ffff7b6c24d	
      11	QMetaObject::metacall	qmetaobject.cpp	296	0x7ffff68075ff	
      12	QQmlPropertyPrivate::write	qqmlproperty.cpp	1329	0x7ffff6e38de1	
      13	QV4::QObjectWrapper::setProperty	qv4qobjectwrapper.cpp	556	0x7ffff6de1ba3	
      14	QV4::QObjectWrapper::setQmlProperty	qv4qobjectwrapper.cpp	443	0x7ffff6de08ce	
      15	QV4::QObjectWrapper::put	qv4qobjectwrapper.cpp	708	0x7ffff6de2641	
      16	QV4::Object::put	qv4object_p.h	280	0x7ffff6cb950d	
      17	QV4::Runtime::setProperty	qv4runtime.cpp	567	0x7ffff6e00972	
      18	QV4::Moth::VME::run	qv4vme_moth.cpp	496	0x7ffff6deedfb	
      19	QV4::Moth::VME::exec	qv4vme_moth.cpp	925	0x7ffff6df2e02	
      20	QV4::ScriptFunction::call	qv4functionobject.cpp	458	0x7ffff6d7cc6d	
      21	QV4::Object::call	qv4object_p.h	302	0x7ffff6cb95da	
      22	QQmlJavaScriptExpression::evaluate	qqmljavascriptexpression.cpp	158	0x7ffff6eb753c	
      23	QQmlBoundSignalExpression::evaluate	qqmlboundsignal.cpp	281	0x7ffff6e4b0c7	
      24	QQmlBoundSignal_callback	qqmlboundsignal.cpp	408	0x7ffff6e4b710	
      25	QQmlNotifier::emitNotify	qqmlnotifier.cpp	73	0x7ffff6e96ca7	
      26	QQmlData::signalEmitted	qqmlengine.cpp	751	0x7ffff6e1fb4c	
      27	QMetaObject::activate	qobject.cpp	3604	0x7ffff683c828	
      28	QQmlVMEMetaObject::activate	qqmlvmemetaobject.cpp	1325	0x7ffff6e1c062	
      29	QQmlVMEMetaObject::metaCall	qqmlvmemetaobject.cpp	914	0x7ffff6e1a052	
      30	QAbstractDynamicMetaObject::metaCall	qobject_p.h	421	0x7ffff6bddea4	
      31	QMetaObject::metacall	qmetaobject.cpp	294	0x7ffff68075df	
      32	QQmlObjectOrGadget::metacall	qqmlpropertycache.cpp	1689	0x7ffff6e90b54	
      33	CallMethod	qv4qobjectwrapper.cpp	1178	0x7ffff6de3de6	
      34	CallPrecise	qv4qobjectwrapper.cpp	1413	0x7ffff6de47bf	
      35	QV4::QObjectMethod::callInternal	qv4qobjectwrapper.cpp	1898	0x7ffff6de6f5f	
      36	QV4::QObjectMethod::call	qv4qobjectwrapper.cpp	1833	0x7ffff6de6951	
      37	QV4::Object::call	qv4object_p.h	302	0x7ffff6cb95da	
      38	QV4::Runtime::callProperty	qv4runtime.cpp	974	0x7ffff6e0327e	
      39	QV4::Moth::VME::run	qv4vme_moth.cpp	556	0x7ffff6def56d	
      40	QV4::Moth::VME::exec	qv4vme_moth.cpp	925	0x7ffff6df2e02	
      41	QV4::ScriptFunction::call	qv4functionobject.cpp	458	0x7ffff6d7cc6d	
      42	QV4::Object::call	qv4object_p.h	302	0x7ffff6cb95da	
      43	QQmlJavaScriptExpression::evaluate	qqmljavascriptexpression.cpp	158	0x7ffff6eb753c	
      44	QQmlBoundSignalExpression::evaluate	qqmlboundsignal.cpp	281	0x7ffff6e4b0c7	
      45	QQmlBoundSignal_callback	qqmlboundsignal.cpp	408	0x7ffff6e4b710	
      46	QQmlNotifier::emitNotify	qqmlnotifier.cpp	73	0x7ffff6e96ca7	
      47	QQmlData::signalEmitted	qqmlengine.cpp	751	0x7ffff6e1fb4c	
      48	QMetaObject::activate	qobject.cpp	3604	0x7ffff683c828	
      49	QMetaObject::activate	qobject.cpp	3583	0x7ffff683c62e	
      50	QQuickTextInput::editingFinished	moc_qquicktextinput_p.cpp	1156	0x7ffff7c1cc65	
      51	QQuickTextInputPrivate::processKeyEvent	qquicktextinput.cpp	4270	0x7ffff7b05db9	
      52	QQuickTextInput::keyPressEvent	qquicktextinput.cpp	1522	0x7ffff7afb110	
      53	QQuickItemPrivate::deliverKeyEvent	qquickitem.cpp	4649	0x7ffff7a7413b	
      54	QQuickItem::event	qquickitem.cpp	7251	0x7ffff7a7a43c	
      55	QQuickTextInput::event	qquicktextinput.cpp	1730	0x7ffff7afbd2f	
      56	QCoreApplicationPrivate::notify_helper	qcoreapplication.cpp	1093	0x7ffff67fed2a	
      57	QCoreApplication::notify	qcoreapplication.cpp	1038	0x7ffff67fea0c	
      58	QGuiApplication::notify	qguiapplication.cpp	1537	0x7ffff727cf3e	
      59	QCoreApplication::notifyInternal	qcoreapplication.cpp	965	0x7ffff67fe916	
      60	QCoreApplication::sendEvent	qcoreapplication.h	224	0x7ffff7a7e7dd	
      61	QQuickWindow::sendEvent	qquickwindow.cpp	2594	0x7ffff7a973eb	
      62	QQuickWindowPrivate::deliverKeyEvent	qquickwindow.cpp	1443	0x7ffff7a9075a	
      63	QQuickWindow::keyPressEvent	qquickwindow.cpp	1421	0x7ffff7a90673	
      64	QWindow::event	qwindow.cpp	1989	0x7ffff728d8c9	
      65	QQuickWindow::event	qquickwindow.cpp	1414	0x7ffff7a9063e	
      66	QCoreApplicationPrivate::notify_helper	qcoreapplication.cpp	1093	0x7ffff67fed2a	
      67	QCoreApplication::notify	qcoreapplication.cpp	1038	0x7ffff67fea0c	
      68	QGuiApplication::notify	qguiapplication.cpp	1537	0x7ffff727cf3e	
      69	QCoreApplication::notifyInternal	qcoreapplication.cpp	965	0x7ffff67fe916	
      70	QCoreApplication::sendSpontaneousEvent	qcoreapplication.h	227	0x7ffff72848f9	
      71	QGuiApplicationPrivate::processKeyEvent	qguiapplication.cpp	1899	0x7ffff727e356	
      72	QGuiApplicationPrivate::processWindowSystemEvent	qguiapplication.cpp	1588	0x7ffff727d0dc	
      73	QWindowSystemInterface::sendWindowSystemEvents	qwindowsysteminterface.cpp	608	0x7ffff72658b1	
      74	userEventSourceDispatch	qeventdispatcher_glib.cpp	70	0x7fffe9d6f510	
      75	g_main_context_dispatch			0x7ffff3b370bd	
      76	g_main_context_iterate.isra			0x7ffff3b37368	
      77	g_main_context_iteration			0x7ffff3b3740c	
      78	QEventDispatcherGlib::processEvents	qeventdispatcher_glib.cpp	418	0x7ffff6874381	
      79	QPAEventDispatcherGlib::processEvents	qeventdispatcher_glib.cpp	115	0x7fffe9d6f732	
      80	QEventLoop::processEvents	qeventloop.cpp	128	0x7ffff67fb516	
      81	QEventLoop::exec	qeventloop.cpp	204	0x7ffff67fb7ef	
      82	QCoreApplication::exec	qcoreapplication.cpp	1229	0x7ffff67feff0	
      83	QGuiApplication::exec	qguiapplication.cpp	1528	0x7ffff727ceee	
      84	main	main.cpp	11	0x400e97	
      

      Doing some research, I found possible source of the problem.
      In QQuickLoaderPrivate::clear() it calls item->setParentItem(0). In QQuickItem::setParentItem() it calls clearFocusInScope() for QQuickWindowPrivate and maybe in other thread the loader object is changed and it has new item property. When setParentItem() continues execution, it tries to remove oneself from parent's children list using pointer to parent. But the pointer now leads to a different item which has different children list and this fails assert.

      Possible fix:

      --- src/quick/items/qquickitem.cpp
      +++ src/quick/items/qquickitem.cpp
      @@ -2510,7 +2510,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
               }
       
               const bool wasVisible = isVisible();
      -        op->removeChild(this);
      +        if (op->childItems.contains(this)) {
      +            op->removeChild(this);
      +        }
               if (wasVisible) {
                   emit oldParentItem->visibleChildrenChanged();
               }
      

      This looks more like a hack, so may be it should be fixed in a different way.

      Attachments

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

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            krnekit Nikita Krupenko
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes