diff options
Diffstat (limited to 'src/plugins/debugger/cdb/cdbengine.cpp')
-rw-r--r-- | src/plugins/debugger/cdb/cdbengine.cpp | 102 |
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}); } |