Debugger: Split long cdbextension commands

Fixes: QTCREATORBUG-22922
Change-Id: I5def321f0f97717728bc5cdcd5309b458a8ecfa1
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2020-03-31 14:09:32 +02:00
parent 41a122641c
commit 9cfd1b5d6c
3 changed files with 177 additions and 27 deletions

View File

@@ -959,6 +959,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](){
@@ -970,11 +977,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.
@@ -982,23 +1004,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);
}
@@ -1011,7 +1045,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)