Debugger: Make DebuggerEngine::runCommand() virtual.

Allows default implementation of e.g. stack retrieval in the base
class.

Change-Id: I96460b19aa31347b2c863736b4ce2b5046eb4de6
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
hjk
2015-11-03 12:01:57 +01:00
parent 3febe4e7a2
commit 2b16b97f19
17 changed files with 252 additions and 318 deletions

View File

@@ -340,8 +340,8 @@ void CdbEngine::syncOperateByInstruction(bool operateByInstruction)
return; return;
QTC_ASSERT(m_accessible, return); QTC_ASSERT(m_accessible, return);
m_operateByInstruction = operateByInstruction; m_operateByInstruction = operateByInstruction;
runCommand(DebuggerCommand(m_operateByInstruction ? QByteArray("l-t") : QByteArray("l+t"))); runCommand({m_operateByInstruction ? "l-t" : "l+t", NoFlags});
runCommand(DebuggerCommand(m_operateByInstruction ? QByteArray("l-s") : QByteArray("l+s"))); runCommand({m_operateByInstruction ? "l-s" : "l+s", NoFlags});
} }
void CdbEngine::syncVerboseLog(bool verboseLog) void CdbEngine::syncVerboseLog(bool verboseLog)
@@ -350,7 +350,7 @@ void CdbEngine::syncVerboseLog(bool verboseLog)
return; return;
QTC_ASSERT(m_accessible, return); QTC_ASSERT(m_accessible, return);
m_verboseLog = verboseLog; m_verboseLog = verboseLog;
runCommand(DebuggerCommand(m_verboseLog ? QByteArray("!sym noisy") : QByteArray("!sym quiet"))); runCommand({m_verboseLog ? "!sym noisy" : "!sym quiet", NoFlags});
} }
bool CdbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const bool CdbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
@@ -474,11 +474,9 @@ void CdbEngine::consoleStubExited()
void CdbEngine::createFullBacktrace() void CdbEngine::createFullBacktrace()
{ {
DebuggerCommand cmd("~*kp"); runCommand({"~*kp", BuiltinCommand, [this](const DebuggerResponse &response) {
cmd.callback = [this](const DebuggerResponse &response) {
Internal::openTextEditor(QLatin1String("Backtrace $"), response.data.toLatin1()); Internal::openTextEditor(QLatin1String("Backtrace $"), response.data.toLatin1());
}; }});
runCommand(cmd, BuiltinCommand);
} }
void CdbEngine::setupEngine() void CdbEngine::setupEngine()
@@ -646,7 +644,7 @@ bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage
m_hasDebuggee = true; m_hasDebuggee = true;
if (isRemote) { // We do not get an 'idle' in a remote session, but are accessible if (isRemote) { // We do not get an 'idle' in a remote session, but are accessible
m_accessible = true; m_accessible = true;
runCommand(DebuggerCommand(".load " + extensionFileName.toLocal8Bit())); runCommand({".load " + extensionFileName.toLocal8Bit(), NoFlags});
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupOk") STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupOk")
notifyEngineSetupOk(); notifyEngineSetupOk();
} }
@@ -659,27 +657,25 @@ void CdbEngine::setupInferior()
qDebug("setupInferior"); qDebug("setupInferior");
const DebuggerRunParameters &rp = runParameters(); const DebuggerRunParameters &rp = runParameters();
if (!rp.commandsAfterConnect.isEmpty()) if (!rp.commandsAfterConnect.isEmpty())
runCommand(DebuggerCommand(rp.commandsAfterConnect)); runCommand({rp.commandsAfterConnect, NoFlags});
// QmlCppEngine expects the QML engine to be connected before any breakpoints are hit // QmlCppEngine expects the QML engine to be connected before any breakpoints are hit
// (attemptBreakpointSynchronization() will be directly called then) // (attemptBreakpointSynchronization() will be directly called then)
attemptBreakpointSynchronization(); attemptBreakpointSynchronization();
if (rp.breakOnMain) { if (rp.breakOnMain) {
const BreakpointParameters bp(BreakpointAtMain); const BreakpointParameters bp(BreakpointAtMain);
BreakpointModelId id(quint16(-1)); BreakpointModelId id(quint16(-1));
DebuggerCommand cmd(cdbAddBreakpointCommand(bp, m_sourcePathMappings, id, true)); runCommand({cdbAddBreakpointCommand(bp, m_sourcePathMappings, id, true), BuiltinCommand,
cmd.callback = [this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }; [this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }});
runCommand(cmd, BuiltinCommand);
} }
runCommand(DebuggerCommand("sxn 0x4000001f")); // Do not break on WowX86 exceptions. runCommand({"sxn 0x4000001f", NoFlags}); // Do not break on WowX86 exceptions.
runCommand(DebuggerCommand("sxn ibp")); // Do not break on initial breakpoints. runCommand({"sxn ibp", NoFlags}); // Do not break on initial breakpoints.
runCommand(DebuggerCommand(".asm source_line")); // Source line in assembly runCommand({".asm source_line", NoFlags}); // Source line in assembly
runCommand(DebuggerCommand(m_extensionCommandPrefixBA + "setparameter maxStringLength=" runCommand({m_extensionCommandPrefixBA + "setparameter maxStringLength="
+ action(MaximalStringLength)->value().toByteArray() + action(MaximalStringLength)->value().toByteArray()
+ " maxStackDepth=" + " maxStackDepth="
+ action(MaximalStackDepth)->value().toByteArray())); + action(MaximalStackDepth)->value().toByteArray(), NoFlags});
DebuggerCommand cmd("pid"); runCommand({"pid", ExtensionCommand, [this](const DebuggerResponse &response) {
cmd.callback = [this](const DebuggerResponse &response) {
// Fails for core dumps. // Fails for core dumps.
if (response.resultClass == ResultDone) if (response.resultClass == ResultDone)
notifyInferiorPid(response.data.data().toULongLong()); notifyInferiorPid(response.data.data().toULongLong());
@@ -692,8 +688,7 @@ void CdbEngine::setupInferior()
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupFailed") STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupFailed")
notifyInferiorSetupFailed(); notifyInferiorSetupFailed();
} }
}; }});
runCommand(cmd, ExtensionCommand);
} }
static QByteArray msvcRunTime(const Abi::OSFlavor flavour) static QByteArray msvcRunTime(const Abi::OSFlavor flavour)
@@ -736,35 +731,25 @@ void CdbEngine::runEngine()
const QStringList breakEvents = stringListSetting(CdbBreakEvents); const QStringList breakEvents = stringListSetting(CdbBreakEvents);
foreach (const QString &breakEvent, breakEvents) foreach (const QString &breakEvent, breakEvents)
runCommand(DebuggerCommand(QByteArray("sxe ") + breakEvent.toLatin1())); runCommand({"sxe " + breakEvent.toLatin1(), NoFlags});
// Break functions: each function must be fully qualified, // Break functions: each function must be fully qualified,
// else the debugger will slow down considerably. // else the debugger will slow down considerably.
DebuggerCommand cmd; const auto cb = [this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); };
cmd.callback = [this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); };
if (boolSetting(CdbBreakOnCrtDbgReport)) { if (boolSetting(CdbBreakOnCrtDbgReport)) {
const QByteArray module = msvcRunTime(runParameters().toolChainAbi.osFlavor()); const QByteArray module = msvcRunTime(runParameters().toolChainAbi.osFlavor());
const QByteArray debugModule = module + 'D'; const QByteArray debugModule = module + 'D';
const QByteArray wideFunc = QByteArray(CdbOptionsPage::crtDbgReport).append('W'); const QByteArray wideFunc = QByteArray(CdbOptionsPage::crtDbgReport).append('W');
cmd.function = breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, module); runCommand({breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, module), BuiltinCommand, cb});
runCommand(cmd, BuiltinCommand); runCommand({breakAtFunctionCommand(wideFunc, module), BuiltinCommand, cb});
cmd.function = breakAtFunctionCommand(wideFunc, module); runCommand({breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, debugModule), BuiltinCommand, cb});
runCommand(cmd, BuiltinCommand);
cmd.function = breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, debugModule);
runCommand(cmd, BuiltinCommand);
cmd.function = breakAtFunctionCommand(wideFunc, debugModule);
runCommand(cmd, BuiltinCommand);
} }
if (boolSetting(BreakOnWarning)) { if (boolSetting(BreakOnWarning)) {
cmd.function = "bm /( QtCored4!qWarning"; // 'bm': All overloads. runCommand({"bm /( QtCored4!qWarning", BuiltinCommand}); // 'bm': All overloads.
runCommand(cmd, BuiltinCommand); runCommand({"bm /( Qt5Cored!QMessageLogger::warning", BuiltinCommand});
cmd.function = "bm /( Qt5Cored!QMessageLogger::warning";
runCommand(cmd, BuiltinCommand);
} }
if (boolSetting(BreakOnFatal)) { if (boolSetting(BreakOnFatal)) {
cmd.function = "bm /( QtCored4!qFatal"; // 'bm': All overloads. runCommand({"bm /( QtCored4!qFatal", BuiltinCommand}); // 'bm': All overloads.
runCommand(cmd, BuiltinCommand); runCommand({"bm /( Qt5Cored!QMessageLogger::fatal", BuiltinCommand});
cmd.function = "bm /( Qt5Cored!QMessageLogger::fatal";
runCommand(cmd, BuiltinCommand);
} }
if (runParameters().startMode == AttachCore) { if (runParameters().startMode == AttachCore) {
QTC_ASSERT(!m_coreStopReason.isNull(), return; ); QTC_ASSERT(!m_coreStopReason.isNull(), return; );
@@ -848,10 +833,10 @@ void CdbEngine::shutdownEngine()
detachDebugger(); detachDebugger();
// Remote requires a bit more force to quit. // Remote requires a bit more force to quit.
if (m_effectiveStartMode == AttachToRemoteServer) { if (m_effectiveStartMode == AttachToRemoteServer) {
runCommand(DebuggerCommand(m_extensionCommandPrefixBA + "shutdownex")); runCommand({m_extensionCommandPrefixBA + "shutdownex", NoFlags});
runCommand(DebuggerCommand("qq")); runCommand({"qq", NoFlags});
} else { } else {
runCommand(DebuggerCommand("q")); runCommand({"q", NoFlags});
} }
} else { } else {
// Remote process. No can do, currently // Remote process. No can do, currently
@@ -885,7 +870,7 @@ void CdbEngine::processFinished()
void CdbEngine::detachDebugger() void CdbEngine::detachDebugger()
{ {
runCommand(DebuggerCommand(".detach")); runCommand({".detach", NoFlags});
} }
static inline bool isWatchIName(const QByteArray &iname) static inline bool isWatchIName(const QByteArray &iname)
@@ -913,21 +898,21 @@ void CdbEngine::executeStep()
{ {
if (!m_operateByInstruction) if (!m_operateByInstruction)
m_sourceStepInto = true; // See explanation at handleStackTrace(). m_sourceStepInto = true; // See explanation at handleStackTrace().
runCommand(DebuggerCommand(QByteArray("t"))); // Step into-> t (trace) runCommand({"t", NoFlags}); // Step into-> t (trace)
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested") STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested")
notifyInferiorRunRequested(); notifyInferiorRunRequested();
} }
void CdbEngine::executeStepOut() void CdbEngine::executeStepOut()
{ {
runCommand(DebuggerCommand(QByteArray("gu"))); // Step out-> gu (go up) runCommand({"gu", NoFlags}); // Step out-> gu (go up)
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested") STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested")
notifyInferiorRunRequested(); notifyInferiorRunRequested();
} }
void CdbEngine::executeNext() void CdbEngine::executeNext()
{ {
runCommand(DebuggerCommand(QByteArray("p"))); // Step over -> p runCommand({"p", NoFlags}); // Step over -> p
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested") STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested")
notifyInferiorRunRequested(); notifyInferiorRunRequested();
} }
@@ -951,7 +936,7 @@ void CdbEngine::continueInferior()
void CdbEngine::doContinueInferior() void CdbEngine::doContinueInferior()
{ {
runCommand(DebuggerCommand(QByteArray("g"))); runCommand({"g", NoFlags});
} }
bool CdbEngine::canInterruptInferior() const bool CdbEngine::canInterruptInferior() const
@@ -1025,9 +1010,8 @@ void CdbEngine::executeRunToLine(const ContextData &data)
bp.lineNumber = data.lineNumber; bp.lineNumber = data.lineNumber;
} }
DebuggerCommand cmd(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true)); runCommand({cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true), BuiltinCommand,
cmd.callback = [this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }; [this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }});
runCommand(cmd, BuiltinCommand);
continueInferior(); continueInferior();
} }
@@ -1036,10 +1020,8 @@ void CdbEngine::executeRunToFunction(const QString &functionName)
// Add one-shot breakpoint // Add one-shot breakpoint
BreakpointParameters bp(BreakpointByFunction); BreakpointParameters bp(BreakpointByFunction);
bp.functionName = functionName; bp.functionName = functionName;
runCommand({cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true), BuiltinCommand,
DebuggerCommand cmd(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true)); [this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }});
cmd.callback = [this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); };
runCommand(cmd, BuiltinCommand);
continueInferior(); continueInferior();
} }
@@ -1049,7 +1031,7 @@ void CdbEngine::setRegisterValue(const QByteArray &name, const QString &value)
QByteArray cmd; QByteArray cmd;
ByteArrayInputStream str(cmd); ByteArrayInputStream str(cmd);
str << "r " << name << '=' << value; str << "r " << name << '=' << value;
runCommand(DebuggerCommand(cmd)); runCommand({cmd, NoFlags});
reloadRegisters(); reloadRegisters();
} }
@@ -1061,25 +1043,25 @@ void CdbEngine::executeJumpToLine(const ContextData &data)
gotoLocation(Location(data.address)); gotoLocation(Location(data.address));
} else { } else {
// Jump to source line: Resolve source line address and go to that location // Jump to source line: Resolve source line address and go to that location
DebuggerCommand cmd; QByteArray cmd;
ByteArrayInputStream str(cmd.function); ByteArrayInputStream str(cmd);
str << "? `" << QDir::toNativeSeparators(data.fileName) << ':' << data.lineNumber << '`'; str << "? `" << QDir::toNativeSeparators(data.fileName) << ':' << data.lineNumber << '`';
cmd.callback = [this, data](const DebuggerResponse &r) { handleJumpToLineAddressResolution(r, data); }; runCommand({cmd, BuiltinCommand, [this, data](const DebuggerResponse &r) {
runCommand(cmd, BuiltinCommand); handleJumpToLineAddressResolution(r, data); }});
} }
} }
void CdbEngine::jumpToAddress(quint64 address) void CdbEngine::jumpToAddress(quint64 address)
{ {
// Fake a jump to address by setting the PC register. // Fake a jump to address by setting the PC register.
QByteArray registerCmd; QByteArray cmd;
ByteArrayInputStream str(registerCmd); ByteArrayInputStream str(cmd);
// PC-register depending on 64/32bit. // PC-register depending on 64/32bit.
str << "r " << (runParameters().toolChainAbi.wordWidth() == 64 ? "rip" : "eip") << '='; str << "r " << (runParameters().toolChainAbi.wordWidth() == 64 ? "rip" : "eip") << '=';
str.setHexPrefix(true); str.setHexPrefix(true);
str.setIntegerBase(16); str.setIntegerBase(16);
str << address; str << address;
runCommand(DebuggerCommand(registerCmd)); runCommand({cmd, NoFlags});
} }
void CdbEngine::handleJumpToLineAddressResolution(const DebuggerResponse &response, const ContextData &context) void CdbEngine::handleJumpToLineAddressResolution(const DebuggerResponse &response, const ContextData &context)
@@ -1144,7 +1126,7 @@ void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const Q
break; break;
} }
runCommand(DebuggerCommand(cmd)); runCommand({cmd, NoFlags});
// Update all locals in case we change a union or something pointed to // Update all locals in case we change a union or something pointed to
// that affects other variables, too. // that affects other variables, too.
updateLocals(); updateLocals();
@@ -1168,11 +1150,11 @@ void CdbEngine::handleThreads(const DebuggerResponse &response)
void CdbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages languages) void CdbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages languages)
{ {
if (languages & CppLanguage) if (languages & CppLanguage)
runCommand(DebuggerCommand(command.toLocal8Bit())); runCommand({command.toLocal8Bit(), NoFlags});
} }
// 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)
{ {
QByteArray cmd = dbgCmd.function + dbgCmd.argsToString(); QByteArray cmd = dbgCmd.function + dbgCmd.argsToString();
if (!m_accessible) { if (!m_accessible) {
@@ -1184,7 +1166,7 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd, int flags)
QByteArray fullCmd; QByteArray fullCmd;
ByteArrayInputStream str(fullCmd); ByteArrayInputStream str(fullCmd);
if (flags & BuiltinCommand) { if (dbgCmd.flags & BuiltinCommand) {
// Post a built-in-command producing free-format output with a callback. // Post a built-in-command producing free-format output with a callback.
// In order to catch the output, it is enclosed in 'echo' commands // In order to catch the output, it is enclosed in 'echo' commands
// printing a specially formatted token to be identifiable in the output. // printing a specially formatted token to be identifiable in the output.
@@ -1192,7 +1174,7 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd, int flags)
str << ".echo \"" << m_tokenPrefix << token << "<\"\n" str << ".echo \"" << m_tokenPrefix << token << "<\"\n"
<< cmd << "\n.echo \"" << m_tokenPrefix << token << ">\""; << cmd << "\n.echo \"" << m_tokenPrefix << token << ">\"";
m_commandForToken.insert(token, dbgCmd); m_commandForToken.insert(token, dbgCmd);
} else if (flags & ExtensionCommand) { } else if (dbgCmd.flags & ExtensionCommand) {
// Post an extension command producing one-line output with a callback, // Post an extension command producing one-line output with a callback,
// pass along token for identification in hash. // pass along token for identification in hash.
const int token = m_nextCommandToken++; const int token = m_nextCommandToken++;
@@ -1331,10 +1313,10 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters)
if (partialUpdate) if (partialUpdate)
str << blankSeparator << updateParameters.partialVariable; str << blankSeparator << updateParameters.partialVariable;
DebuggerCommand cmd("locals"); DebuggerCommand cmd("locals", ExtensionCommand);
cmd.args = QLatin1String(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);
} }
void CdbEngine::updateAll() void CdbEngine::updateAll()
@@ -1349,9 +1331,8 @@ void CdbEngine::selectThread(ThreadId threadId)
threadsHandler()->setCurrentThread(threadId); threadsHandler()->setCurrentThread(threadId);
DebuggerCommand cmd('~' + QByteArray::number(threadId.raw()) + " s"); runCommand({'~' + QByteArray::number(threadId.raw()) + " s", BuiltinCommand,
cmd.callback = [this](const DebuggerResponse &) { reloadFullStack(); }; [this](const DebuggerResponse &) { reloadFullStack(); }});
runCommand(cmd, BuiltinCommand);
} }
// Default address range for showing disassembly. // Default address range for showing disassembly.
@@ -1401,7 +1382,8 @@ void CdbEngine::postDisassemblerCommand(quint64 address, quint64 endAddress,
// Parse: "00000000`77606060 cc int 3" // Parse: "00000000`77606060 cc int 3"
agent->setContents(parseCdbDisassembler(response.data.data())); agent->setContents(parseCdbDisassembler(response.data.data()));
}; };
runCommand(cmd, BuiltinCommand); cmd.flags = BuiltinCommand;
runCommand(cmd);
} }
void CdbEngine::postResolveSymbol(const QString &module, const QString &function, void CdbEngine::postResolveSymbol(const QString &module, const QString &function,
@@ -1413,14 +1395,10 @@ void CdbEngine::postResolveSymbol(const QString &module, const QString &function
const QList<quint64> addresses = m_symbolAddressCache.values(symbol); const QList<quint64> addresses = m_symbolAddressCache.values(symbol);
if (addresses.isEmpty()) { if (addresses.isEmpty()) {
showMessage(QLatin1String("Resolving symbol: ") + symbol + QLatin1String("..."), LogMisc); showMessage(QLatin1String("Resolving symbol: ") + symbol + QLatin1String("..."), LogMisc);
DebuggerCommand cmd(QByteArray("x ") + symbol.toLatin1()); runCommand({"x " + symbol.toLatin1(), BuiltinCommand,
cmd.callback = [this, symbol, agent](const DebuggerResponse &r) { [this, symbol, agent](const DebuggerResponse &r) { handleResolveSymbol(r, symbol, agent); }});
handleResolveSymbol(r, symbol, agent);
};
runCommand(cmd, BuiltinCommand);
} else { } else {
showMessage(QString::fromLatin1("Using cached addresses for %1."). showMessage(QString::fromLatin1("Using cached addresses for %1.").arg(symbol), LogMisc);
arg(symbol), LogMisc);
handleResolveSymbolHelper(addresses, agent); handleResolveSymbolHelper(addresses, agent);
} }
} }
@@ -1556,7 +1534,7 @@ 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", ExtensionCommand);
QByteArray args; QByteArray args;
ByteArrayInputStream str(args); ByteArrayInputStream str(args);
str << cookie.address << ' ' << cookie.length; str << cookie.address << ' ' << cookie.length;
@@ -1570,7 +1548,7 @@ void CdbEngine::postFetchMemory(const MemoryViewCookie &cookie)
showMessage(response.data["msg"].toLatin1(), LogWarning); showMessage(response.data["msg"].toLatin1(), LogWarning);
} }
}; };
runCommand(cmd, ExtensionCommand); runCommand(cmd);
} }
void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data) void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data)
@@ -1580,15 +1558,13 @@ void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, c
const MemoryChangeCookie cookie(addr, data); const MemoryChangeCookie cookie(addr, data);
doInterruptInferiorCustomSpecialStop(qVariantFromValue(cookie)); doInterruptInferiorCustomSpecialStop(qVariantFromValue(cookie));
} else { } else {
runCommand(DebuggerCommand(cdbWriteMemoryCommand(addr, data))); runCommand({cdbWriteMemoryCommand(addr, data), NoFlags});
} }
} }
void CdbEngine::reloadModules() void CdbEngine::reloadModules()
{ {
DebuggerCommand cmd("modules"); runCommand({"modules", ExtensionCommand, CB(handleModules)});
cmd.callback = CB(handleModules);
runCommand(cmd, ExtensionCommand);
} }
void CdbEngine::loadSymbols(const QString & /* moduleName */) void CdbEngine::loadSymbols(const QString & /* moduleName */)
@@ -1607,9 +1583,7 @@ void CdbEngine::requestModuleSymbols(const QString &moduleName)
void CdbEngine::reloadRegisters() void CdbEngine::reloadRegisters()
{ {
QTC_ASSERT(threadsHandler()->currentThreadIndex() >= 0, return); QTC_ASSERT(threadsHandler()->currentThreadIndex() >= 0, return);
DebuggerCommand cmd("registers"); runCommand({"registers", ExtensionCommand, CB(handleRegistersExt)});
cmd.callback = CB(handleRegistersExt);
runCommand(cmd, ExtensionCommand);
} }
void CdbEngine::reloadSourceFiles() void CdbEngine::reloadSourceFiles()
@@ -1620,18 +1594,18 @@ void CdbEngine::reloadFullStack()
{ {
if (debug) if (debug)
qDebug("%s", Q_FUNC_INFO); qDebug("%s", Q_FUNC_INFO);
DebuggerCommand cmd("stack"); DebuggerCommand cmd("stack", ExtensionCommand);
cmd.args = QStringLiteral("unlimited"); cmd.args = QStringLiteral("unlimited");
cmd.callback = CB(handleStackTrace); cmd.callback = CB(handleStackTrace);
runCommand(cmd, ExtensionCommand); runCommand(cmd);
} }
void CdbEngine::listBreakpoints() void CdbEngine::listBreakpoints()
{ {
DebuggerCommand cmd("breakpoints"); DebuggerCommand cmd("breakpoints", ExtensionCommand);
cmd.args = QStringLiteral("-v"); cmd.args = QStringLiteral("-v");
cmd.callback = CB(handleBreakPoints); cmd.callback = CB(handleBreakPoints);
runCommand(cmd, ExtensionCommand); runCommand(cmd);
} }
void CdbEngine::handleModules(const DebuggerResponse &response) void CdbEngine::handleModules(const DebuggerResponse &response)
@@ -1845,8 +1819,7 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
if (!conditionalBreakPointTriggered && !parameters.condition.isEmpty()) { if (!conditionalBreakPointTriggered && !parameters.condition.isEmpty()) {
*message = msgCheckingConditionalBreakPoint(id, number, parameters.condition, *message = msgCheckingConditionalBreakPoint(id, number, parameters.condition,
QString::number(threadId)); QString::number(threadId));
DebuggerCommand cmd("expression", ExtensionCommand);
DebuggerCommand cmd("expression");
QByteArray args = parameters.condition; QByteArray args = parameters.condition;
if (args.contains(' ') && !args.startsWith('"')) { if (args.contains(' ') && !args.startsWith('"')) {
args.prepend('"'); args.prepend('"');
@@ -1856,7 +1829,7 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
cmd.callback = [this, id, stopReason](const DebuggerResponse &response) { cmd.callback = [this, id, stopReason](const DebuggerResponse &response) {
handleExpression(response, id, stopReason); handleExpression(response, id, stopReason);
}; };
runCommand(cmd, ExtensionCommand); runCommand(cmd);
return StopReportLog; return StopReportLog;
} }
@@ -2004,7 +1977,7 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT
// Start sequence to get all relevant data. // Start sequence to get all relevant data.
if (stopFlags & StopInArtificialThread) { if (stopFlags & StopInArtificialThread) {
showMessage(tr("Switching to main thread..."), LogMisc); showMessage(tr("Switching to main thread..."), LogMisc);
runCommand(DebuggerCommand("~0 s")); runCommand({"~0 s", NoFlags});
forcedThreadId = ThreadId(0); forcedThreadId = ThreadId(0);
// Re-fetch stack again. // Re-fetch stack again.
reloadFullStack(); reloadFullStack();
@@ -2019,9 +1992,8 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT
executeStepOut(); executeStepOut();
return; return;
case ParseStackWow64: case ParseStackWow64:
DebuggerCommand cmd("lm m wow64"); runCommand({"lm m wow64", BuiltinCommand,
cmd.callback = [this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); }; [this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); }});
runCommand(cmd, BuiltinCommand);
break; break;
} }
} else { } else {
@@ -2112,9 +2084,8 @@ void CdbEngine::handleCheckWow64(const DebuggerResponse &response, const GdbMi &
// start end module name // start end module name
// 00000000`77490000 00000000`774d5000 wow64 (deferred) // 00000000`77490000 00000000`774d5000 wow64 (deferred)
if (response.data.data().contains("wow64")) { if (response.data.data().contains("wow64")) {
DebuggerCommand cmd("k"); runCommand({"k", BuiltinCommand,
cmd.callback = [this, stack](const DebuggerResponse &r) { ensureUsing32BitStackInWow64(r, stack); }; [this, stack](const DebuggerResponse &r) { ensureUsing32BitStackInWow64(r, stack); }});
runCommand(cmd, BuiltinCommand);
return; return;
} }
m_wow64State = noWow64Stack; m_wow64State = noWow64Stack;
@@ -2134,9 +2105,7 @@ void CdbEngine::ensureUsing32BitStackInWow64(const DebuggerResponse &response, c
return; return;
} else if (line.startsWith("Child-SP")) { } else if (line.startsWith("Child-SP")) {
m_wow64State = wow64Stack64Bit; m_wow64State = wow64Stack64Bit;
DebuggerCommand cmd("!wow64exts.sw"); runCommand({"!wow64exts.sw", BuiltinCommand, CB(handleSwitchWow64Stack)});
cmd.callback = CB(handleSwitchWow64Stack);
runCommand(cmd, BuiltinCommand);
return; return;
} }
} }
@@ -2153,9 +2122,7 @@ void CdbEngine::handleSwitchWow64Stack(const DebuggerResponse &response)
else else
m_wow64State = noWow64Stack; m_wow64State = noWow64Stack;
// reload threads and the stack after switching the mode // reload threads and the stack after switching the mode
DebuggerCommand cmd("threads"); runCommand({"threads", ExtensionCommand, CB(handleThreads)});
cmd.callback = CB(handleThreads);
runCommand(cmd, ExtensionCommand);
} }
void CdbEngine::handleSessionAccessible(unsigned long cdbExState) void CdbEngine::handleSessionAccessible(unsigned long cdbExState)
@@ -2670,6 +2637,7 @@ void CdbEngine::attemptBreakpointSynchronization()
foreach (Breakpoint bp, bps) { foreach (Breakpoint bp, bps) {
BreakpointParameters parameters = bp.parameters(); BreakpointParameters parameters = bp.parameters();
BreakpointModelId id = bp.id(); BreakpointModelId id = bp.id();
const auto handleBreakInsertCB = [this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); };
BreakpointResponse response; BreakpointResponse response;
response.fromParameters(parameters); response.fromParameters(parameters);
response.id = BreakpointResponseId(id.majorPart(), id.minorPart()); response.id = BreakpointResponseId(id.majorPart(), id.minorPart());
@@ -2688,16 +2656,14 @@ void CdbEngine::attemptBreakpointSynchronization()
lineCorrection.reset(new BreakpointCorrectionContext(Internal::cppCodeModelSnapshot(), lineCorrection.reset(new BreakpointCorrectionContext(Internal::cppCodeModelSnapshot(),
CppTools::CppModelManager::instance()->workingCopy())); CppTools::CppModelManager::instance()->workingCopy()));
response.lineNumber = lineCorrection->fixLineNumber(parameters.fileName, parameters.lineNumber); response.lineNumber = lineCorrection->fixLineNumber(parameters.fileName, parameters.lineNumber);
DebuggerCommand cmd(cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false)); QByteArray cmd = cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false);
cmd.callback = [this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }; runCommand({cmd, BuiltinCommand, handleBreakInsertCB});
runCommand(cmd, BuiltinCommand);
} else { } else {
DebuggerCommand cmd(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false)); QByteArray cmd = cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false);
cmd.callback = [this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }; runCommand({cmd, BuiltinCommand, handleBreakInsertCB});
runCommand(cmd, BuiltinCommand);
} }
if (!parameters.enabled) if (!parameters.enabled)
runCommand(DebuggerCommand("bd " + QByteArray::number(breakPointIdToCdbId(id)))); runCommand({"bd " + QByteArray::number(breakPointIdToCdbId(id)), NoFlags});
bp.notifyBreakpointInsertProceeding(); bp.notifyBreakpointInsertProceeding();
bp.notifyBreakpointInsertOk(); bp.notifyBreakpointInsertOk();
m_pendingBreakpointMap.insert(id, response); m_pendingBreakpointMap.insert(id, response);
@@ -2716,24 +2682,23 @@ void CdbEngine::attemptBreakpointSynchronization()
qPrintable(parameters.toString())); qPrintable(parameters.toString()));
if (parameters.enabled != bp.response().enabled) { if (parameters.enabled != bp.response().enabled) {
// Change enabled/disabled breakpoints without triggering update. // Change enabled/disabled breakpoints without triggering update.
runCommand(DebuggerCommand((parameters.enabled ? "be " : "bd ") runCommand({(parameters.enabled ? "be " : "bd ")
+ QByteArray::number(breakPointIdToCdbId(id)))); + QByteArray::number(breakPointIdToCdbId(id)), NoFlags});
response.pending = false; response.pending = false;
response.enabled = parameters.enabled; response.enabled = parameters.enabled;
bp.setResponse(response); bp.setResponse(response);
} else { } else {
// Delete and re-add, triggering update // Delete and re-add, triggering update
addedChanged = true; addedChanged = true;
runCommand(DebuggerCommand(cdbClearBreakpointCommand(id))); runCommand({cdbClearBreakpointCommand(id), NoFlags});
DebuggerCommand cmd(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false)); QByteArray cmd(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false));
cmd.callback = [this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }; runCommand({cmd, BuiltinCommand, handleBreakInsertCB});
runCommand(cmd, BuiltinCommand);
m_pendingBreakpointMap.insert(id, response); m_pendingBreakpointMap.insert(id, response);
} }
bp.notifyBreakpointChangeOk(); bp.notifyBreakpointChangeOk();
break; break;
case BreakpointRemoveRequested: case BreakpointRemoveRequested:
runCommand(DebuggerCommand(cdbClearBreakpointCommand(id))); runCommand({cdbClearBreakpointCommand(id), NoFlags});
bp.notifyBreakpointRemoveProceeding(); bp.notifyBreakpointRemoveProceeding();
bp.notifyBreakpointRemoveOk(); bp.notifyBreakpointRemoveOk();
m_pendingBreakpointMap.remove(id); m_pendingBreakpointMap.remove(id);
@@ -2745,7 +2710,7 @@ void CdbEngine::attemptBreakpointSynchronization()
foreach (BreakpointModelId id, m_insertSubBreakpointMap.keys()) { foreach (BreakpointModelId id, m_insertSubBreakpointMap.keys()) {
addedChanged = true; addedChanged = true;
const BreakpointResponse &response = m_insertSubBreakpointMap.value(id); const BreakpointResponse &response = m_insertSubBreakpointMap.value(id);
runCommand(DebuggerCommand(cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false))); runCommand({cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false), NoFlags});
m_insertSubBreakpointMap.remove(id); m_insertSubBreakpointMap.remove(id);
m_pendingSubBreakpointMap.insert(id, response); m_pendingSubBreakpointMap.insert(id, response);
} }
@@ -2873,9 +2838,7 @@ unsigned CdbEngine::parseStackTrace(const GdbMi &data, bool sourceStepInto)
void CdbEngine::loadAdditionalQmlStack() void CdbEngine::loadAdditionalQmlStack()
{ {
DebuggerCommand cmd("qmlstack"); runCommand({"qmlstack", ExtensionCommand, CB(handleAdditionalQmlStack)});
cmd.callback = CB(handleAdditionalQmlStack);
runCommand(cmd, ExtensionCommand);
} }
void CdbEngine::handleAdditionalQmlStack(const DebuggerResponse &response) void CdbEngine::handleAdditionalQmlStack(const DebuggerResponse &response)
@@ -2920,9 +2883,8 @@ void CdbEngine::handleStackTrace(const DebuggerResponse &response)
GdbMi stack = response.data; GdbMi stack = response.data;
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
if (parseStackTrace(stack, false) == ParseStackWow64) { if (parseStackTrace(stack, false) == ParseStackWow64) {
DebuggerCommand cmd("lm m wow64"); runCommand({"lm m wow64", BuiltinCommand,
cmd.callback = [this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); }; [this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); }});
runCommand(cmd, BuiltinCommand);
} }
} else { } else {
showMessage(stack["msg"].toLatin1(), LogError); showMessage(stack["msg"].toLatin1(), LogError);
@@ -3096,17 +3058,16 @@ void CdbEngine::watchPoint(const QPoint &p)
void CdbEngine::postWidgetAtCommand() void CdbEngine::postWidgetAtCommand()
{ {
DebuggerCommand cmd("widgetat"); DebuggerCommand cmd("widgetat", ExtensionCommand);
cmd.args = QString::fromLatin1("%1 %2").arg(m_watchPointX, m_watchPointY); cmd.args = QString::fromLatin1("%1 %2").arg(m_watchPointX, m_watchPointY);
cmd.callback = CB(handleWidgetAt); runCommand(cmd);
runCommand(cmd, ExtensionCommand);
} }
void CdbEngine::handleCustomSpecialStop(const QVariant &v) void CdbEngine::handleCustomSpecialStop(const QVariant &v)
{ {
if (v.canConvert<MemoryChangeCookie>()) { if (v.canConvert<MemoryChangeCookie>()) {
const MemoryChangeCookie changeData = qvariant_cast<MemoryChangeCookie>(v); const MemoryChangeCookie changeData = qvariant_cast<MemoryChangeCookie>(v);
runCommand(DebuggerCommand(cdbWriteMemoryCommand(changeData.address, changeData.data))); runCommand({cdbWriteMemoryCommand(changeData.address, changeData.data), NoFlags});
return; return;
} }
if (v.canConvert<MemoryViewCookie>()) { if (v.canConvert<MemoryViewCookie>()) {

View File

@@ -127,7 +127,7 @@ private slots:
void readyReadStandardError(); void readyReadStandardError();
void processError(); void processError();
void processFinished(); void processFinished();
void runCommand(const DebuggerCommand &cmd, int flags = 0); void runCommand(const DebuggerCommand &cmd) override;
void operateByInstructionTriggered(bool); void operateByInstructionTriggered(bool);
void verboseLogTriggered(bool); void verboseLogTriggered(bool);
@@ -164,7 +164,7 @@ private:
ParseStackWow64 = 3 // Hit on a frame with 32bit emulation, switch debugger to 32 bit mode ParseStackWow64 = 3 // Hit on a frame with 32bit emulation, switch debugger to 32 bit mode
}; };
enum CommandFlags { enum CommandFlags {
NoCallBack = 0, NoFlags = 0,
BuiltinCommand, BuiltinCommand,
ExtensionCommand, ExtensionCommand,
}; };

View File

@@ -1479,6 +1479,12 @@ void DebuggerEngine::watchPoint(const QPoint &)
{ {
} }
void DebuggerEngine::runCommand(const DebuggerCommand &)
{
// Overridden in the engines that use the interface.
QTC_CHECK(false);
}
void DebuggerEngine::fetchDisassembler(DisassemblerAgent *) void DebuggerEngine::fetchDisassembler(DisassemblerAgent *)
{ {
} }

View File

@@ -33,6 +33,7 @@
#include "debugger_global.h" #include "debugger_global.h"
#include "debuggerconstants.h" #include "debuggerconstants.h"
#include "debuggerprotocol.h"
#include "debuggerstartparameters.h" #include "debuggerstartparameters.h"
#include <projectexplorer/devicesupport/idevice.h> #include <projectexplorer/devicesupport/idevice.h>
@@ -61,7 +62,6 @@ namespace Internal {
class DebuggerEnginePrivate; class DebuggerEnginePrivate;
class DebuggerPluginPrivate; class DebuggerPluginPrivate;
class DisassemblerAgent; class DisassemblerAgent;
class GdbMi;
class MemoryAgent; class MemoryAgent;
class WatchData; class WatchData;
class WatchItem; class WatchItem;
@@ -217,6 +217,7 @@ public:
MemoryView = 0x4 //!< Open a separate view (using the pos-parameter). MemoryView = 0x4 //!< Open a separate view (using the pos-parameter).
}; };
virtual void runCommand(const DebuggerCommand &cmd);
virtual void openMemoryView(const MemoryViewSetupData &data); virtual void openMemoryView(const MemoryViewSetupData &data);
virtual void fetchMemory(Internal::MemoryAgent *, QObject *, virtual void fetchMemory(Internal::MemoryAgent *, QObject *,
quint64 addr, quint64 length); quint64 addr, quint64 length);

View File

@@ -52,9 +52,10 @@ public:
typedef std::function<void(const DebuggerResponse &)> Callback; typedef std::function<void(const DebuggerResponse &)> Callback;
DebuggerCommand() {} DebuggerCommand() {}
DebuggerCommand(const char *f, int fl = 0) : function(f), flags(fl) {} DebuggerCommand(const QByteArray &f) : function(f), flags(0) {}
DebuggerCommand(const QByteArray &f, int fl = 0) : function(f), flags(fl) {} DebuggerCommand(const QByteArray &f, const QJsonValue &a) : function(f), args(a), flags(0) {}
DebuggerCommand(const char *f, const QJsonValue &a, int fl = 0) : function(f), args(a), flags(fl) {} DebuggerCommand(const QByteArray &f, int fl) : function(f), flags(fl) {}
DebuggerCommand(const QByteArray &f, int fl, const Callback &cb) : function(f), callback(cb), flags(fl) {}
void arg(const char *value); void arg(const char *value);
void arg(const char *name, int value); void arg(const char *name, int value);

View File

@@ -75,9 +75,8 @@ void GdbAttachEngine::runEngine()
{ {
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
const qint64 pid = runParameters().attachPID; const qint64 pid = runParameters().attachPID;
DebuggerCommand cmd("attach " + QByteArray::number(pid)); runCommand({"attach " + QByteArray::number(pid), NoFlags,
cmd.callback = [this](const DebuggerResponse &r) { handleAttach(r); }; [this](const DebuggerResponse &r) { handleAttach(r); }});
runCommand(cmd);
showStatusMessage(tr("Attached to process %1.").arg(inferiorPid())); showStatusMessage(tr("Attached to process %1.").arg(inferiorPid()));
} }

View File

@@ -212,9 +212,8 @@ void GdbCoreEngine::setupInferior()
// Do that first, otherwise no symbols are loaded. // Do that first, otherwise no symbols are loaded.
QFileInfo fi(m_executable); QFileInfo fi(m_executable);
QByteArray path = fi.absoluteFilePath().toLocal8Bit(); QByteArray path = fi.absoluteFilePath().toLocal8Bit();
DebuggerCommand cmd("-file-exec-and-symbols \"" + path + '"'); runCommand({"-file-exec-and-symbols \"" + path + '"', NoFlags,
cmd.callback = CB(handleFileExecAndSymbols); CB(handleFileExecAndSymbols)});
runCommand(cmd);
} }
void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response) void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
@@ -237,9 +236,8 @@ void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
void GdbCoreEngine::runEngine() void GdbCoreEngine::runEngine()
{ {
CHECK_STATE(EngineRunRequested); CHECK_STATE(EngineRunRequested);
DebuggerCommand cmd("target core " + coreFileName().toLocal8Bit()); runCommand({"target core " + coreFileName().toLocal8Bit(), NoFlags,
cmd.callback = CB(handleTargetCore); CB(handleTargetCore)});
runCommand(cmd);
} }
void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response) void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
@@ -252,7 +250,7 @@ void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
// symbols yet. Load them in order of importance. // symbols yet. Load them in order of importance.
reloadStack(); reloadStack();
reloadModulesInternal(); reloadModulesInternal();
runCommand("p 5", CB(handleRoundTrip)); runCommand({"p 5", NoFlags, CB(handleRoundTrip)});
return; return;
} }
showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile) showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile)

