QQmlObjectCreator: Clear sharedState componentAttached in destruction/clear
authorAlbert Astals Cid <albert.astals@canonical.com>
Tue, 17 Jun 2014 11:10:35 +0000 (13:10 +0200)
committerAlbert Astals Cid <albert.astals@canonical.com>
Fri, 20 Jun 2014 07:19:29 +0000 (09:19 +0200)
Fixes crash when delegate is being deleted while not totally instantiated

Valgrind trace:
==15748== Invalid write of size 8
==15748==    at 0x57A02DB: QQmlComponentAttached::~QQmlComponentAttached() (qqmlcomponent.cpp:985)
==15748==    by 0x57A0318: QQmlComponentAttached::~QQmlComponentAttached() (qqmlcomponent.cpp:989)
==15748==    by 0x668736B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66900EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x5D1D4B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==15748==    by 0x5D33AE5: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement() (qqmlprivate.h:106)
==15748==    by 0x668736B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66900EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x5D1D4B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==15748==    by 0x5D34655: QQmlPrivate::QQmlElement<QQuickLoader>::~QQmlElement() (qqmlprivate.h:106)
==15748==    by 0x668736B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66900EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x5D1D4B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==15748==    by 0x5D33AE5: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement() (qqmlprivate.h:106)
==15748==    by 0x668736B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66900EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x5D1D4B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==15748==    by 0x5D348A5: QQmlPrivate::QQmlElement<QQuickFocusScope>::~QQmlElement() (qqmlprivate.h:106)
==15748==    by 0x668736B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66900EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x5D1D4B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==15748==    by 0x5D34655: QQmlPrivate::QQmlElement<QQuickLoader>::~QQmlElement() (qqmlprivate.h:106)
==15748==    by 0x668736B: QObjectPrivate::deleteChildren() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66900EB: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x5D1D4B5: QQuickItem::~QQuickItem() (qquickitem.cpp:2064)
==15748==    by 0x5D33AE5: QQmlPrivate::QQmlElement<QQuickItem>::~QQmlElement() (qqmlprivate.h:106)
==15748==    by 0x6689607: QObject::event(QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x5D1B012: QQuickItem::event(QEvent*) (qquickitem.cpp:7114)
==15748==    by 0x6659CDC: QCoreApplication::notify(QObject*, QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66599D4: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x665B826: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66B1242: ??? (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x8EE2E43: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4100.0)
==15748==    by 0x8EE3087: g_main_context_iterate.isra.24 (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4100.0)
==15748==    by 0x8EE312B: g_main_context_iteration (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4100.0)
==15748==    by 0x66B06BB: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66578EA: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x665EF45: QCoreApplication::exec() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x40711B: startShell(int, char const**, void*) (main.cpp:171)
==15748==    by 0x407A74: main (main.cpp:227)
==15748==  Address 0x1be83870 is 64 bytes inside a block of size 112 free'd
==15748==    at 0x4C2C2BC: operator delete(void*) (vg_replace_malloc.c:503)
==15748==    by 0x5815FB0: QQmlObjectCreator::~QQmlObjectCreator() (qqmlobjectcreator.cpp:156)
==15748==    by 0x57A52AA: QQmlIncubatorPrivate::clear() (qscopedpointer.h:62)
==15748==    by 0x57A53C6: QQmlIncubator::clear() (qqmlincubator.cpp:577)
==15748==    by 0x5DCEA20: QQuickLoader::setActive(bool) (qquickloader.cpp:350)
==15748==    by 0x5DCF6D2: QQuickLoader::qt_metacall(QMetaObject::Call, int, void**) (moc_qquickloader_p.cpp:277)
==15748==    by 0x579DC66: QQmlPropertyPrivate::write(QObject*, QQmlPropertyData const&, QVariant const&, QQmlContextData*, QFlags<QQmlPropertyPrivate::WriteFlag>) (qqmlproperty.cpp:1322)
==15748==    by 0x579E76E: QQmlPropertyPrivate::writeValueProperty(QObject*, QQmlPropertyData const&, QVariant const&, QQmlContextData*, QFlags<QQmlPropertyPrivate::WriteFlag>) (qqmlproperty.cpp:1246)
==15748==    by 0x579F2F9: QQmlPropertyPrivate::writeBinding(QObject*, QQmlPropertyData const&, QQmlContextData*, QQmlJavaScriptExpression*, QV4::ValueRef, bool, QFlags<QQmlPropertyPrivate::WriteFlag>) (qqmlproperty.cpp:1578)
==15748==    by 0x580CF69: QQmlBinding::update(QFlags<QQmlPropertyPrivate::WriteFlag>) (qqmlbinding.cpp:266)
==15748==    by 0x580D5BD: QQmlBinding::expressionChanged(QQmlJavaScriptExpression*) (qqmlbinding_p.h:105)
==15748==    by 0x57E6156: QQmlNotifier::emitNotify(QQmlNotifierEndpoint*, void**) (qqmlnotifier.cpp:81)
==15748==    by 0x57E6130: QQmlNotifier::emitNotify(QQmlNotifierEndpoint*, void**) (qqmlnotifier.cpp:76)
==15748==    by 0x57E6130: QQmlNotifier::emitNotify(QQmlNotifierEndpoint*, void**) (qqmlnotifier.cpp:76)
==15748==    by 0x5788FA3: QQmlData::signalEmitted(QAbstractDeclarativeData*, QObject*, int, void**) (qqmlengine.cpp:721)
==15748==    by 0x6688232: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x57882A7: QQmlData::destroyed(QObject*) (qqmlengine.cpp:1658)
==15748==    by 0x668FD7D: QObject::~QObject() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x55E8B64: QQmlDMAbstractItemModelData::~QQmlDMAbstractItemModelData() (qqmladaptormodel.cpp:95)
==15748==    by 0x58643DC: QQmlDelegateModelPrivate::release(QObject*) (qqmldelegatemodel.cpp:520)
==15748==    by 0x586440C: QQmlDelegateModel::release(QObject*) (qqmldelegatemodel.cpp:536)
==15748==    by 0x5DFED4F: QQuickItemViewPrivate::releaseItem(FxViewItem*) (qquickitemview.cpp:2349)
==15748==    by 0x5DBAB94: QQuickGridViewPrivate::addVisibleItems(double, double, double, double, bool) (qquickgridview.cpp:497)
==15748==    by 0x5DFC94E: QQuickItemViewPrivate::refill(double, double) (qquickitemview.cpp:1751)
==15748==    by 0x5DFF26A: QQuickItemViewPrivate::layout() (qquickitemview.cpp:1859)
==15748==    by 0x5D275F7: QQuickWindowPrivate::polishItems() (qquickwindow.cpp:271)
==15748==    by 0x5D02B7D: QSGThreadedRenderLoop::polishAndSync(QSGThreadedRenderLoop::Window*) (qsgthreadedrenderloop.cpp:1150)
==15748==    by 0x5D03167: QSGThreadedRenderLoop::event(QEvent*) (qsgthreadedrenderloop.cpp:1235)
==15748==    by 0x6659CDC: QCoreApplication::notify(QObject*, QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66599D4: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66B00CC: QTimerInfoList::activateTimers() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66B03F0: ??? (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x8EE2E43: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4100.0)
==15748==    by 0x8EE3087: g_main_context_iterate.isra.24 (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4100.0)
==15748==    by 0x8EE312B: g_main_context_iteration (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4100.0)
==15748==    by 0x66B06BB: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x66578EA: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x665EF45: QCoreApplication::exec() (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.3.0)
==15748==    by 0x40711B: startShell(int, char const**, void*) (main.cpp:171)
==15748==    by 0x407A74: main (main.cpp:227)

Change-Id: I2c7d38fa5a2566520173bff7ad4e5f9c966d083e
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/qqmlobjectcreator.cpp

index a8eeeee..16c9dd7 100644 (file)
@@ -153,6 +153,10 @@ QQmlObjectCreator::~QQmlObjectCreator()
             if (ps)
                 ps->d = 0;
         }
+        while (sharedState->componentAttached) {
+            QQmlComponentAttached *a = sharedState->componentAttached;
+            a->rem();
+        }
         delete sharedState.data();
     }
 }
@@ -1253,6 +1257,11 @@ void QQmlObjectCreator::clear()
     while (!sharedState->allCreatedObjects.isEmpty())
         delete sharedState->allCreatedObjects.pop();
 
+    while (sharedState->componentAttached) {
+        QQmlComponentAttached *a = sharedState->componentAttached;
+        a->rem();
+    }
+
     phase = Done;
 }