Docker: Fix debugger auto-detection

Mark detected debuggers as such and give them some bonus to match,
overriding other hacks.

Change-Id: Iaf4d88fa22dd50e68124b61087d4c742f7a56d0f
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2021-07-09 17:39:50 +02:00
parent e8521e6fe1
commit 076d1bf10a
8 changed files with 35 additions and 17 deletions

View File

@@ -57,7 +57,8 @@ const char DEBUGGER_INFORMATION_COMMAND[] = "Binary";
const char DEBUGGER_INFORMATION_DISPLAYNAME[] = "DisplayName";
const char DEBUGGER_INFORMATION_ID[] = "Id";
const char DEBUGGER_INFORMATION_ENGINETYPE[] = "EngineType";
const char DEBUGGER_INFORMATION_AUTODETECTED[] = "AutoDetected";
const char DEBUGGER_INFORMATION_AUTODETECTED[] = "AutoDetected"; // FIXME: Merge into DetectionSource
const char DEBUGGER_INFORMATION_DETECTION_SOURCE[] = "DetectionSource";
const char DEBUGGER_INFORMATION_VERSION[] = "Version";
const char DEBUGGER_INFORMATION_ABIS[] = "Abis";
const char DEBUGGER_INFORMATION_LASTMODIFIED[] = "LastModified";
@@ -113,6 +114,7 @@ DebuggerItem::DebuggerItem(const QVariantMap &data)
m_workingDirectory = FilePath::fromVariant(data.value(DEBUGGER_INFORMATION_WORKINGDIRECTORY));
m_unexpandedDisplayName = data.value(DEBUGGER_INFORMATION_DISPLAYNAME).toString();
m_isAutoDetected = data.value(DEBUGGER_INFORMATION_AUTODETECTED, false).toBool();
m_detectionSource = data.value(DEBUGGER_INFORMATION_DETECTION_SOURCE).toString();
m_version = data.value(DEBUGGER_INFORMATION_VERSION).toString();
m_engineType = DebuggerEngineType(data.value(DEBUGGER_INFORMATION_ENGINETYPE,
static_cast<int>(NoEngineType)).toInt());
@@ -210,8 +212,8 @@ void DebuggerItem::reinitializeFromFile(const Utils::Environment &sysEnv)
const bool unableToFindAVersion = (0 == version);
const bool gdbSupportsConfigurationFlag = (version >= 70700);
if (gdbSupportsConfigurationFlag || unableToFindAVersion) {
const auto gdbConfiguration = getConfigurationOfGdbCommand(m_command, sysEnv);
const auto gdbTargetAbiString =
const QString gdbConfiguration = getConfigurationOfGdbCommand(m_command, sysEnv);
const QString gdbTargetAbiString =
extractGdbTargetAbiStringFromGdbOutput(gdbConfiguration);
if (!gdbTargetAbiString.isEmpty()) {
m_abis.append(Abi::abiFromTargetTriplet(gdbTargetAbiString));
@@ -318,6 +320,7 @@ bool DebuggerItem::operator==(const DebuggerItem &other) const
return m_id == other.m_id
&& m_unexpandedDisplayName == other.m_unexpandedDisplayName
&& m_isAutoDetected == other.m_isAutoDetected
&& m_detectionSource == other.m_detectionSource
&& m_command == other.m_command
&& m_workingDirectory == other.m_workingDirectory;
}
@@ -331,6 +334,7 @@ QVariantMap DebuggerItem::toMap() const
data.insert(DEBUGGER_INFORMATION_WORKINGDIRECTORY, m_workingDirectory.toVariant());
data.insert(DEBUGGER_INFORMATION_ENGINETYPE, int(m_engineType));
data.insert(DEBUGGER_INFORMATION_AUTODETECTED, m_isAutoDetected);
data.insert(DEBUGGER_INFORMATION_DETECTION_SOURCE, m_detectionSource);
data.insert(DEBUGGER_INFORMATION_VERSION, m_version);
data.insert(DEBUGGER_INFORMATION_ABIS, abiNames());
data.insert(DEBUGGER_INFORMATION_LASTMODIFIED, m_lastModified);

View File

@@ -103,6 +103,9 @@ public:
Utils::FilePath workingDirectory() const { return m_workingDirectory; }
void setWorkingDirectory(const Utils::FilePath &workingPath) { m_workingDirectory = workingPath; }
QString detectionSource() const { return m_detectionSource; }
void setDetectionSource(const QString &source) { m_detectionSource = source; }
private:
DebuggerItem(const QVariant &id);
void initMacroExpander();
@@ -116,6 +119,7 @@ private:
QString m_version;
ProjectExplorer::Abis m_abis;
QDateTime m_lastModified;
QString m_detectionSource;
friend class Internal::DebuggerConfigWidget;
friend class Internal::DebuggerItemConfigWidget;

View File

@@ -92,7 +92,7 @@ public:
QVariant registerDebugger(const DebuggerItem &item);
void readDebuggers(const FilePath &fileName, bool isSystem);
void autoDetectCdbDebuggers();
void autoDetectGdbOrLldbDebuggers(const FilePath &deviceRoot);
void autoDetectGdbOrLldbDebuggers(const FilePath &deviceRoot, const QString &detectionSource);
void autoDetectUvscDebuggers();
QString uniqueDisplayName(const QString &base);
@@ -556,7 +556,6 @@ void DebuggerConfigWidget::addDebugger()
{
DebuggerItem item;
item.createId();
item.setAutoDetected(false);
item.setEngineType(NoEngineType);
item.setUnexpandedDisplayName(d->uniqueDisplayName(tr("New Debugger")));
item.setAutoDetected(false);
@@ -715,7 +714,8 @@ static Utils::FilePaths searchGdbPathsFromRegistry()
return searchPaths;
}
void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePath &deviceRoot)
void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePath &deviceRoot,
const QString &detectionSource)
{
const QStringList filters = {"gdb-i686-pc-mingw32", "gdb-i686-pc-mingw32.exe", "gdb",
"gdb.exe", "lldb", "lldb.exe", "lldb-[1-9]*",
@@ -784,14 +784,17 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers(const FilePath &de
}
DebuggerItem item;
item.createId();
item.setDetectionSource(detectionSource);
// Intentionally set items with non-empty source as manual for now to
// give the user a chance to remove them. FIXME: Think of a better way.
item.setAutoDetected(detectionSource.isEmpty());
item.setCommand(command);
item.reinitializeFromFile();
if (item.engineType() == NoEngineType)
continue;
//: %1: Debugger engine type (GDB, LLDB, CDB...), %2: Path
item.setUnexpandedDisplayName(tr("System %1 at %2")
.arg(item.engineTypeName()).arg(command.toUserOutput()));
item.setAutoDetected(true);
const QString name = detectionSource.isEmpty() ? tr("System %1 at %2") : tr("Detected %1 at %2");
item.setUnexpandedDisplayName(name.arg(item.engineTypeName()).arg(command.toUserOutput()));
m_model->addDebugger(item);
}
}
@@ -942,7 +945,7 @@ void DebuggerItemManagerPrivate::restoreDebuggers()
// Auto detect current.
autoDetectCdbDebuggers();
autoDetectGdbOrLldbDebuggers({});
autoDetectGdbOrLldbDebuggers({}, {});
autoDetectUvscDebuggers();
}
@@ -1026,9 +1029,10 @@ void DebuggerItemManager::deregisterDebugger(const QVariant &id)
});
}
void DebuggerItemManager::autoDetectDebuggersForDevice(const Utils::FilePath &deviceRoot)
void DebuggerItemManager::autoDetectDebuggersForDevice(const FilePath &deviceRoot,
const QString &detectionSource)
{
d->autoDetectGdbOrLldbDebuggers(deviceRoot);
d->autoDetectGdbOrLldbDebuggers(deviceRoot, detectionSource);
}
} // namespace Debugger

