forked from qt-creator/qt-creator
Debugger: Use Qt's JSON encoder for debugger protocol
The V4 debug service expects correct JSON as input and gdb, lldb, and pdb expect Python object literals. There is a subset of JSON that is also valid as Python object literals and we use that for the protocol spoken with gdb, lldb, and pdb. The strings passed to CDB are tunneled through JSON strings and converted to byte arrays before sending them. Change-Id: I87319b5450e5c3c3b29c565b75cddaa612767611 Task-number: QTCREATORBUG-14931 Reviewed-by: hjk <hjk@theqtcompany.com>
This commit is contained in:
@@ -1174,7 +1174,7 @@ void CdbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages
|
|||||||
// Post command to the cdb process
|
// Post command to the cdb process
|
||||||
void CdbEngine::runCommand(const DebuggerCommand &dbgCmd, int flags)
|
void CdbEngine::runCommand(const DebuggerCommand &dbgCmd, int flags)
|
||||||
{
|
{
|
||||||
QByteArray cmd = dbgCmd.function + dbgCmd.arguments();
|
QByteArray cmd = dbgCmd.function + dbgCmd.argsToString();
|
||||||
if (!m_accessible) {
|
if (!m_accessible) {
|
||||||
const QString msg = QString::fromLatin1("Attempt to issue command \"%1\" to non-accessible session (%2)")
|
const QString msg = QString::fromLatin1("Attempt to issue command \"%1\" to non-accessible session (%2)")
|
||||||
.arg(QString::fromLocal8Bit(cmd), QString::fromLatin1(stateName(state())));
|
.arg(QString::fromLocal8Bit(cmd), QString::fromLatin1(stateName(state())));
|
||||||
@@ -1197,8 +1197,8 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd, int flags)
|
|||||||
// pass along token for identification in hash.
|
// pass along token for identification in hash.
|
||||||
const int token = m_nextCommandToken++;
|
const int token = m_nextCommandToken++;
|
||||||
str << m_extensionCommandPrefixBA << dbgCmd.function << " -t " << token;
|
str << m_extensionCommandPrefixBA << dbgCmd.function << " -t " << token;
|
||||||
if (!dbgCmd.args.isEmpty())
|
if (dbgCmd.args.isString())
|
||||||
str << ' ' << dbgCmd.args;
|
str << ' ' << dbgCmd.argsToString();
|
||||||
m_commandForToken.insert(token, dbgCmd);
|
m_commandForToken.insert(token, dbgCmd);
|
||||||
} else {
|
} else {
|
||||||
str << cmd;
|
str << cmd;
|
||||||
@@ -1332,7 +1332,7 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters)
|
|||||||
str << blankSeparator << updateParameters.partialVariable;
|
str << blankSeparator << updateParameters.partialVariable;
|
||||||
|
|
||||||
DebuggerCommand cmd("locals");
|
DebuggerCommand cmd("locals");
|
||||||
cmd.args = arguments;
|
cmd.args = QLatin1String(arguments);
|
||||||
cmd.callback = [this, partialUpdate](const DebuggerResponse &r) { handleLocals(r, partialUpdate); };
|
cmd.callback = [this, partialUpdate](const DebuggerResponse &r) { handleLocals(r, partialUpdate); };
|
||||||
runCommand(cmd, ExtensionCommand);
|
runCommand(cmd, ExtensionCommand);
|
||||||
}
|
}
|
||||||
@@ -1557,8 +1557,10 @@ void CdbEngine::fetchMemory(MemoryAgent *agent, QObject *editor, quint64 addr, q
|
|||||||
void CdbEngine::postFetchMemory(const MemoryViewCookie &cookie)
|
void CdbEngine::postFetchMemory(const MemoryViewCookie &cookie)
|
||||||
{
|
{
|
||||||
DebuggerCommand cmd("memory");
|
DebuggerCommand cmd("memory");
|
||||||
ByteArrayInputStream str(cmd.args);
|
QByteArray args;
|
||||||
|
ByteArrayInputStream str(args);
|
||||||
str << cookie.address << ' ' << cookie.length;
|
str << cookie.address << ' ' << cookie.length;
|
||||||
|
cmd.args = QLatin1String(args);
|
||||||
cmd.callback = [this, cookie](const DebuggerResponse &response) {
|
cmd.callback = [this, cookie](const DebuggerResponse &response) {
|
||||||
if (response.resultClass == ResultDone && cookie.agent) {
|
if (response.resultClass == ResultDone && cookie.agent) {
|
||||||
const QByteArray data = QByteArray::fromBase64(response.data.data());
|
const QByteArray data = QByteArray::fromBase64(response.data.data());
|
||||||
@@ -1619,7 +1621,7 @@ void CdbEngine::reloadFullStack()
|
|||||||
if (debug)
|
if (debug)
|
||||||
qDebug("%s", Q_FUNC_INFO);
|
qDebug("%s", Q_FUNC_INFO);
|
||||||
DebuggerCommand cmd("stack");
|
DebuggerCommand cmd("stack");
|
||||||
cmd.args = "unlimited";
|
cmd.args = QStringLiteral("unlimited");
|
||||||
cmd.callback = CB(handleStackTrace);
|
cmd.callback = CB(handleStackTrace);
|
||||||
runCommand(cmd, ExtensionCommand);
|
runCommand(cmd, ExtensionCommand);
|
||||||
}
|
}
|
||||||
@@ -1627,7 +1629,7 @@ void CdbEngine::reloadFullStack()
|
|||||||
void CdbEngine::listBreakpoints()
|
void CdbEngine::listBreakpoints()
|
||||||
{
|
{
|
||||||
DebuggerCommand cmd("breakpoints");
|
DebuggerCommand cmd("breakpoints");
|
||||||
cmd.args = "-v";
|
cmd.args = QStringLiteral("-v");
|
||||||
cmd.callback = CB(handleBreakPoints);
|
cmd.callback = CB(handleBreakPoints);
|
||||||
runCommand(cmd, ExtensionCommand);
|
runCommand(cmd, ExtensionCommand);
|
||||||
}
|
}
|
||||||
@@ -1845,11 +1847,12 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
|
|||||||
QString::number(threadId));
|
QString::number(threadId));
|
||||||
|
|
||||||
DebuggerCommand cmd("expression");
|
DebuggerCommand cmd("expression");
|
||||||
cmd.args = parameters.condition;
|
QByteArray args = parameters.condition;
|
||||||
if (cmd.args.contains(' ') && !cmd.args.startsWith('"')) {
|
if (args.contains(' ') && !args.startsWith('"')) {
|
||||||
cmd.args.prepend('"');
|
args.prepend('"');
|
||||||
cmd.args.append('"');
|
args.append('"');
|
||||||
}
|
}
|
||||||
|
cmd.args = QLatin1String(args);
|
||||||
cmd.callback = [this, id, stopReason](const DebuggerResponse &response) {
|
cmd.callback = [this, id, stopReason](const DebuggerResponse &response) {
|
||||||
handleExpression(response, id, stopReason);
|
handleExpression(response, id, stopReason);
|
||||||
};
|
};
|
||||||
@@ -3092,7 +3095,7 @@ void CdbEngine::watchPoint(const QPoint &p)
|
|||||||
void CdbEngine::postWidgetAtCommand()
|
void CdbEngine::postWidgetAtCommand()
|
||||||
{
|
{
|
||||||
DebuggerCommand cmd("widgetat");
|
DebuggerCommand cmd("widgetat");
|
||||||
cmd.args = QByteArray::number(m_watchPointX) + ' ' + QByteArray::number(m_watchPointY);
|
cmd.args = QString::fromLatin1("%1 %2").arg(m_watchPointX, m_watchPointY);
|
||||||
cmd.callback = CB(handleWidgetAt);
|
cmd.callback = CB(handleWidgetAt);
|
||||||
runCommand(cmd, ExtensionCommand);
|
runCommand(cmd, ExtensionCommand);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QTimeZone>
|
#include <QTimeZone>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
@@ -779,106 +781,80 @@ QString decodeData(const QByteArray &ba, DebuggerEncoding encoding)
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DebuggerCommand::argHelper(const char *name, const QByteArray &data)
|
template<typename Value>
|
||||||
|
QJsonValue addToJsonObject(const QJsonValue &args, const char *name, const Value &value)
|
||||||
{
|
{
|
||||||
args.append('"');
|
QTC_ASSERT(args.isObject() || args.isNull(), return args);
|
||||||
args.append(name);
|
QJsonObject obj = args.toObject();
|
||||||
args.append("\":");
|
obj.insert(QLatin1String(name), value);
|
||||||
args.append(data);
|
return obj;
|
||||||
args.append(",");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *name, int value)
|
void DebuggerCommand::arg(const char *name, int value)
|
||||||
{
|
{
|
||||||
argHelper(name, QByteArray::number(value));
|
args = addToJsonObject(args, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *name, qlonglong value)
|
void DebuggerCommand::arg(const char *name, qlonglong value)
|
||||||
{
|
{
|
||||||
argHelper(name, QByteArray::number(value));
|
args = addToJsonObject(args, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *name, qulonglong value)
|
void DebuggerCommand::arg(const char *name, qulonglong value)
|
||||||
{
|
{
|
||||||
argHelper(name, QByteArray::number(value));
|
// gdb and lldb will correctly cast the value back to unsigned if needed, so this is no problem.
|
||||||
|
args = addToJsonObject(args, name, qint64(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *name, const QString &value)
|
void DebuggerCommand::arg(const char *name, const QString &value)
|
||||||
{
|
{
|
||||||
arg(name, value.toUtf8().data());
|
args = addToJsonObject(args, name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *name, const QByteArray &value)
|
void DebuggerCommand::arg(const char *name, const QByteArray &value)
|
||||||
{
|
{
|
||||||
arg(name, value.data());
|
args = addToJsonObject(args, name, QLatin1String(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *name, const char *value)
|
void DebuggerCommand::arg(const char *name, const char *value)
|
||||||
{
|
{
|
||||||
args.append('"');
|
args = addToJsonObject(args, name, QLatin1String(value));
|
||||||
args.append(name);
|
|
||||||
args.append("\":\"");
|
|
||||||
args.append(value);
|
|
||||||
args.append("\",");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *name, const QList<int> &list)
|
void DebuggerCommand::arg(const char *name, const QList<int> &list)
|
||||||
{
|
{
|
||||||
beginList(name);
|
QJsonArray numbers;
|
||||||
foreach (int item, list) {
|
foreach (int item, list)
|
||||||
args.append(QByteArray::number(item));
|
numbers.append(item);
|
||||||
args.append(',');
|
args = addToJsonObject(args, name, numbers);
|
||||||
}
|
|
||||||
endList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::arg(const char *value)
|
void DebuggerCommand::arg(const char *value)
|
||||||
{
|
{
|
||||||
args.append("\"");
|
QTC_ASSERT(args.isArray() || args.isNull(), return);
|
||||||
args.append(value);
|
QJsonArray arr = args.toArray();
|
||||||
args.append("\",");
|
arr.append(QLatin1String(value));
|
||||||
|
args = arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::beginList(const char *name)
|
void DebuggerCommand::arg(const char *name, const QJsonValue &value)
|
||||||
{
|
{
|
||||||
if (name) {
|
args = addToJsonObject(args, name, value);
|
||||||
args += '"';
|
|
||||||
args += name;
|
|
||||||
args += "\":";
|
|
||||||
}
|
|
||||||
args += '[';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::endList()
|
QByteArray DebuggerCommand::argsToPython() const
|
||||||
{
|
{
|
||||||
if (args.endsWith(','))
|
// TODO: Verify that this is really Python.
|
||||||
args.chop(1);
|
|
||||||
args += "],";
|
if (args.isArray())
|
||||||
|
return QJsonDocument(args.toArray()).toJson(QJsonDocument::Compact);
|
||||||
|
else
|
||||||
|
return QJsonDocument(args.toObject()).toJson(QJsonDocument::Compact);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerCommand::beginGroup(const char *name)
|
QByteArray DebuggerCommand::argsToString() const
|
||||||
{
|
{
|
||||||
if (name) {
|
return args.toString().toLatin1();
|
||||||
args += '"';
|
|
||||||
args += name;
|
|
||||||
args += "\":";
|
|
||||||
}
|
|
||||||
args += '{';
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerCommand::endGroup()
|
|
||||||
{
|
|
||||||
if (args.endsWith(','))
|
|
||||||
args.chop(1);
|
|
||||||
args += "},";
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray DebuggerCommand::arguments() const
|
|
||||||
{
|
|
||||||
QByteArray result = args;
|
|
||||||
if (result.endsWith(','))
|
|
||||||
result.chop(1);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QJsonValue>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -53,7 +55,7 @@ public:
|
|||||||
DebuggerCommand(const char *f, int flags = 0, Callback cb = Callback())
|
DebuggerCommand(const char *f, int flags = 0, Callback cb = Callback())
|
||||||
: function(f), callback(cb), flags(flags)
|
: function(f), callback(cb), flags(flags)
|
||||||
{}
|
{}
|
||||||
DebuggerCommand(const char *f, const char *a, int flags = 0, Callback cb = Callback())
|
DebuggerCommand(const char *f, const QJsonValue &a, int flags = 0, Callback cb = Callback())
|
||||||
: function(f), args(a), callback(cb), flags(flags)
|
: function(f), args(a), callback(cb), flags(flags)
|
||||||
{}
|
{}
|
||||||
DebuggerCommand(const char *f, Callback cb)
|
DebuggerCommand(const char *f, Callback cb)
|
||||||
@@ -61,7 +63,7 @@ public:
|
|||||||
{}
|
{}
|
||||||
DebuggerCommand(const QByteArray &f) : function(f), flags(0) {}
|
DebuggerCommand(const QByteArray &f) : function(f), flags(0) {}
|
||||||
|
|
||||||
void arg(const char *name);
|
void arg(const char *value);
|
||||||
void arg(const char *name, int value);
|
void arg(const char *name, int value);
|
||||||
void arg(const char *name, qlonglong value);
|
void arg(const char *name, qlonglong value);
|
||||||
void arg(const char *name, qulonglong value);
|
void arg(const char *name, qulonglong value);
|
||||||
@@ -69,21 +71,16 @@ public:
|
|||||||
void arg(const char *name, const QByteArray &value);
|
void arg(const char *name, const QByteArray &value);
|
||||||
void arg(const char *name, const char *value);
|
void arg(const char *name, const char *value);
|
||||||
void arg(const char *name, const QList<int> &list);
|
void arg(const char *name, const QList<int> &list);
|
||||||
|
void arg(const char *name, const QJsonValue &value);
|
||||||
|
|
||||||
void beginList(const char *name = 0);
|
QByteArray argsToPython() const;
|
||||||
void endList();
|
QByteArray argsToString() const;
|
||||||
void beginGroup(const char *name = 0);
|
|
||||||
void endGroup();
|
|
||||||
QByteArray arguments() const;
|
|
||||||
|
|
||||||
QByteArray function;
|
QByteArray function;
|
||||||
QByteArray args;
|
QJsonValue args;
|
||||||
Callback callback;
|
Callback callback;
|
||||||
uint postTime; // msecsSinceStartOfDay
|
uint postTime; // msecsSinceStartOfDay
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
private:
|
|
||||||
void argHelper(const char *name, const QByteArray &value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -874,7 +875,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
|
|||||||
|
|
||||||
void GdbEngine::runCommand(const DebuggerCommand &command)
|
void GdbEngine::runCommand(const DebuggerCommand &command)
|
||||||
{
|
{
|
||||||
QByteArray cmd = command.function + "({" + command.args + "})";
|
QByteArray cmd = command.function + "(" + command.argsToPython() + ")";
|
||||||
postCommand("python theDumper." + cmd, command.flags, command.callback);
|
postCommand("python theDumper." + cmd, command.flags, command.callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QToolTip>
|
#include <QToolTip>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -136,7 +137,7 @@ void LldbEngine::runCommand(const DebuggerCommand &command_)
|
|||||||
DebuggerCommand command = command_;
|
DebuggerCommand command = command_;
|
||||||
command.arg("token", tok);
|
command.arg("token", tok);
|
||||||
QByteArray token = QByteArray::number(tok);
|
QByteArray token = QByteArray::number(tok);
|
||||||
QByteArray cmd = command.function + "({" + command.args + "})";
|
QByteArray cmd = command.function + "(" + command.argsToPython() + ")";
|
||||||
showMessage(_(token + cmd + '\n'), LogInput);
|
showMessage(_(token + cmd + '\n'), LogInput);
|
||||||
m_commandForToken[currentToken()] = command;
|
m_commandForToken[currentToken()] = command;
|
||||||
m_lldbProc.write("script theDumper." + cmd + "\n");
|
m_lldbProc.write("script theDumper." + cmd + "\n");
|
||||||
@@ -335,10 +336,10 @@ void LldbEngine::setupInferior()
|
|||||||
cmd2.arg("useTerminal", rp.useTerminal);
|
cmd2.arg("useTerminal", rp.useTerminal);
|
||||||
cmd2.arg("startMode", rp.startMode);
|
cmd2.arg("startMode", rp.startMode);
|
||||||
|
|
||||||
cmd2.beginList("processArgs");
|
QJsonArray processArgs;
|
||||||
foreach (const QString &arg, args.toUnixArgs())
|
foreach (const QString &arg, args.toUnixArgs())
|
||||||
cmd2.arg(arg.toUtf8().toHex());
|
processArgs.append(QLatin1String(arg.toUtf8().toHex()));
|
||||||
cmd2.endList();
|
cmd2.arg("processArgs", processArgs);
|
||||||
|
|
||||||
if (rp.useTerminal) {
|
if (rp.useTerminal) {
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
||||||
@@ -830,7 +831,7 @@ void LldbEngine::doUpdateLocals(const UpdateParameters ¶ms)
|
|||||||
//cmd.arg("resultvarname", m_resultVarName);
|
//cmd.arg("resultvarname", m_resultVarName);
|
||||||
|
|
||||||
m_lastDebuggableCommand = cmd;
|
m_lastDebuggableCommand = cmd;
|
||||||
m_lastDebuggableCommand.args.replace("\"passexceptions\":0", "\"passexceptions\":1");
|
m_lastDebuggableCommand.arg("passexceptions", 0);
|
||||||
|
|
||||||
cmd.callback = [this](const DebuggerResponse &response) {
|
cmd.callback = [this](const DebuggerResponse &response) {
|
||||||
updateLocalsView(response.data);
|
updateLocalsView(response.data);
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ void PdbEngine::postDirectCommand(const QByteArray &command)
|
|||||||
void PdbEngine::runCommand(const DebuggerCommand &cmd)
|
void PdbEngine::runCommand(const DebuggerCommand &cmd)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_proc.state() == QProcess::Running, notifyEngineIll());
|
QTC_ASSERT(m_proc.state() == QProcess::Running, notifyEngineIll());
|
||||||
QByteArray command = "qdebug('" + cmd.function + "',{" + cmd.args + "})";
|
QByteArray command = "qdebug('" + cmd.function + "'," + cmd.argsToPython() + ")";
|
||||||
showMessage(_(command), LogInput);
|
showMessage(_(command), LogInput);
|
||||||
m_proc.write(command + '\n');
|
m_proc.write(command + '\n');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1733,14 +1733,15 @@ QmlV8ObjectData QmlEnginePrivate::extractData(const QVariant &data) const
|
|||||||
|
|
||||||
void QmlEnginePrivate::runCommand(const DebuggerCommand &command, const QmlCallback &cb)
|
void QmlEnginePrivate::runCommand(const DebuggerCommand &command, const QmlCallback &cb)
|
||||||
{
|
{
|
||||||
QByteArray msg = "{\"seq\":" + QByteArray::number(++sequence) + ","
|
QJsonObject object;
|
||||||
+ "\"type\":\"request\","
|
object.insert(QStringLiteral("seq"), ++sequence);
|
||||||
+ "\"command\":\"" + command.function + "\","
|
object.insert(QStringLiteral("type"), QStringLiteral("request"));
|
||||||
+ "\"arguments\":{" + command.arguments() + "}}";
|
object.insert(QStringLiteral("command"), QLatin1String(command.function));
|
||||||
|
object.insert(QStringLiteral("arguments"), command.args);
|
||||||
if (cb)
|
if (cb)
|
||||||
callbackForToken[sequence] = cb;
|
callbackForToken[sequence] = cb;
|
||||||
|
|
||||||
runDirectCommand(V8REQUEST, msg);
|
runDirectCommand(V8REQUEST, QJsonDocument(object).toJson(QJsonDocument::Compact));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlEnginePrivate::runDirectCommand(const QByteArray &type, const QByteArray &msg)
|
void QmlEnginePrivate::runDirectCommand(const QByteArray &type, const QByteArray &msg)
|
||||||
|
|||||||
@@ -58,6 +58,8 @@
|
|||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -1591,57 +1593,55 @@ QByteArray WatchHandler::individualFormatRequests() const
|
|||||||
|
|
||||||
void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
|
void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
|
||||||
{
|
{
|
||||||
cmd->beginList("expanded");
|
QJsonArray expanded;
|
||||||
QSetIterator<QByteArray> jt(m_model->m_expandedINames);
|
QSetIterator<QByteArray> jt(m_model->m_expandedINames);
|
||||||
while (jt.hasNext()) {
|
while (jt.hasNext())
|
||||||
QByteArray iname = jt.next();
|
expanded.append(QLatin1String(jt.next()));
|
||||||
//WatchItem *item = m_model->findItem(iname);
|
|
||||||
cmd->arg(iname);
|
|
||||||
//cmd->arg("format", item->requestedFormat());
|
|
||||||
}
|
|
||||||
cmd->endList();
|
|
||||||
|
|
||||||
cmd->beginGroup("typeformats");
|
cmd->arg("expanded", expanded);
|
||||||
|
|
||||||
|
QJsonObject typeformats;
|
||||||
QHashIterator<QByteArray, int> it(theTypeFormats);
|
QHashIterator<QByteArray, int> it(theTypeFormats);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
const int format = it.value();
|
const int format = it.value();
|
||||||
if (format != AutomaticFormat)
|
if (format != AutomaticFormat)
|
||||||
cmd->arg(it.key(), format);
|
typeformats.insert(QLatin1String(it.key()), format);
|
||||||
}
|
}
|
||||||
cmd->endGroup();
|
cmd->arg("typeformats", typeformats);
|
||||||
|
|
||||||
cmd->beginGroup("formats");
|
QJsonObject formats;
|
||||||
QHashIterator<QByteArray, int> it2(theIndividualFormats);
|
QHashIterator<QByteArray, int> it2(theIndividualFormats);
|
||||||
while (it2.hasNext()) {
|
while (it2.hasNext()) {
|
||||||
it2.next();
|
it2.next();
|
||||||
const int format = it2.value();
|
const int format = it2.value();
|
||||||
if (format != AutomaticFormat)
|
if (format != AutomaticFormat)
|
||||||
cmd->arg(it2.key(), format);
|
formats.insert(QLatin1String(it2.key()), format);
|
||||||
}
|
}
|
||||||
cmd->endGroup();
|
cmd->arg("formats", formats);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QJsonObject watcher(const QByteArray &iname, const QByteArray &exp)
|
||||||
|
{
|
||||||
|
QJsonObject watcher;
|
||||||
|
watcher.insert(QStringLiteral("iname"), QLatin1String(iname));
|
||||||
|
watcher.insert(QStringLiteral("exp"), QLatin1String(exp.toHex()));
|
||||||
|
return watcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchHandler::appendWatchersAndTooltipRequests(DebuggerCommand *cmd)
|
void WatchHandler::appendWatchersAndTooltipRequests(DebuggerCommand *cmd)
|
||||||
{
|
{
|
||||||
cmd->beginList("watchers");
|
QJsonArray watchers;
|
||||||
DebuggerToolTipContexts toolTips = DebuggerToolTipManager::pendingTooltips(m_model->m_engine);
|
DebuggerToolTipContexts toolTips = DebuggerToolTipManager::pendingTooltips(m_model->m_engine);
|
||||||
foreach (const DebuggerToolTipContext &p, toolTips) {
|
foreach (const DebuggerToolTipContext &p, toolTips)
|
||||||
cmd->beginGroup();
|
watchers.append(watcher(p.iname, p.expression.toLatin1()));
|
||||||
cmd->arg("iname", p.iname);
|
|
||||||
cmd->arg("exp", p.expression.toLatin1().toHex());
|
|
||||||
cmd->endGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
QHashIterator<QByteArray, int> it(WatchHandler::watcherNames());
|
QHashIterator<QByteArray, int> it(WatchHandler::watcherNames());
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
cmd->beginGroup();
|
watchers.append(watcher("watch." + QByteArray::number(it.value()), it.key()));
|
||||||
cmd->arg("iname", "watch." + QByteArray::number(it.value()));
|
|
||||||
cmd->arg("exp", it.key().toHex());
|
|
||||||
cmd->endGroup();
|
|
||||||
}
|
}
|
||||||
cmd->endList();
|
cmd->arg("watchers", watchers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchHandler::addDumpers(const GdbMi &dumpers)
|
void WatchHandler::addDumpers(const GdbMi &dumpers)
|
||||||
|
|||||||
Reference in New Issue
Block a user