From 14d590590f7ca9428491d2ca1c3e327ce9272056 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Fri, 25 Feb 2011 13:43:06 +0100 Subject: [PATCH] Debugger: Use Startparameters.debuggerCommand for command. Use in both engines preferred over ABI if it is compatible. Report start parameters. Introduce gdb configuration check. --- src/plugins/debugger/cdb/cdbengine.cpp | 29 ++++++--- src/plugins/debugger/debuggerplugin.cpp | 61 ++++++++++++++++++ src/plugins/debugger/debuggerrunner.cpp | 56 +++++++--------- .../debugger/debuggerstartparameters.h | 3 - .../debugger/debuggertoolchaincombobox.cpp | 5 +- .../debugger/debuggertoolchaincombobox.h | 1 - src/plugins/debugger/gdb/codagdbadapter.cpp | 2 +- src/plugins/debugger/gdb/coregdbadapter.cpp | 2 +- src/plugins/debugger/gdb/gdbengine.cpp | 64 ++++++++++++++----- src/plugins/debugger/gdb/gdbengine.h | 1 - .../debugger/gdb/remotegdbserveradapter.cpp | 2 +- .../debugger/gdb/remoteplaingdbadapter.cpp | 3 +- src/plugins/debugger/gdb/trkgdbadapter.cpp | 2 +- 13 files changed, 163 insertions(+), 68 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 2a8ed5ebf03..34a433b50ea 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -333,6 +333,18 @@ static inline QString msgNoCdbBinaryForToolChain(const ProjectExplorer::Abi &tc) return CdbEngine::tr("There is no CDB binary available for binaries in format '%1'").arg(tc.toString()); } +static QString cdbBinary(const DebuggerStartParameters &sp) +{ + if (!sp.debuggerCommand.isEmpty()) { + // Do not use a GDB binary if we got started for a project with MinGW runtime. + const bool abiMatch = sp.toolChainAbi.os() == ProjectExplorer::Abi::WindowsOS + && sp.toolChainAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvcFlavor; + if (abiMatch) + return sp.debuggerCommand; + } + return debuggerCore()->debuggerForAbi(sp.toolChainAbi, CdbEngineType); +} + bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check) { #ifdef Q_OS_WIN @@ -344,13 +356,6 @@ bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck return false; } - if (debuggerCore()->debuggerForAbi(sp.toolChainAbi, CdbEngineType).isEmpty()) { - check->errorDetails.push_back(msgNoCdbBinaryForToolChain(sp.toolChainAbi)); - check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); - check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); - return false; - } - if (!validMode(sp.startMode)) { check->errorDetails.push_back(CdbEngine::tr("The CDB engine does not support start mode %1.").arg(sp.startMode)); return false; @@ -361,6 +366,14 @@ bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck arg(sp.toolChainAbi.toString())); return false; } + + if (cdbBinary(sp).isEmpty()) { + check->errorDetails.push_back(msgNoCdbBinaryForToolChain(sp.toolChainAbi)); + check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); + check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); + return false; + } + return true; #else Q_UNUSED(sp); @@ -652,7 +665,7 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa // 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 = debuggerCore()->debuggerForAbi(sp.toolChainAbi, CdbEngineType); + const QString executable = cdbBinary(sp); if (executable.isEmpty()) { *errorMessage = tr("There is no CDB executable specified."); return false; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 6a6968db288..95750339f5e 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2349,6 +2349,66 @@ void DebuggerPluginPrivate::createNewDock(QWidget *widget) dockWidget->show(); } +static QString formatStartParameters(DebuggerStartParameters &sp) +{ + QString rc; + QTextStream str(&rc); + str << "Start parameters: '" << sp.displayName << "' mode: " << sp.startMode + << "\nABI: " << sp.toolChainAbi.toString() << '\n'; + if (!sp.executable.isEmpty()) { + str << "Executable: " << QDir::toNativeSeparators(sp.executable) << ' ' << sp.processArgs; + if (sp.useTerminal) + str << " [terminal]"; + str << '\n'; + if (!sp.workingDirectory.isEmpty()) + str << "Directory: " << QDir::toNativeSeparators(sp.workingDirectory) << '\n'; + if (sp.executableUid) { + str << "UID: 0x"; + str.setIntegerBase(16); + str << sp.executableUid << '\n'; + str.setIntegerBase(10); + } + } + if (!sp.debuggerCommand.isEmpty()) + str << "Debugger: " << QDir::toNativeSeparators(sp.debuggerCommand) << '\n'; + if (!sp.coreFile.isEmpty()) + str << "Core: " << QDir::toNativeSeparators(sp.coreFile) << '\n'; + if (sp.attachPID > 0) + str << "PID: " << sp.attachPID << ' ' << sp.crashParameter << '\n'; + if (!sp.projectDir.isEmpty()) { + str << "Project: " << QDir::toNativeSeparators(sp.projectDir); + if (!sp.projectBuildDir.isEmpty()) + str << " (built: " << QDir::toNativeSeparators(sp.projectBuildDir); + str << '\n'; + } + if (!sp.qmlServerAddress.isEmpty()) + str << "QML server: " << sp.qmlServerAddress << ':' << sp.qmlServerPort << '\n'; + if (!sp.remoteChannel.isEmpty()) { + str << "Remote: " << sp.remoteChannel << ", " << sp.remoteArchitecture << '\n'; + if (!sp.remoteDumperLib.isEmpty()) + str << "Remote dumpers: " << sp.remoteDumperLib << '\n'; + if (!sp.remoteSourcesDir.isEmpty()) + str << "Remote sources: " << sp.remoteSourcesDir << '\n'; + if (!sp.remoteMountPoint.isEmpty()) + str << "Remote mount point: " << sp.remoteMountPoint << " Local: " << sp.localMountDir << '\n'; + } + if (!sp.gnuTarget.isEmpty()) + str << "Gnu target: " << sp.gnuTarget << '\n'; + if (!sp.sysRoot.isEmpty()) + str << "Sysroot: " << sp.sysRoot << '\n'; + if (!sp.symbolFileName.isEmpty()) + str << "Symbol file: " << sp.symbolFileName << '\n'; + if (sp.useServerStartScript) + str << "Using server start script: " << sp.serverStartScript; + if (!sp.dumperLibrary.isEmpty()) { + str << "Dumper libraries: " << QDir::toNativeSeparators(sp.dumperLibrary); + foreach (const QString &dl, sp.dumperLibraryLocations) + str << ' ' << QDir::toNativeSeparators(dl); + str << '\n'; + } + return rc; +} + void DebuggerPluginPrivate::runControlStarted(DebuggerEngine *engine) { activateDebugMode(); @@ -2356,6 +2416,7 @@ void DebuggerPluginPrivate::runControlStarted(DebuggerEngine *engine) .arg(engine->objectName()) .arg(engine->startParameters().toolChainAbi.toString()); showMessage(message, StatusBar); + showMessage(formatStartParameters(engine->startParameters()), LogDebug); showMessage(m_debuggerSettings->dump(), LogDebug); m_snapshotHandler->appendSnapshot(engine); connectEngine(engine); diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 9eb243c4a0d..fc702e59d6f 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -78,11 +78,13 @@ namespace Internal { bool isCdbEngineEnabled(); // Check the configuration page bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check); - DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp, DebuggerEngine *masterEngine, QString *error); + +bool checkGdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check); DebuggerEngine *createGdbEngine(const DebuggerStartParameters &sp, DebuggerEngine *masterEngine); + DebuggerEngine *createScriptEngine(const DebuggerStartParameters &sp); DebuggerEngine *createPdbEngine(const DebuggerStartParameters &sp); DebuggerEngine *createTcfEngine(const DebuggerStartParameters &sp); @@ -476,34 +478,6 @@ static QList<DebuggerEngineType> engineTypes(const DebuggerStartParameters &sp) return result; } -// Engine detection logic: Configuration checks. - -QString msgNoBinaryForToolChain(const ProjectExplorer::Abi &tc, DebuggerEngineType et) -{ - return DebuggerPlugin::tr("There is no binary available for debugging binaries of type '%1' using the engine '%2'"). - arg(tc.toString(), QLatin1String(engineTypeName(et))); -} - -static inline bool engineConfigurationCheck(const DebuggerStartParameters &sp, - DebuggerEngineType et, - ConfigurationCheck *check) -{ - switch (et) { - case Debugger::CdbEngineType: - return checkCdbConfiguration(sp, check); - case Debugger::GdbEngineType: - if (debuggerCore()->debuggerForAbi(sp.toolChainAbi, et).isEmpty()) { - check->errorDetails.push_back(msgNoBinaryForToolChain(sp.toolChainAbi, et)); - check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); - check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); - return false; - } - default: - break; - } - return true; -} - // Engine detection logic: ConfigurationCheck. ConfigurationCheck::ConfigurationCheck() : masterSlaveEngineTypes(NoEngineType, NoEngineType) @@ -575,9 +549,25 @@ DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(const DebuggerStartPa } if (debug) qDebug() << " Usable engines: " << engineTypeNames(usableTypes); - // Configuration check: Strip off non-configured engines. - while (!usableTypes.isEmpty() && !engineConfigurationCheck(sp, usableTypes.front(), &result)) - usableTypes.pop_front(); + // Configuration check: Strip off non-configured engines, find first one to use. + while (!usableTypes.isEmpty()) { + bool configurationOk = true; + switch (usableTypes.front()) { + case Debugger::CdbEngineType: + configurationOk = checkCdbConfiguration(sp, &result); + break; + case Debugger::GdbEngineType: + configurationOk = checkGdbConfiguration(sp, &result); + break; + default: + break; + } + if (configurationOk) { + break; + } else { + usableTypes.pop_front(); + } + } if (debug) qDebug() << "Configured engines: " << engineTypeNames(usableTypes); if (usableTypes.isEmpty()) { @@ -585,6 +575,8 @@ DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(const DebuggerStartPa return result; } // Anything left: Happy. + result.errorMessage.clear(); + result.errorDetails.clear(); if (qmlLanguage && cppLanguage) { result.masterSlaveEngineTypes.first = QmlCppEngineType; result.masterSlaveEngineTypes.second = usableTypes.front(); diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index 64f0199ee01..2e762367834 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -96,9 +96,6 @@ public: QString projectBuildDir; QString projectDir; - // Used by combined cpp+qml debugging. - DebuggerEngineType cppEngineType; - // Used by remote debugging. QString remoteChannel; QString remoteArchitecture; diff --git a/src/plugins/debugger/debuggertoolchaincombobox.cpp b/src/plugins/debugger/debuggertoolchaincombobox.cpp index b11125d1a07..3a269c6d210 100644 --- a/src/plugins/debugger/debuggertoolchaincombobox.cpp +++ b/src/plugins/debugger/debuggertoolchaincombobox.cpp @@ -54,10 +54,11 @@ void DebuggerToolChainComboBox::init(bool hostAbiOnly) { const ProjectExplorer::Abi hostAbi = ProjectExplorer::Abi::hostAbi(); foreach (const ProjectExplorer::ToolChain *tc, ProjectExplorer::ToolChainManager::instance()->toolChains()) { - if (!hostAbiOnly || hostAbi.isCompatibleWith(tc->targetAbi())) { + if (!hostAbiOnly || hostAbi.os() == hostAbi.os()) { // Offer MSVC and Mingw, etc. const QString debuggerCommand = tc->debuggerCommand(); if (!debuggerCommand.isEmpty()) { - const QString name = tr("%1 (%2)").arg(tc->displayName(), QFileInfo(debuggerCommand).baseName()); + const QString completeBase = QFileInfo(debuggerCommand).completeBaseName(); + const QString name = tr("%1 (%2)").arg(tc->displayName(), completeBase); addItem(name, qVariantFromValue(tc->targetAbi())); } } diff --git a/src/plugins/debugger/debuggertoolchaincombobox.h b/src/plugins/debugger/debuggertoolchaincombobox.h index f853092dec5..edf3783746c 100644 --- a/src/plugins/debugger/debuggertoolchaincombobox.h +++ b/src/plugins/debugger/debuggertoolchaincombobox.h @@ -59,7 +59,6 @@ protected: virtual bool event(QEvent *event); private: - ProjectExplorer::Abi abiAt(int index) const; }; diff --git a/src/plugins/debugger/gdb/codagdbadapter.cpp b/src/plugins/debugger/gdb/codagdbadapter.cpp index dc6132c27fd..1439b74909d 100644 --- a/src/plugins/debugger/gdb/codagdbadapter.cpp +++ b/src/plugins/debugger/gdb/codagdbadapter.cpp @@ -377,7 +377,7 @@ void CodaGdbAdapter::startGdb() { QStringList gdbArgs; gdbArgs.append(_("--nx")); // Do not read .gdbinit file - if (!m_engine->startGdb(gdbArgs, QString(), QString())) { + if (!m_engine->startGdb(gdbArgs)) { cleanup(); return; } diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index 1142d0277c5..b6dd5923016 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -79,7 +79,7 @@ void CoreGdbAdapter::startAdapter() QStringList args; args.append(_("-ex")); args.append(_("set auto-solib-add off")); - if (!m_engine->startGdb(args)) + if (!m_engine->startGdb(args, QString())) return; //if (m_executable.isEmpty()) { diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2acecec49b5..3c050a71238 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -76,6 +76,7 @@ #include <coreplugin/icore.h> #include <coreplugin/ifile.h> #include <projectexplorer/toolchain.h> +#include <projectexplorer/projectexplorerconstants.h> #include <texteditor/itexteditor.h> #include <utils/qtcassert.h> @@ -4203,23 +4204,62 @@ void GdbEngine::handleFetchDisassemblerByCliRangePlain(const GdbResponse &respon .arg(QString::fromLocal8Bit(msg)), 5000); } +// Binary/configuration check logic. + +static QString gdbBinary(const DebuggerStartParameters &sp) +{ + // 1) Environment. + const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH"); + if (!envBinary.isEmpty()) + return QString::fromLocal8Bit(envBinary); + // 2) Command explicitly specified. + if (!sp.debuggerCommand.isEmpty()) { +#ifdef Q_OS_WIN + // Do not use a CDB binary if we got started for a project with MSVC runtime. + const bool abiMatch = sp.toolChainAbi.os() != ProjectExplorer::Abi::WindowsOS + || sp.toolChainAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor; +#else + const bool abiMatch = true; +#endif + if (abiMatch) + return sp.debuggerCommand; + } + // 3) Find one from toolchains. + return debuggerCore()->debuggerForAbi(sp.toolChainAbi, GdbEngineType); +} + +bool checkGdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check) +{ + const QString binary = gdbBinary(sp); + if (gdbBinary(sp).isEmpty()) { + check->errorDetails.push_back(msgNoGdbBinaryForToolChain(sp.toolChainAbi)); + check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); + check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); + return false; + } +#ifdef Q_OS_WIN + // See initialization below, we need an absolute path to be able to locate Python on Windows. + if (!QFileInfo(binary).isAbsolute()) { + check->errorDetails.push_back(GdbEngine::tr("The gdb location must be given as an " + "absolute path in the debugger settings (%1).").arg(binary)); + check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); + check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY); + return false; + } +#endif + return true; +} // // Starting up & shutting down // -bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, - const QString &settingsIdHint) +bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint) { gdbProc()->disconnect(); // From any previous runs const DebuggerStartParameters &sp = startParameters(); - m_gdb = QString::fromLocal8Bit(qgetenv("QTC_DEBUGGER_PATH")); - if (m_gdb.isEmpty() && sp.startMode != StartRemoteGdb) { - m_gdb = debuggerCore()->debuggerForAbi(startParameters().toolChainAbi, GdbEngineType); - } - if (m_gdb.isEmpty()) - m_gdb = gdb; + m_gdb = gdbBinary(sp); if (m_gdb.isEmpty()) { handleAdapterStartFailed( msgNoGdbBinaryForToolChain(sp.toolChainAbi), @@ -4237,13 +4277,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, // Set python path. By convention, python is located below gdb executable. // Extend the environment set on the process in startAdapter(). const QFileInfo fi(m_gdb); - if (!fi.isAbsolute()) { - showMessage(_("GDB %1 DOES NOT HAVE ABSOLUTE LOCATION.").arg(m_gdb)); - const QString msg = tr("The gdb location must be given as an " - "absolute path in the debugger settings."); - handleAdapterStartFailed(msg, settingsIdHint); - return false; - } + QTC_ASSERT(fi.isAbsolute(), return false; ) const QString winPythonVersion = _(winPythonVersionC); const QDir dir = fi.absoluteDir(); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 68ab7e949a1..1919e52ff27 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -132,7 +132,6 @@ private: ////////// Gdb Process Management ////////// AbstractGdbAdapter *createAdapter(); bool startGdb(const QStringList &args = QStringList(), - const QString &gdb = QString(), const QString &settingsIdHint = QString()); void handleInferiorShutdown(const GdbResponse &response); void handleGdbExit(const GdbResponse &response); diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index 49b13c54db4..ccae4db8004 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -317,7 +317,7 @@ void RemoteGdbServerAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPor void RemoteGdbServerAdapter::handleSetupDone() { - if (m_engine->startGdb(QStringList(), startParameters().debuggerCommand)) + if (m_engine->startGdb()) m_engine->handleAdapterStarted(); } diff --git a/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp b/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp index aa3dea22651..18f06455262 100644 --- a/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp @@ -123,8 +123,7 @@ void RemotePlainGdbAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPort void RemotePlainGdbAdapter::handleGdbStarted() { - if (m_engine->startGdb(QStringList(), - m_engine->startParameters().debuggerCommand)) + if (m_engine->startGdb()) m_engine->handleAdapterStarted(); } diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 00ffe5b3721..5876e25e07f 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -1475,7 +1475,7 @@ void TrkGdbAdapter::slotStartGdb() { QStringList gdbArgs; gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file - if (!m_engine->startGdb(gdbArgs, QString(), QString())) { + if (!m_engine->startGdb(gdbArgs)) { cleanup(); return; } -- GitLab