summaryrefslogtreecommitdiff
path: root/src/plugins/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/debugger')
-rw-r--r--src/plugins/debugger/debuggerkitconfigwidget.cpp313
-rw-r--r--src/plugins/debugger/debuggerkitinformation.cpp36
-rw-r--r--src/plugins/debugger/debuggerkitinformation.h8
3 files changed, 181 insertions, 176 deletions
diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp
index c2955fa798..fead22df0a 100644
--- a/src/plugins/debugger/debuggerkitconfigwidget.cpp
+++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp
@@ -86,20 +86,104 @@ DebuggerKitInformation::DebuggerKitInformation()
QVariant DebuggerKitInformation::defaultValue(Kit *k) const
{
-// This is only called from Kit::Kit()
-// if (isValidDebugger(k)) {
-// DebuggerItem *item = DebuggerItemManager::debuggerFromKit(k);
-// QTC_ASSERT(item, return QVariant());
-// return item->id;
-// }
-
ToolChain *tc = ToolChainKitInformation::toolChain(k);
- return DebuggerItemManager::defaultDebugger(tc);
+ QTC_ASSERT(tc, return QVariant());
+
+ const Abi toolChainAbi = tc->targetAbi();
+ foreach (const DebuggerItem &item, DebuggerItemManager::debuggers())
+ foreach (const Abi targetAbi, item.abis())
+ if (targetAbi.isCompatibleWith(toolChainAbi))
+ return item.id();
+
+ return QVariant();
}
void DebuggerKitInformation::setup(Kit *k)
{
- k->setValue(DebuggerKitInformation::id(), defaultValue(k));
+ // Get one of the available debugger matching the kit's toolchain.
+ const ToolChain *tc = ToolChainKitInformation::toolChain(k);
+ const Abi toolChainAbi = tc ? tc->targetAbi() : Abi::hostAbi();
+
+ // This can be anything (Id, binary path, "auto")
+ const QVariant rawId = k->value(DebuggerKitInformation::id());
+
+ enum {
+ NotDetected, DetectedAutomatically, DetectedByFile, DetectedById
+ } detection = NotDetected;
+ DebuggerEngineType autoEngine = NoEngineType;
+ FileName fileName;
+
+ // With 3.0 we have:
+ // <value type="QString" key="Debugger.Information">{75ecf347-f221-44c3-b613-ea1d29929cd4}</value>
+ // Before we had:
+ // <valuemap type="QVariantMap" key="Debugger.Information">
+ // <value type="QString" key="Binary">/data/dev/debugger/gdb-git/gdb/gdb</value>
+ // <value type="int" key="EngineType">1</value>
+ // </valuemap>
+ // Or for force auto-detected CDB
+ // <valuemap type="QVariantMap" key="Debugger.Information">
+ // <value type="QString" key="Binary">auto</value>
+ // <value type="int" key="EngineType">4</value>
+ // </valuemap>
+
+ if (rawId.type() == QVariant::String) {
+ detection = DetectedById;
+ } else {
+ QMap<QString, QVariant> map = rawId.toMap();
+ QString binary = map.value(QLatin1String("Binary")).toString();
+ if (binary == QLatin1String("auto")) {
+ detection = DetectedAutomatically;
+ autoEngine = DebuggerEngineType(map.value(QLatin1String("EngineType")).toInt());
+ } else {
+ detection = DetectedByFile;
+ fileName = FileName::fromUserInput(binary);
+ }
+ }
+
+ QTC_CHECK(detection != NotDetected);
+
+ const DebuggerItem *bestItem = 0;
+ DebuggerItem::MatchLevel bestLevel = DebuggerItem::DoesNotMatch;
+ foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) {
+ const DebuggerItem *goodItem = 0;
+ if (detection == DetectedById && item.id() == rawId)
+ goodItem = &item;
+ if (detection == DetectedByFile && item.command() == fileName)
+ goodItem = &item;
+ if (detection == DetectedAutomatically && item.engineType() == autoEngine)
+ goodItem = &item;
+
+ if (goodItem) {
+ DebuggerItem::MatchLevel level = goodItem->matchTarget(toolChainAbi);
+ if (level > bestLevel) {
+ bestLevel = level;
+ bestItem = goodItem;
+ }
+ }
+ }
+
+ // If we have an existing debugger with matching id _and_
+ // matching target ABI we are fine.
+ if (bestItem) {
+ k->setValue(DebuggerKitInformation::id(), bestItem->id());
+ return;
+ }
+
+ // We didn't find an existing debugger that matched by whatever
+ // data we found in the kit (i.e. no id, filename, "auto")
+ // (or what we found did not match ABI-wise)
+ // Let's try to pick one with matching ABI.
+ QVariant bestId;
+ bestLevel = DebuggerItem::DoesNotMatch;
+ foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) {
+ DebuggerItem::MatchLevel level = item.matchTarget(toolChainAbi);
+ if (level > bestLevel) {
+ bestLevel = level;
+ bestId = item.id();
+ }
+ }
+
+ k->setValue(DebuggerKitInformation::id(), bestId);
}
// Check the configuration errors and return a flag mask. Provide a quick check and
@@ -145,57 +229,9 @@ static unsigned debuggerConfigurationErrors(const Kit *k)
const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit)
{
- if (!kit)
- return 0;
-
+ QTC_ASSERT(kit, return 0);
const QVariant id = kit->value(DebuggerKitInformation::id());
-
- enum Detection { NotDetected, DetectedAutomatically, DetectedByFile, DetectedById };
- Detection detection = NotDetected;
-
- DebuggerEngineType autoEngine = NoEngineType;
-
- FileName fileName;
-
- // With 3.0 we have:
- // <value type="QString" key="Debugger.Information">{75ecf347-f221-44c3-b613-ea1d29929cd4}</value>
- // Before we had:
- // <valuemap type="QVariantMap" key="Debugger.Information">
- // <value type="QString" key="Binary">/data/dev/debugger/gdb-git/gdb/gdb</value>
- // <value type="int" key="EngineType">1</value>
- // </valuemap>
- // Or for force auto-detected CDB
- // <valuemap type="QVariantMap" key="Debugger.Information">
- // <value type="QString" key="Binary">auto</value>
- // <value type="int" key="EngineType">4</value>
- // </valuemap>
-
- if (id.type() == QVariant::String) {
- detection = DetectedById;
- } else {
- QMap<QString, QVariant> map = id.toMap();
- QString binary = map.value(QLatin1String("Binary")).toString();
- if (binary == QLatin1String("auto")) {
- detection = DetectedAutomatically;
- autoEngine = DebuggerEngineType(map.value(QLatin1String("EngineType")).toInt());
- } else {
- detection = DetectedByFile;
- fileName = FileName::fromUserInput(binary);
- }
- }
-
- QTC_CHECK(detection != NotDetected);
-
- foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) {
- if (detection == DetectedById && item.id() == id)
- return &item;
- if (detection == DetectedByFile && item.command() == fileName)
- return &item;
- if (detection == DetectedAutomatically && item.engineType() == autoEngine)
- return &item;
- }
-
- return 0;
+ return DebuggerItemManager::findById(id);
}
bool DebuggerKitInformation::isValidDebugger(const Kit *k)
@@ -297,32 +333,39 @@ static FileName userSettingsFileName()
return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME));
}
-static QList<DebuggerItem> readDebuggers(const FileName &fileName)
+static void readDebuggers(const FileName &fileName, bool isSystem)
{
- QList<DebuggerItem> result;
-
PersistentSettingsReader reader;
if (!reader.load(fileName))
- return result;
+ return;
QVariantMap data = reader.restoreValues();
// Check version
int version = data.value(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 0).toInt();
if (version < 1)
- return result;
+ return;
int count = data.value(QLatin1String(DEBUGGER_COUNT_KEY), 0).toInt();
for (int i = 0; i < count; ++i) {
const QString key = QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(i);
if (!data.contains(key))
- break;
+ continue;
const QVariantMap dbMap = data.value(key).toMap();
DebuggerItem item;
item.fromMap(dbMap);
- result.append(item);
+ if (isSystem) {
+ item.setAutoDetected(true);
+ // SDK debuggers are always considered to be up-to-date, so no need to recheck them.
+ } else {
+ // User settings.
+ if (item.isAutoDetected() && !item.isValid()) {
+ qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid")
+ .arg(item.command().toString()).arg(item.id().toString());
+ continue;
+ }
+ }
+ DebuggerItemManager::registerDebugger(item);
}
-
- return result;
}
QList<DebuggerItem> DebuggerItemManager::m_debuggers;
@@ -361,7 +404,7 @@ DebuggerItemModel *DebuggerItemManager::model()
return m_model;
}
-void DebuggerItemManager::autoDetectCdbDebugger()
+void DebuggerItemManager::autoDetectCdbDebuggers()
{
QList<FileName> cdbs;
@@ -419,16 +462,34 @@ void DebuggerItemManager::autoDetectCdbDebugger()
}
}
-void DebuggerItemManager::autoDetectDebuggers()
+void DebuggerItemManager::autoDetectGdbOrLldbDebuggers()
{
- autoDetectCdbDebugger();
-
QStringList filters;
filters.append(QLatin1String("gdb-i686-pc-mingw32"));
filters.append(QLatin1String("gdb"));
filters.append(QLatin1String("lldb"));
filters.append(QLatin1String("lldb-*"));
+// DebuggerItem result;
+// result.setAutoDetected(true);
+// result.setDisplayName(tr("Auto-detected for Tool Chain %1").arg(tc->displayName()));
+ /*
+ // Check suggestions from the SDK.
+ Environment env = Environment::systemEnvironment();
+ if (tc) {
+ tc->addToEnvironment(env); // Find MinGW gdb in toolchain environment.
+ QString path = tc->suggestedDebugger().toString();
+ if (!path.isEmpty()) {
+ const QFileInfo fi(path);
+ if (!fi.isAbsolute())
+ path = env.searchInPath(path);
+ result.command = FileName::fromString(path);
+ result.engineType = engineTypeFromBinary(path);
+ return maybeAddDebugger(result, false);
+ }
+ }
+ */
+
QFileInfoList suspects;
QStringList path = Environment::systemEnvironment().path();
@@ -512,46 +573,16 @@ const DebuggerItem *DebuggerItemManager::findById(const QVariant &id)
void DebuggerItemManager::restoreDebuggers()
{
- QList<DebuggerItem> dbsToCheck;
-
// Read debuggers from SDK
QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName());
- QList<DebuggerItem> dbsToRegister =
- readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)));
-
- // These are autodetected.
- for (int i = 0, n = dbsToRegister.size(); i != n; ++i)
- dbsToRegister[i].setAutoDetected(true);
-
- // SDK debuggers are always considered to be up-to-date, so no need to recheck them.
+ readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)), true);
// Read all debuggers from user file.
- foreach (const DebuggerItem &item, readDebuggers(userSettingsFileName())) {
- if (item.isAutoDetected())
- dbsToCheck.append(item);
- else
- dbsToRegister.append(item);
- }
-
- // Keep debuggers that were not rediscovered but are still executable and delete the rest
- foreach (const DebuggerItem &item, dbsToCheck) {
- if (!item.isValid()) {
- qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid")
- .arg(item.command().toString()).arg(item.id().toString());
- } else {
- dbsToRegister.append(item);
- }
- }
-
- for (int i = 0, n = dbsToRegister.size(); i != n; ++i) {
- DebuggerItem item = dbsToRegister.at(i);
- if (findByCommand(item.command()))
- continue;
- addDebugger(item);
- }
+ readDebuggers(userSettingsFileName(), false);
// Auto detect current.
- autoDetectDebuggers();
+ autoDetectCdbDebuggers();
+ autoDetectGdbOrLldbDebuggers();
// Add debuggers from pre-3.x profiles.xml
readLegacyDebuggers();
@@ -639,72 +670,6 @@ void DebuggerItemManager::setItemData(const QVariant &id, const QString &display
}
}
-QVariant DebuggerItemManager::defaultDebugger(ToolChain *tc)
-{
- QTC_ASSERT(tc, return QVariant());
-
- DebuggerItem result;
- result.setAutoDetected(true);
- result.setDisplayName(tr("Auto-detected for Tool Chain %1").arg(tc->displayName()));
-
- Abi abi = Abi::hostAbi();
- if (tc)
- abi = tc->targetAbi();
-
-// if (abis.first().wordWidth() == 32)
-// result.first = cdb.toString();
-// else if (abis.first().wordWidth() == 64)
-// result.second = cdb.toString();
-// // prefer 64bit debugger, even for 32bit binaries:
-// if (!result.second.isEmpty())
-// result.first = result.second;
-
-
- foreach (const DebuggerItem &item, m_debuggers)
- foreach (const Abi targetAbi, item.abis())
- if (targetAbi.isCompatibleWith(abi))
- return item.id();
-
- return QVariant();
-
- /*
- // CDB for windows:
- if (abi.os() == Abi::WindowsOS && abi.osFlavor() != Abi::WindowsMSysFlavor) {
- QPair<QString, QString> cdbs = autoDetectCdbDebugger();
- result.command = FileName::fromString(abi.wordWidth() == 32 ? cdbs.first : cdbs.second);
- result.engineType = CdbEngineType;
- return maybeAddDebugger(result, false);
- }
-
- // Check suggestions from the SDK.
- Environment env = Environment::systemEnvironment();
- if (tc) {
- tc->addToEnvironment(env); // Find MinGW gdb in toolchain environment.
- QString path = tc->suggestedDebugger().toString();
- if (!path.isEmpty()) {
- const QFileInfo fi(path);
- if (!fi.isAbsolute())
- path = env.searchInPath(path);
- result.command = FileName::fromString(path);
- result.engineType = engineTypeFromBinary(path);
- return maybeAddDebugger(result, false);
- }
- }
-
- // Default to GDB, system GDB
- result.engineType = GdbEngineType;
- QString gdb;
- const QString systemGdb = QLatin1String("gdb");
- // MinGW: Search for the python-enabled gdb first.
- if (abi.os() == Abi::WindowsOS && abi.osFlavor() == Abi::WindowsMSysFlavor)
- gdb = env.searchInPath(QLatin1String("gdb-i686-pc-mingw32"));
- if (gdb.isEmpty())
- gdb = env.searchInPath(systemGdb);
- result.command = FileName::fromString(env.searchInPath(gdb.isEmpty() ? systemGdb : gdb));
- return maybeAddDebugger(result, false);
- */
-}
-
namespace Internal {
static QList<QStandardItem *> describeItem(const DebuggerItem &item)
@@ -946,7 +911,9 @@ void DebuggerKitConfigWidget::manageDebuggers()
void DebuggerKitConfigWidget::currentDebuggerChanged(int)
{
- m_kit->setValue(DebuggerKitInformation::id(), m_comboBox->itemData(m_comboBox->currentIndex()));
+ int currentIndex = m_comboBox->currentIndex();
+ QVariant id = m_comboBox->itemData(currentIndex);
+ m_kit->setValue(DebuggerKitInformation::id(), id);
}
void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id, const QString &displayName)
diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp
index c57dde729b..2bd4492dec 100644
--- a/src/plugins/debugger/debuggerkitinformation.cpp
+++ b/src/plugins/debugger/debuggerkitinformation.cpp
@@ -185,6 +185,42 @@ void DebuggerItem::setAbi(const Abi &abi)
m_abis.append(abi);
}
+static DebuggerItem::MatchLevel matchSingle(const Abi &debuggerAbi, const Abi &targetAbi)
+{
+ if (debuggerAbi.architecture() != targetAbi.architecture())
+ return DebuggerItem::DoesNotMatch;
+
+ if (debuggerAbi.os() != targetAbi.os())
+ return DebuggerItem::DoesNotMatch;
+
+ if (debuggerAbi.binaryFormat() != targetAbi.binaryFormat())
+ return DebuggerItem::DoesNotMatch;
+
+ if (debuggerAbi.wordWidth() != targetAbi.wordWidth())
+ return DebuggerItem::DoesNotMatch;
+
+ if (debuggerAbi.os() == Abi::WindowsOS) {
+ if (debuggerAbi.osFlavor() == Abi::WindowsMSysFlavor && targetAbi.osFlavor() != Abi::WindowsMSysFlavor)
+ return DebuggerItem::DoesNotMatch;
+ if (debuggerAbi.osFlavor() != Abi::WindowsMSysFlavor && targetAbi.osFlavor() == Abi::WindowsMSysFlavor)
+ return DebuggerItem::DoesNotMatch;
+ return DebuggerItem::MatchesSomewhat;
+ }
+
+ return DebuggerItem::MatchesPerfectly;
+}
+
+DebuggerItem::MatchLevel DebuggerItem::matchTarget(const Abi &targetAbi) const
+{
+ MatchLevel bestMatch = DoesNotMatch;
+ foreach (const Abi &debuggerAbi, m_abis) {
+ MatchLevel currentMatch = matchSingle(debuggerAbi, targetAbi);
+ if (currentMatch > bestMatch)
+ bestMatch = currentMatch;
+ }
+ return bestMatch;
+}
+
bool Debugger::DebuggerItem::isValid() const
{
return m_engineType != NoEngineType;
diff --git a/src/plugins/debugger/debuggerkitinformation.h b/src/plugins/debugger/debuggerkitinformation.h
index e0b66fc08a..92e8d935fd 100644
--- a/src/plugins/debugger/debuggerkitinformation.h
+++ b/src/plugins/debugger/debuggerkitinformation.h
@@ -77,6 +77,9 @@ public:
void setAbis(const QList<ProjectExplorer::Abi> &abis);
void setAbi(const ProjectExplorer::Abi &abi);
+ enum MatchLevel { DoesNotMatch, MatchesSomewhat, MatchesPerfectly };
+ MatchLevel matchTarget(const ProjectExplorer::Abi &targetAbi) const;
+
QStringList abiNames() const;
private:
@@ -113,7 +116,6 @@ public:
static const DebuggerItem *findByCommand(const Utils::FileName &command);
static const DebuggerItem *findById(const QVariant &id);
- static QVariant defaultDebugger(ProjectExplorer::ToolChain *tc);
static void restoreDebuggers();
static QString uniqueDisplayName(const QString &base);
static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName);
@@ -126,8 +128,8 @@ public slots:
private:
explicit DebuggerItemManager(QObject *parent = 0);
- static void autoDetectDebuggers();
- static void autoDetectCdbDebugger();
+ static void autoDetectGdbOrLldbDebuggers();
+ static void autoDetectCdbDebuggers();
static void readLegacyDebuggers();
static Utils::PersistentSettingsWriter *m_writer;