aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2025-09-10 15:00:39 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2025-09-12 03:27:53 +0000
commit1f89af3cfdb44a4b892a4968adc08ce23f694620 (patch)
tree37d05e6cb24797711926616f5c0c2be5a7835790
parent407ee44ae1f871c74b06adc6c2457d618d6e8c7e (diff)
QtQml: Check for locals in metatypes stack frame before accessing them
ScopedStackFrame has no locals and we don't want to crash if we manage to run the GC while e.g. initializing a component. Amends commmit 2d016a2653c59f10a57dc1903b817f71d16d0622 Fixes: QTBUG-140057 Pick-to: 6.8 Change-Id: I7aeb39d6cb1f0ca0a661b8cfa2e7c159f968e224 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> (cherry picked from commit 024e43c68f77f6462c9ffd9e01a2b29feeefa5a3) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit c4bf8c9f801cc78ab2b493f43a89cf86f2ea5b96)
-rw-r--r--src/qml/memory/qv4mm.cpp14
-rw-r--r--tests/auto/qml/qv4mm/tst_qv4mm.cpp13
2 files changed, 20 insertions, 7 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index bae688a13c..ab7f7599c3 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -1480,13 +1480,13 @@ void MemoryManager::collectFromJSStack(MarkStack *markStack) const
if (!frame->isMetaTypesFrame())
continue;
- const QQmlPrivate::AOTTrackedLocalsStorage *locals
- = static_cast<const MetaTypesStackFrame *>(frame)->locals();
-
- // locals have to be initialized first thing when calling the function
- Q_ASSERT(locals);
-
- locals->markObjects(markStack);
+ if (const QQmlPrivate::AOTTrackedLocalsStorage *locals
+ = static_cast<const MetaTypesStackFrame *>(frame)->locals()) {
+ // Actual AOT-compiled functions initialize the locals firsth thing when they
+ // are called. However, the ScopedStackFrame has no locals, but still uses a
+ // MetaTypesStackFrame.
+ locals->markObjects(markStack);
+ }
}
}
diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
index 561ad2b6cc..d8b342bd52 100644
--- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
@@ -57,6 +57,8 @@ private slots:
void scopedConvertToObjectFromReturnedValueDoesNotAccessGarbageOnTheStackOnAllocation();
void scopedConvertToStringFromValueDoesNotAccessGarbageOnTheStackOnAllocation();
void scopedConvertToObjectFromValueDoesNotAccessGarbageOnTheStackOnAllocation();
+
+ void dontCrashOnScopedStackFrame();
};
tst_qv4mm::tst_qv4mm()
@@ -1019,6 +1021,17 @@ void tst_qv4mm::scopedConvertToObjectFromValueDoesNotAccessGarbageOnTheStackOnAl
QV4::ScopedObject object(scope, QV4::StaticValue::fromBoolean(true).asValue<QV4::Value>(), QV4::ScopedObject::Convert);
}
+void tst_qv4mm::dontCrashOnScopedStackFrame()
+{
+ QJSEngine jsengine;
+ QV4::ExecutionEngine *engine = jsengine.handle();
+
+ QV4::Scope scope(engine);
+ QV4::ScopedStackFrame frame(scope, engine->rootContext());
+
+ jsengine.collectGarbage();
+}
+
QTEST_MAIN(tst_qv4mm)
#include "tst_qv4mm.moc"