aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-24 16:17:27 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-12-02 14:11:25 +0000
commitc3f03bbff1db14dc5b5436d8aef834512207d498 (patch)
tree279d2fdf57c1155392c31ba31a6291c68cb8d71c /src/plugins
parentec5a886d4b92a18669d5bbd01b43a57f7d81b856 (diff)
Support multiple QML engines in V4 debugger
Whenever the debugger is paused, there is exactly one engine that caused the debuggerPaused() slot to be called. We can only interact with that engine in any meaningful way. Of course you can shoot yourself in the foot with this tool. You can, for example, set a breakpoint that will be hit by multiple engines and then get confused about which engine just hit the breakpoint. Similar things are also possible with other kinds of debuggers, though. If this becomes a problem we can add an engine ID to the responses. Also, this does not fix the other debug services. So you might still not see the "correct" locals and expressions from the QQmlEngineDebugService while the debugger is not paused. Task-number: QTBUG-49615 Change-Id: Ie044f0aedb51481c4cf851635d7c12839251cbd0 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp25
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h3
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp38
5 files changed, 55 insertions, 19 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
index 6198e2c039..014de1f4cb 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
@@ -189,6 +189,12 @@ void QV4Debugger::setBreakOnThrow(bool onoff)
m_breakOnThrow = onoff;
}
+void QV4Debugger::clearPauseRequest()
+{
+ QMutexLocker locker(&m_lock);
+ m_pauseRequested = false;
+}
+
QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const
{
ExecutionState state;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
index adc58141d0..8662259264 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
@@ -124,6 +124,8 @@ public:
void setBreakOnThrow(bool onoff);
+ void clearPauseRequest();
+
// used for testing
struct ExecutionState
{
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
index da43257b24..8bd9547032 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
@@ -44,22 +44,19 @@ QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugServiceImpl *debugService)
: m_breakOnThrow(false), m_debugService(debugService)
{}
-QV4Debugger *QV4DebuggerAgent::firstDebugger() const
+QV4Debugger *QV4DebuggerAgent::pausedDebugger() const
{
- // Currently only 1 single engine is supported, so:
- if (m_debuggers.isEmpty())
- return 0;
- else
- return m_debuggers.first();
+ foreach (QV4Debugger *debugger, m_debuggers) {
+ if (debugger->state() == QV4Debugger::Paused)
+ return debugger;
+ }
+ return 0;
}
bool QV4DebuggerAgent::isRunning() const
{
- // Currently only 1 single engine is supported, so:
- if (QV4Debugger *debugger = firstDebugger())
- return debugger->state() == QV4Debugger::Running;
- else
- return false;
+ // "running" means none of the engines are paused.
+ return pausedDebugger() == 0;
}
void QV4DebuggerAgent::debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason)
@@ -221,4 +218,10 @@ void QV4DebuggerAgent::setBreakOnThrow(bool onoff)
}
}
+void QV4DebuggerAgent::clearAllPauseRequests()
+{
+ foreach (QV4Debugger *debugger, m_debuggers)
+ debugger->clearPauseRequest();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h
index d133c6954b..dea9d74088 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.h
@@ -46,7 +46,7 @@ class QV4DebuggerAgent : public QObject
public:
QV4DebuggerAgent(QV4DebugServiceImpl *m_debugService);
- QV4Debugger *firstDebugger() const;
+ QV4Debugger *pausedDebugger() const;
bool isRunning() const;
void addDebugger(QV4Debugger *debugger);
@@ -64,6 +64,7 @@ public:
bool breakOnThrow() const { return m_breakOnThrow; }
void setBreakOnThrow(bool onoff);
+ void clearAllPauseRequests();
public slots:
void debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index dbfbcb25bb..505617b8f9 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -271,7 +271,11 @@ public:
int toFrame = arguments.value(QStringLiteral("toFrame")).toInt(fromFrame + 10);
// no idea what the bottom property is for, so we'll ignore it.
- QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve backtraces."));
+ return;
+ }
QJsonArray frameArray;
QVector<QV4::StackFrame> frames = debugger->stackTrace(toFrame);
@@ -308,7 +312,12 @@ public:
const int frameNr = arguments.value(QStringLiteral("number")).toInt(
debugService->selectedFrame());
- QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve frames."));
+ return;
+ }
+
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("frame command has invalid frame number"));
@@ -341,7 +350,12 @@ public:
debugService->selectedFrame());
const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0);
- QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scope."));
+ return;
+ }
+
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("scope command has invalid frame number"));
@@ -399,7 +413,12 @@ public:
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused in order to continue."));
+ return;
+ }
+ debugService->debuggerAgent.clearAllPauseRequests();
if (arguments.empty()) {
debugger->resume(QV4Debugger::FullThrottle);
@@ -507,7 +526,12 @@ public:
}
// do it:
- QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (!debugger) {
+ createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scripts."));
+ return;
+ }
+
GatherSourcesJob job(debugger->engine());
debugger->runInEngine(&job);
@@ -562,8 +586,8 @@ public:
virtual void handleRequest()
{
- QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
- if (debugger->state() == QV4Debugger::Paused) {
+ QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
+ if (debugger) {
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
QString expression = arguments.value(QStringLiteral("expression")).toString();
const int frame = arguments.value(QStringLiteral("frame")).toInt(0);