aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2012-09-05 14:56:08 +0200
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>2012-09-05 15:49:11 +0200
commitaf6bbc442ecb60d2ddcb37752215f6a2e3e5bea4 (patch)
tree1819ebb9f2fea4bdbb30e96c2783c6508ebc5726
parent824d04252e1c2d461dadc09c657d2c896b0c74ad (diff)
Add debugger engine type to configuration.
Introduce a struct DebuggerItem as a debugger configuration item, containing debugger engine type and binary. Store information as a variant map. Add a combo box. Remove engine guessing logic. Parts of it are still required when checking the suggested debugger from the SDK. Split error checking to be able to do a quick error check and find only valid profiles in the matchers. Pass on errors up to RunControl::create(). Change-Id: I08653e2a76ca2c371701082f8173b0b8f8ed462e Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
-rw-r--r--src/plugins/debugger/debuggerdialogs.cpp3
-rw-r--r--src/plugins/debugger/debuggerkitconfigwidget.cpp109
-rw-r--r--src/plugins/debugger/debuggerkitconfigwidget.h20
-rw-r--r--src/plugins/debugger/debuggerkitinformation.cpp215
-rw-r--r--src/plugins/debugger/debuggerkitinformation.h41
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp68
-rw-r--r--src/plugins/debugger/debuggerrunner.cpp87
-rw-r--r--src/plugins/debugger/debuggerstartparameters.h4
-rw-r--r--src/plugins/debugger/gdb/startgdbserverdialog.cpp2
-rw-r--r--src/plugins/debugger/lldb/lldbenginehost.cpp1
10 files changed, 370 insertions, 180 deletions
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 893cbb13f0..504dcd338e 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -374,8 +374,7 @@ bool StartApplicationDialog::run(QWidget *parent, QSettings *settings, DebuggerS
}
Kit *kit = dialog.d->kitChooser->currentKit();
- QTC_ASSERT(kit, return false);
- fillParameters(sp, kit);
+ QTC_ASSERT(kit && fillParameters(sp, kit), return false);
sp->executable = newParameters.localExecutable;
sp->displayName = newParameters.displayName();
diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp
index 96cf2b04a7..6ceb478fb2 100644
--- a/src/plugins/debugger/debuggerkitconfigwidget.cpp
+++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp
@@ -29,7 +29,6 @@
**************************************************************************/
#include "debuggerkitconfigwidget.h"
-
#include "debuggerkitinformation.h"
#include <projectexplorer/abi.h>
@@ -48,6 +47,8 @@
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>
+#include <QLabel>
+#include <QComboBox>
namespace Debugger {
namespace Internal {
@@ -55,6 +56,7 @@ namespace Internal {
static const char dgbToolsDownloadLink32C[] = "http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx";
static const char dgbToolsDownloadLink64C[] = "http://www.microsoft.com/whdc/devtools/debugging/install64bit.Mspx";
+
// -----------------------------------------------------------------------
// DebuggerKitConfigWidget:
// -----------------------------------------------------------------------
@@ -65,34 +67,26 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *k,
ProjectExplorer::KitConfigWidget(parent),
m_kit(k),
m_info(ki),
- m_chooser(new Utils::PathChooser)
+ m_comboBox(new QComboBox(this)),
+ m_label(new QLabel(this)),
+ m_chooser(new Utils::PathChooser(this))
{
setToolTip(tr("The debugger to use for this kit."));
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
- ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k);
- if (tc && tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS
- && tc->targetAbi().osFlavor() != ProjectExplorer::Abi::WindowsMSysFlavor) {
- QLabel *msvcDebuggerConfigLabel = new QLabel;
-#ifdef Q_OS_WIN
- const bool is64bit = Utils::winIs64BitSystem();
-#else
- const bool is64bit = false;
-#endif
- const QString link = is64bit ? QLatin1String(dgbToolsDownloadLink64C) : QLatin1String(dgbToolsDownloadLink32C);
- //: Label text for path configuration. %2 is "x-bit version".
- msvcDebuggerConfigLabel->setText(tr("<html><body><p>Specify the path to the "
- "<a href=\"%1\">Windows Console Debugger executable</a>"
- " (%2) here.</p>"
- "</body></html>").arg(link, (is64bit ? tr("64-bit version")
- : tr("32-bit version"))));
- msvcDebuggerConfigLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- msvcDebuggerConfigLabel->setOpenExternalLinks(true);
- layout->addWidget(msvcDebuggerConfigLabel);
-
+ m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(GdbEngineType), QVariant(int(GdbEngineType)));
+ if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::WindowsOS) {
+ m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(CdbEngineType), QVariant(int(CdbEngineType)));
+ } else {
+ m_comboBox->addItem(DebuggerKitInformation::debuggerEngineName(LldbEngineType), QVariant(int(LldbEngineType)));
}
+ layout->addWidget(m_comboBox);
+
+ m_label->setTextInteractionFlags(Qt::TextBrowserInteraction);
+ m_label->setOpenExternalLinks(true);
+ layout->addWidget(m_label);
m_chooser->setContentsMargins(0, 0, 0, 0);
m_chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
@@ -102,6 +96,8 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(ProjectExplorer::Kit *k,
discard();
connect(m_chooser, SIGNAL(changed(QString)), this, SIGNAL(dirty()));
+ connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(dirty()));
+ connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(refreshLabel()));
}
QString DebuggerKitConfigWidget::displayName() const
@@ -111,23 +107,26 @@ QString DebuggerKitConfigWidget::displayName() const
void DebuggerKitConfigWidget::makeReadOnly()
{
+ m_comboBox->setEnabled(false);
m_chooser->setEnabled(false);
}
void DebuggerKitConfigWidget::apply()
{
- Utils::FileName fn = m_chooser->fileName();
- DebuggerKitInformation::setDebuggerCommand(m_kit, fn);
+ DebuggerKitInformation::setDebuggerItem(m_kit, DebuggerKitInformation::DebuggerItem(engineType(), fileName()));
}
void DebuggerKitConfigWidget::discard()
{
- m_chooser->setFileName(DebuggerKitInformation::debuggerCommand(m_kit));
+ const DebuggerKitInformation::DebuggerItem item = DebuggerKitInformation::debuggerItem(m_kit);
+ setEngineType(item.engineType);
+ setFileName(item.binary);
}
bool DebuggerKitConfigWidget::isDirty() const
{
- return m_chooser->fileName() != DebuggerKitInformation::debuggerCommand(m_kit);
+ const DebuggerKitInformation::DebuggerItem item = DebuggerKitInformation::debuggerItem(m_kit);
+ return item.engineType != engineType() || item.binary != fileName();
}
QWidget *DebuggerKitConfigWidget::buttonWidget() const
@@ -137,8 +136,62 @@ QWidget *DebuggerKitConfigWidget::buttonWidget() const
void DebuggerKitConfigWidget::autoDetectDebugger()
{
- QVariant v = m_info->defaultValue(m_kit);
- m_chooser->setFileName(Utils::FileName::fromString(v.toString()));
+ const DebuggerKitInformation::DebuggerItem item = DebuggerKitInformation::autoDetectItem(m_kit);
+ setEngineType(item.engineType);
+ setFileName(item.binary);
+}
+
+DebuggerEngineType DebuggerKitConfigWidget::engineType() const
+{
+ const int index = m_comboBox->currentIndex();
+ return static_cast<DebuggerEngineType>(m_comboBox->itemData(index).toInt());
+}
+
+void DebuggerKitConfigWidget::setEngineType(DebuggerEngineType et)
+{
+ const int size = m_comboBox->count();
+ for (int i = 0; i < size; ++i) {
+ if (m_comboBox->itemData(i).toInt() == et) {
+ m_comboBox->setCurrentIndex(i);
+ refreshLabel();
+ break;
+ }
+ }
+}
+
+Utils::FileName DebuggerKitConfigWidget::fileName() const
+{
+ return m_chooser->fileName();
+}
+
+void DebuggerKitConfigWidget::setFileName(const Utils::FileName &fn)
+{
+ m_chooser->setFileName(fn);
+}
+
+void DebuggerKitConfigWidget::refreshLabel()
+{
+ QString text;
+ switch (engineType()) {
+ case CdbEngineType: {
+#ifdef Q_OS_WIN
+ const bool is64bit = Utils::winIs64BitSystem();
+#else
+ const bool is64bit = false;
+#endif
+ const QString link = is64bit ? QLatin1String(dgbToolsDownloadLink64C) : QLatin1String(dgbToolsDownloadLink32C);
+ const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version");
+ //: Label text for path configuration. %2 is "x-bit version".
+ text = tr("<html><body><p>Specify the path to the "
+ "<a href=\"%1\">Windows Console Debugger executable</a>"
+ " (%2) here.</p>""</body></html>").arg(link, versionString);
+ }
+ break;
+ default:
+ break;
+ }
+ m_label->setText(text);
+ m_label->setVisible(!text.isEmpty());
}
} // namespace Internal
diff --git a/src/plugins/debugger/debuggerkitconfigwidget.h b/src/plugins/debugger/debuggerkitconfigwidget.h
index b818f3817f..a54ee648b8 100644
--- a/src/plugins/debugger/debuggerkitconfigwidget.h
+++ b/src/plugins/debugger/debuggerkitconfigwidget.h
@@ -33,11 +33,16 @@
#include <projectexplorer/kitconfigwidget.h>
-#include <QLabel>
-#include <debuggerkitinformation.h>
+#include "debuggerconstants.h"
+
+QT_FORWARD_DECLARE_CLASS(QLabel)
+QT_FORWARD_DECLARE_CLASS(QComboBox)
namespace ProjectExplorer { class Kit; }
-namespace Utils { class PathChooser; }
+namespace Utils {
+class PathChooser;
+class FileName;
+}
namespace Debugger {
class DebuggerKitInformation;
@@ -65,12 +70,21 @@ public:
bool isDirty() const;
QWidget *buttonWidget() const;
+ DebuggerEngineType engineType() const;
+ void setEngineType(DebuggerEngineType et);
+
+ Utils::FileName fileName() const;
+ void setFileName(const Utils::FileName &fn);
+
private slots:
void autoDetectDebugger();
+ void refreshLabel();
private:
ProjectExplorer::Kit *m_kit;
const DebuggerKitInformation *m_info;
+ QComboBox *m_comboBox;
+ QLabel *m_label;
Utils::PathChooser *m_chooser;
};
diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp
index 8d7db74f57..7501237983 100644
--- a/src/plugins/debugger/debuggerkitinformation.cpp
+++ b/src/plugins/debugger/debuggerkitinformation.cpp
@@ -114,12 +114,32 @@ static QPair<QString, QString> autoDetectCdbDebugger()
namespace Debugger {
+static DebuggerEngineType engineTypeFromBinary(const QString &binary)
+{
+ if (binary.contains(QLatin1String("cdb"), Qt::CaseInsensitive))
+ return CdbEngineType;
+ if (binary.contains(QLatin1String("lldb"), Qt::CaseInsensitive))
+ return LldbEngineType;
+ return GdbEngineType;
+}
+
// --------------------------------------------------------------------------
// DebuggerKitInformation:
// --------------------------------------------------------------------------
static const char DEBUGGER_INFORMATION[] = "Debugger.Information";
+DebuggerKitInformation::DebuggerItem::DebuggerItem()
+ : engineType(NoEngineType)
+{
+}
+
+DebuggerKitInformation::DebuggerItem::DebuggerItem(DebuggerEngineType et, const Utils::FileName &fn)
+ : engineType(et)
+ , binary(fn)
+{
+}
+
DebuggerKitInformation::DebuggerKitInformation()
{
setObjectName(QLatin1String("DebuggerKitInformation"));
@@ -136,9 +156,10 @@ unsigned int DebuggerKitInformation::priority() const
return 28000;
}
-QVariant DebuggerKitInformation::defaultValue(Kit *k) const
+DebuggerKitInformation::DebuggerItem DebuggerKitInformation::autoDetectItem(const Kit *k)
{
- ToolChain *tc = ToolChainKitInformation::toolChain(k);
+ DebuggerItem result;
+ const ToolChain *tc = ToolChainKitInformation::toolChain(k);
Abi abi = Abi::hostAbi();
if (tc)
abi = tc->targetAbi();
@@ -146,59 +167,100 @@ QVariant DebuggerKitInformation::defaultValue(Kit *k) const
// CDB for windows:
if (abi.os() == Abi::WindowsOS && abi.osFlavor() != Abi::WindowsMSysFlavor) {
QPair<QString, QString> cdbs = autoDetectCdbDebugger();
- return (abi.wordWidth() == 32) ? cdbs.first : cdbs.second;
+ result.binary = Utils::FileName::fromString(abi.wordWidth() == 32 ? cdbs.first : cdbs.second);
+ result.engineType = CdbEngineType;
+ return result;
}
- // fall back to system GDB:
- QString debugger = QLatin1String("gdb");
+ // Check suggestions from the SDK.
+ const Environment env = Environment::systemEnvironment();
if (tc) {
- // Check suggestions from the SDK:
- const QString path = tc->suggestedDebugger().toString();
+ QString path = tc->suggestedDebugger().toString();
if (!path.isEmpty()) {
- QFileInfo fi(path);
- if (fi.isAbsolute())
- return path;
- debugger = path;
+ const QFileInfo fi(path);
+ if (!fi.isAbsolute())
+ path = env.searchInPath(path);
+ result.binary = Utils::FileName::fromString(path);
+ result.engineType = engineTypeFromBinary(path);
+ return result;
}
}
- Environment env = Environment::systemEnvironment();
- return env.searchInPath(debugger);
+ // 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.binary = Utils::FileName::fromString(env.searchInPath(gdb.isEmpty() ? systemGdb : gdb));
+ return result;
}
-QList<Task> DebuggerKitInformation::validate(Kit *k) const
+// Check the configuration errors and return a flag mask. Provide a quick check and
+// a verbose one with a list of errors.
+
+enum DebuggerConfigurationErrors {
+ NoDebugger = 0x1,
+ DebuggerNotFound = 0x2,
+ DebuggerNotExecutable = 0x4,
+ DebuggerNeedsAbsolutePath = 0x8
+};
+
+static unsigned debuggerConfigurationErrors(const ProjectExplorer::Kit *p)
{
- const Core::Id id(Constants::TASK_CATEGORY_BUILDSYSTEM);
- QList<Task> result;
- FileName dbg = debuggerCommand(k);
- if (dbg.isEmpty()) {
- result << Task(Task::Warning, tr("No debugger set up."), FileName(), -1, id);
- return result;
+ unsigned result = 0;
+ const DebuggerKitInformation::DebuggerItem item = DebuggerKitInformation::debuggerItem(p);
+ if (item.engineType == NoEngineType || item.binary.isEmpty())
+ return NoDebugger;
+
+ const QFileInfo fi = item.binary.toFileInfo();
+ if (!fi.exists() || fi.isDir()) {
+ result |= DebuggerNotFound;
+ } else if (!fi.isExecutable()) {
+ result |= DebuggerNotExecutable;
}
- QFileInfo fi = dbg.toFileInfo();
if (!fi.exists() || fi.isDir())
- result << Task(Task::Error, tr("Debugger not found."), FileName(), -1, id);
- else if (!fi.isExecutable())
- result << Task(Task::Error, tr("Debugger not exectutable."), FileName(), -1, id);
-
- if (ToolChain *tc = ToolChainKitInformation::toolChain(k)) {
// We need an absolute path to be able to locate Python on Windows.
- const Abi abi = tc->targetAbi();
- if (abi.os() == Abi::WindowsOS && !fi.isAbsolute()) {
- result << Task(Task::Error, tr("The debugger location must be given as an "
- "absolute path (%1).").arg(dbg.toString()), FileName(), -1, id);
- }
- // FIXME: Make sure debugger matches toolchain.
- // if (isCdb()) {
- // if (abi.binaryFormat() != Abi::PEFormat || abi.os() != Abi::WindowsOS) {
- // result << Task(Tas->errorDetails.push_back(CdbEngine::tr("The CDB debug engine does not support the %1 ABI.").
- // arg(abi.toString()));
- // return false;
- // }
- // }
- }
+ if (item.engineType == GdbEngineType)
+ if (const ToolChain *tc = ToolChainKitInformation::toolChain(p))
+ if (tc->targetAbi().os() == Abi::WindowsOS && !fi.isAbsolute())
+ result |= DebuggerNeedsAbsolutePath;
+ return result;
+}
+
+bool DebuggerKitInformation::isValidDebugger(const ProjectExplorer::Kit *p)
+{
+ return debuggerConfigurationErrors(p) == 0;
+}
+
+QList<ProjectExplorer::Task> DebuggerKitInformation::validateDebugger(const ProjectExplorer::Kit *p)
+{
+ const unsigned errors = debuggerConfigurationErrors(p);
+ const Core::Id id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
+ QList<Task> result;
+ if (errors & NoDebugger)
+ result << Task(Task::Warning, tr("No debugger set up."), FileName(), -1, id);
+ if (errors & DebuggerNotFound) {
+ const QString path = DebuggerKitInformation::debuggerCommand(p).toUserOutput();
+ result << Task(Task::Error, tr("Debugger '%1' not found.").arg(path),
+ FileName(), -1, id);
+ }
+ if (errors & DebuggerNotExecutable) {
+ const QString path = DebuggerKitInformation::debuggerCommand(p).toUserOutput();
+ result << Task(Task::Error, tr("Debugger '%1' not executable.").arg(path), FileName(), -1, id);
+ }
+ if (errors & DebuggerNeedsAbsolutePath) {
+ const QString path = DebuggerKitInformation::debuggerCommand(p).toUserOutput();
+ const QString message =
+ tr("The debugger location must be given as an "
+ "absolute path (%1).").arg(path);
+ result << Task(Task::Error, message, FileName(), -1, id);
+ }
return result;
}
@@ -207,20 +269,81 @@ KitConfigWidget *DebuggerKitInformation::createConfigWidget(Kit *k) const
return new Internal::DebuggerKitConfigWidget(k, this);
}
+QString DebuggerKitInformation::userOutput(const ProjectExplorer::Kit *k)
+{
+ const DebuggerItem item = DebuggerKitInformation::debuggerItem(k);
+ return tr("%1 using '%2'").arg(debuggerEngineName(item.engineType),
+ item.binary.toUserOutput());
+}
+
KitInformation::ItemList DebuggerKitInformation::toUserOutput(Kit *k) const
{
- return ItemList() << qMakePair(tr("Debugger"), debuggerCommand(k).toUserOutput());
+ return ItemList() << qMakePair(tr("Debugger"), DebuggerKitInformation::userOutput(k));
+}
+
+static const char engineTypeKeyC[] = "EngineType";
+static const char binaryKeyC[] = "Binary";
+
+DebuggerKitInformation::DebuggerItem DebuggerKitInformation::variantToItem(const QVariant &v)
+{
+ DebuggerItem result;
+ if (v.type() == QVariant::String) { // Convert legacy config items, remove later.
+ const QString binary = v.toString();
+ result.binary = Utils::FileName::fromString(binary);
+ result.engineType = engineTypeFromBinary(binary);
+ return result;
+ }
+ QTC_ASSERT(v.type() == QVariant::Map, return result);
+ const QVariantMap vmap = v.toMap();
+ result.binary = Utils::FileName::fromString(vmap.value(QLatin1String(binaryKeyC)).toString());
+ result.engineType = static_cast<DebuggerEngineType>(vmap.value(QLatin1String(engineTypeKeyC)).toInt());
+ return result;
}
-FileName DebuggerKitInformation::debuggerCommand(const Kit *k)
+QVariant DebuggerKitInformation::itemToVariant(const DebuggerItem &i)
{
- return FileName::fromString(k ? k->value(Core::Id(DEBUGGER_INFORMATION)).toString() : QString());
+ QVariantMap vmap;
+ vmap.insert(QLatin1String(binaryKeyC), QVariant(i.binary.toUserOutput()));
+ vmap.insert(QLatin1String(engineTypeKeyC), QVariant(int(i.engineType)));
+ return QVariant(vmap);
}
-void DebuggerKitInformation::setDebuggerCommand(Kit *k, const FileName &command)
+DebuggerKitInformation::DebuggerItem DebuggerKitInformation::debuggerItem(const ProjectExplorer::Kit *p)
{
- QTC_ASSERT(k, return);
- k->setValue(Core::Id(DEBUGGER_INFORMATION), command.toString());
+ return p ?
+ DebuggerKitInformation::variantToItem(p->value(Core::Id(DEBUGGER_INFORMATION))) :
+ DebuggerItem();
+}
+
+void DebuggerKitInformation::setDebuggerItem(ProjectExplorer::Kit *p, const DebuggerItem &item)
+{
+ QTC_ASSERT(p, return);
+ p->setValue(Core::Id(DEBUGGER_INFORMATION), itemToVariant(item));
+}
+
+void DebuggerKitInformation::setDebuggerCommand(ProjectExplorer::Kit *k, const FileName &command)
+{
+ setDebuggerItem(k, DebuggerItem(engineType(k), command));
+}
+
+void DebuggerKitInformation::setEngineType(ProjectExplorer::Kit *p, DebuggerEngineType type)
+{
+ setDebuggerItem(p, DebuggerItem(type, debuggerCommand(p)));
+}
+
+QString DebuggerKitInformation::debuggerEngineName(DebuggerEngineType t)
+{
+ switch (t) {
+ case Debugger::GdbEngineType:
+ return tr("GDB Engine");
+ case Debugger::CdbEngineType:
+ return tr("CDB Engine");
+ case Debugger::LldbEngineType:
+ return tr("LLDB Engine");
+ default:
+ break;
+ }
+ return QString();
}
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerkitinformation.h b/src/plugins/debugger/debuggerkitinformation.h
index e6d9dab6c8..ceb119d08d 100644
--- a/src/plugins/debugger/debuggerkitinformation.h
+++ b/src/plugins/debugger/debuggerkitinformation.h
@@ -32,6 +32,7 @@
#define DEBUGGER_DEBUGGERKITINFORMATION_H
#include "debugger_global.h"
+#include "debuggerconstants.h"
#include <projectexplorer/kitinformation.h>
@@ -42,22 +43,54 @@ class DEBUGGER_EXPORT DebuggerKitInformation : public ProjectExplorer::KitInform
Q_OBJECT
public:
+ class DEBUGGER_EXPORT DebuggerItem {
+ public:
+ DebuggerItem();
+ DebuggerItem(DebuggerEngineType engineType, const Utils::FileName &fn);
+
+ DebuggerEngineType engineType;
+ Utils::FileName binary;
+ };
+
DebuggerKitInformation();
Core::Id dataId() const;
unsigned int priority() const; // the higher the closer to the top.
- QVariant defaultValue(ProjectExplorer::Kit *k) const;
+ static DebuggerItem autoDetectItem(const ProjectExplorer::Kit *k);
+ QVariant defaultValue(ProjectExplorer::Kit *k) const
+ { return DebuggerKitInformation::itemToVariant(DebuggerKitInformation::autoDetectItem(k)); }
+
+ QList<ProjectExplorer::Task> validate(ProjectExplorer::Kit *k) const
+ { return DebuggerKitInformation::validateDebugger(k); }
- QList<ProjectExplorer::Task> validate(ProjectExplorer::Kit *k) const;
+ static QList<ProjectExplorer::Task> validateDebugger(const ProjectExplorer::Kit *p);
+ static bool isValidDebugger(const ProjectExplorer::Kit *p);
ProjectExplorer::KitConfigWidget *createConfigWidget(ProjectExplorer::Kit *k) const;
ItemList toUserOutput(ProjectExplorer::Kit *k) const;
+ static QString userOutput(const ProjectExplorer::Kit *k);
+
+ static DebuggerItem debuggerItem(const ProjectExplorer::Kit *p);
+ static void setDebuggerItem(ProjectExplorer::Kit *p, const DebuggerItem &item);
+
+ static Utils::FileName debuggerCommand(const ProjectExplorer::Kit *p)
+ { return debuggerItem(p).binary; }
+
+ static void setDebuggerCommand(ProjectExplorer::Kit *p, const Utils::FileName &command);
+
+ static DebuggerEngineType engineType(const ProjectExplorer::Kit *p)
+ { return debuggerItem(p).engineType; }
+
+ static void setEngineType(ProjectExplorer::Kit *p, DebuggerEngineType type);
+
+ static QString debuggerEngineName(DebuggerEngineType t);
- static Utils::FileName debuggerCommand(const ProjectExplorer::Kit *k);
- static void setDebuggerCommand(ProjectExplorer::Kit *k, const Utils::FileName &command);
+private:
+ static DebuggerItem variantToItem(const QVariant &v);
+ static QVariant itemToVariant(const DebuggerItem &i);
};
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 27ece76ae1..0df27ac819 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -567,8 +567,10 @@ public:
explicit AbiKitMatcher(const QList<Abi> &abis) : m_abis(abis) {}
bool matches(const Kit *p) const
{
- if (const ToolChain *tc = ToolChainKitInformation::toolChain(p))
- return m_abis.contains(tc->targetAbi());
+ if (const ToolChain *tc = ToolChainKitInformation::toolChain(p)) {
+ return m_abis.contains(tc->targetAbi())
+ && DebuggerKitInformation::isValidDebugger(p);
+ }
return false;
}
@@ -584,7 +586,7 @@ public:
{
if (const ToolChain *tc = ToolChainKitInformation::toolChain(p))
foreach (const Abi &a, m_abis)
- if (a.isCompatibleWith(tc->targetAbi()))
+ if (a.isCompatibleWith(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(p))
return true;
return false;
}
@@ -600,18 +602,14 @@ public:
bool matches(const Kit *k) const
{
- const ToolChain *tc = ToolChainKitInformation::toolChain(k);
- QTC_ASSERT(tc, return false);
- const Abi abi = tc->targetAbi();
- if (abi.architecture() != Abi::X86Architecture
- || abi.os() != Abi::WindowsOS
- || abi.binaryFormat() != Abi::PEFormat)
- return false;
- if (abi.osFlavor() == Abi::WindowsMSysFlavor
- || abi.osFlavor() == Abi::WindowsCEFlavor)
- return false;
- if (m_wordWidth && abi.wordWidth() != m_wordWidth)
+ if (DebuggerKitInformation::engineType(k) != CdbEngineType
+ || !DebuggerKitInformation::isValidDebugger(k)) {
return false;
+ }
+ if (m_wordWidth) {
+ const ToolChain *tc = ToolChainKitInformation::toolChain(k);
+ return tc && m_wordWidth == tc->targetAbi().wordWidth();
+ }
return true;
}
@@ -634,7 +632,7 @@ private:
const char m_wordWidth;
};
-void fillParameters(DebuggerStartParameters *sp, const Kit *kit /* = 0 */)
+bool fillParameters(DebuggerStartParameters *sp, const Kit *kit /* = 0 */, QString *errorMessage /* = 0 */)
{
if (!kit) {
// This code can only be reached when starting via the command line
@@ -664,6 +662,27 @@ void fillParameters(DebuggerStartParameters *sp, const Kit *kit /* = 0 */)
kit = KitManager::instance()->defaultKit();
}
+ // Verify that debugger and profile are valid
+ if (!kit) {
+ sp->startMode = NoStartMode;
+ if (errorMessage)
+ *errorMessage = DebuggerKitInformation::tr("No kit found.");
+ return false;
+ }
+ const QList<ProjectExplorer::Task> tasks = DebuggerKitInformation::validateDebugger(kit);
+ if (!tasks.isEmpty()) {
+ sp->startMode = NoStartMode;
+ if (errorMessage) {
+ foreach (const ProjectExplorer::Task &t, tasks) {
+ if (errorMessage->isEmpty())
+ errorMessage->append(QLatin1Char('\n'));
+ errorMessage->append(t.description);
+ }
+ }
+ return false;
+ }
+
+ sp->cppEngineType = DebuggerKitInformation::engineType(kit);
sp->sysRoot = SysRootKitInformation::sysRoot(kit).toString();
sp->debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
@@ -676,6 +695,7 @@ void fillParameters(DebuggerStartParameters *sp, const Kit *kit /* = 0 */)
sp->connParams = device->sshParameters();
sp->remoteChannel = sp->connParams.host + QLatin1Char(':') + QString::number(sp->connParams.port);
}
+ return true;
}
static TextEditor::ITextEditor *currentTextEditor()
@@ -1438,7 +1458,8 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
}
}
}
- fillParameters(&sp, kit);
+ if (fillParameters(&sp, kit, errorMessage))
+ return false;
if (sp.startMode == StartExternal) {
sp.displayName = tr("Executable file \"%1\"").arg(sp.executable);
sp.startMessage = tr("Debugging file %1.").arg(sp.executable);
@@ -1458,7 +1479,8 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
return false;
}
DebuggerStartParameters sp;
- fillParameters(&sp, CdbMatcher::findUniversalCdbKit());
+ if (!fillParameters(&sp, CdbMatcher::findUniversalCdbKit(), errorMessage))
+ return false;
sp.startMode = AttachCrashedExternal;
sp.crashParameter = it->section(QLatin1Char(':'), 0, 0);
sp.attachPID = it->section(QLatin1Char(':'), 1, 1).toULongLong();
@@ -1596,7 +1618,7 @@ void DebuggerPluginPrivate::attachCore()
DebuggerStartParameters sp;
QString display = dlg.isLocal() ? dlg.localCoreFile() : dlg.remoteCoreFile();
- fillParameters(&sp, dlg.kit());
+ QTC_ASSERT(fillParameters(&sp, dlg.kit()), return);
sp.masterEngineType = GdbEngineType;
sp.executable = dlg.localExecutableFile();
sp.coreFile = dlg.localCoreFile();
@@ -1612,8 +1634,7 @@ void DebuggerPluginPrivate::startRemoteCdbSession()
const QString connectionKey = _("CdbRemoteConnection");
DebuggerStartParameters sp;
Kit *kit = CdbMatcher::findUniversalCdbKit();
- QTC_ASSERT(kit, return);
- fillParameters(&sp, kit);
+ QTC_ASSERT(kit && fillParameters(&sp, kit), return);
sp.startMode = AttachToRemoteServer;
sp.closeMode = KillAtClose;
StartRemoteCdbDialog dlg(mainWindow());
@@ -1683,7 +1704,7 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
if (device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
DebuggerStartParameters sp;
- fillParameters(&sp, kit);
+ QTC_ASSERT(fillParameters(&sp, kit), return);
sp.attachPID = process.pid;
sp.displayName = tr("Process %1").arg(process.pid);
sp.executable = process.exe;
@@ -1708,7 +1729,7 @@ void DebuggerPluginPrivate::attachExternalApplication(ProjectExplorer::RunContro
if (const RunConfiguration *runConfiguration = rc->runConfiguration())
if (const Target *target = runConfiguration->target())
kit = target->kit();
- fillParameters(&sp, kit);
+ QTC_ASSERT(fillParameters(&sp, kit), return);
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
@@ -1731,11 +1752,10 @@ void DebuggerPluginPrivate::attachToQmlPort()
return;
Kit *kit = dlg.kit();
- QTC_ASSERT(kit, return);
+ QTC_ASSERT(kit && fillParameters(&sp, kit), return);
setConfigValue(_("LastQmlServerPort"), dlg.port());
setConfigValue(_("LastProfile"), kit->id().toString());
- fillParameters(&sp, kit);
sp.qmlServerAddress = sp.connParams.host;
sp.qmlServerPort = dlg.port();
sp.startMode = AttachToRemoteProcess;
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index 476d23e3ac..e0ddc0122a 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -259,11 +259,6 @@ public:
explicit DebuggerRunControlPrivate(DebuggerRunControl *parent,
RunConfiguration *runConfiguration);
- DebuggerEngineType engineForExecutable(unsigned enabledEngineTypes,
- const QString &executable);
- DebuggerEngineType engineForMode(unsigned enabledEngineTypes,
- DebuggerStartMode mode);
-
public:
DebuggerRunControl *q;
DebuggerEngine *m_engine;
@@ -476,7 +471,7 @@ QString DebuggerRunControlFactory::displayName() const
return DebuggerPlugin::tr("Debug");
}
-static DebuggerStartParameters localStartParameters(RunConfiguration *runConfiguration)
+static DebuggerStartParameters localStartParameters(RunConfiguration *runConfiguration, QString *errorMessage)
{
DebuggerStartParameters sp;
QTC_ASSERT(runConfiguration, return sp);
@@ -486,7 +481,8 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu
Target *target = runConfiguration->target();
Kit *kit = target ? target->kit() : KitManager::instance()->defaultKit();
- fillParameters(&sp, kit);
+ if (!fillParameters(&sp, kit, errorMessage))
+ return sp;
sp.environment = rc->environment();
sp.workingDirectory = rc->workingDirectory();
@@ -547,7 +543,7 @@ RunControl *DebuggerRunControlFactory::create
{
Q_UNUSED(errorMessage)
QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0);
- DebuggerStartParameters sp = localStartParameters(runConfiguration);
+ DebuggerStartParameters sp = localStartParameters(runConfiguration, errorMessage);
if (sp.startMode == NoStartMode)
return 0;
if (mode == DebugRunModeWithBreakOnMain)
@@ -556,92 +552,43 @@ RunControl *DebuggerRunControlFactory::create
return doCreate(sp, runConfiguration, errorMessage);
}
-static DebuggerEngineType guessUnixCppEngineType(const DebuggerStartParameters &sp)
-{
- if (sp.debuggerCommand.contains(QLatin1String("lldb")))
- return LldbEngineType;
- return GdbEngineType;
-}
-
-static DebuggerEngineType guessCppEngineTypeForAbi(const DebuggerStartParameters &sp, const Abi &abi)
-{
- switch (abi.binaryFormat()) {
- case Abi::ElfFormat:
- case Abi::MachOFormat:
- return guessUnixCppEngineType(sp) ;
- case Abi::PEFormat:
- if (abi.osFlavor() == Abi::WindowsMSysFlavor)
- return guessUnixCppEngineType(sp);
- return CdbEngineType;
- default:
- break;
- }
- return NoEngineType;
-}
-
-static DebuggerEngineType guessCppEngineType(const DebuggerStartParameters &sp)
-{
- if (sp.toolChainAbi.isValid()) {
- const DebuggerEngineType et = guessCppEngineTypeForAbi(sp, sp.toolChainAbi);
- if (et != NoEngineType)
- return et;
- }
-
- #ifdef Q_OS_WIN
- // If a file has PDB files, it has been compiled by VS.
- if (sp.executable.endsWith(_(".exe"), Qt::CaseInsensitive)) {
- QStringList pdbFiles;
- QString errorMessage;
- if (getPDBFiles(sp.executable, &pdbFiles, &errorMessage) && !pdbFiles.isEmpty())
- return CdbEngineType;
- }
- #endif
-
- QList<Abi> abis = Abi::abisOfBinary(FileName::fromString(sp.executable));
- foreach (const Abi &abi, abis) {
- DebuggerEngineType et = guessCppEngineTypeForAbi(sp, abi);
- if (et != NoEngineType)
- return et;
- }
-
- return guessUnixCppEngineType(sp);
-}
-
-static void fixupEngineTypes(DebuggerStartParameters &sp, RunConfiguration *rc)
+static bool fixupEngineTypes(DebuggerStartParameters &sp, RunConfiguration *rc, QString *errorMessage)
{
if (sp.masterEngineType != NoEngineType)
- return;
+ return true;
if (sp.executable.endsWith(_(".js"))) {
sp.masterEngineType = ScriptEngineType;
- return;
+ return true;
}
if (sp.executable.endsWith(_(".py"))) {
sp.masterEngineType = PdbEngineType;
- return;
+ return true;
}
if (rc) {
DebuggerRunConfigurationAspect *aspect = rc->debuggerAspect();
if (const Target *target = rc->target())
- fillParameters(&sp, target->kit());
+ if (!fillParameters(&sp, target->kit(), errorMessage))
+ return false;
const bool useCppDebugger = aspect->useCppDebugger();
const bool useQmlDebugger = aspect->useQmlDebugger();
if (useQmlDebugger) {
if (useCppDebugger) {
sp.masterEngineType = QmlCppEngineType;
- sp.firstSlaveEngineType = guessCppEngineType(sp);
+ sp.firstSlaveEngineType = sp.cppEngineType;
sp.secondSlaveEngineType = QmlCppEngineType;
} else {
sp.masterEngineType = QmlEngineType;
}
} else {
- sp.masterEngineType = guessCppEngineType(sp);
+ sp.masterEngineType = sp.cppEngineType;
}
- return;
+ return true;
}
- sp.masterEngineType = guessCppEngineType(sp);
+ sp.masterEngineType = sp.cppEngineType;
+ return true;
}
DebuggerRunControl *DebuggerRunControlFactory::doCreate
@@ -664,10 +611,8 @@ DebuggerRunControl *DebuggerRunControlFactory::doCreate
}
}
- fixupEngineTypes(sp, rc);
- if (!sp.masterEngineType) {
+ if (!fixupEngineTypes(sp, rc, errorMessage))
return 0;
- }
return new DebuggerRunControl(rc, sp);
}
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index 09e0a4f554..3db9f9b218 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -60,6 +60,7 @@ public:
: masterEngineType(NoEngineType),
firstSlaveEngineType(NoEngineType),
secondSlaveEngineType(NoEngineType),
+ cppEngineType(NoEngineType),
isSnapshot(false),
attachPID(-1),
useTerminal(false),
@@ -81,6 +82,7 @@ public:
DebuggerEngineType masterEngineType;
DebuggerEngineType firstSlaveEngineType;
DebuggerEngineType secondSlaveEngineType;
+ DebuggerEngineType cppEngineType;
QString sysRoot;
QString debuggerCommand;
ProjectExplorer::Abi toolChainAbi;
@@ -140,7 +142,7 @@ public:
namespace Internal {
-void fillParameters(DebuggerStartParameters *sp, const ProjectExplorer::Kit *kit = 0);
+bool fillParameters(DebuggerStartParameters *sp, const ProjectExplorer::Kit *kit = 0, QString *errorMessage = 0);
} // namespace Internal
} // namespace Debugger
diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.cpp b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
index 20a08293ce..e32b49282a 100644
--- a/src/plugins/debugger/gdb/startgdbserverdialog.cpp
+++ b/src/plugins/debugger/gdb/startgdbserverdialog.cpp
@@ -207,7 +207,7 @@ void GdbServerStarter::attach(int port)
}
DebuggerStartParameters sp;
- fillParameters(&sp, d->kit);
+ QTC_ASSERT(fillParameters(&sp, d->kit), return);
sp.masterEngineType = GdbEngineType;
sp.connParams.port = port;
sp.displayName = tr("Remote: \"%1:%2\"").arg(sp.connParams.host).arg(port);
diff --git a/src/plugins/debugger/lldb/lldbenginehost.cpp b/src/plugins/debugger/lldb/lldbenginehost.cpp
index 810ab62de8..486020c66f 100644
--- a/src/plugins/debugger/lldb/lldbenginehost.cpp
+++ b/src/plugins/debugger/lldb/lldbenginehost.cpp
@@ -140,6 +140,7 @@ LldbEngineHost::LldbEngineHost(const DebuggerStartParameters &startParameters)
:IPCEngineHost(startParameters), m_ssh(0)
{
showMessage(QLatin1String("setting up coms"));
+ setObjectName(QLatin1String("LLDBEngine"));
if (startParameters.startMode == StartRemoteEngine)
{