View File

@@ -851,7 +851,7 @@ void GdbEngine::interruptInferior()
return; return;
if (usesExecInterrupt()) { if (usesExecInterrupt()) {
runCommand("-exec-interrupt"); runCommand({"-exec-interrupt", NoFlags});
} else { } else {
showStatusMessage(tr("Stop requested..."), 5000); showStatusMessage(tr("Stop requested..."), 5000);
showMessage(_("TRYING TO INTERRUPT INFERIOR")); showMessage(_("TRYING TO INTERRUPT INFERIOR"));
@@ -898,20 +898,6 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
notifyInferiorPid(pid); notifyInferiorPid(pid);
} }
void GdbEngine::runCommand(const QByteArray &command, const DebuggerCommand::Callback &callback, int flags)
{
DebuggerCommand cmd(command);
cmd.callback = callback;
cmd.flags = flags;
runCommand(cmd);
}
void GdbEngine::runCommand(const QByteArray &command, int flags)
{
DebuggerCommand cmd(command, flags);
runCommand(cmd);
}
void GdbEngine::runCommand(const DebuggerCommand &command) void GdbEngine::runCommand(const DebuggerCommand &command)
{ {
const int token = ++currentToken(); const int token = ++currentToken();
@@ -1227,7 +1213,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages
if (!(languages & CppLanguage)) if (!(languages & CppLanguage))
return; return;
QTC_CHECK(acceptsDebuggerCommands()); QTC_CHECK(acceptsDebuggerCommands());
runCommand(command.toLatin1()); runCommand({command.toLatin1(), NoFlags});
} }
// This is triggered when switching snapshots. // This is triggered when switching snapshots.
@@ -1240,7 +1226,7 @@ void GdbEngine::updateAll()
cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); }; cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); };
runCommand(cmd); runCommand(cmd);
stackHandler()->setCurrentIndex(0); stackHandler()->setCurrentIndex(0);
runCommand("-thread-info", CB(handleThreadInfo)); runCommand({"-thread-info", NoFlags, CB(handleThreadInfo)});
reloadRegisters(); reloadRegisters();
updateLocals(); updateLocals();
} }
@@ -1386,9 +1372,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
bool gotoHandleStop1 = true; bool gotoHandleStop1 = true;
if (!m_fullStartDone) { if (!m_fullStartDone) {
m_fullStartDone = true; m_fullStartDone = true;
DebuggerCommand cmd("sharedlibrary .*"); runCommand({"sharedlibrary .*", NoFlags,
cmd.callback = [this, data](const DebuggerResponse &) { handleStop1(data); }; [this, data](const DebuggerResponse &) { handleStop1(data); }});
runCommand(cmd);
gotoHandleStop1 = false; gotoHandleStop1 = false;
} }
@@ -1544,9 +1529,9 @@ void GdbEngine::handleStop1(const GdbMi &data)
if (!m_systemDumpersLoaded) { if (!m_systemDumpersLoaded) {
m_systemDumpersLoaded = true; m_systemDumpersLoaded = true;
if (m_gdbVersion >= 70400 && boolSetting(LoadGdbDumpers)) if (m_gdbVersion >= 70400 && boolSetting(LoadGdbDumpers))
runCommand("importPlainDumpers on"); runCommand({"importPlainDumpers on", NoFlags});
else else
runCommand("importPlainDumpers off"); runCommand({"importPlainDumpers off", NoFlags});
} }
handleStop2(data); handleStop2(data);
@@ -1701,12 +1686,12 @@ void GdbEngine::handleShowVersion(const DebuggerResponse &response)
.arg(gdbBuildVersion).arg(_(isMacGdb ? " (APPLE)" : ""))); .arg(gdbBuildVersion).arg(_(isMacGdb ? " (APPLE)" : "")));
if (usesExecInterrupt()) if (usesExecInterrupt())
runCommand("set target-async on", ConsoleCommand); runCommand({"set target-async on", ConsoleCommand});
else else
runCommand("set target-async off", ConsoleCommand); runCommand({"set target-async off", ConsoleCommand});
if (runParameters().multiProcess) if (runParameters().multiProcess)
runCommand("set detach-on-fork off", ConsoleCommand); runCommand({"set detach-on-fork off", ConsoleCommand});
//runCommand("set build-id-verbose 2", ConsoleCommand); //runCommand("set build-id-verbose 2", ConsoleCommand);
} }
@@ -1892,8 +1877,8 @@ void GdbEngine::notifyAdapterShutdownOk()
switch (m_gdbProc.state()) { switch (m_gdbProc.state()) {
case QProcess::Running: { case QProcess::Running: {
if (runParameters().closeMode == KillAndExitMonitorAtClose) if (runParameters().closeMode == KillAndExitMonitorAtClose)
runCommand("monitor exit"); runCommand({"monitor exit", NoFlags});
runCommand("exitGdb", CB(handleGdbExit), ExitRequest|PythonCommand); runCommand({"exitGdb", ExitRequest|PythonCommand, CB(handleGdbExit)});
break; break;
} }
case QProcess::NotRunning: case QProcess::NotRunning:
@@ -2093,20 +2078,19 @@ void GdbEngine::executeStepI()
void GdbEngine::executeStepOut() void GdbEngine::executeStepOut()
{ {
CHECK_STATE(InferiorStopOk); CHECK_STATE(InferiorStopOk);
runCommand("-stack-select-frame 0", Discardable); runCommand({"-stack-select-frame 0", Discardable});
setTokenBarrier(); setTokenBarrier();
notifyInferiorRunRequested(); notifyInferiorRunRequested();
showStatusMessage(tr("Finish function requested..."), 5000); showStatusMessage(tr("Finish function requested..."), 5000);
if (isNativeMixedActiveFrame()) { if (isNativeMixedActiveFrame()) {
DebuggerCommand cmd("executeStepOut", RunRequest|PythonCommand); runCommand({"executeStepOut", RunRequest|PythonCommand});
runCommand(cmd);
} else { } else {
runCommand("-exec-finish", CB(handleExecuteContinue), RunRequest); runCommand({"-exec-finish", RunRequest, CB(handleExecuteContinue)});
// -exec-finish in 'main' results (correctly) in // -exec-finish in 'main' results (correctly) in
// 40^error,msg="\"finish\" not meaningful in the outermost frame." // 40^error,msg="\"finish\" not meaningful in the outermost frame."
// However, this message does not seem to get flushed before // However, this message does not seem to get flushed before
// anything else happen - i.e. "never". Force some extra output. // anything else happen - i.e. "never". Force some extra output.
runCommand("print 32"); runCommand({"print 32"});
} }
} }
@@ -2186,11 +2170,9 @@ void GdbEngine::executeRunToLine(const ContextData &data)
else else
loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':' loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':'
+ QByteArray::number(data.lineNumber); + QByteArray::number(data.lineNumber);
runCommand("tbreak " + loc); runCommand({"tbreak " + loc, NoFlags});
DebuggerCommand cmd("continue", RunRequest); runCommand({"continue", RunRequest, CB(handleExecuteRunToLine)});
cmd.callback = CB(handleExecuteRunToLine);
runCommand(cmd);
#else #else
// Seems to jump to unpredicatable places. Observed in the manual // Seems to jump to unpredicatable places. Observed in the manual
// tests in the Foo::Foo() constructor with both gdb 6.8 and 7.1. // tests in the Foo::Foo() constructor with both gdb 6.8 and 7.1.
@@ -2204,7 +2186,7 @@ void GdbEngine::executeRunToFunction(const QString &functionName)
{ {
CHECK_STATE(InferiorStopOk); CHECK_STATE(InferiorStopOk);
setTokenBarrier(); setTokenBarrier();
runCommand("-break-insert -t " + functionName.toLatin1()); runCommand({"-break-insert -t " + functionName.toLatin1(), NoFlags});
showStatusMessage(tr("Run to function %1 requested...").arg(functionName), 5000); showStatusMessage(tr("Run to function %1 requested...").arg(functionName), 5000);
continueInferiorInternal(); continueInferiorInternal();
} }
@@ -2218,12 +2200,10 @@ void GdbEngine::executeJumpToLine(const ContextData &data)
else else
loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':' loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':'
+ QByteArray::number(data.lineNumber); + QByteArray::number(data.lineNumber);
runCommand("tbreak " + loc); runCommand({"tbreak " + loc, NoFlags});
notifyInferiorRunRequested(); notifyInferiorRunRequested();
DebuggerCommand cmd("jump" + loc, RunRequest); runCommand({"jump" + loc, RunRequest, CB(handleExecuteJumpToLine)});
cmd.callback = CB(handleExecuteJumpToLine);
runCommand(cmd);
// will produce something like // will produce something like
// &"jump \"/home/apoenitz/dev/work/test1/test1.cpp\":242" // &"jump \"/home/apoenitz/dev/work/test1/test1.cpp\":242"
// ~"Continuing at 0x4058f3." // ~"Continuing at 0x4058f3."
@@ -2238,7 +2218,7 @@ void GdbEngine::executeReturn()
setTokenBarrier(); setTokenBarrier();
notifyInferiorRunRequested(); notifyInferiorRunRequested();
showStatusMessage(tr("Immediate return from function requested..."), 5000); showStatusMessage(tr("Immediate return from function requested..."), 5000);
runCommand("-exec-finish", CB(handleExecuteReturn), RunRequest); runCommand({"-exec-finish", RunRequest, CB(handleExecuteReturn)});
} }
void GdbEngine::handleExecuteReturn(const DebuggerResponse &response) void GdbEngine::handleExecuteReturn(const DebuggerResponse &response)
@@ -2891,7 +2871,7 @@ void GdbEngine::removeBreakpoint(Breakpoint bp)
void GdbEngine::loadSymbols(const QString &modulePath) void GdbEngine::loadSymbols(const QString &modulePath)
{ {
// FIXME: gdb does not understand quoted names here (tested with 6.8) // FIXME: gdb does not understand quoted names here (tested with 6.8)
runCommand("sharedlibrary " + dotEscape(modulePath.toLocal8Bit())); runCommand({"sharedlibrary " + dotEscape(modulePath.toLocal8Bit()), NoFlags});
reloadModulesInternal(); reloadModulesInternal();
reloadStack(); reloadStack();
updateLocals(); updateLocals();
@@ -2899,7 +2879,7 @@ void GdbEngine::loadSymbols(const QString &modulePath)
void GdbEngine::loadAllSymbols() void GdbEngine::loadAllSymbols()
{ {
runCommand("sharedlibrary .*"); runCommand({"sharedlibrary .*", NoFlags});
reloadModulesInternal(); reloadModulesInternal();
reloadStack(); reloadStack();
updateLocals(); updateLocals();
@@ -2915,8 +2895,8 @@ void GdbEngine::loadSymbolsForStack()
foreach (const Module &module, modules) { foreach (const Module &module, modules) {
if (module.startAddress <= frame.address if (module.startAddress <= frame.address
&& frame.address < module.endAddress) { && frame.address < module.endAddress) {
runCommand("sharedlibrary " runCommand({"sharedlibrary " + dotEscape(module.modulePath.toLocal8Bit()),
+ dotEscape(module.modulePath.toLocal8Bit())); NoFlags});
needUpdate = true; needUpdate = true;
} }
} }
@@ -3059,7 +3039,7 @@ void GdbEngine::reloadModules()
void GdbEngine::reloadModulesInternal() void GdbEngine::reloadModulesInternal()
{ {
runCommand("info shared", CB(handleModulesList), NeedsStop); runCommand({"info shared", NeedsStop, CB(handleModulesList)});
} }
static QString nameFromPath(const QString &path) static QString nameFromPath(const QString &path)
@@ -3246,10 +3226,9 @@ void GdbEngine::loadAdditionalQmlStack()
return; return;
} }
// Call the debug function of QML with the context address to obtain the QML stack trace. // Call the debug function of QML with the context address to obtain the QML stack trace.
DebuggerCommand cmd = "-data-evaluate-expression \"qt_v4StackTrace((QV4::ExecutionContext *)0x" runCommand({"-data-evaluate-expression \"qt_v4StackTrace((QV4::ExecutionContext *)0x"
+ QByteArray::number(contextAddress, 16) + ")\""; + QByteArray::number(contextAddress, 16) + ")\"",
cmd.callback = CB(handleQmlStackTrace); NoFlags, CB(handleQmlStackTrace)});
runCommand(cmd);
}; };
runCommand(cmd); runCommand(cmd);
} }
@@ -3345,8 +3324,7 @@ void GdbEngine::activateFrame(int frameIndex)
// after a response to this -stack-select-frame here. // after a response to this -stack-select-frame here.
//if (!m_currentThread.isEmpty()) //if (!m_currentThread.isEmpty())
// cmd += " --thread " + m_currentThread; // cmd += " --thread " + m_currentThread;
DebuggerCommand cmd("-stack-select-frame " + QByteArray::number(frameIndex), Discardable); runCommand({"-stack-select-frame " + QByteArray::number(frameIndex), Discardable});
runCommand(cmd);
} }
updateLocals(); updateLocals();
@@ -3366,14 +3344,14 @@ void GdbEngine::handleThreadInfo(const DebuggerResponse &response)
} }
updateViews(); // Adjust Threads combobox. updateViews(); // Adjust Threads combobox.
if (boolSetting(ShowThreadNames)) { if (boolSetting(ShowThreadNames)) {
runCommand("threadnames " + action(MaximalStackDepth)->value().toByteArray(), runCommand({"threadnames " + action(MaximalStackDepth)->value().toByteArray(),
CB(handleThreadNames), Discardable); Discardable, CB(handleThreadNames)});
} }
reloadStack(); // Will trigger register reload. reloadStack(); // Will trigger register reload.
} else { } else {
// Fall back for older versions: Try to get at least a list // Fall back for older versions: Try to get at least a list
// of running threads. // of running threads.
runCommand("-thread-list-ids", CB(handleThreadListIds), Discardable); runCommand({"-thread-list-ids", Discardable, CB(handleThreadListIds)});
} }
} }
@@ -3474,15 +3452,17 @@ void GdbEngine::reloadRegisters()
if (!m_registerNamesListed) { if (!m_registerNamesListed) {
// The MI version does not give register size. // The MI version does not give register size.
// runCommand("-data-list-register-names", CB(handleRegisterListNames)); // runCommand("-data-list-register-names", CB(handleRegisterListNames));
runCommand("maintenance print raw-registers", CB(handleRegisterListing)); runCommand({"maintenance print raw-registers", NoFlags,
CB(handleRegisterListing)});
m_registerNamesListed = true; m_registerNamesListed = true;
} }
// Can cause i386-linux-nat.c:571: internal-error: Got request // Can cause i386-linux-nat.c:571: internal-error: Got request
// for bad register number 41.\nA problem internal to GDB has been detected. // for bad register number 41.\nA problem internal to GDB has been detected.
runCommand("-data-list-register-values r", runCommand({"-data-list-register-values r", Discardable,
CB(handleRegisterListValues), Discardable); CB(handleRegisterListValues)});
} else { } else {
runCommand("maintenance print cooked-registers", CB(handleMaintPrintRegisters)); runCommand({"maintenance print cooked-registers", NoFlags,
CB(handleMaintPrintRegisters)});
} }
} }
@@ -3547,7 +3527,7 @@ void GdbEngine::setRegisterValue(const QByteArray &name, const QString &value)
QByteArray fullName = name; QByteArray fullName = name;
if (name.startsWith("xmm")) if (name.startsWith("xmm"))
fullName += ".uint128"; fullName += ".uint128";
runCommand("set $" + fullName + "=" + value.toLatin1()); runCommand({"set $" + fullName + "=" + value.toLatin1(), NoFlags});
reloadRegisters(); reloadRegisters();
} }
@@ -3684,9 +3664,8 @@ void GdbEngine::watchPoint(const QPoint &pnt)
{ {
QByteArray x = QByteArray::number(pnt.x()); QByteArray x = QByteArray::number(pnt.x());
QByteArray y = QByteArray::number(pnt.y()); QByteArray y = QByteArray::number(pnt.y());
runCommand("print " + qtNamespace() + "QApplication::widgetAt(" runCommand({"print " + qtNamespace() + "QApplication::widgetAt(" + x + ',' + y + ')',
+ x + ',' + y + ')', NeedsStop, CB(handleWatchPoint)});
CB(handleWatchPoint), NeedsStop);
} }
void GdbEngine::handleWatchPoint(const DebuggerResponse &response) void GdbEngine::handleWatchPoint(const DebuggerResponse &response)
@@ -3822,9 +3801,9 @@ public:
void GdbEngine::fetchDisassembler(DisassemblerAgent *agent) void GdbEngine::fetchDisassembler(DisassemblerAgent *agent)
{ {
if (boolSetting(IntelFlavor)) if (boolSetting(IntelFlavor))
runCommand("set disassembly-flavor intel"); runCommand({"set disassembly-flavor intel"});
else else
runCommand("set disassembly-flavor att"); runCommand({"set disassembly-flavor att"});
fetchDisassemblerByCliPointMixed(agent); fetchDisassemblerByCliPointMixed(agent);
} }
@@ -4025,9 +4004,9 @@ void GdbEngine::startGdb(const QStringList &args)
} }
showMessage(_("GDB STARTED, INITIALIZING IT")); showMessage(_("GDB STARTED, INITIALIZING IT"));
runCommand("show version", CB(handleShowVersion)); runCommand({"show version", NoFlags, CB(handleShowVersion)});
//runCommand("-list-features", CB(handleListFeatures)); //runCommand("-list-features", CB(handleListFeatures));
runCommand("show debug-file-directory",CB(handleDebugInfoLocation)); runCommand({"show debug-file-directory", NoFlags, CB(handleDebugInfoLocation)});
//runCommand("-enable-timings"); //runCommand("-enable-timings");
//rurun print static-members off"); // Seemingly doesn't work. //rurun print static-members off"); // Seemingly doesn't work.
@@ -4037,7 +4016,7 @@ void GdbEngine::startGdb(const QStringList &args)
//runCommand("define hookpost-stop\nprint 5\nend"); //runCommand("define hookpost-stop\nprint 5\nend");
//runCommand("define hook-call\nprint 6\nend"); //runCommand("define hook-call\nprint 6\nend");
//runCommand("define hookpost-call\nprint 7\nend"); //runCommand("define hookpost-call\nprint 7\nend");
runCommand("set print object on"); runCommand({"set print object on"});
//runCommand("set step-mode on"); // we can't work with that yes //runCommand("set step-mode on"); // we can't work with that yes
//runCommand("set exec-done-display on"); //runCommand("set exec-done-display on");
//runCommand("set print pretty on"); //runCommand("set print pretty on");
@@ -4048,8 +4027,8 @@ void GdbEngine::startGdb(const QStringList &args)
// (Mac OS 10.6), but does so for gdb-966 (10.5): // (Mac OS 10.6), but does so for gdb-966 (10.5):
//runCommand("set print inferior-events 1"); //runCommand("set print inferior-events 1");
runCommand("set breakpoint pending on"); runCommand({"set breakpoint pending on"});
runCommand("set print elements 10000"); runCommand({"set print elements 10000"});
// Produces a few messages during symtab loading // Produces a few messages during symtab loading
//runCommand("set verbose on"); //runCommand("set verbose on");
@@ -4077,11 +4056,11 @@ void GdbEngine::startGdb(const QStringList &args)
// We need "print" as otherwise we will get no feedback whatsoever // We need "print" as otherwise we will get no feedback whatsoever
// when Custom DebuggingHelper crash (which happen regularly when accessing // when Custom DebuggingHelper crash (which happen regularly when accessing
// uninitialized variables). // uninitialized variables).
runCommand("handle SIGSEGV nopass stop print"); runCommand({"handle SIGSEGV nopass stop print"});
runCommand("set unwindonsignal on"); runCommand({"set unwindonsignal on"});
runCommand("set width 0"); runCommand({"set width 0"});
runCommand("set height 0"); runCommand({"set height 0"});
// FIXME: Provide proper Gui settings for these: // FIXME: Provide proper Gui settings for these:
//runCommand("set breakpoint always-inserted on", ConsoleCommand); //runCommand("set breakpoint always-inserted on", ConsoleCommand);
@@ -4111,39 +4090,39 @@ void GdbEngine::startGdb(const QStringList &args)
for (auto it = completeSourcePathMap.constBegin(), cend = completeSourcePathMap.constEnd(); for (auto it = completeSourcePathMap.constBegin(), cend = completeSourcePathMap.constEnd();
it != cend; it != cend;
++it) { ++it) {
runCommand("set substitute-path " + it.key().toLocal8Bit() runCommand({"set substitute-path " + it.key().toLocal8Bit()
+ " " + it.value().toLocal8Bit()); + " " + it.value().toLocal8Bit(), NoFlags});
} }
// Spaces just will not work. // Spaces just will not work.
foreach (const QString &src, rp.debugSourceLocation) { foreach (const QString &src, rp.debugSourceLocation) {
if (QDir(src).exists()) if (QDir(src).exists())
runCommand("directory " + src.toLocal8Bit()); runCommand({"directory " + src.toLocal8Bit(), NoFlags});
else else
showMessage(_("# directory does not exist: ") + src, LogInput); showMessage(_("# directory does not exist: ") + src, LogInput);
} }
const QByteArray sysroot = rp.sysRoot.toLocal8Bit(); const QByteArray sysroot = rp.sysRoot.toLocal8Bit();
if (!sysroot.isEmpty()) { if (!sysroot.isEmpty()) {
runCommand("set sysroot " + sysroot); runCommand({"set sysroot " + sysroot, NoFlags});
// sysroot is not enough to correctly locate the sources, so explicitly // sysroot is not enough to correctly locate the sources, so explicitly
// relocate the most likely place for the debug source // relocate the most likely place for the debug source
runCommand("set substitute-path /usr/src " + sysroot + "/usr/src"); runCommand({"set substitute-path /usr/src " + sysroot + "/usr/src", NoFlags});
} }
//QByteArray ba = QFileInfo(sp.dumperLibrary).path().toLocal8Bit(); //QByteArray ba = QFileInfo(sp.dumperLibrary).path().toLocal8Bit();
//if (!ba.isEmpty()) //if (!ba.isEmpty())
// runCommand("set solib-search-path " + ba); // runCommand("set solib-search-path " + ba);
if (attemptQuickStart()) { if (attemptQuickStart()) {
runCommand("set auto-solib-add off", ConsoleCommand); runCommand({"set auto-solib-add off", ConsoleCommand});
} else { } else {
m_fullStartDone = true; m_fullStartDone = true;
runCommand("set auto-solib-add on", ConsoleCommand); runCommand({"set auto-solib-add on", ConsoleCommand});
} }
if (boolSetting(MultiInferior)) { if (boolSetting(MultiInferior)) {
//runCommand("set follow-exec-mode new"); //runCommand("set follow-exec-mode new");
runCommand("set detach-on-fork off"); runCommand({"set detach-on-fork off"});
} }
// Finally, set up Python. // Finally, set up Python.
@@ -4154,15 +4133,15 @@ void GdbEngine::startGdb(const QStringList &args)
ICore::resourcePath().toLocal8Bit() + "/debugger/"; ICore::resourcePath().toLocal8Bit() + "/debugger/";
if (terminal()->isUsable()) if (terminal()->isUsable())
runCommand("set inferior-tty " + terminal()->slaveDevice()); runCommand({"set inferior-tty " + terminal()->slaveDevice(), NoFlags});
const QFileInfo gdbBinaryFile(m_gdb); const QFileInfo gdbBinaryFile(m_gdb);
const QByteArray uninstalledData = gdbBinaryFile.absolutePath().toLocal8Bit() const QByteArray uninstalledData = gdbBinaryFile.absolutePath().toLocal8Bit()
+ "/data-directory/python"; + "/data-directory/python";
runCommand("python sys.path.insert(1, '" + dumperSourcePath + "')"); runCommand({"python sys.path.insert(1, '" + dumperSourcePath + "')", NoFlags});
runCommand("python sys.path.append('" + uninstalledData + "')"); runCommand({"python sys.path.append('" + uninstalledData + "')", NoFlags});
runCommand("python from gdbbridge import *"); runCommand({"python from gdbbridge import *", NoFlags});
const QString path = stringSetting(ExtraDumperFile); const QString path = stringSetting(ExtraDumperFile);
if (!path.isEmpty() && QFileInfo(path).isReadable()) { if (!path.isEmpty() && QFileInfo(path).isReadable()) {
@@ -4173,11 +4152,9 @@ void GdbEngine::startGdb(const QStringList &args)
const QString commands = stringSetting(ExtraDumperCommands); const QString commands = stringSetting(ExtraDumperCommands);
if (!commands.isEmpty()) if (!commands.isEmpty())
runCommand(commands.toLocal8Bit()); runCommand({commands.toLocal8Bit(), NoFlags});
DebuggerCommand cmd("loadDumpers", PythonCommand); runCommand({"loadDumpers", PythonCommand, CB(handlePythonSetup)});
cmd.callback = CB(handlePythonSetup);
runCommand(cmd);
} }
void GdbEngine::handleGdbStartFailed() void GdbEngine::handleGdbStartFailed()
@@ -4189,7 +4166,7 @@ void GdbEngine::loadInitScript()
const QString script = runParameters().overrideStartScript; const QString script = runParameters().overrideStartScript;
if (!script.isEmpty()) { if (!script.isEmpty()) {
if (QFileInfo(script).isReadable()) { if (QFileInfo(script).isReadable()) {
runCommand("source " + script.toLocal8Bit()); runCommand({"source " + script.toLocal8Bit(), NoFlags});
} else { } else {
AsynchronousMessageBox::warning( AsynchronousMessageBox::warning(
tr("Cannot find debugger initialization script"), tr("Cannot find debugger initialization script"),
@@ -4201,7 +4178,7 @@ void GdbEngine::loadInitScript()
} else { } else {
const QString commands = stringSetting(GdbStartupCommands); const QString commands = stringSetting(GdbStartupCommands);
if (!commands.isEmpty()) if (!commands.isEmpty())
runCommand(commands.toLocal8Bit()); runCommand({commands.toLocal8Bit(), NoFlags});
} }
} }
@@ -4211,15 +4188,16 @@ void GdbEngine::setEnvironmentVariables()
Environment runEnv = runParameters().environment; Environment runEnv = runParameters().environment;
foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) { foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) {
if (item.unset) if (item.unset)
runCommand("unset environment " + item.name.toUtf8()); runCommand({"unset environment " + item.name.toUtf8(), NoFlags});
else else
runCommand("-gdb-set environment " + item.name.toUtf8() + '=' + item.value.toUtf8()); runCommand({"-gdb-set environment " + item.name.toUtf8() + '='
+ item.value.toUtf8(), NoFlags});
} }
} }
void GdbEngine::reloadDebuggingHelpers() void GdbEngine::reloadDebuggingHelpers()
{ {
runCommand("reloadDumpers", PythonCommand); runCommand({"reloadDumpers", PythonCommand});
reloadLocals(); reloadLocals();
} }
@@ -4274,7 +4252,7 @@ void GdbEngine::resetInferior()
foreach (QByteArray command, commands.split('\n')) { foreach (QByteArray command, commands.split('\n')) {
command = command.trimmed(); command = command.trimmed();
if (!command.isEmpty()) if (!command.isEmpty())
runCommand(command, int(ConsoleCommand | NeedsStop)); runCommand({command, ConsoleCommand | NeedsStop});
} }
} }
m_rerunPending = true; m_rerunPending = true;
@@ -4313,16 +4291,15 @@ void GdbEngine::handleInferiorPrepared()
if (!rp.commandsAfterConnect.isEmpty()) { if (!rp.commandsAfterConnect.isEmpty()) {
QByteArray commands = globalMacroExpander()->expand(rp.commandsAfterConnect); QByteArray commands = globalMacroExpander()->expand(rp.commandsAfterConnect);
foreach (QByteArray command, commands.split('\n')) { foreach (QByteArray command, commands.split('\n'))
runCommand(command); runCommand({command, NoFlags});
}
} }
//runCommand("set follow-exec-mode new"); //runCommand("set follow-exec-mode new");
if (rp.breakOnMain) { if (rp.breakOnMain) {
QByteArray cmd = "tbreak "; QByteArray cmd = "tbreak ";
cmd += rp.toolChainAbi.os() == Abi::WindowsOS ? "qMain" : "main"; cmd += rp.toolChainAbi.os() == Abi::WindowsOS ? "qMain" : "main";
runCommand(cmd); runCommand({cmd, NoFlags});
} }
// Initial attempt to set breakpoints. // Initial attempt to set breakpoints.
@@ -4348,15 +4325,15 @@ void GdbEngine::finishInferiorSetup()
notifyInferiorSetupOk(); // No breakpoints in core files. notifyInferiorSetupOk(); // No breakpoints in core files.
} else { } else {
if (boolSetting(BreakOnAbort)) if (boolSetting(BreakOnAbort))
runCommand("-break-insert -f abort"); runCommand({"-break-insert -f abort"});
if (boolSetting(BreakOnWarning)) { if (boolSetting(BreakOnWarning)) {
runCommand("-break-insert -f '" + qtNamespace() + "qWarning'"); runCommand({"-break-insert -f '" + qtNamespace() + "qWarning'", NoFlags});
runCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::warning'"); runCommand({"-break-insert -f '" + qtNamespace() + "QMessageLogger::warning'", NoFlags});
} }
if (boolSetting(BreakOnFatal)) { if (boolSetting(BreakOnFatal)) {
auto cb = [this](const DebuggerResponse &r) { handleBreakOnQFatal(r, false); }; auto cb = [this](const DebuggerResponse &r) { handleBreakOnQFatal(r, false); };
runCommand("-break-insert -f '" + qtNamespace() + "qFatal'", cb); runCommand({"-break-insert -f '" + qtNamespace() + "qFatal'", NoFlags, cb});
runCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::fatal'", cb); runCommand({"-break-insert -f '" + qtNamespace() + "QMessageLogger::fatal'", NoFlags, cb});
} else { } else {
notifyInferiorSetupOk(); notifyInferiorSetupOk();
} }
@@ -4369,13 +4346,10 @@ void GdbEngine::handleDebugInfoLocation(const DebuggerResponse &response)
const QByteArray debugInfoLocation = runParameters().debugInfoLocation.toLocal8Bit(); const QByteArray debugInfoLocation = runParameters().debugInfoLocation.toLocal8Bit();
if (QFile::exists(QString::fromLocal8Bit(debugInfoLocation))) { if (QFile::exists(QString::fromLocal8Bit(debugInfoLocation))) {
const QByteArray curDebugInfoLocations = response.consoleStreamOutput.split('"').value(1); const QByteArray curDebugInfoLocations = response.consoleStreamOutput.split('"').value(1);
if (curDebugInfoLocations.isEmpty()) { QByteArray cmd = "set debug-file-directory " + debugInfoLocation;
runCommand("set debug-file-directory " + debugInfoLocation); if (!curDebugInfoLocations.isEmpty())
} else { cmd += HostOsInfo::pathListSeparator().toLatin1() + curDebugInfoLocations;
runCommand("set debug-file-directory " + debugInfoLocation runCommand({cmd, NoFlags});
+ HostOsInfo::pathListSeparator().toLatin1()
+ curDebugInfoLocations);
}
} }
} }
} }
@@ -4388,7 +4362,7 @@ void GdbEngine::handleBreakOnQFatal(const DebuggerResponse &response, bool conti
BreakpointResponseId rid(number.data()); BreakpointResponseId rid(number.data());
if (rid.isValid()) { if (rid.isValid()) {
m_qFatalBreakpointResponseId = rid; m_qFatalBreakpointResponseId = rid;
runCommand("-break-commands " + number.data() + " return"); runCommand({"-break-commands " + number.data() + " return", NoFlags});
} }
} }

