8#include <private/qv4engine_p.h>
9#include <private/qv4function_p.h>
10#include <private/qqmldebugconnector_p.h>
11#include <private/qversionedpacket_p.h>
13#include <QtCore/QJsonArray>
14#include <QtCore/QJsonDocument>
15#include <QtCore/QJsonObject>
16#include <QtCore/QJsonValue>
23#define NO_PROTOCOL_TRACING
24#ifdef NO_PROTOCOL_TRACING
25# define TRACE_PROTOCOL(x)
27#include <QtCore/QDebug>
28# define TRACE_PROTOCOL(x) x
38int QV4DebugServiceImpl::sequence = 0;
129 void handleRequest()
override
132 addRequestSequence();
137 QLatin1String(
"this is not V8, this is V4 in Qt " QT_VERSION_STR));
150 void handleRequest() final
157 if (m_args.isEmpty()) {
158 createErrorResponse(
QStringLiteral(
"breakpoint request with empty arguments object"));
162 const int id = handleBreakPointRequest();
164 createErrorResponse(m_error);
168 addRequestSequence();
179 virtual int handleBreakPointRequest() = 0;
186class V4SetBreakPointRequest:
public V4BreakPointRequest
189 V4SetBreakPointRequest(): V4BreakPointRequest(
QStringLiteral(
"setbreakpoint")) {}
191 int handleBreakPointRequest() final
209 m_error =
QStringLiteral(
"breakpoint has an invalid line number");
225class V4ClearBreakPointRequest:
public V4BreakPointRequest
228 V4ClearBreakPointRequest(): V4BreakPointRequest(
QStringLiteral(
"clearbreakpoint")) {}
230 int handleBreakPointRequest() final
232 const int id = m_args.value(
QLatin1String(
"breakpoint")).toInt(-1);
236 debugService->debuggerAgent.removeBreakPoint(
id);
242class V4ChangeBreakPointRequest:
public V4BreakPointRequest
245 V4ChangeBreakPointRequest(): V4BreakPointRequest(
QStringLiteral(
"changebreakpoint")) {}
247 int handleBreakPointRequest() final
249 const int id = m_args.value(
QLatin1String(
"breakpoint")).toInt(-1);
257 m_error =
QStringLiteral(
"missing bool \"enabled\" in breakpoint change request");
262 debugService->debuggerAgent.enableBreakPoint(
id,
enabled.toBool());
272 void handleRequest()
override
281 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
283 createErrorResponse(
QStringLiteral(
"Debugger has to be paused to retrieve backtraces."));
292 addRequestSequence();
295 addBody(job.returnValue());
304 void handleRequest()
override
309 debugService->selectedFrame());
311 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
313 createErrorResponse(
QStringLiteral(
"Debugger has to be paused to retrieve frames."));
318 createErrorResponse(
QStringLiteral(
"frame command has invalid frame number"));
324 if (!job.wasSuccessful()) {
329 debugService->selectFrame(frameNr);
333 addRequestSequence();
336 addBody(job.returnValue());
345 void handleRequest()
override
350 debugService->selectedFrame());
353 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
355 createErrorResponse(
QStringLiteral(
"Debugger has to be paused to retrieve scope."));
360 createErrorResponse(
QStringLiteral(
"scope command has invalid frame number"));
364 createErrorResponse(
QStringLiteral(
"scope command has invalid scope number"));
370 if (!job.wasSuccessful()) {
377 addRequestSequence();
380 addBody(job.returnValue());
389 void handleRequest()
override
395 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
397 const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
398 if (debuggers.size() > 1) {
399 createErrorResponse(
QStringLiteral(
"Cannot lookup values if multiple debuggers are running and none is paused"));
401 }
else if (debuggers.size() == 0) {
402 createErrorResponse(
QStringLiteral(
"No debuggers available to lookup values"));
405 debugger = debuggers.first();
410 if (!job.exceptionMessage().isEmpty()) {
411 createErrorResponse(job.exceptionMessage());
415 addRequestSequence();
418 addBody(job.returnValue());
428 void handleRequest()
override
433 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
435 createErrorResponse(
QStringLiteral(
"Debugger has to be paused in order to continue."));
438 debugService->debuggerAgent.clearAllPauseRequests();
447 qWarning() <<
"Step count other than 1 is not supported.";
456 createErrorResponse(
QStringLiteral(
"continue command has invalid stepaction"));
463 addRequestSequence();
474 void handleRequest()
override
476 debugService->debuggerAgent.removeAllBreakPoints();
477 debugService->debuggerAgent.resumeAll();
481 addRequestSequence();
492 void handleRequest()
override
494 bool wasEnabled = debugService->debuggerAgent.breakOnThrow();
504 createErrorResponse(
QStringLiteral(
"breaking only on uncaught exceptions is not supported yet"));
507 createErrorResponse(
QStringLiteral(
"invalid type for break on exception"));
512 debugService->debuggerAgent.setBreakOnThrow(
enabled);
516 body[
QLatin1String(
"enabled")] = debugService->debuggerAgent.breakOnThrow();
522 addRequestSequence();
532 void handleRequest()
override
537 if (types < 0 || types > 7) {
538 createErrorResponse(
QStringLiteral(
"invalid types value in scripts command"));
540 }
else if (
types != 4) {
541 createErrorResponse(
QStringLiteral(
"unsupported types value in scripts command"));
546 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
548 createErrorResponse(
QStringLiteral(
"Debugger has to be paused to retrieve scripts."));
567 addRequestSequence();
604 void handleRequest()
override
611 QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
613 const QList<QV4Debugger *> &debuggers = debugService->debuggerAgent.debuggers();
614 if (debuggers.size() > 1) {
615 createErrorResponse(
QStringLiteral(
"Cannot evaluate expressions if multiple debuggers are running and none is paused"));
617 }
else if (debuggers.size() == 0) {
618 createErrorResponse(
QStringLiteral(
"No debuggers available to evaluate expressions"));
621 debugger = debuggers.first();
629 if (job.hasExeption()) {
630 createErrorResponse(job.exceptionMessage());
633 addRequestSequence();
636 addBody(job.returnValue());
644 handlers[handler->
command()] = handler;
653 return unknownV4CommandHandler.
data();
658 debuggerAgent(
this), theSelectedFrame(0),
661 addHandler(
new V4VersionRequest);
662 addHandler(
new V4SetBreakPointRequest);
663 addHandler(
new V4ClearBreakPointRequest);
664 addHandler(
new V4ChangeBreakPointRequest);
665 addHandler(
new V4BacktraceRequest);
666 addHandler(
new V4FrameRequest);
667 addHandler(
new V4ScopeRequest);
668 addHandler(
new V4LookupRequest);
669 addHandler(
new V4ContinueRequest);
670 addHandler(
new V4DisconnectRequest);
671 addHandler(
new V4SetExceptionBreakRequest);
672 addHandler(
new V4ScriptsRequest);
673 addHandler(
new V4EvaluateRequest);
689 if (
state() == Enabled)
716 if (
state == Enabled) {
737 for (
const QString &
signal : std::as_const(breakOnSignals)) {
738 if (
signal == signalName) {
755 if (
header ==
"V8DEBUG") {
758 ms >>
type >> payload;
777 breakOnSignals.append(signalName);
779 breakOnSignals.removeOne(signalName);
780 }
else if (
type ==
"v8request") {
781 handleV4Request(payload);
784 handleV4Request(payload);
796 emit messageToClient(
name(), packMessage(
type, rs.data()));
799void QV4DebugServiceImpl::handleV4Request(
const QByteArray &payload)
818 rs << cmd << command <<
message;
827#ifdef NO_PROTOCOL_TRACING
835 emit messageToClient(
name(), packMessage(
"v8message", responseData));
840 theSelectedFrame = frameNr;
845 return theSelectedFrame;
850#include "moc_qv4debugservice.cpp"
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
T value(const Key &key) const noexcept
The QJSEngine class provides an environment for evaluating JavaScript code.
QV4::ExecutionEngine * handle() const
\inmodule QtCore\reentrant
void append(const QJsonValue &value)
Inserts value at the end of the array.
\inmodule QtCore\reentrant
QByteArray toJson(JsonFormat format=Indented) const
void setObject(const QJsonObject &object)
Sets object as the main object of this document.
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error=nullptr)
Parses json as a UTF-8 encoded JSON document, and creates a QJsonDocument from it.
\inmodule QtCore\reentrant
iterator insert(const QString &key, const QJsonValue &value)
Inserts a new item with the key key and a value of value.
QJsonValue value(const QString &key) const
Returns a QJsonValue representing the value for the key key.
bool isEmpty() const
Returns true if the object is empty.
\inmodule QtCore\reentrant
int toInt(int defaultValue=0) const
QString toString() const
Converts the value to a QString and returns it.
bool empty() const noexcept
T value(qsizetype i) const
QThread * thread() const
Returns the thread in which the object lives.
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL)
Changes the thread affinity for this object and its children and returns true on success.
QRecursiveMutex m_configMutex
static QQmlDebugConnector * instance()
T * data() const noexcept
Returns the value of the pointer referenced by this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
int toInt(bool *ok=nullptr, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
int selectedFrame() const
void send(QJsonObject v4Payload)
void engineAboutToBeRemoved(QJSEngine *engine) override
QV4DebuggerAgent debuggerAgent
void messageReceived(const QByteArray &) override
QV4DebugServiceImpl(QObject *parent=nullptr)
void stateAboutToBeChanged(State state) override
void signalEmitted(const QString &signal) override
void sendSomethingToSomebody(const char *type, int magicNumber=1)
void engineAdded(QJSEngine *engine) override
void selectFrame(int frameNr)
~QV4DebugServiceImpl() override
const QList< QV4Debugger * > & debuggers()
void addDebugger(QV4Debugger *debugger)
void removeDebugger(QV4Debugger *debugger)
void runInEngine(QV4DebugJob *job)
QV4::ExecutionEngine * engine() const
const QV4DataCollector * collector() const
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
UnknownV4CommandHandler()
void handleRequest() override
virtual ~V4CommandHandler()
int requestSequenceNr() const
QV4DebugServiceImpl * debugService
void addSuccess(bool success)
void createErrorResponse(const QString &msg)
void addBody(const QJsonValue &body)
V4CommandHandler(const QString &command)
virtual void handleRequest()=0
void handle(const QJsonObject &request, QV4DebugServiceImpl *s)
void addRequestSequence()
qDeleteAll(list.begin(), list.end())
QList< QVariant > arguments
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall DBusPendingCall return DBusPendingCall return dbus_int32_t return DBusServer * server
static QString header(const QString &name)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
GLsizei GLenum GLenum * types
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint GLsizei const GLchar * message
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
QLatin1StringView QLatin1String
#define QStringLiteral(str)
const char *const V4_CONNECT
const char *const V4_BREAK_ON_SIGNAL
const char *const V4_DISCONNECT
#define TRACE_PROTOCOL(x)
const char *const V4_PAUSE
QNetworkRequest request(url)
\inmodule QtCore \reentrant
QV4::Debugging::Debugger * debugger() const
void setDebugger(Debugging::Debugger *)