Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4debuggeragent.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
7
8#include <private/qv4stackframe_p.h>
9
10#include <QtCore/qjsonobject.h>
11#include <QtCore/qjsonarray.h>
12
14
15QV4Debugger *QV4DebuggerAgent::pausedDebugger() const
16{
17 for (QV4Debugger *debugger : m_debuggers) {
18 if (debugger->state() == QV4Debugger::Paused)
19 return debugger;
20 }
21 return nullptr;
22}
23
25{
26 // "running" means none of the engines are paused.
27 return pausedDebugger() == nullptr;
28}
29
31{
32 Q_UNUSED(reason);
33
35
36 QJsonObject event, body, script;
37 event.insert(QStringLiteral("type"), QStringLiteral("event"));
38
39 switch (reason) {
43 event.insert(QStringLiteral("event"), QStringLiteral("break"));
44 QV4::CppStackFrame *frame = debugger->engine()->currentStackFrame;
45 if (!frame)
46 break;
47
48 body.insert(QStringLiteral("invocationText"), frame->function());
49 body.insert(QStringLiteral("sourceLine"), qAbs(frame->lineNumber()) - 1);
50// if (frame->column > 0)
51// body.insert(QStringLiteral("sourceColumn"), frame->column);
52 QJsonArray breakPoints;
53 const QList<int> ids = breakPointIds(frame->source(), frame->lineNumber());
54 for (int breakPointId : ids)
55 breakPoints.push_back(breakPointId);
56 body.insert(QStringLiteral("breakpoints"), breakPoints);
57 script.insert(QStringLiteral("name"), frame->source());
58 } break;
60 // TODO: complete this!
61 event.insert(QStringLiteral("event"), QStringLiteral("exception"));
62 break;
63 }
64
65 if (!script.isEmpty())
66 body.insert(QStringLiteral("script"), script);
67 if (!body.isEmpty())
68 event.insert(QStringLiteral("body"), body);
69 m_debugService->send(event);
70}
71
73{
74 Q_ASSERT(!m_debuggers.contains(debugger));
75 m_debuggers << debugger;
76
77 debugger->setBreakOnThrow(m_breakOnThrow);
78
79 for (const BreakPoint &breakPoint : std::as_const(m_breakPoints))
80 if (breakPoint.enabled)
81 debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
82
83 connect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted);
84 connect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused,
85 Qt::QueuedConnection);
86}
87
89{
90 m_debuggers.removeAll(debugger);
91 disconnect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted);
92 disconnect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused);
93}
94
96{
97 return m_debuggers;
98}
99
101{
102 m_debuggers.removeAll(static_cast<QV4Debugger *>(debugger));
103}
104
105void QV4DebuggerAgent::pause(QV4Debugger *debugger) const
106{
107 debugger->pause();
108}
109
111{
112 for (QV4Debugger *debugger : m_debuggers)
113 pause(debugger);
114}
115
117{
118 for (QV4Debugger *debugger : m_debuggers)
119 if (debugger->state() == QV4Debugger::Paused)
120 debugger->resume(QV4Debugger::FullThrottle);
121}
122
123int QV4DebuggerAgent::addBreakPoint(const QString &fileName, int lineNumber, bool enabled, const QString &condition)
124{
125 if (enabled) {
126 for (QV4Debugger *debugger : std::as_const(m_debuggers))
127 debugger->addBreakPoint(fileName, lineNumber, condition);
128 }
129
130 const int id = ++m_lastBreakPointId;
131 m_breakPoints.insert(id, BreakPoint(fileName, lineNumber, enabled, condition));
132 return id;
133}
134
136{
137 BreakPoint breakPoint = m_breakPoints.value(id);
138 if (!breakPoint.isValid())
139 return;
140
141 m_breakPoints.remove(id);
142
143 if (breakPoint.enabled)
144 for (QV4Debugger *debugger : std::as_const(m_debuggers))
145 debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr);
146}
147
149{
150 for (auto it = m_breakPoints.keyBegin(), end = m_breakPoints.keyEnd(); it != end; ++it)
152}
153
154void QV4DebuggerAgent::enableBreakPoint(int id, bool onoff)
155{
156 BreakPoint &breakPoint = m_breakPoints[id];
157 if (!breakPoint.isValid() || breakPoint.enabled == onoff)
158 return;
159 breakPoint.enabled = onoff;
160
161 for (QV4Debugger *debugger : std::as_const(m_debuggers)) {
162 if (onoff)
163 debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
164 else
165 debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr);
166 }
167}
168
169QList<int> QV4DebuggerAgent::breakPointIds(const QString &fileName, int lineNumber) const
170{
171 QList<int> ids;
172
173 for (QHash<int, BreakPoint>::const_iterator i = m_breakPoints.begin(), ei = m_breakPoints.end(); i != ei; ++i)
174 if (i->lineNr == lineNumber && fileName.endsWith(i->fileName))
175 ids.push_back(i.key());
176
177 return ids;
178}
179
181{
182 if (onoff != m_breakOnThrow) {
183 m_breakOnThrow = onoff;
184 for (QV4Debugger *debugger : std::as_const(m_debuggers))
185 debugger->setBreakOnThrow(onoff);
186 }
187}
188
190{
191 for (QV4Debugger *debugger : std::as_const(m_debuggers))
192 debugger->clearPauseRequest();
193}
194
195QT_END_NAMESPACE
196
197#include "moc_qv4debuggeragent.cpp"
void setBreakOnThrow(bool onoff)
const QList< QV4Debugger * > & debuggers()
QList< int > breakPointIds(const QString &fileName, int lineNumber) const
void handleDebuggerDeleted(QObject *debugger)
int addBreakPoint(const QString &fileName, int lineNumber, bool enabled=true, const QString &condition=QString())
void addDebugger(QV4Debugger *debugger)
void removeDebugger(QV4Debugger *debugger)
void pause(QV4Debugger *debugger) const
void removeBreakPoint(int id)
void enableBreakPoint(int id, bool onoff)
void debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason)
QV4DataCollector * collector()
void setBreakOnThrow(bool onoff)