From 2942ae876cba9c2082dc383842fbd781766ddef8 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 12 Jun 2019 12:33:46 +0200 Subject: [PATCH] Debugger: Use Utils::CommandLine handling in CDB Change-Id: I124f7eeee5eb5028fb3316f69144fdcdfe63bc4d Reviewed-by: David Schulz --- src/plugins/debugger/cdb/cdbengine.cpp | 118 +++++++++---------------- src/plugins/debugger/cdb/cdbengine.h | 2 +- 2 files changed, 44 insertions(+), 76 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 6c6e5de61a2..95935cc514b 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -295,35 +295,6 @@ QString CdbEngine::extensionLibraryName(bool is64Bit) return rc; } -// Determine environment for CDB.exe, start out with run config and -// add CDB extension path merged with system value should there be one. -static QStringList mergeEnvironment(QStringList runConfigEnvironment, - QString cdbExtensionPath) -{ - // Determine CDB extension path from Qt Creator - static const char cdbExtensionPathVariableC[] = "_NT_DEBUGGER_EXTENSION_PATH"; - const QByteArray oldCdbExtensionPath = qgetenv(cdbExtensionPathVariableC); - if (!oldCdbExtensionPath.isEmpty()) { - cdbExtensionPath.append(';'); - cdbExtensionPath.append(QString::fromLocal8Bit(oldCdbExtensionPath)); - } - // We do not assume someone sets _NT_DEBUGGER_EXTENSION_PATH in the run - // config, just to make sure, delete any existing entries - const QString cdbExtensionPathVariableAssign = - QLatin1String(cdbExtensionPathVariableC) + '='; - for (QStringList::iterator it = runConfigEnvironment.begin(); it != runConfigEnvironment.end() ; ) { - if (it->startsWith(cdbExtensionPathVariableAssign)) { - it = runConfigEnvironment.erase(it); - break; - } else { - ++it; - } - } - runConfigEnvironment.append(cdbExtensionPathVariableAssign + - QDir::toNativeSeparators(cdbExtensionPath)); - return runConfigEnvironment; -} - int CdbEngine::elapsedLogTime() const { const int elapsed = m_logTime.elapsed(); @@ -372,18 +343,16 @@ void CdbEngine::setupEngine() m_effectiveStartMode = sp.startMode; } - const QChar blank(' '); // Start engine which will run until initial breakpoint: // Determine binary (force MSVC), extension lib name and path to use // The extension is passed as relative name with the path variable set //(does not work with absolute path names) - const QString executable = sp.debugger.executable; - if (executable.isEmpty()) { + if (sp.debugger.executable.isEmpty()) { handleSetupFailure(tr("There is no CDB executable specified.")); return; } - bool cdbIs64Bit = Utils::is64BitWindowsBinary(executable); + bool cdbIs64Bit = Utils::is64BitWindowsBinary(sp.debugger.executable); if (!cdbIs64Bit) m_wow64State = noWow64Stack; const QFileInfo extensionFi(CdbEngine::extensionLibraryName(cdbIs64Bit)); @@ -401,28 +370,32 @@ void CdbEngine::setupEngine() Core::Constants::IDE_DISPLAY_NAME)); return; } + + // Prepare command line. + CommandLine debugger{FilePath::fromString(sp.debugger.executable)}; + const QString extensionFileName = extensionFi.fileName(); - // Prepare arguments - QStringList arguments; const bool isRemote = sp.startMode == AttachToRemoteServer; if (isRemote) { // Must be first - arguments << "-remote" << sp.remoteChannel; + debugger.addArgs({"-remote", sp.remoteChannel}); } else { - arguments << ("-a" + extensionFileName); + debugger.addArg("-a" + extensionFileName); } + // Source line info/No terminal breakpoint / Pull extension - arguments << "-lines" << "-G" - // register idle (debuggee stop) notification - << "-c" - << ".idle_cmd " + m_extensionCommandPrefix + "idle"; + debugger.addArgs({"-lines", "-G", + // register idle (debuggee stop) notification + "-c", ".idle_cmd " + m_extensionCommandPrefix + "idle"}); + if (sp.useTerminal) // Separate console - arguments << "-2"; + debugger.addArg("-2"); + if (boolSetting(IgnoreFirstChanceAccessViolation)) - arguments << "-x"; + debugger.addArg("-x"); const QStringList &sourcePaths = stringListSetting(CdbSourcePaths); if (!sourcePaths.isEmpty()) - arguments << "-srcpath" << sourcePaths.join(';'); + debugger.addArgs({"-srcpath", sourcePaths.join(';')}); QStringList symbolPaths = stringListSetting(CdbSymbolPaths); QString symbolPath = sp.inferior.environment.value("_NT_ALT_SYMBOL_PATH"); @@ -431,48 +404,39 @@ void CdbEngine::setupEngine() symbolPath = sp.inferior.environment.value("_NT_SYMBOL_PATH"); if (!symbolPath.isEmpty()) symbolPaths += symbolPath; - arguments << "-y" << (symbolPaths.isEmpty() ? "\"\"" : symbolPaths.join(';')); + debugger.addArgs({"-y", symbolPaths.join(';')}); - // Compile argument string preserving quotes - QString nativeArguments = expand(stringSetting(CdbAdditionalArguments)); switch (sp.startMode) { case StartInternal: case StartExternal: - if (!nativeArguments.isEmpty()) - nativeArguments.push_back(blank); - QtcProcess::addArgs(&nativeArguments, - QStringList(QDir::toNativeSeparators(sp.inferior.executable))); - if (!sp.inferior.commandLineArguments.isEmpty()) { // Complete native argument string. - if (!nativeArguments.isEmpty()) - nativeArguments.push_back(blank); - nativeArguments += sp.inferior.commandLineArguments; - } + debugger.addArg(QDir::toNativeSeparators(sp.inferior.executable)); + // Complete native argument string. + debugger.addArgs(sp.inferior.commandLineArguments, CommandLine::Raw); break; case AttachToRemoteServer: break; case AttachExternal: case AttachCrashedExternal: - arguments << "-p" << QString::number(sp.attachPID.pid()); + debugger.addArgs({"-p", QString::number(sp.attachPID.pid())}); if (sp.startMode == AttachCrashedExternal) { - arguments << "-e" << sp.crashParameter << "-g"; + debugger.addArgs({"-e", sp.crashParameter, "-g"}); } else { if (terminal()) - arguments << "-pr" << "-pb"; + debugger.addArgs({"-pr", "-pb"}); } break; case AttachCore: - arguments << "-z" << sp.coreFile; + debugger.addArgs({"-z", sp.coreFile}); break; default: handleSetupFailure(QString("Internal error: Unsupported start mode %1.").arg(sp.startMode)); return; } - const QString msg = QString("Launching %1 %2\nusing %3 of %4."). - arg(QDir::toNativeSeparators(executable), - arguments.join(blank) + blank + nativeArguments, - QDir::toNativeSeparators(extensionFi.absoluteFilePath()), - extensionFi.lastModified().toString(Qt::SystemLocaleShortDate)); + const QString msg = QString("Launching %1\nusing %2 of %3.") + .arg(debugger.toUserOutput(), + QDir::toNativeSeparators(extensionFi.absoluteFilePath()), + extensionFi.lastModified().toString(Qt::SystemLocaleShortDate)); showMessage(msg, LogMisc); m_outputBuffer.clear(); @@ -486,25 +450,29 @@ void CdbEngine::setupEngine() if (!sp.useTerminal && !inferiorEnvironment.hasKey(qtLoggingToConsoleKey)) inferiorEnvironment.set(qtLoggingToConsoleKey, "0"); - m_process.setEnvironment(mergeEnvironment(inferiorEnvironment.toStringList(), - extensionFi.absolutePath())); + static const char cdbExtensionPathVariableC[] = "_NT_DEBUGGER_EXTENSION_PATH"; + inferiorEnvironment.prependOrSet(cdbExtensionPathVariableC, extensionFi.absolutePath()); + const QByteArray oldCdbExtensionPath = qgetenv(cdbExtensionPathVariableC); + if (!oldCdbExtensionPath.isEmpty()) { + inferiorEnvironment.appendOrSet(cdbExtensionPathVariableC, + QString::fromLocal8Bit(oldCdbExtensionPath)); + } + + m_process.setEnvironment(inferiorEnvironment); if (!sp.inferior.workingDirectory.isEmpty()) m_process.setWorkingDirectory(sp.inferior.workingDirectory); -#ifdef Q_OS_WIN - if (!nativeArguments.isEmpty()) // Appends - m_process.setNativeArguments(nativeArguments); -#endif - m_process.start(executable, arguments); + m_process.setCommand(debugger); + m_process.start(); if (!m_process.waitForStarted()) { handleSetupFailure(QString("Internal error: Cannot start process %1: %2"). - arg(QDir::toNativeSeparators(executable), m_process.errorString())); + arg(debugger.toUserOutput(), m_process.errorString())); return; } const qint64 pid = m_process.processId(); - showMessage(QString("%1 running as %2"). - arg(QDir::toNativeSeparators(executable)).arg(pid), LogMisc); + showMessage(QString("%1 running as %2").arg(debugger.executable().toUserOutput()).arg(pid), + LogMisc); m_hasDebuggee = true; m_initialSessionIdleHandled = false; if (isRemote) { // We do not get an 'idle' in a remote session, but are accessible diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 16b71b954b4..29f7ccc4d63 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -202,7 +202,7 @@ private: const QString m_tokenPrefix; void handleSetupFailure(const QString &errorMessage); - QProcess m_process; + Utils::QtcProcess m_process; DebuggerStartMode m_effectiveStartMode = NoStartMode; QByteArray m_outputBuffer; //! Debugger accessible (expecting commands)