forked from qt-creator/qt-creator
Cdb: Replace CdbCommand with DebuggerCommand.
Change-Id: Ie4d4d17c01d54cfdb5957138076a45bb7a9f5455 Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
This commit is contained in:
@@ -343,8 +343,8 @@ void CdbEngine::syncOperateByInstruction(bool operateByInstruction)
|
|||||||
return;
|
return;
|
||||||
QTC_ASSERT(m_accessible, return);
|
QTC_ASSERT(m_accessible, return);
|
||||||
m_operateByInstruction = operateByInstruction;
|
m_operateByInstruction = operateByInstruction;
|
||||||
postCommand(m_operateByInstruction ? QByteArray("l-t") : QByteArray("l+t"));
|
postCommand(DebuggerCommand(m_operateByInstruction ? QByteArray("l-t") : QByteArray("l+t")));
|
||||||
postCommand(m_operateByInstruction ? QByteArray("l-s") : QByteArray("l+s"));
|
postCommand(DebuggerCommand(m_operateByInstruction ? QByteArray("l-s") : QByteArray("l+s")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::syncVerboseLog(bool verboseLog)
|
void CdbEngine::syncVerboseLog(bool verboseLog)
|
||||||
@@ -353,7 +353,7 @@ void CdbEngine::syncVerboseLog(bool verboseLog)
|
|||||||
return;
|
return;
|
||||||
QTC_ASSERT(m_accessible, return);
|
QTC_ASSERT(m_accessible, return);
|
||||||
m_verboseLog = verboseLog;
|
m_verboseLog = verboseLog;
|
||||||
postCommand(m_verboseLog ? QByteArray("!sym noisy") : QByteArray("!sym quiet"));
|
postCommand(DebuggerCommand(m_verboseLog ? QByteArray("!sym noisy") : QByteArray("!sym quiet")));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
|
bool CdbEngine::canHandleToolTip(const DebuggerToolTipContext &context) const
|
||||||
@@ -477,7 +477,7 @@ void CdbEngine::consoleStubExited()
|
|||||||
|
|
||||||
void CdbEngine::createFullBacktrace()
|
void CdbEngine::createFullBacktrace()
|
||||||
{
|
{
|
||||||
postBuiltinCommand("~*kp", CB(handleCreateFullBackTrace));
|
postCommand(DebuggerCommand("~*kp", BuiltinCommand, CB(handleCreateFullBackTrace)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleCreateFullBackTrace(const DebuggerResponse &response)
|
void CdbEngine::handleCreateFullBackTrace(const DebuggerResponse &response)
|
||||||
@@ -650,9 +650,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;
|
||||||
const QByteArray loadCommand = QByteArray(".load ")
|
postCommand(DebuggerCommand(".load " + extensionFileName.toLocal8Bit()));
|
||||||
+ extensionFileName.toLocal8Bit();
|
|
||||||
postCommand(loadCommand);
|
|
||||||
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupOk")
|
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupOk")
|
||||||
notifyEngineSetupOk();
|
notifyEngineSetupOk();
|
||||||
}
|
}
|
||||||
@@ -665,24 +663,26 @@ void CdbEngine::setupInferior()
|
|||||||
qDebug("setupInferior");
|
qDebug("setupInferior");
|
||||||
const DebuggerRunParameters &rp = runParameters();
|
const DebuggerRunParameters &rp = runParameters();
|
||||||
if (!rp.commandsAfterConnect.isEmpty())
|
if (!rp.commandsAfterConnect.isEmpty())
|
||||||
postCommand(rp.commandsAfterConnect);
|
postCommand(DebuggerCommand(rp.commandsAfterConnect));
|
||||||
// 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));
|
||||||
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, id, true),
|
postCommand(DebuggerCommand(
|
||||||
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
cdbAddBreakpointCommand(bp, m_sourcePathMappings, id, true),
|
||||||
|
BuiltinCommand,
|
||||||
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }));
|
||||||
}
|
}
|
||||||
postCommand("sxn 0x4000001f"); // Do not break on WowX86 exceptions.
|
postCommand(DebuggerCommand("sxn 0x4000001f")); // Do not break on WowX86 exceptions.
|
||||||
postCommand("sxn ibp"); // Do not break on initial breakpoints.
|
postCommand(DebuggerCommand("sxn ibp")); // Do not break on initial breakpoints.
|
||||||
postCommand(".asm source_line"); // Source line in assembly
|
postCommand(DebuggerCommand(".asm source_line")); // Source line in assembly
|
||||||
postCommand(m_extensionCommandPrefixBA + "setparameter maxStringLength="
|
postCommand(DebuggerCommand(m_extensionCommandPrefixBA + "setparameter maxStringLength="
|
||||||
+ action(MaximalStringLength)->value().toByteArray()
|
+ action(MaximalStringLength)->value().toByteArray()
|
||||||
+ " maxStackDepth="
|
+ " maxStackDepth="
|
||||||
+ action(MaximalStackDepth)->value().toByteArray());
|
+ action(MaximalStackDepth)->value().toByteArray()));
|
||||||
postExtensionCommand("pid", QByteArray(), CB(handlePid));
|
postCommand(DebuggerCommand("pid", ExtensionCommand, CB(handlePid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray msvcRunTime(const Abi::OSFlavor flavour)
|
static QByteArray msvcRunTime(const Abi::OSFlavor flavour)
|
||||||
@@ -725,33 +725,37 @@ void CdbEngine::runEngine()
|
|||||||
|
|
||||||
const QStringList breakEvents = stringListSetting(CdbBreakEvents);
|
const QStringList breakEvents = stringListSetting(CdbBreakEvents);
|
||||||
foreach (const QString &breakEvent, breakEvents)
|
foreach (const QString &breakEvent, breakEvents)
|
||||||
postCommand(QByteArray("sxe ") + breakEvent.toLatin1());
|
postCommand(DebuggerCommand(QByteArray("sxe ") + breakEvent.toLatin1()));
|
||||||
// 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.
|
||||||
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');
|
||||||
postBuiltinCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, module),
|
postCommand(DebuggerCommand(
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, module), BuiltinCommand,
|
||||||
postBuiltinCommand(breakAtFunctionCommand(wideFunc, module),
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
postCommand(DebuggerCommand(
|
||||||
postBuiltinCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, debugModule),
|
breakAtFunctionCommand(wideFunc, module), BuiltinCommand,
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
postBuiltinCommand(breakAtFunctionCommand(wideFunc, debugModule),
|
postCommand(DebuggerCommand(
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, debugModule), BuiltinCommand,
|
||||||
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
|
postCommand(DebuggerCommand(
|
||||||
|
breakAtFunctionCommand(wideFunc, debugModule), BuiltinCommand,
|
||||||
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
}
|
}
|
||||||
if (boolSetting(BreakOnWarning)) {
|
if (boolSetting(BreakOnWarning)) {
|
||||||
postBuiltinCommand("bm /( QtCored4!qWarning", // 'bm': All overloads.
|
postCommand(DebuggerCommand( "bm /( QtCored4!qWarning", BuiltinCommand, // 'bm': All overloads.
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
postBuiltinCommand("bm /( Qt5Cored!QMessageLogger::warning",
|
postCommand(DebuggerCommand( "bm /( Qt5Cored!QMessageLogger::warning", BuiltinCommand,
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
}
|
}
|
||||||
if (boolSetting(BreakOnFatal)) {
|
if (boolSetting(BreakOnFatal)) {
|
||||||
postBuiltinCommand("bm /( QtCored4!qFatal", // 'bm': All overloads.
|
postCommand(DebuggerCommand("bm /( QtCored4!qFatal", BuiltinCommand, // 'bm': All overloads.
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
postBuiltinCommand("bm /( Qt5Cored!QMessageLogger::fatal",
|
postCommand(DebuggerCommand("bm /( Qt5Cored!QMessageLogger::fatal", BuiltinCommand,
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
}
|
}
|
||||||
if (runParameters().startMode == AttachCore) {
|
if (runParameters().startMode == AttachCore) {
|
||||||
QTC_ASSERT(!m_coreStopReason.isNull(), return; );
|
QTC_ASSERT(!m_coreStopReason.isNull(), return; );
|
||||||
@@ -835,10 +839,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) {
|
||||||
postCommand(m_extensionCommandPrefixBA + "shutdownex");
|
postCommand(DebuggerCommand(m_extensionCommandPrefixBA + "shutdownex"));
|
||||||
postCommand("qq");
|
postCommand(DebuggerCommand("qq"));
|
||||||
} else {
|
} else {
|
||||||
postCommand("q");
|
postCommand(DebuggerCommand("q"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Remote process. No can do, currently
|
// Remote process. No can do, currently
|
||||||
@@ -872,7 +876,7 @@ void CdbEngine::processFinished()
|
|||||||
|
|
||||||
void CdbEngine::detachDebugger()
|
void CdbEngine::detachDebugger()
|
||||||
{
|
{
|
||||||
postCommand(".detach");
|
postCommand(DebuggerCommand(".detach"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool isWatchIName(const QByteArray &iname)
|
static inline bool isWatchIName(const QByteArray &iname)
|
||||||
@@ -900,21 +904,21 @@ void CdbEngine::executeStep()
|
|||||||
{
|
{
|
||||||
if (!m_operateByInstruction)
|
if (!m_operateByInstruction)
|
||||||
m_sourceStepInto = true; // See explanation at handleStackTrace().
|
m_sourceStepInto = true; // See explanation at handleStackTrace().
|
||||||
postCommand(QByteArray("t")); // Step into-> t (trace)
|
postCommand(DebuggerCommand(QByteArray("t"))); // 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()
|
||||||
{
|
{
|
||||||
postCommand(QByteArray("gu")); // Step out-> gu (go up)
|
postCommand(DebuggerCommand(QByteArray("gu"))); // 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()
|
||||||
{
|
{
|
||||||
postCommand(QByteArray("p")); // Step over -> p
|
postCommand(DebuggerCommand(QByteArray("p"))); // Step over -> p
|
||||||
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested")
|
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorRunRequested")
|
||||||
notifyInferiorRunRequested();
|
notifyInferiorRunRequested();
|
||||||
}
|
}
|
||||||
@@ -938,7 +942,7 @@ void CdbEngine::continueInferior()
|
|||||||
|
|
||||||
void CdbEngine::doContinueInferior()
|
void CdbEngine::doContinueInferior()
|
||||||
{
|
{
|
||||||
postCommand(QByteArray("g"));
|
postCommand(DebuggerCommand(QByteArray("g")));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdbEngine::canInterruptInferior() const
|
bool CdbEngine::canInterruptInferior() const
|
||||||
@@ -1011,8 +1015,10 @@ void CdbEngine::executeRunToLine(const ContextData &data)
|
|||||||
bp.fileName = data.fileName;
|
bp.fileName = data.fileName;
|
||||||
bp.lineNumber = data.lineNumber;
|
bp.lineNumber = data.lineNumber;
|
||||||
}
|
}
|
||||||
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
postCommand(DebuggerCommand(
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
||||||
|
BuiltinCommand,
|
||||||
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
continueInferior();
|
continueInferior();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1022,8 +1028,10 @@ void CdbEngine::executeRunToFunction(const QString &functionName)
|
|||||||
BreakpointParameters bp(BreakpointByFunction);
|
BreakpointParameters bp(BreakpointByFunction);
|
||||||
bp.functionName = functionName;
|
bp.functionName = functionName;
|
||||||
|
|
||||||
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
postCommand(DebuggerCommand(
|
||||||
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
||||||
|
BuiltinCommand,
|
||||||
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); }));
|
||||||
continueInferior();
|
continueInferior();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1033,7 +1041,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;
|
||||||
postCommand(cmd);
|
postCommand(DebuggerCommand(cmd));
|
||||||
reloadRegisters();
|
reloadRegisters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1048,7 +1056,8 @@ void CdbEngine::executeJumpToLine(const ContextData &data)
|
|||||||
QByteArray cmd;
|
QByteArray cmd;
|
||||||
ByteArrayInputStream str(cmd);
|
ByteArrayInputStream str(cmd);
|
||||||
str << "? `" << QDir::toNativeSeparators(data.fileName) << ':' << data.lineNumber << '`';
|
str << "? `" << QDir::toNativeSeparators(data.fileName) << ':' << data.lineNumber << '`';
|
||||||
postBuiltinCommand(cmd, [this, data](const DebuggerResponse &r) { handleJumpToLineAddressResolution(r, data); });
|
postCommand(DebuggerCommand(cmd, BuiltinCommand,
|
||||||
|
[this, data](const DebuggerResponse &r) { handleJumpToLineAddressResolution(r, data); }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1062,7 +1071,7 @@ void CdbEngine::jumpToAddress(quint64 address)
|
|||||||
str.setHexPrefix(true);
|
str.setHexPrefix(true);
|
||||||
str.setIntegerBase(16);
|
str.setIntegerBase(16);
|
||||||
str << address;
|
str << address;
|
||||||
postCommand(registerCmd);
|
postCommand(DebuggerCommand(registerCmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleJumpToLineAddressResolution(const DebuggerResponse &response, const ContextData &context)
|
void CdbEngine::handleJumpToLineAddressResolution(const DebuggerResponse &response, const ContextData &context)
|
||||||
@@ -1127,7 +1136,7 @@ void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const Q
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
postCommand(cmd);
|
postCommand(DebuggerCommand(cmd));
|
||||||
// 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();
|
||||||
@@ -1151,81 +1160,52 @@ 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)
|
||||||
postCommand(command.toLocal8Bit());
|
postCommand(DebuggerCommand(command.toLocal8Bit()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post command to the cdb process
|
// Post command to the cdb process
|
||||||
void CdbEngine::postCommand(const QByteArray &cmd)
|
void CdbEngine::postCommand(const DebuggerCommand &dbgCmd)
|
||||||
{
|
{
|
||||||
if (debug)
|
QByteArray cmd = dbgCmd.function + dbgCmd.arguments();
|
||||||
qDebug("CdbEngine::postCommand %dms '%s' %s\n",
|
if (!m_accessible) {
|
||||||
elapsedLogTime(), cmd.constData(), stateName(state()));
|
const QString msg = QString::fromLatin1("Attempt to issue command \"%1\" to non-accessible session (%2)")
|
||||||
showMessage(QString::fromLocal8Bit(cmd), LogInput);
|
.arg(QString::fromLocal8Bit(cmd), QString::fromLatin1(stateName(state())));
|
||||||
m_process.write(cmd + '\n');
|
showMessage(msg, LogError);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray fullCmd;
|
||||||
|
ByteArrayInputStream str(fullCmd);
|
||||||
|
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.
|
||||||
void CdbEngine::postBuiltinCommand(const QByteArray &cmd,
|
|
||||||
CommandHandler handler)
|
|
||||||
{
|
|
||||||
if (!m_accessible) {
|
|
||||||
const QString msg = QString::fromLatin1("Attempt to issue builtin command \"%1\" to non-accessible session (%2)")
|
|
||||||
.arg(QString::fromLocal8Bit(cmd), QString::fromLatin1(stateName(state())));
|
|
||||||
showMessage(msg, LogError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const int token = m_nextCommandToken++;
|
const int token = m_nextCommandToken++;
|
||||||
CdbCommandPtr pendingCommand(new CdbCommand(handler));
|
|
||||||
|
|
||||||
m_commandForToken.insert(token, pendingCommand);
|
|
||||||
// Enclose command in echo-commands for token
|
|
||||||
QByteArray fullCmd;
|
|
||||||
ByteArrayInputStream str(fullCmd);
|
|
||||||
str << ".echo \"" << m_tokenPrefix << token << "<\"\n"
|
str << ".echo \"" << m_tokenPrefix << token << "<\"\n"
|
||||||
<< cmd << "\n.echo \"" << m_tokenPrefix << token << ">\"";
|
<< cmd << "\n.echo \"" << m_tokenPrefix << token << ">\"";
|
||||||
if (debug)
|
m_commandForToken.insert(token, dbgCmd);
|
||||||
qDebug("CdbEngine::postBuiltinCommand %dms '%s' token=%d %s, pending=%d",
|
} else if (dbgCmd.flags & ExtensionCommand) {
|
||||||
elapsedLogTime(), cmd.constData(), token, stateName(state()),
|
|
||||||
m_commandForToken.size());
|
|
||||||
if (debug > 1)
|
|
||||||
qDebug("CdbEngine::postBuiltinCommand: resulting command '%s'\n",
|
|
||||||
fullCmd.constData());
|
|
||||||
postCommand(fullCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 queue.
|
// pass along token for identification in hash.
|
||||||
void CdbEngine::postExtensionCommand(const QByteArray &cmd,
|
|
||||||
const QByteArray &arguments,
|
|
||||||
CommandHandler handler)
|
|
||||||
{
|
|
||||||
if (!m_accessible) {
|
|
||||||
const QString msg = QString::fromLatin1("Attempt to issue extension command \"%1\" to non-accessible session (%2)")
|
|
||||||
.arg(QString::fromLocal8Bit(cmd), QString::fromLatin1(stateName(state())));
|
|
||||||
showMessage(msg, LogError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int token = m_nextCommandToken++;
|
const int token = m_nextCommandToken++;
|
||||||
|
str << m_extensionCommandPrefixBA << dbgCmd.function << " -t " << token;
|
||||||
// Format full command with token to be recognizeable in the output
|
if (!dbgCmd.args.isEmpty())
|
||||||
QByteArray fullCmd;
|
str << ' ' << dbgCmd.args;
|
||||||
ByteArrayInputStream str(fullCmd);
|
m_commandForToken.insert(token, dbgCmd);
|
||||||
str << m_extensionCommandPrefixBA << cmd << " -t " << token;
|
} else {
|
||||||
if (!arguments.isEmpty())
|
str << cmd;
|
||||||
str << ' ' << arguments;
|
}
|
||||||
|
if (debug) {
|
||||||
CdbCommandPtr pendingCommand(new CdbCommand(handler));
|
qDebug("CdbEngine::postCommand %dms '%s' %s, pending=%d",
|
||||||
|
elapsedLogTime(), dbgCmd.function.data(), stateName(state()),
|
||||||
m_commandForToken.insert(token, pendingCommand);
|
|
||||||
// Enclose command in echo-commands for token
|
|
||||||
if (debug)
|
|
||||||
qDebug("CdbEngine::postExtensionCommand %dms '%s' token=%d %s, pending=%d",
|
|
||||||
elapsedLogTime(), fullCmd.constData(), token, stateName(state()),
|
|
||||||
m_commandForToken.size());
|
m_commandForToken.size());
|
||||||
postCommand(fullCmd);
|
}
|
||||||
|
if (debug > 1) {
|
||||||
|
qDebug("CdbEngine::postCommand: resulting command '%s'\n",
|
||||||
|
fullCmd.constData());
|
||||||
|
}
|
||||||
|
showMessage(QString::fromLocal8Bit(cmd), LogInput);
|
||||||
|
m_process.write(fullCmd + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::activateFrame(int index)
|
void CdbEngine::activateFrame(int index)
|
||||||
@@ -1343,8 +1323,8 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters)
|
|||||||
if (partialUpdate)
|
if (partialUpdate)
|
||||||
str << blankSeparator << updateParameters.partialVariable;
|
str << blankSeparator << updateParameters.partialVariable;
|
||||||
|
|
||||||
postExtensionCommand("locals", arguments,
|
postCommand(DebuggerCommand("locals", arguments.constData(), ExtensionCommand,
|
||||||
[this, partialUpdate](const DebuggerResponse &r) { handleLocals(r, partialUpdate); });
|
[this, partialUpdate](const DebuggerResponse &r) { handleLocals(r, partialUpdate); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::updateAll()
|
void CdbEngine::updateAll()
|
||||||
@@ -1360,9 +1340,9 @@ void CdbEngine::selectThread(ThreadId threadId)
|
|||||||
threadsHandler()->setCurrentThread(threadId);
|
threadsHandler()->setCurrentThread(threadId);
|
||||||
|
|
||||||
const QByteArray cmd = '~' + QByteArray::number(threadId.raw()) + " s";
|
const QByteArray cmd = '~' + QByteArray::number(threadId.raw()) + " s";
|
||||||
postBuiltinCommand(cmd, [this](const DebuggerResponse &) {
|
postCommand(DebuggerCommand(cmd, BuiltinCommand, [this](const DebuggerResponse &) {
|
||||||
postExtensionCommand("stack", "unlimited", CB(handleStackTrace));
|
reloadFullStack();
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default address range for showing disassembly.
|
// Default address range for showing disassembly.
|
||||||
@@ -1408,7 +1388,8 @@ void CdbEngine::postDisassemblerCommand(quint64 address, quint64 endAddress,
|
|||||||
QByteArray cmd;
|
QByteArray cmd;
|
||||||
ByteArrayInputStream str(cmd);
|
ByteArrayInputStream str(cmd);
|
||||||
str << "u " << hex <<hexPrefixOn << address << ' ' << endAddress;
|
str << "u " << hex <<hexPrefixOn << address << ' ' << endAddress;
|
||||||
postBuiltinCommand(cmd, [this, agent](const DebuggerResponse &r) { handleDisassembler(r, agent); });
|
postCommand(DebuggerCommand(cmd, BuiltinCommand,
|
||||||
|
[this, agent](const DebuggerResponse &r) { handleDisassembler(r, agent); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::postResolveSymbol(const QString &module, const QString &function,
|
void CdbEngine::postResolveSymbol(const QString &module, const QString &function,
|
||||||
@@ -1420,8 +1401,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);
|
||||||
postBuiltinCommand(QByteArray("x ") + symbol.toLatin1(),
|
postCommand(DebuggerCommand(QByteArray("x ") + symbol.toLatin1(), BuiltinCommand,
|
||||||
[this, symbol, agent](const DebuggerResponse &r) { handleResolveSymbol(r, symbol, agent); });
|
[this, symbol, agent](const DebuggerResponse &r) {
|
||||||
|
handleResolveSymbol(r, symbol, agent);
|
||||||
|
}));
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1("Using cached addresses for %1.").
|
showMessage(QString::fromLatin1("Using cached addresses for %1.").
|
||||||
arg(symbol), LogMisc);
|
arg(symbol), LogMisc);
|
||||||
@@ -1569,8 +1552,8 @@ void CdbEngine::postFetchMemory(const MemoryViewCookie &cookie)
|
|||||||
QByteArray args;
|
QByteArray args;
|
||||||
ByteArrayInputStream str(args);
|
ByteArrayInputStream str(args);
|
||||||
str << cookie.address << ' ' << cookie.length;
|
str << cookie.address << ' ' << cookie.length;
|
||||||
postExtensionCommand("memory", args,
|
postCommand(DebuggerCommand("memory", args, ExtensionCommand,
|
||||||
[this, cookie](const DebuggerResponse &r) { handleMemory(r, cookie); });
|
[this, cookie](const DebuggerResponse &r) { handleMemory(r, cookie); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data)
|
void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data)
|
||||||
@@ -1580,7 +1563,7 @@ 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 {
|
||||||
postCommand(cdbWriteMemoryCommand(addr, data));
|
postCommand(DebuggerCommand(cdbWriteMemoryCommand(addr, data)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1598,7 +1581,7 @@ void CdbEngine::handleMemory(const DebuggerResponse &response, const MemoryViewC
|
|||||||
|
|
||||||
void CdbEngine::reloadModules()
|
void CdbEngine::reloadModules()
|
||||||
{
|
{
|
||||||
postExtensionCommand("modules", QByteArray(), CB(handleModules));
|
postCommand(DebuggerCommand("modules", ExtensionCommand, CB(handleModules)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::loadSymbols(const QString & /* moduleName */)
|
void CdbEngine::loadSymbols(const QString & /* moduleName */)
|
||||||
@@ -1617,7 +1600,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);
|
||||||
postExtensionCommand("registers", QByteArray(), CB(handleRegistersExt));
|
postCommand(DebuggerCommand("registers", ExtensionCommand, CB(handleRegistersExt)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::reloadSourceFiles()
|
void CdbEngine::reloadSourceFiles()
|
||||||
@@ -1628,12 +1611,12 @@ void CdbEngine::reloadFullStack()
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug("%s", Q_FUNC_INFO);
|
qDebug("%s", Q_FUNC_INFO);
|
||||||
postExtensionCommand("stack", "unlimited", CB(handleStackTrace));
|
postCommand(DebuggerCommand("stack", "unlimited", ExtensionCommand, CB(handleStackTrace)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::listBreakpoints()
|
void CdbEngine::listBreakpoints()
|
||||||
{
|
{
|
||||||
postExtensionCommand("breakpoints", QByteArray("-v"), CB(handleBreakPoints));
|
postCommand(DebuggerCommand("breakpoints", "-v", ExtensionCommand, CB(handleBreakPoints)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handlePid(const DebuggerResponse &response)
|
void CdbEngine::handlePid(const DebuggerResponse &response)
|
||||||
@@ -1861,8 +1844,8 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
|
|||||||
exp.prepend('"');
|
exp.prepend('"');
|
||||||
exp.append('"');
|
exp.append('"');
|
||||||
}
|
}
|
||||||
postExtensionCommand("expression", exp,
|
postCommand(DebuggerCommand("expression", exp, ExtensionCommand,
|
||||||
[this, id, stopReason](const DebuggerResponse &r) { handleExpression(r, id, stopReason); });
|
[this, id, stopReason](const DebuggerResponse &r) { handleExpression(r, id, stopReason); }));
|
||||||
|
|
||||||
return StopReportLog;
|
return StopReportLog;
|
||||||
}
|
}
|
||||||
@@ -2010,7 +1993,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);
|
||||||
postCommand("~0 s");
|
postCommand(DebuggerCommand("~0 s"));
|
||||||
forcedThreadId = ThreadId(0);
|
forcedThreadId = ThreadId(0);
|
||||||
// Re-fetch stack again.
|
// Re-fetch stack again.
|
||||||
reloadFullStack();
|
reloadFullStack();
|
||||||
@@ -2025,8 +2008,8 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT
|
|||||||
executeStepOut();
|
executeStepOut();
|
||||||
return;
|
return;
|
||||||
case ParseStackWow64:
|
case ParseStackWow64:
|
||||||
postBuiltinCommand("lm m wow64",
|
postCommand(DebuggerCommand("lm m wow64", BuiltinCommand,
|
||||||
[this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); });
|
[this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); }));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2117,7 +2100,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")) {
|
||||||
postBuiltinCommand("k", [this, stack](const DebuggerResponse &r) { ensureUsing32BitStackInWow64(r, stack); });
|
postCommand(DebuggerCommand("k", BuiltinCommand,
|
||||||
|
[this, stack](const DebuggerResponse &r) { ensureUsing32BitStackInWow64(r, stack); }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_wow64State = noWow64Stack;
|
m_wow64State = noWow64Stack;
|
||||||
@@ -2137,7 +2121,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;
|
||||||
postBuiltinCommand("!wow64exts.sw", CB(handleSwitchWow64Stack));
|
postCommand(DebuggerCommand("!wow64exts.sw", BuiltinCommand, CB(handleSwitchWow64Stack)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2154,7 +2138,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
|
||||||
postExtensionCommand("threads", QByteArray(), CB(handleThreads));
|
postCommand(DebuggerCommand("threads", ExtensionCommand, CB(handleThreads)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleSessionAccessible(unsigned long cdbExState)
|
void CdbEngine::handleSessionAccessible(unsigned long cdbExState)
|
||||||
@@ -2239,13 +2223,12 @@ void CdbEngine::handleExtensionMessage(char t, int token, const QByteArray &what
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Did the command finish? Take off queue and complete, invoke CB
|
// Did the command finish? Take off queue and complete, invoke CB
|
||||||
const CdbCommandPtr command = m_commandForToken.take(token);
|
const DebuggerCommand command = m_commandForToken.take(token);
|
||||||
if (!command.isNull()) {
|
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug("### Completed extension command for token=%d, pending=%d",
|
qDebug("### Completed extension command '%s' for token=%d, pending=%d",
|
||||||
token, m_commandForToken.size());
|
command.function.data(), token, m_commandForToken.size());
|
||||||
|
|
||||||
if (!command->handler)
|
if (!command.callback)
|
||||||
return;
|
return;
|
||||||
DebuggerResponse response;
|
DebuggerResponse response;
|
||||||
response.data.m_name = "data";
|
response.data.m_name = "data";
|
||||||
@@ -2265,10 +2248,9 @@ void CdbEngine::handleExtensionMessage(char t, int token, const QByteArray &what
|
|||||||
response.data.m_type = GdbMi::Tuple;
|
response.data.m_type = GdbMi::Tuple;
|
||||||
response.data.m_children.push_back(msg);
|
response.data.m_children.push_back(msg);
|
||||||
}
|
}
|
||||||
command->handler(response);
|
command.callback(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (what == "debuggee_output") {
|
if (what == "debuggee_output") {
|
||||||
showMessage(StringFromBase64EncodedUtf16(message), AppOutput);
|
showMessage(StringFromBase64EncodedUtf16(message), AppOutput);
|
||||||
@@ -2421,25 +2403,25 @@ void CdbEngine::parseOutputLine(QByteArray line)
|
|||||||
QTC_ASSERT(!isStartToken, return);
|
QTC_ASSERT(!isStartToken, return);
|
||||||
if (isCommandToken) {
|
if (isCommandToken) {
|
||||||
// Did the command finish? Invoke callback and remove from queue.
|
// Did the command finish? Invoke callback and remove from queue.
|
||||||
|
const DebuggerCommand &command = m_commandForToken.take(token);
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug("### Completed builtin command for token=%d, %d lines, pending=%d",
|
qDebug("### Completed builtin command '%s' for token=%d, %d lines, pending=%d",
|
||||||
m_currentBuiltinResponseToken, m_currentBuiltinResponse.count('\n'),
|
command.function.data(), m_currentBuiltinResponseToken,
|
||||||
m_commandForToken.size() - 1);
|
m_currentBuiltinResponse.count('\n'), m_commandForToken.size() - 1);
|
||||||
QTC_ASSERT(token == m_currentBuiltinResponseToken, return);
|
QTC_ASSERT(token == m_currentBuiltinResponseToken, return);
|
||||||
if (boolSetting(VerboseLog))
|
if (boolSetting(VerboseLog))
|
||||||
showMessage(QLatin1String(m_currentBuiltinResponse), LogMisc);
|
showMessage(QLatin1String(m_currentBuiltinResponse), LogMisc);
|
||||||
const CdbCommandPtr ¤tCommand = m_commandForToken.take(token);
|
m_currentBuiltinResponseToken = -1;
|
||||||
QTC_ASSERT(!currentCommand.isNull(), return);
|
m_currentBuiltinResponse.clear();
|
||||||
|
if (!command.callback)
|
||||||
|
return;
|
||||||
DebuggerResponse response;
|
DebuggerResponse response;
|
||||||
response.token = token;
|
response.token = token;
|
||||||
response.data.m_name = "data";
|
response.data.m_name = "data";
|
||||||
response.data.m_data = m_currentBuiltinResponse;
|
response.data.m_data = m_currentBuiltinResponse;
|
||||||
response.data.m_type = GdbMi::Tuple;
|
response.data.m_type = GdbMi::Tuple;
|
||||||
response.resultClass = ResultDone;
|
response.resultClass = ResultDone;
|
||||||
if (currentCommand->handler)
|
command.callback(response);
|
||||||
currentCommand->handler(response);
|
|
||||||
m_currentBuiltinResponseToken = -1;
|
|
||||||
m_currentBuiltinResponse.clear();
|
|
||||||
} else {
|
} else {
|
||||||
// Record output of current command
|
// Record output of current command
|
||||||
if (!m_currentBuiltinResponse.isEmpty())
|
if (!m_currentBuiltinResponse.isEmpty())
|
||||||
@@ -2688,16 +2670,18 @@ 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);
|
||||||
postBuiltinCommand(
|
postCommand(DebuggerCommand(
|
||||||
cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false),
|
cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false),
|
||||||
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
BuiltinCommand,
|
||||||
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }));
|
||||||
} else {
|
} else {
|
||||||
postBuiltinCommand(
|
postCommand(DebuggerCommand(
|
||||||
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
||||||
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
BuiltinCommand,
|
||||||
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }));
|
||||||
}
|
}
|
||||||
if (!parameters.enabled)
|
if (!parameters.enabled)
|
||||||
postCommand("bd " + QByteArray::number(breakPointIdToCdbId(id)));
|
postCommand(DebuggerCommand("bd " + QByteArray::number(breakPointIdToCdbId(id))));
|
||||||
bp.notifyBreakpointInsertProceeding();
|
bp.notifyBreakpointInsertProceeding();
|
||||||
bp.notifyBreakpointInsertOk();
|
bp.notifyBreakpointInsertOk();
|
||||||
m_pendingBreakpointMap.insert(id, response);
|
m_pendingBreakpointMap.insert(id, response);
|
||||||
@@ -2716,24 +2700,25 @@ 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.
|
||||||
postCommand((parameters.enabled ? "be " : "bd ")
|
postCommand(DebuggerCommand((parameters.enabled ? "be " : "bd ")
|
||||||
+ QByteArray::number(breakPointIdToCdbId(id)));
|
+ QByteArray::number(breakPointIdToCdbId(id))));
|
||||||
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;
|
||||||
postCommand(cdbClearBreakpointCommand(id));
|
postCommand(DebuggerCommand(cdbClearBreakpointCommand(id)));
|
||||||
postBuiltinCommand(
|
postCommand(DebuggerCommand(
|
||||||
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
||||||
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
BuiltinCommand,
|
||||||
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); }));
|
||||||
m_pendingBreakpointMap.insert(id, response);
|
m_pendingBreakpointMap.insert(id, response);
|
||||||
}
|
}
|
||||||
bp.notifyBreakpointChangeOk();
|
bp.notifyBreakpointChangeOk();
|
||||||
break;
|
break;
|
||||||
case BreakpointRemoveRequested:
|
case BreakpointRemoveRequested:
|
||||||
postCommand(cdbClearBreakpointCommand(id));
|
postCommand(DebuggerCommand(cdbClearBreakpointCommand(id)));
|
||||||
bp.notifyBreakpointRemoveProceeding();
|
bp.notifyBreakpointRemoveProceeding();
|
||||||
bp.notifyBreakpointRemoveOk();
|
bp.notifyBreakpointRemoveOk();
|
||||||
m_pendingBreakpointMap.remove(id);
|
m_pendingBreakpointMap.remove(id);
|
||||||
@@ -2745,7 +2730,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);
|
||||||
postCommand(cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false));
|
postCommand(DebuggerCommand(cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false)));
|
||||||
m_insertSubBreakpointMap.remove(id);
|
m_insertSubBreakpointMap.remove(id);
|
||||||
m_pendingSubBreakpointMap.insert(id, response);
|
m_pendingSubBreakpointMap.insert(id, response);
|
||||||
}
|
}
|
||||||
@@ -2872,7 +2857,7 @@ unsigned CdbEngine::parseStackTrace(const GdbMi &data, bool sourceStepInto)
|
|||||||
|
|
||||||
void CdbEngine::loadAdditionalQmlStack()
|
void CdbEngine::loadAdditionalQmlStack()
|
||||||
{
|
{
|
||||||
postExtensionCommand("qmlstack", QByteArray(), CB(handleAdditionalQmlStack));
|
postCommand(DebuggerCommand("qmlstack", ExtensionCommand, CB(handleAdditionalQmlStack)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleAdditionalQmlStack(const DebuggerResponse &response)
|
void CdbEngine::handleAdditionalQmlStack(const DebuggerResponse &response)
|
||||||
@@ -2917,8 +2902,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) {
|
||||||
postBuiltinCommand("lm m wow64",
|
postCommand(DebuggerCommand("lm m wow64", BuiltinCommand,
|
||||||
[this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); });
|
[this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); }));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showMessage(stack["msg"].toLatin1(), LogError);
|
showMessage(stack["msg"].toLatin1(), LogError);
|
||||||
@@ -3095,14 +3080,14 @@ void CdbEngine::postWidgetAtCommand()
|
|||||||
QByteArray arguments = QByteArray::number(m_watchPointX);
|
QByteArray arguments = QByteArray::number(m_watchPointX);
|
||||||
arguments.append(' ');
|
arguments.append(' ');
|
||||||
arguments.append(QByteArray::number(m_watchPointY));
|
arguments.append(QByteArray::number(m_watchPointY));
|
||||||
postExtensionCommand("widgetat", arguments, CB(handleWidgetAt));
|
postCommand(DebuggerCommand("widgetat", arguments.constData(), ExtensionCommand, CB(handleWidgetAt)));
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
postCommand(cdbWriteMemoryCommand(changeData.address, changeData.data));
|
postCommand(DebuggerCommand(cdbWriteMemoryCommand(changeData.address, changeData.data)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (v.canConvert<MemoryViewCookie>()) {
|
if (v.canConvert<MemoryViewCookie>()) {
|
||||||
|
|||||||
@@ -127,14 +127,7 @@ private slots:
|
|||||||
void readyReadStandardError();
|
void readyReadStandardError();
|
||||||
void processError();
|
void processError();
|
||||||
void processFinished();
|
void processFinished();
|
||||||
void postCommand(const QByteArray &cmd);
|
void postCommand(const DebuggerCommand &cmd);
|
||||||
void postBuiltinCommand(const QByteArray &cmd,
|
|
||||||
CommandHandler handler);
|
|
||||||
|
|
||||||
void postExtensionCommand(const QByteArray &cmd,
|
|
||||||
const QByteArray &arguments,
|
|
||||||
CommandHandler handler);
|
|
||||||
|
|
||||||
void operateByInstructionTriggered(bool);
|
void operateByInstructionTriggered(bool);
|
||||||
void verboseLogTriggered(bool);
|
void verboseLogTriggered(bool);
|
||||||
|
|
||||||
@@ -170,7 +163,11 @@ private:
|
|||||||
ParseStackStepOut = 2, // Need to step out, hit on a frame without debug information
|
ParseStackStepOut = 2, // Need to step out, hit on a frame without debug information
|
||||||
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 {
|
||||||
|
NoCallBack = 0,
|
||||||
|
BuiltinCommand,
|
||||||
|
ExtensionCommand,
|
||||||
|
};
|
||||||
|
|
||||||
bool startConsole(const DebuggerRunParameters &sp, QString *errorMessage);
|
bool startConsole(const DebuggerRunParameters &sp, QString *errorMessage);
|
||||||
void init();
|
void init();
|
||||||
@@ -245,7 +242,7 @@ private:
|
|||||||
SpecialStopMode m_specialStopMode;
|
SpecialStopMode m_specialStopMode;
|
||||||
ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation;
|
ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation;
|
||||||
int m_nextCommandToken;
|
int m_nextCommandToken;
|
||||||
QHash<int, CdbCommandPtr> m_commandForToken;
|
QHash<int, DebuggerCommand> m_commandForToken;
|
||||||
QByteArray m_currentBuiltinResponse;
|
QByteArray m_currentBuiltinResponse;
|
||||||
int m_currentBuiltinResponseToken;
|
int m_currentBuiltinResponseToken;
|
||||||
QMap<QString, NormalizedSourceFileName> m_normalizedFileCache;
|
QMap<QString, NormalizedSourceFileName> m_normalizedFileCache;
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ 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())
|
||||||
|
: function(f), args(a), callback(cb), flags(flags)
|
||||||
|
{}
|
||||||
DebuggerCommand(const char *f, Callback cb)
|
DebuggerCommand(const char *f, Callback cb)
|
||||||
: function(f), callback(cb), flags(0)
|
: function(f), callback(cb), flags(0)
|
||||||
{}
|
{}
|
||||||
|
|||||||
Reference in New Issue
Block a user