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// Qt-Security score:significant
4
8
9#include <private/qv4stackframe_p.h>
10
11#include <QtCore/qjsonobject.h>
12#include <QtCore/qjsonarray.h>
13
15
16QV4Debugger *QV4DebuggerAgent::pausedDebugger() const
17{
18 for (QV4Debugger *debugger : m_debuggers) {
19 if (debugger->state() == QV4Debugger::Paused)
20 return debugger;
21 }
22 return nullptr;
23}
24
26{
27 // "running" means none of the engines are paused.
28 return pausedDebugger() == nullptr;
29}
30
32{
33 Q_UNUSED(reason);
34
36
37 QJsonObject event, body, script;
38 event.insert(QStringLiteral("type"), QStringLiteral("event"));
39
40 switch (reason) {
44 event.insert(QStringLiteral("event"), QStringLiteral("break"));
45 QV4::CppStackFrame *frame = debugger->engine()->currentStackFrame;
46 if (!frame)
47 break;
48
49 body.insert(QStringLiteral("invocationText"), frame->function());
50 body.insert(QStringLiteral("sourceLine"), qAbs(frame->lineNumber()) - 1);
51// if (frame->column > 0)
52// body.insert(QStringLiteral("sourceColumn"), frame->column);
53 QJsonArray breakPoints;
54 const QList<int> ids = breakPointIds(frame->source(), frame->lineNumber());
55 for (int breakPointId : ids)
56 breakPoints.push_back(breakPointId);
57 body.insert(QStringLiteral("breakpoints"), breakPoints);
58 script.insert(QStringLiteral("name"), frame->source());
59 } break;
61 // TODO: complete this!
62 event.insert(QStringLiteral("event"), QStringLiteral("exception"));
63 break;
64 }
65
66 if (!script.isEmpty())
67 body.insert(QStringLiteral("script"), script);
68 if (!body.isEmpty())
69 event.insert(QStringLiteral("body"), body);
70 m_debugService->send(event);
71}
72
74{
75 Q_ASSERT(!m_debuggers.contains(debugger));
76 m_debuggers << debugger;
77
78 debugger->setBreakOnThrow(m_breakOnThrow);
79
80 for (const BreakPoint &breakPoint : std::as_const(m_breakPoints))
81 if (breakPoint.enabled)
82 debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
83
84 connect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted);
85 connect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused,
86 Qt::QueuedConnection);
87}
88
90{
91 m_debuggers.removeAll(debugger);
92 disconnect(debugger, &QObject::destroyed, this, &QV4DebuggerAgent::handleDebuggerDeleted);
93 disconnect(debugger, &QV4Debugger::debuggerPaused, this, &QV4DebuggerAgent::debuggerPaused);
94}
95
97{
98 return m_debuggers;
99}
100
102{
103 m_debuggers.removeAll(static_cast<QV4Debugger *>(debugger));
104}
105
106void QV4DebuggerAgent::pause(QV4Debugger *debugger) const
107{
108 debugger->pause();
109}
110
112{
113 for (QV4Debugger *debugger : m_debuggers)
114 pause(debugger);
115}
116
118{
119 for (QV4Debugger *debugger : m_debuggers)
120 if (debugger->state() == QV4Debugger::Paused)
121 debugger->resume(QV4Debugger::FullThrottle);
122}
123
124int QV4DebuggerAgent::addBreakPoint(const QString &fileName, int lineNumber, bool enabled, const QString &condition)
125{
126 if (enabled) {
127 for (QV4Debugger *debugger : std::as_const(m_debuggers))
128 debugger->addBreakPoint(fileName, lineNumber, condition);
129 }
130
131 const int id = ++m_lastBreakPointId;
132 m_breakPoints.insert(id, BreakPoint(fileName, lineNumber, enabled, condition));
133 return id;
134}
135
137{
138 BreakPoint breakPoint = m_breakPoints.value(id);
139 if (!breakPoint.isValid())
140 return;
141
142 m_breakPoints.remove(id);
143
144 if (breakPoint.enabled)
145 for (QV4Debugger *debugger : std::as_const(m_debuggers))
146 debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr);
147}
148
150{
151 for (auto it = m_breakPoints.keyBegin(), end = m_breakPoints.keyEnd(); it != end; ++it)
153}
154
155void QV4DebuggerAgent::enableBreakPoint(int id, bool onoff)
156{
157 BreakPoint &breakPoint = m_breakPoints[id];
158 if (!breakPoint.isValid() || breakPoint.enabled == onoff)
159 return;
160 breakPoint.enabled = onoff;
161
162 for (QV4Debugger *debugger : std::as_const(m_debuggers)) {
163 if (onoff)
164 debugger->addBreakPoint(breakPoint.fileName, breakPoint.lineNr, breakPoint.condition);
165 else
166 debugger->removeBreakPoint(breakPoint.fileName, breakPoint.lineNr);
167 }
168}
169
170QList<int> QV4DebuggerAgent::breakPointIds(const QString &fileName, int lineNumber) const
171{
172 QList<int> ids;
173
174 for (QHash<int, BreakPoint>::const_iterator i = m_breakPoints.begin(), ei = m_breakPoints.end(); i != ei; ++i)
175 if (i->lineNr == lineNumber && fileName.endsWith(i->fileName))
176 ids.push_back(i.key());
177
178 return ids;
179}
180
182{
183 if (onoff != m_breakOnThrow) {
184 m_breakOnThrow = onoff;
185 for (QV4Debugger *debugger : std::as_const(m_debuggers))
186 debugger->setBreakOnThrow(onoff);
187 }
188}
189
191{
192 for (QV4Debugger *debugger : std::as_const(m_debuggers))
193 debugger->clearPauseRequest();
194}
195
196QT_END_NAMESPACE
197
198#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)
Combined button and popup list for selecting options.