View File

@@ -52,7 +52,8 @@ public:
static QVariant registerDebugger(const DebuggerItem &item);
static void deregisterDebugger(const QVariant &id);
static void autoDetectDebuggersForDevice(const Utils::FilePath &deviceRoot);
static void autoDetectDebuggersForDevice(const Utils::FilePath &deviceRoot,
const QString &detectionSource);
static const DebuggerItem *findByCommand(const Utils::FilePath &command);
static const DebuggerItem *findById(const QVariant &id);

View File

@@ -185,9 +185,12 @@ void DebuggerKitAspect::setup(Kit *k)
// This improves the situation a bit if a cross-compilation tool chain has the
// same ABI as the host.
if (level == DebuggerItem::MatchesPerfectly
&& !item.command().needsDevice()
&& systemEnvironment.path().contains(item.command().parentDir())) {
level = DebuggerItem::MatchesPerfectlyInPath;
}
if (!item.detectionSource().isEmpty() && item.detectionSource() == k->autoDetectionSource())
level = DebuggerItem::MatchLevel(level + 2);
} else if (rawId.type() == QVariant::String) {
// New structure.
if (item.id() == rawId) {

View File

@@ -1746,9 +1746,10 @@ void DebuggerPlugin::getEnginesState(QByteArray *json) const
*json = QJsonDocument(QJsonObject::fromVariantMap(result)).toJson();
}
void DebuggerPlugin::autoDetectDebuggersForDevice(const FilePath &deviceRoot)
void DebuggerPlugin::autoDetectDebuggersForDevice(const FilePath &deviceRoot,
const QString &detectionId)
{
dd->m_debuggerItemManager.autoDetectDebuggersForDevice(deviceRoot);
dd->m_debuggerItemManager.autoDetectDebuggersForDevice(deviceRoot, detectionId);
}
void DebuggerPluginPrivate::attachToQmlPort()

View File

@@ -59,7 +59,7 @@ private:
Q_SLOT void getEnginesState(QByteArray *json) const;
// Called from DockerDevice
Q_SLOT void autoDetectDebuggersForDevice(const Utils::FilePath &deviceRoot);
Q_SLOT void autoDetectDebuggersForDevice(const Utils::FilePath &deviceRoot, const QString &detectionId);
QVector<QObject *> createTestObjects() const override;
};

View File

@@ -570,7 +570,8 @@ void KitDetectorPrivate::autoDetectDebugger()
const FilePath deviceRoot = m_device->mapToGlobalPath({});
const bool res = QMetaObject::invokeMethod(debuggerPlugin,
"autoDetectDebuggersForDevice",
Q_ARG(Utils::FilePath, deviceRoot));
Q_ARG(Utils::FilePath, deviceRoot),
Q_ARG(QString, m_sharedId));
QTC_CHECK(res);
}