aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSemih Yavuz <semih.yavuz@qt.io>2022-11-17 14:36:47 +0100
committerSemih Yavuz <semih.yavuz@qt.io>2022-11-25 15:47:00 +0000
commitfe32f58008f89b7174e9f41a781e6fba5799c026 (patch)
tree3ebda2cae678b0382ede57d0d70a55ce9563a27b
parentd9dfe91417e87db59825500d7b2791ad4d7516b6 (diff)
Debugger: Initialize scoped context correctly
Initialize scopedContext with valid qmlContext. Otherwise debugger crashes on attempt to lookup an object that includes a v4Function property Pick-to: 6.2 6.4 Fixes: QTBUG-107607 Change-Id: Iea59bdf9d379a5415abe1767f76f851978b1be3f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp4
-rw-r--r--tests/auto/qml/debugger/qv4debugger/CMakeLists.txt12
-rw-r--r--tests/auto/qml/debugger/qv4debugger/commontypes.h20
-rw-r--r--tests/auto/qml/debugger/qv4debugger/data/qtbug_107607.qml10
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp55
5 files changed, 97 insertions, 4 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index 383668833b..6ed24f29d1 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -175,8 +175,8 @@ void ValueLookupJob::run()
QScopedPointer<QObject> scopeObject;
QV4::ExecutionEngine *engine = collector->engine();
QV4::Scope scope(engine);
- QV4::Heap::ExecutionContext *qmlContext = nullptr;
- if (engine->qmlEngine() && !engine->qmlContext()) {
+ QV4::Heap::ExecutionContext *qmlContext = engine->qmlContext();
+ if (engine->qmlEngine() && !qmlContext) {
scopeObject.reset(new QObject);
qmlContext = QV4::QmlContext::create(engine->currentContext(),
QQmlContextData::get(engine->qmlEngine()->rootContext()),
diff --git a/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt b/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt
index 4d45ecdd1a..519acaedff 100644
--- a/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt
+++ b/tests/auto/qml/debugger/qv4debugger/CMakeLists.txt
@@ -13,6 +13,17 @@ file(GLOB_RECURSE test_data_glob
data/*)
list(APPEND test_data ${test_data_glob})
+qt_add_library(testCppTypes STATIC)
+qt_autogen_tools_initial_setup(testCppTypes)
+target_link_libraries(testCppTypes PRIVATE Qt::Qml Qt::QmlPrivate Qt::Quick)
+
+qt6_add_qml_module(testCppTypes
+ VERSION 1.0
+ URI TestTypes
+ SOURCES
+ commontypes.h
+)
+
qt_internal_add_test(tst_qv4debugger
SOURCES
../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp ../../../../../src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -28,6 +39,7 @@ qt_internal_add_test(tst_qv4debugger
Qt::Network
Qt::QmlPrivate
Qt::QuickTestUtilsPrivate
+ testCppTypesplugin
TESTDATA ${test_data}
)
diff --git a/tests/auto/qml/debugger/qv4debugger/commontypes.h b/tests/auto/qml/debugger/qv4debugger/commontypes.h
new file mode 100644
index 0000000000..01b2125ae3
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/commontypes.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef COMMONTYPES_H
+#define COMMONTYPES_H
+
+#include <QtQuick/qquickitem.h>
+#include <QtQml/qqmlregistration.h>
+#include <QtQml/private/qv4engine_p.h>
+
+class MyType : public QQuickItem
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ MyType(QQuickItem *parent = nullptr) : QQuickItem(parent) {}
+ Q_INVOKABLE void name(QQmlV4Function*) const {}
+};
+
+#endif // COMMONTYPES_H
diff --git a/tests/auto/qml/debugger/qv4debugger/data/qtbug_107607.qml b/tests/auto/qml/debugger/qv4debugger/data/qtbug_107607.qml
new file mode 100644
index 0000000000..a7758de8a8
--- /dev/null
+++ b/tests/auto/qml/debugger/qv4debugger/data/qtbug_107607.qml
@@ -0,0 +1,10 @@
+import QtQuick
+import TestTypes
+MyType {
+ objectName: "patron"
+ Item {
+ Component.onCompleted: {
+ console.log("Hallo Welt");
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index cdb7b1dee0..6f147446f0 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -16,10 +16,13 @@
#include <private/qv4string_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
#include <private/qqmldebugservice_p.h>
+#include <QtQml/qqmlextensionplugin.h>
using namespace QV4;
using namespace QV4::Debugging;
+Q_IMPORT_QML_PLUGIN(TestTypesPlugin);
+
typedef QV4::ReturnedValue (*InjectedFunction)(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int);
Q_DECLARE_METATYPE(InjectedFunction)
@@ -176,7 +179,15 @@ public slots:
ExpressionEvalJob job(debugger->engine(), request.frameNr, request.context,
request.expression, &collector);
debugger->runInEngine(&job);
- m_expressionResults << job.returnValue();
+ const QJsonObject& result = job.returnValue();
+ m_expressionResults << result;
+
+ if (request.shouldLookup) {
+ QJsonArray handles {result.value("handle").toInt()};
+ ValueLookupJob job(handles, &collector);
+ debugger->runInEngine(&job);
+ m_lookupResults << job.returnValue();
+ }
}
if (m_captureContextInfo)
@@ -249,10 +260,14 @@ public:
QString expression;
int frameNr;
int context;
+ bool shouldLookup = false;
};
+
+
QVector<ExpressionRequest> m_expressionRequests;
QV4Debugger::Speed m_resumeSpeed;
QList<QJsonObject> m_expressionResults;
+ QList<QJsonObject> m_lookupResults;
QV4Debugger *m_debugger;
// Utility methods:
@@ -306,7 +321,7 @@ private slots:
void readThis();
void signalParameters();
-
+ void debuggerNoCrash();
private:
QV4Debugger *debugger() const
{
@@ -916,6 +931,42 @@ void tst_qv4debugger::signalParameters()
QCOMPARE(obj->property("resultCallbackExternal").toString(), QLatin1String("unset"));
}
+void tst_qv4debugger::debuggerNoCrash()
+{
+ QQmlEngine engine;
+ QV4::ExecutionEngine *v4 = engine.handle();
+ QPointer<QV4Debugger> v4Debugger = new QV4Debugger(v4);
+ v4->setDebugger(v4Debugger.data());
+
+ QScopedPointer<QThread> debugThread(new QThread);
+ debugThread->start();
+ QScopedPointer<TestAgent> debuggerAgent(new TestAgent(v4));
+ debuggerAgent->addDebugger(v4Debugger);
+ debuggerAgent->moveToThread(debugThread.data());
+
+ const QString qmlFileName("qtbug_107607.qml");
+ const QString qmlFilePath(testFile(qmlFileName));
+ QQmlComponent component(&engine, qmlFilePath);
+
+ TestAgent::ExpressionRequest request;
+ request.expression = "this.parent";
+ request.frameNr = 0;
+ request.context = -1;
+ request.shouldLookup = true;
+ debuggerAgent->m_expressionRequests << request;
+ v4Debugger->addBreakPoint(qmlFileName, 7);
+
+ QScopedPointer<QObject> obj(component.create());
+
+ QVERIFY(debuggerAgent->m_lookupResults.size() > 0);
+ const QJsonObject result = debuggerAgent->m_lookupResults[0];
+ const QJsonArray properties = result["0"].toObject().value("properties").toArray();
+ QCOMPARE(properties[0].toObject().value("value").toString(), QStringLiteral("patron"));
+
+ debugThread->quit();
+ debugThread->wait();
+}
+
tst_qv4debugger::tst_qv4debugger() : QQmlDataTest(QT_QMLTEST_DATADIR) { }
QTEST_MAIN(tst_qv4debugger)