diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 812928811b6132620c0d0a35c1597636ebecd52e..eb39966d37ac21434f0147932c13f3d195ac118e 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1268,7 +1268,7 @@ void AndroidConfigurations::updateAutomaticKitList() // Update code for 3.0 beta, which shipped with a bug for the debugger settings ToolChain *tc = ToolChainKitInformation::toolChain(k, ToolChain::Language::Cxx); - if (tc && Debugger::DebuggerKitInformation::debuggerCommand(k) != tc->suggestedDebugger()) { + if (tc && Debugger::DebuggerKitInformation::runnable(k).executable != tc->suggestedDebugger().toString()) { Debugger::DebuggerItem debugger; debugger.setCommand(tc->suggestedDebugger()); debugger.setEngineType(Debugger::GdbEngineType); diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index a1ec4a0824e3cc7f7cafe134650f7aaf134793b7..e3c7e7a5a2492311ff8a65ce83c6d5734cf3a62c 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -506,7 +506,7 @@ bool CdbEngine::launchCDB(const DebuggerRunParameters &sp, QString *errorMessage // 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.debuggerCommand; + const QString executable = sp.debugger.executable; if (executable.isEmpty()) { *errorMessage = tr("There is no CDB executable specified."); return false; @@ -975,7 +975,7 @@ void CdbEngine::doInterruptInferior(SpecialStopMode sm) connect(m_signalOperation.data(), &DeviceProcessSignalOperation::finished, this, &CdbEngine::handleDoInterruptInferior); - m_signalOperation->setDebuggerCommand(runParameters().debuggerCommand); + m_signalOperation->setDebuggerCommand(runParameters().debugger.executable); m_signalOperation->interruptProcess(inferiorPid()); } diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 607d8613eacaf891fcd9211a520b367be637b90e..e7117bfc3c994debc2ea62e3cc67da52e5d4d54f 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -104,7 +104,7 @@ QDebug operator<<(QDebug str, const DebuggerRunParameters &sp) << " coreFile=" << sp.coreFile << " processArgs=" << sp.inferior.commandLineArguments << " inferior environment=<" << sp.inferior.environment.size() << " variables>" - << " debugger environment=<" << sp.debuggerEnvironment.size() << " variables>" + << " debugger environment=<" << sp.debugger.environment.size() << " variables>" << " workingDir=" << sp.inferior.workingDirectory << " attachPID=" << sp.attachPID << " useTerminal=" << sp.useTerminal diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index cf5acf4db1cac3e24eda0922fbcdb0866c1c58e7..a7664bfd50796baf1aca575b52a74d0de6922bed 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -27,10 +27,12 @@ #include "debugger_global.h" #include "debuggerconstants.h" +#include "debuggeritem.h" #include "debuggerprotocol.h" #include "debuggerstartparameters.h" #include +#include #include #include @@ -89,7 +91,7 @@ public: bool breakOnMain = false; bool multiProcess = false; // Whether to set detach-on-fork off. - QString debuggerCommand; + ProjectExplorer::StandardRunnable debugger; QString coreFile; QString overrideStartScript; // Used in attach to core and remote debugging QString startMessage; // First status message shown. diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index 977904e4bf2d8cf1be3d55686459770a45d1cdf9..9af62e949e4067ea43eeee063e86331b26e02d08 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -29,6 +29,7 @@ #include "debuggeroptionspage.h" #include "debuggerprotocol.h" +#include #include #include @@ -59,6 +60,7 @@ const char DEBUGGER_INFORMATION_AUTODETECTION_SOURCE[] = "AutoDetectionSource"; const char DEBUGGER_INFORMATION_VERSION[] = "Version"; const char DEBUGGER_INFORMATION_ABIS[] = "Abis"; const char DEBUGGER_INFORMATION_LASTMODIFIED[] = "LastModified"; +const char DEBUGGER_INFORMATION_WORKINGDIRECTORY[] = "WorkingDirectory"; namespace Debugger { @@ -81,8 +83,9 @@ DebuggerItem::DebuggerItem(const QVariant &id) DebuggerItem::DebuggerItem(const QVariantMap &data) { - m_command = FileName::fromUserInput(data.value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString()); m_id = data.value(QLatin1String(DEBUGGER_INFORMATION_ID)).toString(); + m_command = FileName::fromUserInput(data.value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString()); + m_workingDirectory = FileName::fromUserInput(data.value(DEBUGGER_INFORMATION_WORKINGDIRECTORY).toString()); m_unexpandedDisplayName = data.value(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME)).toString(); m_isAutoDetected = data.value(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), false).toBool(); m_autoDetectionSource = data.value(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTION_SOURCE)).toString(); @@ -213,9 +216,15 @@ QDateTime DebuggerItem::lastModified() const return m_lastModified; } -bool DebuggerItem::isGood() const +QIcon DebuggerItem::decoration() const { - return m_engineType != NoEngineType; + if (m_engineType == NoEngineType) + return Core::Icons::ERROR.icon(); + if (!m_command.toFileInfo().isExecutable()) + return Core::Icons::WARNING.icon(); + if (!m_workingDirectory.isEmpty() && !m_workingDirectory.toFileInfo().isDir()) + return Core::Icons::WARNING.icon(); + return QIcon(); } QString DebuggerItem::validityMessage() const @@ -230,7 +239,8 @@ bool DebuggerItem::operator==(const DebuggerItem &other) const return m_id == other.m_id && m_unexpandedDisplayName == other.m_unexpandedDisplayName && m_isAutoDetected == other.m_isAutoDetected - && m_command == other.m_command; + && m_command == other.m_command + && m_workingDirectory == other.m_workingDirectory; } QVariantMap DebuggerItem::toMap() const @@ -239,6 +249,7 @@ QVariantMap DebuggerItem::toMap() const data.insert(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME), m_unexpandedDisplayName); data.insert(QLatin1String(DEBUGGER_INFORMATION_ID), m_id); data.insert(QLatin1String(DEBUGGER_INFORMATION_COMMAND), m_command.toString()); + data.insert(QLatin1String(DEBUGGER_INFORMATION_WORKINGDIRECTORY), m_workingDirectory.toString()); data.insert(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE), int(m_engineType)); data.insert(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), m_isAutoDetected); data.insert(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTION_SOURCE), m_autoDetectionSource); diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h index 9ba7220191ba33fdc423dd8864695870a3a2bbae..5526c52130aa66ebbc75a133bb18b0fa928524a0 100644 --- a/src/plugins/debugger/debuggeritem.h +++ b/src/plugins/debugger/debuggeritem.h @@ -94,7 +94,7 @@ public: QStringList abiNames() const; QDateTime lastModified() const; - bool isGood() const; + QIcon decoration() const; QString validityMessage() const; bool operator==(const DebuggerItem &other) const; @@ -102,6 +102,9 @@ public: void reinitializeFromFile(); + Utils::FileName workingDirectory() const { return m_workingDirectory; } + void setWorkingDirectory(const Utils::FileName &workingPath) { m_workingDirectory = workingPath; } + private: DebuggerItem(const QVariant &id); void initMacroExpander(); @@ -110,6 +113,7 @@ private: QString m_unexpandedDisplayName; DebuggerEngineType m_engineType; Utils::FileName m_command; + Utils::FileName m_workingDirectory; bool m_isAutoDetected; QString m_autoDetectionSource; QString m_version; diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp index bf80b93f89c06c9454115e34cc3384f9d5d8b70b..da20b9170ca3ef855d5f0a838f8a598fe71af841 100644 --- a/src/plugins/debugger/debuggerkitinformation.cpp +++ b/src/plugins/debugger/debuggerkitinformation.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -244,6 +245,18 @@ const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit) return DebuggerItemManager::findById(id); } +StandardRunnable DebuggerKitInformation::runnable(const Kit *kit) +{ + StandardRunnable runnable; + if (const DebuggerItem *item = debugger(kit)) { + runnable.executable = item->command().toString(); + runnable.workingDirectory = item->workingDirectory().toString(); + runnable.environment = Utils::Environment::systemEnvironment(); + runnable.environment.set("LC_NUMERIC", "C"); + } + return runnable; +} + bool DebuggerKitInformation::isValidDebugger(const Kit *k) { return debuggerConfigurationErrors(k) == 0; @@ -326,14 +339,6 @@ KitInformation::ItemList DebuggerKitInformation::toUserOutput(const Kit *k) cons return ItemList() << qMakePair(tr("Debugger"), displayString(k)); } -FileName DebuggerKitInformation::debuggerCommand(const Kit *k) -{ - const DebuggerItem *item = debugger(k); - if (item) - return item->command(); - return FileName(); -} - DebuggerEngineType DebuggerKitInformation::engineType(const Kit *k) { const DebuggerItem *item = debugger(k); diff --git a/src/plugins/debugger/debuggerkitinformation.h b/src/plugins/debugger/debuggerkitinformation.h index 44af814954ae0b4a5c00f69bff4cc1b2de586d5c..cae68aaf5ae3dff684f497bc9475314f1451cc0d 100644 --- a/src/plugins/debugger/debuggerkitinformation.h +++ b/src/plugins/debugger/debuggerkitinformation.h @@ -29,6 +29,7 @@ #include "debuggerconstants.h" #include +#include namespace Debugger { class DebuggerItem; @@ -49,6 +50,7 @@ public: void fix(ProjectExplorer::Kit *k) override; static const DebuggerItem *debugger(const ProjectExplorer::Kit *kit); + static ProjectExplorer::StandardRunnable runnable(const ProjectExplorer::Kit *kit); static QList validateDebugger(const ProjectExplorer::Kit *k); static bool isValidDebugger(const ProjectExplorer::Kit *k); @@ -61,7 +63,6 @@ public: static void setDebugger(ProjectExplorer::Kit *k, const QVariant &id); static Core::Id id(); - static Utils::FileName debuggerCommand(const ProjectExplorer::Kit *k); static DebuggerEngineType engineType(const ProjectExplorer::Kit *k); static QString displayString(const ProjectExplorer::Kit *k); }; diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp index 701a84c671123335dff5b22dbbb614dff86d113e..757a6a44d29193a826d4e63ca0a9428ac7f674ec 100644 --- a/src/plugins/debugger/debuggeroptionspage.cpp +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -65,8 +65,6 @@ public: QVariant data(int column, int role) const { - static const QIcon errorIcon = Core::Icons::ERROR.icon(); - switch (role) { case Qt::DisplayRole: switch (column) { @@ -74,19 +72,23 @@ public: case 1: return m_item.command().toUserOutput(); case 2: return m_item.engineTypeName(); } + break; + + case Qt::FontRole: + if (m_changed) { + QFont font; + font.setBold(true); + return font; + } + break; + + case Qt::DecorationRole: + if (column == 0) + return m_item.decoration(); + break; - case Qt::FontRole: { - QFont font; - font.setBold(m_changed); - return font; - } - case Qt::DecorationRole: { - if (column == 0 && !m_item.isGood()) - return errorIcon; - } - case Qt::ToolTipRole: { + case Qt::ToolTipRole: return m_item.validityMessage(); - } } return QVariant(); } @@ -214,6 +216,7 @@ private: QLabel *m_cdbLabel; QLineEdit *m_versionLabel; PathChooser *m_binaryChooser; + PathChooser *m_workingDirectoryChooser; QLineEdit *m_abis; bool m_autodetected; DebuggerEngineType m_engineType; @@ -231,7 +234,12 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) m_binaryChooser = new PathChooser(this); m_binaryChooser->setExpectedKind(PathChooser::ExistingCommand); m_binaryChooser->setMinimumWidth(400); - m_binaryChooser->setHistoryCompleter(QLatin1String("DebuggerPaths")); + m_binaryChooser->setHistoryCompleter("DebuggerPaths"); + + m_workingDirectoryChooser = new PathChooser(this); + m_workingDirectoryChooser->setExpectedKind(PathChooser::Directory); + m_workingDirectoryChooser->setMinimumWidth(400); + m_workingDirectoryChooser->setHistoryCompleter("DebuggerPaths"); m_cdbLabel = new QLabel(this); m_cdbLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); @@ -252,9 +260,12 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) formLayout->addRow(new QLabel(tr("Type:")), m_typeLineEdit); formLayout->addRow(new QLabel(tr("ABIs:")), m_abis); formLayout->addRow(new QLabel(tr("Version:")), m_versionLabel); + formLayout->addRow(new QLabel(tr("Working directory:")), m_workingDirectoryChooser); connect(m_binaryChooser, &PathChooser::pathChanged, this, &DebuggerItemConfigWidget::binaryPathHasChanged); + connect(m_workingDirectoryChooser, &PathChooser::pathChanged, + this, &DebuggerItemConfigWidget::store); connect(m_displayNameLineEdit, &QLineEdit::textChanged, this, &DebuggerItemConfigWidget::store); } @@ -264,6 +275,7 @@ DebuggerItem DebuggerItemConfigWidget::item() const DebuggerItem item(m_id); item.setUnexpandedDisplayName(m_displayNameLineEdit->text()); item.setCommand(m_binaryChooser->fileName()); + item.setWorkingDirectory(m_workingDirectoryChooser->fileName()); item.setAutoDetected(m_autodetected); QList abiList; foreach (const QString &a, m_abis->text().split(QRegExp(QLatin1String("[^A-Za-z0-9-_]+")))) { @@ -305,6 +317,9 @@ void DebuggerItemConfigWidget::load(const DebuggerItem *item) m_binaryChooser->setReadOnly(item->isAutoDetected()); m_binaryChooser->setFileName(item->command()); + m_workingDirectoryChooser->setReadOnly(item->isAutoDetected()); + m_workingDirectoryChooser->setFileName(item->workingDirectory()); + QString text; QString versionCommand; if (item->engineType() == CdbEngineType) { diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 73100c637b0c682799536b062eda59f140cea89a..5f118ed6cde8be73ba67024b7f0b476fb8f57142 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1204,7 +1204,7 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, } rp.inferior.environment = Utils::Environment::systemEnvironment(); rp.stubEnvironment = Utils::Environment::systemEnvironment(); - rp.debuggerEnvironment = Utils::Environment::systemEnvironment(); + rp.debugger.environment = Utils::Environment::systemEnvironment(); if (!kit) kit = guessKitFromParameters(rp); @@ -2912,7 +2912,7 @@ static QString formatStartParameters(DebuggerRunParameters &sp) str << "Directory: " << QDir::toNativeSeparators(sp.inferior.workingDirectory) << '\n'; } - QString cmd = sp.debuggerCommand; + QString cmd = sp.debugger.executable; if (!cmd.isEmpty()) str << "Debugger: " << QDir::toNativeSeparators(cmd) << '\n'; if (!sp.coreFile.isEmpty()) diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index fe468b9f5b82ec6d3af6e2cc67606caeef3a2822..a0ead85150e976c6516530663f290dee54314c8a 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -354,11 +354,20 @@ static DebuggerRunControl *doCreate(DebuggerRunParameters rp, RunConfiguration * if (rp.symbolFile.isEmpty()) rp.symbolFile = rp.inferior.executable; + rp.debugger = DebuggerKitInformation::runnable(kit); + const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH"); + if (!envBinary.isEmpty()) + rp.debugger.executable = QString::fromLocal8Bit(envBinary); + if (runConfig) { if (auto envAspect = runConfig->extraAspect()) { rp.inferior.environment = envAspect->environment(); // Correct. rp.stubEnvironment = rp.inferior.environment; // FIXME: Wrong, but contains DYLD_IMAGE_SUFFIX - rp.debuggerEnvironment = rp.inferior.environment; // FIXME: Wrong, but contains DYLD_IMAGE_SUFFIX + + // Copy over DYLD_IMAGE_SUFFIX etc + for (auto var : QStringList({"DYLD_IMAGE_SUFFIX", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH"})) + if (rp.inferior.environment.hasKey(var)) + rp.debugger.environment.set(var, rp.inferior.environment.value(var)); } if (Project *project = runConfig->target()->project()) { rp.projectSourceDirectory = project->projectDirectory().toString(); @@ -380,7 +389,6 @@ static DebuggerRunControl *doCreate(DebuggerRunParameters rp, RunConfiguration * rp.cppEngineType = DebuggerKitInformation::engineType(kit); rp.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - rp.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); rp.device = DeviceKitInformation::device(kit); if (rp.displayName.isEmpty() && runConfig) diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index 7416cf59672ff9f55239805ebe8e20f929119a96..6e02ef4371758cbd0586e4d393ba964341943e9d 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -72,7 +72,6 @@ public: ProjectExplorer::StandardRunnable inferior; QString displayName; // Used in the Snapshots view. - Utils::Environment debuggerEnvironment; Utils::Environment stubEnvironment; qint64 attachPID = InvalidPid; QStringList solibSearchPath; diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp index 0d372a10ac7fca70a61932eba5c4025552134830..88ef01a5b6b86973e9b081ba8f2456559e62a1fb 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.cpp +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -45,10 +45,6 @@ void GdbAttachEngine::setupEngine() QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage("TRYING TO START ADAPTER"); - if (!runParameters().inferior.workingDirectory.isEmpty()) - m_gdbProc.setWorkingDirectory(runParameters().inferior.workingDirectory); - m_gdbProc.setEnvironment(runParameters().debuggerEnvironment); - startGdb(); } diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index 4534c295a55c47946eb650c1d775b26396c9453e..689e62ee3d8d31dbed2959f2ccf22679cbf5ab0f 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -39,6 +39,7 @@ #include using namespace Utils; +using namespace ProjectExplorer; namespace Debugger { namespace Internal { @@ -121,7 +122,7 @@ static QString findExecutableFromName(const QString &fileNameFromCore, const QSt } GdbCoreEngine::CoreInfo -GdbCoreEngine::readExecutableNameFromCore(const QString &debuggerCommand, const QString &coreFile) +GdbCoreEngine::readExecutableNameFromCore(const StandardRunnable &debugger, const QString &coreFile) { CoreInfo cinfo; #if 0 @@ -139,7 +140,7 @@ GdbCoreEngine::readExecutableNameFromCore(const QString &debuggerCommand, const QStringList envLang = QProcess::systemEnvironment(); Utils::Environment::setupEnglishOutput(&envLang); proc.setEnvironment(envLang); - SynchronousProcessResponse response = proc.runBlocking(debuggerCommand, args); + SynchronousProcessResponse response = proc.runBlocking(debugger.executable, args); if (response.result == SynchronousProcessResponse::Finished) { QString output = response.stdOut(); @@ -171,9 +172,8 @@ void GdbCoreEngine::continueSetupEngine() m_tempCoreFile.close(); } if (isCore && m_executable.isEmpty()) { - GdbCoreEngine::CoreInfo cinfo = readExecutableNameFromCore( - runParameters().debuggerCommand, - coreFileName()); + GdbCoreEngine::CoreInfo cinfo = + readExecutableNameFromCore(runParameters().debugger, coreFileName()); if (cinfo.isCore) { m_executable = cinfo.foundExecutableName; diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h index cdc0987b63be20372766c1f86bea80d03baae2aa..0067200e5b089e791d38c0ccc27ce19610f96596 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.h +++ b/src/plugins/debugger/gdb/coregdbadapter.h @@ -46,7 +46,8 @@ public: QString foundExecutableName; // empty if no corresponding exec could be found bool isCore = false; }; - static CoreInfo readExecutableNameFromCore(const QString &debuggerCmd, const QString &coreFile); + static CoreInfo readExecutableNameFromCore(const ProjectExplorer::StandardRunnable &debugger, + const QString &coreFile); private: void setupEngine() override; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 31c4eb82c60d784fb02658a446bfa299d5bd8107..1cb7158a41e28375d5a132ef5c3d0fab4a4ead59 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -267,14 +267,19 @@ DebuggerStartMode GdbEngine::startMode() const return runParameters().startMode; } +QString GdbEngine::failedToStartMessage() +{ + return tr("The gdb process failed to start."); +} + QString GdbEngine::errorMessage(QProcess::ProcessError error) { switch (error) { case QProcess::FailedToStart: - return tr("The gdb process failed to start. Either the " + return failedToStartMessage() + ' ' + tr("Either the " "invoked program \"%1\" is missing, or you may have insufficient " "permissions to invoke the program.\n%2") - .arg(m_gdb, m_gdbProc.errorString()); + .arg(runParameters().debugger.executable, m_gdbProc.errorString()); case QProcess::Crashed: if (targetState() == DebuggerFinished) return tr("The gdb process crashed some time after starting " @@ -860,7 +865,7 @@ void GdbEngine::interruptInferior() connect(m_signalOperation.data(), &DeviceProcessSignalOperation::finished, this, &GdbEngine::handleInterruptDeviceInferior); - m_signalOperation->setDebuggerCommand(runParameters().debuggerCommand); + m_signalOperation->setDebuggerCommand(runParameters().debugger.executable); m_signalOperation->interruptProcess(inferiorPid()); } else { interruptInferior2(); @@ -3945,18 +3950,6 @@ bool GdbEngine::handleCliDisassemblerResult(const QString &output, DisassemblerA return false; } -// Binary/configuration check logic. - -static QString gdbBinary(const DebuggerRunParameters &sp) -{ - // 1) Environment. - const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH"); - if (!envBinary.isEmpty()) - return QString::fromLocal8Bit(envBinary); - // 2) Command from profile. - return sp.debuggerCommand; -} - static SourcePathMap mergeStartParametersSourcePathMap(const DebuggerRunParameters &sp, const SourcePathMap &in) { @@ -3982,14 +3975,14 @@ void GdbEngine::startGdb(const QStringList &args) m_gdbProc.disconnect(); // From any previous runs const DebuggerRunParameters &rp = runParameters(); - m_gdb = gdbBinary(rp); - if (m_gdb.isEmpty()) { + if (rp.debugger.executable.isEmpty()) { handleGdbStartFailed(); handleAdapterStartFailed( msgNoGdbBinaryForToolChain(rp.toolChainAbi), Constants::DEBUGGER_COMMON_SETTINGS_ID); return; } + QStringList gdbArgs; gdbArgs << "-i"; gdbArgs << "mi"; @@ -4004,16 +3997,21 @@ void GdbEngine::startGdb(const QStringList &args) connect(&m_gdbProc, &QtcProcess::readyReadStandardOutput, this, &GdbEngine::readGdbStandardOutput); connect(&m_gdbProc, &QtcProcess::readyReadStandardError, this, &GdbEngine::readGdbStandardError); - showMessage("STARTING " + m_gdb + " " + gdbArgs.join(' ')); - m_gdbProc.setCommand(m_gdb, QtcProcess::joinArgs(gdbArgs)); - Environment env = Environment(m_gdbProc.systemEnvironment()); - env.set("LC_NUMERIC", "C"); - m_gdbProc.setEnvironment(env); + showMessage("STARTING " + rp.debugger.executable + " " + gdbArgs.join(' ')); + m_gdbProc.setCommand(rp.debugger.executable, QtcProcess::joinArgs(gdbArgs)); + if (QFileInfo(rp.debugger.workingDirectory).isDir()) + m_gdbProc.setWorkingDirectory(rp.debugger.workingDirectory); + m_gdbProc.setEnvironment(rp.debugger.environment); m_gdbProc.start(); if (!m_gdbProc.waitForStarted()) { handleGdbStartFailed(); - const QString msg = errorMessage(QProcess::FailedToStart); + QString msg; + QString wd = m_gdbProc.workingDirectory(); + if (!QFileInfo(wd).isDir()) + msg = failedToStartMessage() + ' ' + tr("The working directory \"%s\" is not usable.").arg(wd); + else + msg = errorMessage(QProcess::FailedToStart); handleAdapterStartFailed(msg); return; } @@ -4136,7 +4134,7 @@ void GdbEngine::startGdb(const QStringList &args) if (terminal()->isUsable()) runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice()), NoFlags}); - const QFileInfo gdbBinaryFile(m_gdb); + const QFileInfo gdbBinaryFile(rp.debugger.executable); const QString uninstalledData = gdbBinaryFile.absolutePath() + "/data-directory/python"; runCommand({"python sys.path.insert(1, '" + dumperSourcePath + "')", NoFlags}); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 6fdfd10b1afbfca24ae9a5f961535f2446a4e2cd..5f8bcce0631f884f402e9aa117499055dc1d0d9d 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -397,13 +398,12 @@ protected: // void reloadDebuggingHelpers() override; - QString m_gdb; - // // Convenience Functions // QString errorMessage(QProcess::ProcessError error); void showExecutionError(const QString &message); + QString failedToStartMessage(); static QString tooltipIName(const QString &exp); diff --git a/src/plugins/debugger/gdb/gdbplainengine.cpp b/src/plugins/debugger/gdb/gdbplainengine.cpp index 1c827bdb57df1de8f62d694772317b704e8a63c6..7df122d82080289c9f23332746c2d827ade159a9 100644 --- a/src/plugins/debugger/gdb/gdbplainengine.cpp +++ b/src/plugins/debugger/gdb/gdbplainengine.cpp @@ -121,10 +121,6 @@ void GdbPlainEngine::setupEngine() } gdbArgs.append("--tty=" + m_outputCollector.serverName()); - QString workingDirectory = runParameters().inferior.workingDirectory; - if (!workingDirectory.isEmpty() && QFileInfo::exists(workingDirectory)) - m_gdbProc.setWorkingDirectory(workingDirectory); - startGdb(gdbArgs); } diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index c279a0a9f438b1d262c733ba70c3b3475f5454ec..0d40d703a14491f9f93b5f024f23a4ce21d16aa6 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -86,8 +86,6 @@ void GdbRemoteServerEngine::setupEngine() m_uploadProc.start(arglist); m_uploadProc.waitForStarted(); } - if (!runParameters().inferior.workingDirectory.isEmpty()) - m_gdbProc.setWorkingDirectory(runParameters().inferior.workingDirectory); if (runParameters().remoteSetupNeeded) { notifyEngineRequestRemoteSetup(); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 19761ba6dee1d75d841978660ef145b81fce0ec9..b5b37351e00b3504d82bf63830ba5119e225c1a4 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -247,7 +247,7 @@ void LldbEngine::setupEngine() void LldbEngine::startLldb() { - m_lldbCmd = runParameters().debuggerCommand; + QString lldbCmd = runParameters().debugger.executable; connect(&m_lldbProc, static_cast(&QProcess::error), this, &LldbEngine::handleLldbError); connect(&m_lldbProc, static_cast(&QProcess::finished), @@ -260,17 +260,17 @@ void LldbEngine::startLldb() connect(this, &LldbEngine::outputReady, this, &LldbEngine::handleResponse, Qt::QueuedConnection); - showMessage("STARTING LLDB: " + m_lldbCmd); - m_lldbProc.setEnvironment(runParameters().debuggerEnvironment); - if (!runParameters().inferior.workingDirectory.isEmpty()) - m_lldbProc.setWorkingDirectory(runParameters().inferior.workingDirectory); + showMessage("STARTING LLDB: " + lldbCmd); + m_lldbProc.setEnvironment(runParameters().debugger.environment); + if (QFileInfo(runParameters().debugger.workingDirectory).isDir()) + m_lldbProc.setWorkingDirectory(runParameters().debugger.workingDirectory); - m_lldbProc.setCommand(m_lldbCmd, QString()); + m_lldbProc.setCommand(lldbCmd, QString()); m_lldbProc.start(); if (!m_lldbProc.waitForStarted()) { const QString msg = tr("Unable to start LLDB \"%1\": %2") - .arg(m_lldbCmd, m_lldbProc.errorString()); + .arg(lldbCmd, m_lldbProc.errorString()); notifyEngineSetupFailed(); showMessage("ADAPTER START FAILED"); if (!msg.isEmpty()) @@ -852,7 +852,7 @@ QString LldbEngine::errorMessage(QProcess::ProcessError error) const return tr("The LLDB process failed to start. Either the " "invoked program \"%1\" is missing, or you may have insufficient " "permissions to invoke the program.") - .arg(m_lldbCmd); + .arg(runParameters().debugger.executable); case QProcess::Crashed: return tr("The LLDB process crashed some time after starting " "successfully."); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 8129cc4042f2c966723bdce05fde3dda88b73b2b..c3aca9df412c69808993a895cc9201d00caecf9c 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -150,7 +150,6 @@ private: QString m_inbuffer; QString m_scriptFileName; Utils::QtcProcess m_lldbProc; - QString m_lldbCmd; // FIXME: Make generic. int m_lastAgentId; diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp index 31d4a6064a5520fea1da9be77c114803c819f49b..4241a50889997835f1b64f7a0aa9cfdaa3793096 100644 --- a/src/plugins/debugger/loadcoredialog.cpp +++ b/src/plugins/debugger/loadcoredialog.cpp @@ -363,9 +363,8 @@ void AttachCoreDialog::coreFileChanged(const QString &core) if (!HostOsInfo::isWindowsHost() && QFile::exists(core)) { Kit *k = d->kitChooser->currentKit(); QTC_ASSERT(k, return); - FileName cmd = DebuggerKitInformation::debuggerCommand(k); - GdbCoreEngine::CoreInfo cinfo = - GdbCoreEngine::readExecutableNameFromCore(cmd.toString(), core); + StandardRunnable debugger = DebuggerKitInformation::runnable(k); + GdbCoreEngine::CoreInfo cinfo = GdbCoreEngine::readExecutableNameFromCore(debugger, core); if (!cinfo.foundExecutableName.isEmpty()) d->localExecFileName->setFileName(FileName::fromString(cinfo.foundExecutableName)); else if (!d->localExecFileName->isValid() && !cinfo.rawStringFromCore.isEmpty()) diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index 9aa864e588633bf13176f1c7f6aae516f658173b..e0969d0221bba2cef79004dd2d7c9fe0c3ae5626 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -136,7 +136,7 @@ void PdbEngine::setupEngine() QStringList args = { bridge, scriptFile.fileName() }; args.append(Utils::QtcProcess::splitArgs(runParameters().inferior.workingDirectory)); showMessage("STARTING " + m_interpreter + QLatin1Char(' ') + args.join(QLatin1Char(' '))); - m_proc.setEnvironment(runParameters().debuggerEnvironment.toStringList()); + m_proc.setEnvironment(runParameters().debugger.environment.toStringList()); m_proc.start(m_interpreter, args); if (!m_proc.waitForStarted()) {