View File

@@ -172,12 +172,7 @@ private: ////////// Gdb Command Management //////////
}; };
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag) Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
protected: void runCommand(const DebuggerCommand &command) override;
void runCommand(const DebuggerCommand &command);
void runCommand(const QByteArray &command, int flags);
void runCommand(const QByteArray &command,
const DebuggerCommand::Callback &callback,
int flags = NoFlags);
private: private:
Q_SLOT void commandTimeout(); Q_SLOT void commandTimeout();

View File

@@ -60,10 +60,10 @@ void GdbPlainEngine::setupInferior()
setEnvironmentVariables(); setEnvironmentVariables();
if (!runParameters().processArgs.isEmpty()) { if (!runParameters().processArgs.isEmpty()) {
QString args = runParameters().processArgs; QString args = runParameters().processArgs;
runCommand("-exec-arguments " + toLocalEncoding(args)); runCommand({"-exec-arguments " + toLocalEncoding(args), NoFlags});
} }
runCommand("-file-exec-and-symbols \"" + execFilePath() + '"', runCommand({"-file-exec-and-symbols \"" + execFilePath() + '"', NoFlags,
CB(handleFileExecAndSymbols)); CB(handleFileExecAndSymbols)});
} }
void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response) void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
@@ -84,9 +84,9 @@ void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
void GdbPlainEngine::runEngine() void GdbPlainEngine::runEngine()
{ {
if (runParameters().useContinueInsteadOfRun) if (runParameters().useContinueInsteadOfRun)
runCommand("-exec-continue", CB(handleExecuteContinue), RunRequest); runCommand({"-exec-continue", RunRequest, CB(handleExecuteContinue)});
else else
runCommand("-exec-run", CB(handleExecRun), RunRequest); runCommand({"-exec-run", RunRequest, CB(handleExecRun)});
} }
void GdbPlainEngine::handleExecRun(const DebuggerResponse &response) void GdbPlainEngine::handleExecRun(const DebuggerResponse &response)
{ {
@@ -98,7 +98,7 @@ void GdbPlainEngine::handleExecRun(const DebuggerResponse &response)
showMessage(msgInferiorSetupOk(), StatusBar); showMessage(msgInferiorSetupOk(), StatusBar);
// FIXME: That's the wrong place for it. // FIXME: That's the wrong place for it.
if (boolSetting(EnableReverseDebugging)) if (boolSetting(EnableReverseDebugging))
runCommand("target record"); runCommand({"target record", NoFlags});
} else { } else {
QString msg = fromLocalEncoding(response.data["msg"].data()); QString msg = fromLocalEncoding(response.data["msg"].data());
//QTC_CHECK(status() == InferiorRunOk); //QTC_CHECK(status() == InferiorRunOk);

View File

@@ -183,10 +183,10 @@ void GdbRemoteServerEngine::setupInferior()
// postCommand("set architecture " + remoteArch); // postCommand("set architecture " + remoteArch);
const QString solibSearchPath = rp.solibSearchPath.join(HostOsInfo::pathListSeparator()); const QString solibSearchPath = rp.solibSearchPath.join(HostOsInfo::pathListSeparator());
if (!solibSearchPath.isEmpty()) if (!solibSearchPath.isEmpty())
runCommand("set solib-search-path " + solibSearchPath.toLocal8Bit()); runCommand({"set solib-search-path " + solibSearchPath.toLocal8Bit(), NoFlags});
if (!args.isEmpty()) if (!args.isEmpty())
runCommand("-exec-arguments " + args.toLocal8Bit()); runCommand({"-exec-arguments " + args.toLocal8Bit(), NoFlags});
setEnvironmentVariables(); setEnvironmentVariables();
@@ -210,7 +210,7 @@ void GdbRemoteServerEngine::setupInferior()
// mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)' // mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
// failed.\nA problem internal to GDB has been detected,[...] // failed.\nA problem internal to GDB has been detected,[...]
if (boolSetting(TargetAsync)) if (boolSetting(TargetAsync))
runCommand("set target-async on", CB(handleSetTargetAsync)); runCommand({"set target-async on", NoFlags, CB(handleSetTargetAsync)});
if (executableFileName.isEmpty()) { if (executableFileName.isEmpty()) {
showMessage(tr("No symbol file given."), StatusBar); showMessage(tr("No symbol file given."), StatusBar);
@@ -219,8 +219,8 @@ void GdbRemoteServerEngine::setupInferior()
} }
if (!executableFileName.isEmpty()) { if (!executableFileName.isEmpty()) {
runCommand("-file-exec-and-symbols \"" + executableFileName.toLocal8Bit() + '"', runCommand({"-file-exec-and-symbols \"" + executableFileName.toLocal8Bit() + '"',
CB(handleFileExecAndSymbols)); NoFlags, CB(handleFileExecAndSymbols)});
} }
} }
@@ -270,11 +270,11 @@ void GdbRemoteServerEngine::callTargetRemote()
} }
if (m_isQnxGdb) if (m_isQnxGdb)
runCommand("target qnx " + channel, CB(handleTargetQnx)); runCommand({"target qnx " + channel, NoFlags, CB(handleTargetQnx)});
else if (runParameters().multiProcess) else if (runParameters().multiProcess)
runCommand("target extended-remote " + channel, CB(handleTargetExtendedRemote)); runCommand({"target extended-remote " + channel, NoFlags, CB(handleTargetExtendedRemote)});
else else
runCommand("target remote " + channel, CB(handleTargetRemote)); runCommand({"target remote " + channel, NoFlags, CB(handleTargetRemote)});
} }
void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response) void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
@@ -287,7 +287,7 @@ void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
QString postAttachCommands = stringSetting(GdbPostAttachCommands); QString postAttachCommands = stringSetting(GdbPostAttachCommands);
if (!postAttachCommands.isEmpty()) { if (!postAttachCommands.isEmpty()) {
foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n'))) foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n')))
runCommand(cmd.toLatin1()); runCommand({cmd.toLatin1(), NoFlags});
} }
handleInferiorPrepared(); handleInferiorPrepared();
} else { } else {
@@ -307,15 +307,15 @@ void GdbRemoteServerEngine::handleTargetExtendedRemote(const DebuggerResponse &r
QString postAttachCommands = stringSetting(GdbPostAttachCommands); QString postAttachCommands = stringSetting(GdbPostAttachCommands);
if (!postAttachCommands.isEmpty()) { if (!postAttachCommands.isEmpty()) {
foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n'))) foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n')))
runCommand(cmd.toLatin1()); runCommand({cmd.toLatin1(), NoFlags});
} }
if (runParameters().attachPID > 0) { // attach to pid if valid if (runParameters().attachPID > 0) { // attach to pid if valid
// gdb server will stop the remote application itself. // gdb server will stop the remote application itself.
runCommand("attach " + QByteArray::number(runParameters().attachPID), runCommand({"attach " + QByteArray::number(runParameters().attachPID),
CB(handleTargetExtendedAttach)); NoFlags, CB(handleTargetExtendedAttach)});
} else { } else {
runCommand("-gdb-set remote exec-file " + runParameters().remoteExecutable.toLatin1(), runCommand({"-gdb-set remote exec-file " + runParameters().remoteExecutable.toLatin1(),
CB(handleTargetExtendedAttach)); NoFlags, CB(handleTargetExtendedAttach)});
} }
} else { } else {
QString msg = msgConnectRemoteServerFailed( QString msg = msgConnectRemoteServerFailed(
@@ -349,9 +349,9 @@ void GdbRemoteServerEngine::handleTargetQnx(const DebuggerResponse &response)
const qint64 pid = isMasterEngine() ? runParameters().attachPID : masterEngine()->runParameters().attachPID; const qint64 pid = isMasterEngine() ? runParameters().attachPID : masterEngine()->runParameters().attachPID;
const QString remoteExecutable = isMasterEngine() ? runParameters().remoteExecutable : masterEngine()->runParameters().remoteExecutable; const QString remoteExecutable = isMasterEngine() ? runParameters().remoteExecutable : masterEngine()->runParameters().remoteExecutable;
if (pid > -1) if (pid > -1)
runCommand("attach " + QByteArray::number(pid), CB(handleAttach)); runCommand({"attach " + QByteArray::number(pid), NoFlags, CB(handleAttach)});
else if (!remoteExecutable.isEmpty()) else if (!remoteExecutable.isEmpty())
runCommand("set nto-executable " + remoteExecutable.toLatin1(), CB(handleSetNtoExecutable)); runCommand({"set nto-executable " + remoteExecutable.toLatin1(), NoFlags, CB(handleSetNtoExecutable)});
else else
handleInferiorPrepared(); handleInferiorPrepared();
} else { } else {
@@ -409,7 +409,7 @@ void GdbRemoteServerEngine::runEngine()
const QString remoteExecutable = runParameters().remoteExecutable; const QString remoteExecutable = runParameters().remoteExecutable;
if (!remoteExecutable.isEmpty()) { if (!remoteExecutable.isEmpty()) {
runCommand("-exec-run", CB(handleExecRun), RunRequest); runCommand({"-exec-run", RunRequest, CB(handleExecRun)});
} else { } else {
notifyEngineRunAndInferiorStopOk(); notifyEngineRunAndInferiorStopOk();
continueInferiorInternal(); continueInferiorInternal();
@@ -434,7 +434,7 @@ void GdbRemoteServerEngine::interruptInferior2()
{ {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
if (boolSetting(TargetAsync)) { if (boolSetting(TargetAsync)) {
runCommand("-exec-interrupt", CB(handleInterruptInferior)); runCommand({"-exec-interrupt", NoFlags, CB(handleInterruptInferior)});
} else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) { } else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) {
m_gdbProc.interrupt(); m_gdbProc.interrupt();
} else { } else {

View File

@@ -134,9 +134,8 @@ void GdbTermEngine::runEngine()
{ {
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
const qint64 attachedPID = m_stubProc.applicationPID(); const qint64 attachedPID = m_stubProc.applicationPID();
DebuggerCommand cmd("attach " + QByteArray::number(attachedPID)); runCommand({"attach " + QByteArray::number(attachedPID), NoFlags,
cmd.callback = [this](const DebuggerResponse &r) { handleStubAttached(r); }; [this](const DebuggerResponse &r) { handleStubAttached(r); }});
runCommand(cmd);
} }
void GdbTermEngine::handleStubAttached(const DebuggerResponse &response) void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)

View File

@@ -130,17 +130,17 @@ void LldbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguage
runCommand(cmd); runCommand(cmd);
} }
void LldbEngine::runCommand(const DebuggerCommand &command_) void LldbEngine::runCommand(const DebuggerCommand &cmd)
{ {
QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll()); QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll());
const int tok = ++currentToken(); const int tok = ++currentToken();
DebuggerCommand command = command_; DebuggerCommand command = cmd;
command.arg("token", tok); command.arg("token", tok);
QByteArray token = QByteArray::number(tok); QByteArray token = QByteArray::number(tok);
QByteArray cmd = command.function + "(" + command.argsToPython() + ")"; QByteArray function = command.function + "(" + command.argsToPython() + ")";
showMessage(_(token + cmd + '\n'), LogInput); showMessage(_(token + function + '\n'), LogInput);
m_commandForToken[currentToken()] = command; m_commandForToken[currentToken()] = command;
m_lldbProc.write("script theDumper." + cmd + "\n"); m_lldbProc.write("script theDumper." + function + "\n");
} }
void LldbEngine::debugLastCommand() void LldbEngine::debugLastCommand()
@@ -151,7 +151,7 @@ void LldbEngine::debugLastCommand()
void LldbEngine::shutdownInferior() void LldbEngine::shutdownInferior()
{ {
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
runCommand(DebuggerCommand("shutdownInferior")); runCommand({"shutdownInferior"});
} }
void LldbEngine::shutdownEngine() void LldbEngine::shutdownEngine()
@@ -405,37 +405,37 @@ void LldbEngine::runEngine()
void LldbEngine::interruptInferior() void LldbEngine::interruptInferior()
{ {
showStatusMessage(tr("Interrupt requested..."), 5000); showStatusMessage(tr("Interrupt requested..."), 5000);
runCommand("interruptInferior"); runCommand({"interruptInferior"});
} }
void LldbEngine::executeStep() void LldbEngine::executeStep()
{ {
notifyInferiorRunRequested(); notifyInferiorRunRequested();
runCommand("executeStep"); runCommand({"executeStep"});
} }
void LldbEngine::executeStepI() void LldbEngine::executeStepI()
{ {
notifyInferiorRunRequested(); notifyInferiorRunRequested();
runCommand("executeStepI"); runCommand({"executeStepI"});
} }
void LldbEngine::executeStepOut() void LldbEngine::executeStepOut()
{ {
notifyInferiorRunRequested(); notifyInferiorRunRequested();
runCommand("executeStepOut"); runCommand({"executeStepOut"});
} }
void LldbEngine::executeNext() void LldbEngine::executeNext()
{ {
notifyInferiorRunRequested(); notifyInferiorRunRequested();
runCommand("executeNext"); runCommand({"executeNext"});
} }
void LldbEngine::executeNextI() void LldbEngine::executeNextI()
{ {
notifyInferiorRunRequested(); notifyInferiorRunRequested();
runCommand("executeNextI"); runCommand({"executeNextI"});
} }
void LldbEngine::continueInferior() void LldbEngine::continueInferior()
@@ -984,7 +984,7 @@ void LldbEngine::reloadRegisters()
void LldbEngine::reloadDebuggingHelpers() void LldbEngine::reloadDebuggingHelpers()
{ {
runCommand("reloadDumpers"); runCommand({"reloadDumpers"});
updateAll(); updateAll();
} }
@@ -1037,7 +1037,7 @@ void LldbEngine::fetchFullBacktrace()
Internal::openTextEditor(_("Backtrace $"), Internal::openTextEditor(_("Backtrace $"),
QString::fromUtf8(QByteArray::fromHex(response.data.data()))); QString::fromUtf8(QByteArray::fromHex(response.data.data())));
}; };
runCommand("fetchFullBacktrace"); runCommand(cmd);
} }
void LldbEngine::fetchMemory(MemoryAgent *agent, QObject *editorToken, void LldbEngine::fetchMemory(MemoryAgent *agent, QObject *editorToken,

View File

@@ -147,7 +147,7 @@ private:
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result) override; void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result) override;
void runCommand(const DebuggerCommand &cmd); void runCommand(const DebuggerCommand &cmd) override;
void debugLastCommand() override; void debugLastCommand() override;
private: private:

