aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/debugger/cdb/cdbengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/debugger/cdb/cdbengine.cpp')
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp102
1 files changed, 70 insertions, 32 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index a98ee3e9a7..472f8597d3 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -58,20 +58,22 @@
#include <projectexplorer/taskhub.h>
#include <texteditor/texteditor.h>
-#include <utils/synchronousprocess.h>
-#include <utils/qtcprocess.h>
-#include <utils/winutils.h>
-#include <utils/qtcassert.h>
-#include <utils/savedaction.h>
#include <utils/consoleprocess.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
+#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
+#include <utils/savedaction.h>
+#include <utils/stringutils.h>
+#include <utils/synchronousprocess.h>
+#include <utils/winutils.h>
#include <cplusplus/findcdbbreakpoint.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cppworkingcopy.h>
#include <QDir>
+#include <QRegularExpression>
#include <cctype>
@@ -363,7 +365,7 @@ void CdbEngine::setupEngine()
"you will need to build a separate CDB extension with the "
"same bitness as the CDB you want to use.").
arg(QDir::toNativeSeparators(extensionFi.absoluteFilePath()),
- Core::Constants::IDE_DISPLAY_NAME));
+ QString(Core::Constants::IDE_DISPLAY_NAME)));
return;
}
@@ -425,7 +427,7 @@ void CdbEngine::setupEngine()
const QString msg = QString("Launching %1\nusing %2 of %3.")
.arg(debugger.toUserOutput(),
QDir::toNativeSeparators(extensionFi.absoluteFilePath()),
- extensionFi.lastModified().toString(Qt::SystemLocaleShortDate));
+ QLocale::system().toString(extensionFi.lastModified(), QLocale::ShortFormat));
showMessage(msg, LogMisc);
m_outputBuffer.clear();
@@ -966,6 +968,13 @@ void CdbEngine::executeDebuggerCommand(const QString &command)
// Post command to the cdb process
void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
{
+ constexpr int maxCommandLength = 4096;
+ constexpr int maxTokenLength = 4 /*" -t "*/
+ + 5 /* 99999 tokens should be enough for a single qc run time*/
+ + 1 /* token part splitter '.' */
+ + 3 /* 1000 parts should also be more than enough */
+ + 1 /* final space */;
+
QString cmd = dbgCmd.function + dbgCmd.argsToString();
if (!m_accessible) {
doInterruptInferior([this, dbgCmd](){
@@ -977,11 +986,26 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
return;
}
+ if (dbgCmd.flags == ScriptCommand) {
+ // repack script command into an extension command
+ DebuggerCommand newCmd("script", ExtensionCommand, dbgCmd.callback);
+ if (!dbgCmd.args.isNull())
+ newCmd.args = QString{dbgCmd.function + '(' + dbgCmd.argsToPython() + ')'};
+ else
+ newCmd.args = dbgCmd.function;
+ runCommand(newCmd);
+ return;
+ }
+
QString fullCmd;
if (dbgCmd.flags == NoFlags) {
- fullCmd = cmd;
+ fullCmd = cmd + '\n';
+ if (fullCmd.length() > maxCommandLength) {
+ showMessage("Command is longer than 4096 characters execution will likely fail.",
+ LogWarning);
+ }
} else {
- const int token = m_nextCommandToken++;
+ const int token = ++m_nextCommandToken;
StringInputStream str(fullCmd);
if (dbgCmd.flags == BuiltinCommand) {
// Post a built-in-command producing free-format output with a callback.
@@ -989,23 +1013,35 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
// printing a specially formatted token to be identifiable in the output.
str << ".echo \"" << m_tokenPrefix << token << "<\"\n"
<< cmd << "\n"
- << ".echo \"" << m_tokenPrefix << token << ">\"";
+ << ".echo \"" << m_tokenPrefix << token << ">\"" << '\n';
+ if (fullCmd.length() > maxCommandLength) {
+ showMessage("Command is longer than 4096 characters execution will likely fail.",
+ LogWarning);
+ }
} else if (dbgCmd.flags == ExtensionCommand) {
+
// Post an extension command producing one-line output with a callback,
// pass along token for identification in hash.
- str << m_extensionCommandPrefix << dbgCmd.function << "%1%2";
- if (dbgCmd.args.isString())
- str << ' ' << dbgCmd.argsToString();
- cmd = fullCmd.arg("", "");
- fullCmd = fullCmd.arg(" -t ").arg(token);
- } else if (dbgCmd.flags == ScriptCommand) {
- // Add extension prefix and quotes the script command
- // pass along token for identification in hash.
- str << m_extensionCommandPrefix + "script %1%2 " << dbgCmd.function;
- if (!dbgCmd.args.isNull())
- str << '(' << dbgCmd.argsToPython() << ')';
- cmd = fullCmd.arg("", "");
- fullCmd = fullCmd.arg(" -t ").arg(token);
+ const QString prefix = m_extensionCommandPrefix + dbgCmd.function;
+ QList<QStringRef> splittedArguments;
+ if (dbgCmd.args.isString()) {
+ const QString &arguments = dbgCmd.argsToString();
+ cmd = prefix + arguments;
+ int argumentSplitPos = 0;
+ QList<QStringRef> splittedArguments;
+ int maxArgumentSize = maxCommandLength - prefix.length() - maxTokenLength;
+ while (argumentSplitPos < arguments.size()) {
+ splittedArguments << arguments.midRef(argumentSplitPos, maxArgumentSize);
+ argumentSplitPos += splittedArguments.last().length();
+ }
+ QTC_CHECK(argumentSplitPos == arguments.size());
+ int tokenPart = splittedArguments.size();
+ for (const QStringRef &part : qAsConst(splittedArguments))
+ str << prefix << " -t " << token << '.' << --tokenPart << ' ' << part << '\n';
+ } else {
+ cmd = prefix;
+ str << prefix << " -t " << token << '.' << 0 << '\n';
+ }
}
m_commandForToken.insert(token, dbgCmd);
}
@@ -1018,7 +1054,7 @@ void CdbEngine::runCommand(const DebuggerCommand &dbgCmd)
qDebug("CdbEngine::postCommand: resulting command '%s'\n", qPrintable(fullCmd));
}
showMessage(cmd, LogInput);
- m_process.write(fullCmd.toLocal8Bit() + '\n');
+ m_process.write(fullCmd.toLocal8Bit());
}
void CdbEngine::activateFrame(int index)
@@ -2289,11 +2325,12 @@ void CdbEngine::parseOutputLine(QString line)
}
const char versionString[] = "Microsoft (R) Windows Debugger Version";
if (line.startsWith(versionString)) {
- QRegExp versionRegEx("(\\d+)\\.(\\d+)\\.\\d+\\.\\d+");
- if (versionRegEx.indexIn(line) > -1) {
+ const QRegularExpression versionRegEx("(\\d+)\\.(\\d+)\\.\\d+\\.\\d+");
+ const QRegularExpressionMatch match = versionRegEx.match(line);
+ if (match.hasMatch()) {
bool ok = true;
- int major = versionRegEx.cap(1).toInt(&ok);
- int minor = versionRegEx.cap(2).toInt(&ok);
+ int major = match.captured(1).toInt(&ok);
+ int minor = match.captured(2).toInt(&ok);
if (ok) {
// for some incomprehensible reasons Microsoft cdb version 6.2 is newer than 6.12
m_autoBreakPointCorrection = major > 6 || (major == 6 && minor >= 2 && minor < 10);
@@ -2306,9 +2343,10 @@ void CdbEngine::parseOutputLine(QString line)
} else if (line.startsWith("ModLoad: ")) {
// output(64): ModLoad: 00007ffb`842b0000 00007ffb`843ee000 C:\Windows\system32\KERNEL32.DLL
// output(32): ModLoad: 00007ffb 00007ffb C:\Windows\system32\KERNEL32.DLL
- QRegExp moduleRegExp("[0-9a-fA-F]+(`[0-9a-fA-F]+)? [0-9a-fA-F]+(`[0-9a-fA-F]+)? (.*)");
- if (moduleRegExp.indexIn(line) > -1)
- showStatusMessage(tr("Module loaded: %1").arg(moduleRegExp.cap(3).trimmed()), 3000);
+ const QRegularExpression moduleRegExp("[0-9a-fA-F]+(`[0-9a-fA-F]+)? [0-9a-fA-F]+(`[0-9a-fA-F]+)? (.*)");
+ const QRegularExpressionMatch match = moduleRegExp.match(line);
+ if (match.hasMatch())
+ showStatusMessage(tr("Module loaded: %1").arg(match.captured(3).trimmed()), 3000);
} else {
showMessage(line, LogMisc);
}
@@ -2726,7 +2764,7 @@ void CdbEngine::setupScripting(const DebuggerResponse &response)
}
const QString commands = stringSetting(ExtraDumperCommands);
if (!commands.isEmpty()) {
- for (const auto &command : commands.split('\n', QString::SkipEmptyParts))
+ for (const auto &command : commands.split('\n', Utils::SkipEmptyParts))
runCommand({command, ScriptCommand});
}