aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2016-07-25 16:07:16 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-08-05 18:55:39 +0000
commit68bfc9332cd65c1eb88d1ec87164447b0db43237 (patch)
treec668872cf02f9671fd25c64e916733e8b9ccb93d /src
parentff645deb25c18eeae3d248a6a60bc2954129ee28 (diff)
Fix crash with Component.onDestruction
A call to a handler of Component.onDestruction may end up causing WeakValues such as QQmlData::jsWrapper to be set again, even though they've been set to undefined in an earlier iteration of the loop that walks through the weak references. That in turn may result in invalid object references to objects that are scheduled for destruction by the collector. So after calling all destroy handlers for QObjects, reset all of the weak values again. Task-number: QTBUG-54939 Change-Id: I00ebabb76274e296fb1bd90d8d3e21dbbb920b57 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/memory/qv4mm.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 7ab6d15041..4592dd5c9b 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -428,7 +428,7 @@ void MemoryManager::sweep(bool lastSweep)
Managed *m = (*it).as<Managed>();
if (m->markBit())
continue;
- // we need to call detroyObject on qobjectwrappers now, so that they can emit the destroyed
+ // we need to call destroyObject on qobjectwrappers now, so that they can emit the destroyed
// signal before we start sweeping the heap
if (QObjectWrapper *qobjectWrapper = (*it).as<QObjectWrapper>())
qobjectWrapper->destroyObject(lastSweep);
@@ -436,6 +436,17 @@ void MemoryManager::sweep(bool lastSweep)
(*it) = Primitive::undefinedValue();
}
+ // onDestruction handlers may have accessed other QObject wrappers and reset their value, so ensure
+ // that they are all set to undefined.
+ for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) {
+ if (!(*it).isManaged())
+ continue;
+ Managed *m = (*it).as<Managed>();
+ if (m->markBit())
+ continue;
+ (*it) = Primitive::undefinedValue();
+ }
+
// Now it is time to free QV4::QObjectWrapper Value, we must check the Value's tag to make sure its object has been destroyed
const int pendingCount = m_pendingFreedObjectWrapperValue.count();
if (pendingCount) {