View File

@@ -300,7 +300,7 @@ void PdbEngine::loadAllSymbols()
void PdbEngine::reloadModules() void PdbEngine::reloadModules()
{ {
runCommand("listModules"); runCommand({"listModules"});
} }
void PdbEngine::refreshModules(const GdbMi &modules) void PdbEngine::refreshModules(const GdbMi &modules)
@@ -557,7 +557,7 @@ void PdbEngine::refreshStack(const GdbMi &stack)
void PdbEngine::updateAll() void PdbEngine::updateAll()
{ {
runCommand("stackListFrames"); runCommand({"stackListFrames"});
updateLocals(); updateLocals();
} }

View File

@@ -98,7 +98,7 @@ private:
bool isSynchronous() const override { return true; } bool isSynchronous() const override { return true; }
void updateItem(const QByteArray &iname) override; void updateItem(const QByteArray &iname) override;
void runCommand(const DebuggerCommand &cmd); void runCommand(const DebuggerCommand &cmd) override;
void postDirectCommand(const QByteArray &command); void postDirectCommand(const QByteArray &command);
void refreshLocation(const GdbMi &reportedLocation); void refreshLocation(const GdbMi &reportedLocation);

View File

@@ -612,7 +612,7 @@ void QmlEngine::shutdownInferior()
// "type" : "request", // "type" : "request",
// "command" : "disconnect", // "command" : "disconnect",
// } // }
d->runCommand(DISCONNECT); d->runCommand({DISCONNECT});
if (isSlaveEngine()) if (isSlaveEngine())
resetLocation(); resetLocation();
@@ -2504,7 +2504,7 @@ void QmlEnginePrivate::stateChanged(State state)
/// Start session. /// Start session.
flushSendBuffer(); flushSendBuffer();
runDirectCommand(CONNECT); runDirectCommand(CONNECT);
runCommand(VERSION); // Only used for logging. runCommand({VERSION}); // Only used for logging.
} }
} }