Commit 081fb1f0 authored by hjk's avatar hjk

debugger: simplify parameter guessing

With profiles we have more reliable information, no need for some
of the guessing anymore.

Change-Id: I1818fbb112d44c99ef96c8643256432805a1b97b
Reviewed-by: default avatarJoerg Bornemann <joerg.bornemann@nokia.com>
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 4b55ea13
......@@ -367,48 +367,48 @@ static inline bool isMsvcFlavor(Abi::OSFlavor osf)
|| osf == Abi::WindowsMsvc2012Flavor;
}
bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check)
{
#ifdef Q_OS_WIN
const Abi abi = sp.toolChainAbi;
if (!isCdbEngineEnabled()) {
check->errorDetails.push_back(CdbEngine::tr("The CDB debug engine required for %1 is currently disabled.").
arg(abi.toString()));
check->settingsCategory = QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
check->settingsPage = CdbOptionsPage::settingsId();
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;
}
if (abi.binaryFormat() != Abi::PEFormat || abi.os() != Abi::WindowsOS) {
check->errorDetails.push_back(CdbEngine::tr("The CDB debug engine does not support the %1 ABI.").
arg(abi.toString()));
return false;
}
if (sp.startMode == AttachCore && !isMsvcFlavor(abi.osFlavor())) {
check->errorDetails.push_back(CdbEngine::tr("The CDB debug engine cannot debug gdb core files."));
return false;
}
if (sp.debuggerCommand.isEmpty()) {
check->errorDetails.push_back(msgNoCdbBinaryForToolChain(abi));
check->settingsCategory = QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
check->settingsPage = QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
return false;
}
return true;
#else
Q_UNUSED(sp);
check->errorDetails.push_back(QString::fromLatin1("Unsupported debug mode"));
return false;
#endif
}
//bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check)
//{
//#ifdef Q_OS_WIN
// const Abi abi = sp.toolChainAbi;
// if (!isCdbEngineEnabled()) {
// check->errorDetails.push_back(CdbEngine::tr("The CDB debug engine required for %1 is currently disabled.").
// arg(abi.toString()));
// check->settingsCategory = QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
// check->settingsPage = CdbOptionsPage::settingsId();
// 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;
// }
// if (abi.binaryFormat() != Abi::PEFormat || abi.os() != Abi::WindowsOS) {
// check->errorDetails.push_back(CdbEngine::tr("The CDB debug engine does not support the %1 ABI.").
// arg(abi.toString()));
// return false;
// }
// if (sp.startMode == AttachCore && !isMsvcFlavor(abi.osFlavor())) {
// check->errorDetails.push_back(CdbEngine::tr("The CDB debug engine cannot debug gdb core files."));
// return false;
// }
// if (sp.debuggerCommand.isEmpty()) {
// check->errorDetails.push_back(msgNoCdbBinaryForToolChain(abi));
// check->settingsCategory = QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
// check->settingsPage = QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY);
// return false;
// }
// return true;
//#else
// Q_UNUSED(sp);
// check->errorDetails.push_back(QString::fromLatin1("Unsupported debug mode"));
// return false;
//#endif
//}
void addCdbOptionPages(QList<Core::IOptionsPage *> *opts)
{
......
......@@ -815,9 +815,7 @@ public slots:
void setConfigValue(const QString &name, const QVariant &value);
QVariant configValue(const QString &name) const;
DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp,
RunConfiguration *rc = 0);
void startDebugger(RunControl *runControl);
//void startDebugger(RunControl *runControl);
void displayDebugger(DebuggerEngine *engine, bool updateEngine = true);
void dumpLog();
......@@ -1093,9 +1091,6 @@ public slots:
DebuggerToolTipManager *toolTipManager() const { return m_toolTipManager; }
QSharedPointer<GlobalDebuggerOptions> globalDebuggerOptions() const { return m_globalDebuggerOptions; }
// FIXME: Remove.
void maybeEnrichParameters(DebuggerStartParameters *sp);
void updateQmlActions() {
action(QmlUpdateOnSave)->setEnabled(boolSetting(ShowQmlObjectTree));
}
......@@ -1272,24 +1267,6 @@ static QString msgParameterMissing(const QString &a)
return DebuggerPlugin::tr("Option '%1' is missing the parameter.").arg(a);
}
void DebuggerPluginPrivate::maybeEnrichParameters(DebuggerStartParameters *sp)
{
if (!boolSetting(AutoEnrichParameters))
return;
const QString sysroot = sp->sysRoot;
if (sp->debugInfoLocation.isEmpty()) {
sp->debugInfoLocation = sysroot + QLatin1String("/usr/lib/debug");
}
if (sp->debugSourceLocation.isEmpty()) {
QString base = sysroot + QLatin1String("/usr/src/debug/");
sp->debugSourceLocation.append(base + QLatin1String("qt5base/src/corelib"));
sp->debugSourceLocation.append(base + QLatin1String("qt5base/src/gui"));
sp->debugSourceLocation.append(base + QLatin1String("qt5base/src/network"));
sp->debugSourceLocation.append(base + QLatin1String("qt5base/src/v8"));
sp->debugSourceLocation.append(base + QLatin1String("qt5declarative/src/qml"));
}
}
bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
const QStringList::const_iterator &cend, QString *errorMessage)
{
......@@ -1477,10 +1454,8 @@ void DebuggerPluginPrivate::debugProjectBreakMain()
void DebuggerPluginPrivate::startAndDebugApplication()
{
DebuggerStartParameters sp;
if (StartApplicationDialog::run(mainWindow(), m_coreSettings, &sp)) {
if (RunControl *rc = createDebugger(sp))
startDebugger(rc);
}
if (StartApplicationDialog::run(mainWindow(), m_coreSettings, &sp))
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
void DebuggerPluginPrivate::attachCore()
......@@ -1505,14 +1480,14 @@ void DebuggerPluginPrivate::attachCore()
DebuggerStartParameters sp;
QString display = dlg.isLocal() ? dlg.localCoreFile() : dlg.remoteCoreFile();
fillParameters(&sp, dlg.profileId());
sp.masterEngineType = GdbEngineType;
sp.executable = dlg.localExecutableFile();
sp.coreFile = dlg.localCoreFile();
sp.displayName = tr("Core file \"%1\"").arg(display);
sp.startMode = AttachCore;
sp.closeMode = DetachAtClose;
sp.overrideStartScript = dlg.overrideStartScript();
if (DebuggerRunControl *rc = createDebugger(sp))
startDebugger(rc);
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
struct RemoteCdbMatcher : ProfileMatcher
......@@ -1557,8 +1532,7 @@ void DebuggerPluginPrivate::startRemoteCdbSession()
return;
sp.remoteChannel = dlg.connection();
setConfigValue(connectionKey, sp.remoteChannel);
if (RunControl *rc = createDebugger(sp))
startDebugger(rc);
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
void DebuggerPluginPrivate::attachToRemoteServer()
......@@ -1568,8 +1542,7 @@ void DebuggerPluginPrivate::attachToRemoteServer()
if (StartApplicationDialog::run(mainWindow(), m_coreSettings, &sp)) {
sp.closeMode = KillAtClose;
sp.serverStartScript.clear();
if (RunControl *rc = createDebugger(sp))
startDebugger(rc);
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
}
......@@ -1629,8 +1602,7 @@ void DebuggerPluginPrivate::attachToProcess(bool startServerOnly)
sp.executable = process.exe;
sp.startMode = AttachExternal;
sp.closeMode = DetachAtClose;
if (DebuggerRunControl *rc = createDebugger(sp))
startDebugger(rc);
DebuggerRunControlFactory::createAndScheduleRun(sp);
} else {
GdbServerStarter *starter = new GdbServerStarter(dlg, startServerOnly);
starter->run();
......@@ -1690,9 +1662,7 @@ void DebuggerPluginPrivate::attachToQmlPort()
sourceFiles << project->files(Project::ExcludeGeneratedFiles);
sp.projectSourceFiles = sourceFiles;
if (RunControl *rc = createDebugger(sp))
startDebugger(rc);
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
void DebuggerPluginPrivate::startRemoteEngine()
......@@ -1714,8 +1684,7 @@ void DebuggerPluginPrivate::startRemoteEngine()
sp.executable = dlg.inferiorPath();
sp.serverStartScript = dlg.enginePath();
sp.startMode = StartRemoteEngine;
if (RunControl *rc = createDebugger(sp))
startDebugger(rc);
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value)
......@@ -1728,12 +1697,8 @@ void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &valu
void DebuggerPluginPrivate::runScheduled()
{
foreach (const DebuggerStartParameters &sp, m_scheduledStarts) {
RunControl *rc = createDebugger(sp);
QTC_ASSERT(rc, qDebug() << "CANNOT CREATE RUN CONTROL"; continue);
showStatusMessage(sp.startMessage);
startDebugger(rc);
}
foreach (const DebuggerStartParameters &sp, m_scheduledStarts)
DebuggerRunControlFactory::createAndScheduleRun(sp);
}
void DebuggerPluginPrivate::editorOpened(IEditor *editor)
......@@ -1949,14 +1914,6 @@ void DebuggerPluginPrivate::requestMark(ITextEditor *editor,
}
}
DebuggerRunControl *DebuggerPluginPrivate::createDebugger
(const DebuggerStartParameters &sp0, RunConfiguration *rc)
{
DebuggerStartParameters sp = sp0;
maybeEnrichParameters(&sp);
return m_debuggerRunControlFactory->create(sp, rc);
}
// If updateEngine is set, the engine will update its threads/modules and so forth.
void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateEngine)
{
......@@ -1968,12 +1925,11 @@ void DebuggerPluginPrivate::displayDebugger(DebuggerEngine *engine, bool updateE
engine->updateViews();
}
void DebuggerPluginPrivate::startDebugger(RunControl *rc)
{
QTC_ASSERT(rc, return);
ProjectExplorerPlugin::instance()->startRunControl(rc, DebugRunMode);
}
//void DebuggerPluginPrivate::startDebugger(RunControl *rc)
//{
// QTC_ASSERT(rc, return);
// ProjectExplorerPlugin::instance()->startRunControl(rc, DebugRunMode);
//}
void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
{
......@@ -3362,15 +3318,15 @@ void DebuggerPlugin::remoteCommand(const QStringList &options,
theDebuggerCore->remoteCommand(options, list);
}
//void DebuggerPlugin::startDebugger(RunControl *runControl)
//{
// theDebuggerCore->startDebugger(runControl);
//}
DebuggerRunControl *DebuggerPlugin::createDebugger
(const DebuggerStartParameters &sp, RunConfiguration *rc)
{
return theDebuggerCore->createDebugger(sp, rc);
}
void DebuggerPlugin::startDebugger(RunControl *runControl)
{
theDebuggerCore->startDebugger(runControl);
return DebuggerRunControlFactory::doCreate(sp, rc);
}
void DebuggerPlugin::extensionsInitialized()
......@@ -3460,10 +3416,8 @@ static LocalApplicationRunConfiguration *activeLocalRunConfiguration()
void DebuggerPluginPrivate::testRunProject(const DebuggerStartParameters &sp, const TestCallBack &cb)
{
m_testCallbacks.append(cb);
RunControl *rctl = createDebugger(sp);
QVERIFY(rctl);
connect(rctl, SIGNAL(finished()), this, SLOT(testRunControlFinished()));
ProjectExplorerPlugin::instance()->startRunControl(rctl, DebugRunMode);
RunControl *rc = DebuggerRunControlFactory::createAndScheduleRun(sp);
connect(rc, SIGNAL(finished()), this, SLOT(testRunControlFinished()));
}
void DebuggerPluginPrivate::testRunControlFinished()
......
......@@ -58,15 +58,16 @@ public:
~DebuggerPlugin();
// Used by Maemo debugging support.
static DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *rc = 0);
static void startDebugger(ProjectExplorer::RunControl *runControl);
//static void startDebugger(ProjectExplorer::RunControl *runControl);
// Used by QmlJSInspector.
static bool isActiveDebugLanguage(int language);
static DebuggerMainWindow *mainWindow();
static QAction *visibleDebugAction();
static DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *rc);
private:
// IPlugin implementation.
bool initialize(const QStringList &arguments, QString *errorMessage);
......
......@@ -34,7 +34,11 @@
#include <projectexplorer/runconfiguration.h>
namespace Debugger {
class DebuggerEngine;
class DebuggerRunControl;
class DebuggerStartParameters;
namespace Internal {
class DebuggerRunControlFactory
......@@ -43,27 +47,30 @@ class DebuggerRunControlFactory
public:
explicit DebuggerRunControlFactory(QObject *parent);
// This is used by the "Non-Standard" scenarios, e.g. Attach to Core.
// FIXME: What to do in case of a 0 runConfiguration?
typedef ProjectExplorer::RunConfiguration RunConfiguration;
typedef ProjectExplorer::RunControl RunControl;
typedef ProjectExplorer::RunMode RunMode;
DebuggerRunControl *create(const DebuggerStartParameters &sp,
RunConfiguration *runConfiguration = 0);
// ProjectExplorer::IRunControlFactory
// FIXME: Used by qmljsinspector.cpp:469
RunControl *create(RunConfiguration *runConfiguration, RunMode mode);
bool canRun(RunConfiguration *runConfiguration, RunMode mode) const;
ProjectExplorer::RunControl *create(
ProjectExplorer::RunConfiguration *runConfiguration,
ProjectExplorer::RunMode mode);
bool canRun(ProjectExplorer::RunConfiguration *runConfiguration,
ProjectExplorer::RunMode mode) const;
static DebuggerEngine *createEngine(DebuggerEngineType et,
const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine,
QString *errorMessage);
const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine,
QString *errorMessage);
static DebuggerRunControl *createAndScheduleRun(
const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *runConfiguration = 0);
static DebuggerRunControl *doCreate(const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *rc);
private:
QString displayName() const;
ProjectExplorer::RunConfigWidget *createConfigurationWidget(RunConfiguration *runConfiguration);
ProjectExplorer::RunConfigWidget *createConfigurationWidget(
ProjectExplorer::RunConfiguration *runConfiguration);
};
} // namespace Internal
......
......@@ -50,12 +50,12 @@
#endif
#include <projectexplorer/abi.h>
#include <projectexplorer/applicationrunconfiguration.h> // For LocalApplication*
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/applicationrunconfiguration.h> // For LocalApplication*
#include <utils/outputformat.h>
#include <utils/synchronousprocess.h>
......@@ -84,11 +84,11 @@ namespace Debugger {
namespace Internal {
bool isCdbEngineEnabled(); // Check the configuration page
bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check);
//bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check);
DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine, QString *error);
bool checkGdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check);
//bool checkGdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check);
DebuggerEngine *createGdbEngine(const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine);
......@@ -97,8 +97,7 @@ DebuggerEngine *createPdbEngine(const DebuggerStartParameters &sp);
QmlEngine *createQmlEngine(const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine);
DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp,
DebuggerEngineType slaveEngineType,
QString *errorMessage);
QString *errorMessage);
DebuggerEngine *createLldbEngine(const DebuggerStartParameters &sp);
extern QString msgNoBinaryForToolChain(const Abi &abi);
......@@ -319,8 +318,7 @@ DebuggerRunControlPrivate::DebuggerRunControlPrivate(DebuggerRunControl *parent,
} // namespace Internal
DebuggerRunControl::DebuggerRunControl(RunConfiguration *runConfiguration,
const DebuggerStartParameters &sp,
const QPair<DebuggerEngineType, DebuggerEngineType> &masterSlaveEngineTypes)
const DebuggerStartParameters &sp)
: RunControl(runConfiguration, DebugRunMode),
d(new DebuggerRunControlPrivate(this, runConfiguration))
{
......@@ -328,10 +326,8 @@ DebuggerRunControl::DebuggerRunControl(RunConfiguration *runConfiguration,
// Create the engine. Could arguably be moved to the factory, but
// we still have a derived S60DebugControl. Should rarely fail, though.
QString errorMessage;
d->m_engine = masterSlaveEngineTypes.first == QmlCppEngineType ?
createQmlCppEngine(sp, masterSlaveEngineTypes.second, &errorMessage) :
DebuggerRunControlFactory::createEngine(masterSlaveEngineTypes.first, sp,
0, &errorMessage);
d->m_engine = DebuggerRunControlFactory::createEngine(sp.masterEngineType, sp, 0, &errorMessage);
if (d->m_engine) {
DebuggerToolTipManager::instance()->registerEngine(d->m_engine);
} else {
......@@ -493,311 +489,6 @@ RunConfiguration *DebuggerRunControl::runConfiguration() const
return d->m_myRunConfiguration.data();
}
////////////////////////////////////////////////////////////////////////
//
// Engine detection logic: Detection functions depending on tool chain, binary,
// etc. Return a list of possible engines (order of prefererence) without
// consideration of configuration, etc.
//
////////////////////////////////////////////////////////////////////////
static QList<DebuggerEngineType> enginesForToolChain(const Abi &toolChain,
DebuggerLanguages languages)
{
QList<DebuggerEngineType> result;
switch (toolChain.binaryFormat()) {
case Abi::ElfFormat:
case Abi::MachOFormat:
result.push_back(LldbEngineType);
result.push_back(GdbEngineType);
if (languages & QmlLanguage)
result.push_back(QmlEngineType);
break;
case Abi::PEFormat:
if (toolChain.osFlavor() == Abi::WindowsMSysFlavor) {
result.push_back(GdbEngineType);
result.push_back(CdbEngineType);
} else {
result.push_back(CdbEngineType);
//result.push_back(GdbEngineType);
}
if (languages & QmlLanguage)
result.push_back(QmlEngineType);
break;
case Abi::RuntimeQmlFormat:
result.push_back(QmlEngineType);
break;
default:
break;
}
return result;
}
static inline QList<DebuggerEngineType> enginesForScriptExecutables(const QString &executable)
{
QList<DebuggerEngineType> result;
if (executable.endsWith(_(".js"))) {
result.push_back(ScriptEngineType);
} else if (executable.endsWith(_(".py"))) {
result.push_back(PdbEngineType);
}
return result;
}
static QList<DebuggerEngineType> enginesForExecutable(const QString &executable)
{
QList<DebuggerEngineType> result = enginesForScriptExecutables(executable);
if (!result.isEmpty())
return result;
#ifdef Q_OS_WIN
// A remote executable?
if (!executable.endsWith(_(".exe"), Qt::CaseInsensitive)) {
result.push_back(GdbEngineType);
return result;
}
// If a file has PDB files, it has been compiled by VS.
QStringList pdbFiles;
QString errorMessage;
if (getPDBFiles(executable, &pdbFiles, &errorMessage) && !pdbFiles.isEmpty()) {
result.push_back(CdbEngineType);
result.push_back(GdbEngineType);
return result;
}
// Fixme: Gdb should only be preferred if MinGW can positively be detected.
result.push_back(GdbEngineType);
result.push_back(CdbEngineType);
#else
result.push_back(LldbEngineType);
result.push_back(GdbEngineType);
#endif
return result;
}
// Debugger type for mode.
static QList<DebuggerEngineType> enginesForMode(DebuggerStartMode startMode,
DebuggerLanguages languages,
bool hardConstraintsOnly)
{
QList<DebuggerEngineType> result;
if (languages == QmlLanguage) {
QTC_ASSERT(startMode == StartInternal
|| startMode == AttachToRemoteServer
|| startMode == AttachToRemoteProcess,
qDebug() << "qml debugging not supported for mode"
<< startMode);
// Qml language only
result.push_back(QmlEngineType);
return result;
}
switch (startMode) {
case NoStartMode:
break;
case StartInternal:
case StartExternal:
case AttachExternal:
if (!hardConstraintsOnly) {
#ifdef Q_OS_WIN
result.push_back(CdbEngineType); // Preferably Windows debugger for attaching locally.
#endif
result.push_back(GdbEngineType);
if (languages & QmlLanguage)
result.push_back(QmlEngineType);
}
break;
case LoadRemoteCore:
result.push_back(GdbEngineType);
break;
case AttachCore:
#ifdef Q_OS_WIN
result.push_back(CdbEngineType);
#endif
result.push_back(GdbEngineType);
break;
case StartRemoteProcess:
case StartRemoteGdb:
result.push_back(GdbEngineType);
if (languages & QmlLanguage)
result.push_back(QmlEngineType);
break;
case AttachToRemoteProcess:
case AttachToRemoteServer:
if (!hardConstraintsOnly) {
#ifdef Q_OS_WIN
result.push_back(CdbEngineType);
#endif
result.push_back(GdbEngineType);
if (languages & QmlLanguage)
result.push_back(QmlEngineType);
}
break;
case AttachCrashedExternal:
result.push_back(CdbEngineType); // Only CDB can do this
break;
case StartRemoteEngine:
// FIXME: Unclear IPC override. Someone please have a better idea.
// For now thats the only supported IPC engine.
result.push_back(LldbEngineType);
break;
}
return result;
}
// Engine detection logic: Call all detection functions in order.
static QList<DebuggerEngineType> engineTypes(const DebuggerStartParameters &sp)
{
// Script executables and certain start modes are 'hard constraints'.
QList<DebuggerEngineType> result = enginesForScriptExecutables(sp.executable);
if (!result.isEmpty())