Commit 1f6764a5 authored by hjk's avatar hjk

Debugger: Move run parameters from engine to tool runner

The parameters belong to the run control, they should not
be triplicated in case of a combined engine.

Change-Id: I4dd84220edbd7a44b902cc52627fe01d0568db75
Reviewed-by: Christian Stenger's avatarChristian Stenger <christian.stenger@qt.io>
parent c9cd6b12
......@@ -200,11 +200,11 @@ static inline bool validMode(DebuggerStartMode sm)
}
// Accessed by RunControlFactory
DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *errors)
DebuggerEngine *createCdbEngine(QStringList *errors, DebuggerStartMode sm)
{
if (HostOsInfo::isWindowsHost()) {
if (validMode(rp.startMode))
return new CdbEngine(rp);
if (validMode(sm))
return new CdbEngine();
errors->append(CdbEngine::tr("Internal error: Invalid start parameters passed for the CDB engine."));
} else {
errors->append(CdbEngine::tr("Unsupported CDB host system."));
......@@ -222,8 +222,7 @@ void addCdbOptionPages(QList<Core::IOptionsPage *> *opts)
#define QT_CREATOR_CDB_EXT "qtcreatorcdbext"
CdbEngine::CdbEngine(const DebuggerRunParameters &sp) :
DebuggerEngine(sp),
CdbEngine::CdbEngine() :
m_tokenPrefix("<token>"),
m_effectiveStartMode(NoStartMode),
m_accessible(false),
......
......@@ -56,7 +56,7 @@ public:
typedef QSharedPointer<CdbCommand> CdbCommandPtr;
typedef std::function<void(const DebuggerResponse &)> CommandHandler;
CdbEngine(const DebuggerRunParameters &sp);
explicit CdbEngine();
~CdbEngine() override;
// Factory function that returns 0 if the debug engine library cannot be found.
......
......@@ -47,6 +47,9 @@ namespace CPlusPlus { class Snapshot; }
namespace Utils { class SavedAction; }
namespace Debugger {
class DebuggerRunTool;
namespace Internal {
class BreakHandler;
......@@ -63,7 +66,7 @@ enum TestCases
};
// Some convenience.
void updateState(DebuggerEngine *engine);
void updateState(DebuggerRunTool *runTool);
void updateWatchersWindow(bool showWatch, bool showReturn);
const CPlusPlus::Snapshot &cppCodeModelSnapshot();
bool hasSnapshots();
......@@ -73,9 +76,9 @@ void openTextEditor(const QString &titlePattern, const QString &contents);
void showMessage(const QString &msg, int channel, int timeout = -1);
bool isReverseDebugging();
void runControlStarted(DebuggerEngine *engine);
void runControlFinished(DebuggerEngine *engine);
void displayDebugger(DebuggerEngine *engine, bool updateEngine);
void runControlStarted(DebuggerRunTool *runTool);
void runControlFinished(DebuggerRunTool *runTool);
void displayDebugger(DebuggerRunTool *runTool, bool updateEngine);
void synchronizeBreakpoints();
void saveModeToRestore();
......
......@@ -89,9 +89,6 @@ using namespace Utils;
#include <valgrind/callgrind.h>
#endif
// VariableManager Prefix
const char PrefixDebugExecutable[] = "DebuggedExecutable";
namespace Debugger {
QDebug operator<<(QDebug d, DebuggerState state)
......@@ -227,9 +224,8 @@ class DebuggerEnginePrivate : public QObject
Q_OBJECT
public:
DebuggerEnginePrivate(DebuggerEngine *engine, const DebuggerRunParameters &sp)
DebuggerEnginePrivate(DebuggerEngine *engine)
: m_engine(engine),
m_runParameters(sp),
m_modulesHandler(engine),
m_registerHandler(engine),
m_sourceFilesHandler(engine),
......@@ -243,10 +239,6 @@ public:
this, &DebuggerEnginePrivate::resetLocation);
connect(action(IntelFlavor), &Utils::SavedAction::valueChanged,
this, &DebuggerEnginePrivate::reloadDisassembly);
Utils::globalMacroExpander()->registerFileVariables(PrefixDebugExecutable,
tr("Debugged executable"),
[this] { return m_runParameters.inferior.executable; });
}
void doSetupEngine();
......@@ -350,8 +342,6 @@ public:
DebuggerEngine *m_masterEngine = nullptr; // Not owned
QPointer<DebuggerRunTool> m_runTool; // Not owned.
DebuggerRunParameters m_runParameters;
// The current state.
DebuggerState m_state = DebuggerNotReady;
......@@ -397,9 +387,10 @@ public:
//
//////////////////////////////////////////////////////////////////////
DebuggerEngine::DebuggerEngine(const DebuggerRunParameters &startParameters)
: d(new DebuggerEnginePrivate(this, startParameters))
{}
DebuggerEngine::DebuggerEngine()
: d(new DebuggerEnginePrivate(this))
{
}
DebuggerEngine::~DebuggerEngine()
{
......@@ -572,13 +563,13 @@ void DebuggerEngine::start()
fp->setKeepOnFinish(FutureProgress::HideOnFinish);
d->m_progress.reportStarted();
d->m_inferiorPid = d->m_runParameters.attachPID.isValid()
? d->m_runParameters.attachPID : ProcessHandle();
DebuggerRunParameters &rp = runParameters();
d->m_inferiorPid = rp.attachPID.isValid() ? rp.attachPID : ProcessHandle();
if (d->m_inferiorPid.isValid())
runControl()->setApplicationProcessHandle(d->m_inferiorPid);
if (isNativeMixedActive())
d->m_runParameters.inferior.environment.set("QV4_FORCE_INTERPRETER", "1");
rp.inferior.environment.set("QV4_FORCE_INTERPRETER", "1");
action(OperateByInstruction)->setEnabled(hasCapability(DisassemblerCapability));
......@@ -669,12 +660,12 @@ void DebuggerEngine::handleFinished()
const DebuggerRunParameters &DebuggerEngine::runParameters() const
{
return d->m_runParameters;
return runTool()->runParameters();
}
DebuggerRunParameters &DebuggerEngine::runParameters()
{
return d->m_runParameters;
return runTool()->runParameters();
}
DebuggerState DebuggerEngine::state() const
......@@ -774,7 +765,7 @@ void DebuggerEnginePrivate::doSetupEngine()
{
m_engine->showMessage("CALL: SETUP ENGINE");
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << m_engine << state());
m_engine->validateExecutable(&m_runParameters);
m_engine->validateExecutable();
m_engine->setupEngine();
}
......@@ -805,7 +796,6 @@ void DebuggerEngine::notifyEngineSetupOk()
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
setState(EngineSetupOk);
Internal::runControlStarted(this);
d->queueSetupInferior();
}
......@@ -838,7 +828,7 @@ void DebuggerEngine::notifyInferiorSetupOk()
#ifdef WITH_BENCHMARK
CALLGRIND_START_INSTRUMENTATION;
#endif
runTool()->aboutToNotifyInferiorSetupOk();
runTool()->aboutToNotifyInferiorSetupOk(); // FIXME: Remove, only used for Android.
showMessage("NOTE: INFERIOR SETUP OK");
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state());
setState(InferiorSetupOk);
......@@ -905,21 +895,22 @@ void DebuggerEngine::setRemoteParameters(const RemoteSetupResult &result)
showMessage(QString("NOTE: REMOTE SETUP DONE: GDB SERVER PORT: %1 QML PORT %2")
.arg(result.gdbServerPort.number()).arg(result.qmlServerPort.number()));
DebuggerRunParameters &rp = runParameters();
if (result.gdbServerPort.isValid()) {
QString &rc = d->m_runParameters.remoteChannel;
QString &rc = rp.remoteChannel;
const int sepIndex = rc.lastIndexOf(':');
if (sepIndex != -1) {
rc.replace(sepIndex + 1, rc.count() - sepIndex - 1,
QString::number(result.gdbServerPort.number()));
}
} else if (result.inferiorPid != InvalidPid && runParameters().startMode == AttachExternal) {
} else if (result.inferiorPid != InvalidPid && rp.startMode == AttachExternal) {
// e.g. iOS Simulator
runParameters().attachPID = ProcessHandle(result.inferiorPid);
rp.attachPID = ProcessHandle(result.inferiorPid);
}
if (result.qmlServerPort.isValid()) {
d->m_runParameters.qmlServer.port = result.qmlServerPort;
d->m_runParameters.inferior.commandLineArguments.replace("%qml_port%",
rp.qmlServer.port = result.qmlServerPort;
rp.inferior.commandLineArguments.replace("%qml_port%",
QString::number(result.qmlServerPort.number()));
}
}
......@@ -1298,7 +1289,8 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
}
if (state == InferiorUnrunnable || state == InferiorRunOk) {
if (isMasterEngine() && runTool())
// FIXME: Called again for combined engine.
if (isMasterEngine() && runTool() && !runTool()->runControl()->isRunning())
runTool()->reportStarted();
}
......@@ -1325,8 +1317,7 @@ void DebuggerEngine::updateViews()
{
// The slave engines are not entitled to change the view. Their wishes
// should be coordinated by their master engine.
if (isMasterEngine())
Internal::updateState(this);
Internal::updateState(runTool());
}
bool DebuggerEngine::isSlaveEngine() const
......@@ -1373,7 +1364,7 @@ void DebuggerEngine::removeBreakpointMarker(const Breakpoint &bp)
QString DebuggerEngine::expand(const QString &string) const
{
return d->m_runParameters.macroExpander->expand(string);
return runParameters().macroExpander->expand(string);
}
QString DebuggerEngine::nativeStartupCommands() const
......@@ -1456,10 +1447,9 @@ void DebuggerEngine::notifyInferiorPid(const ProcessHandle &pid)
if (pid.isValid()) {
runControl()->setApplicationProcessHandle(pid);
showMessage(tr("Taking notice of pid %1").arg(pid.pid()));
if (d->m_runParameters.startMode == StartInternal
|| d->m_runParameters.startMode == StartExternal
|| d->m_runParameters.startMode == AttachExternal)
QTimer::singleShot(0, d, &DebuggerEnginePrivate::raiseApplication);
DebuggerStartMode sm = runParameters().startMode;
if (sm == StartInternal || sm == StartExternal || sm == AttachExternal)
QTimer::singleShot(0, d, &DebuggerEnginePrivate::raiseApplication);
}
}
......@@ -1542,7 +1532,7 @@ RunControl *DebuggerEngine::runControl() const
DebuggerRunTool *DebuggerEngine::runTool() const
{
return d->m_masterEngine ? d->m_masterEngine->runTool() : d->m_runTool.data();
return d->m_runTool.data();
}
Terminal *DebuggerEngine::terminal() const
......@@ -1919,8 +1909,9 @@ void DebuggerEngine::setStateDebugging(bool on)
d->m_isStateDebugging = on;
}
void DebuggerEngine::validateExecutable(DebuggerRunParameters *sp)
void DebuggerEngine::validateExecutable()
{
DebuggerRunParameters *sp = &runParameters();
if (sp->skipExecutableValidation)
return;
if (sp->languages == QmlLanguage)
......
......@@ -194,7 +194,7 @@ class DebuggerEngine : public QObject
Q_OBJECT
public:
explicit DebuggerEngine(const DebuggerRunParameters &sp);
explicit DebuggerEngine();
virtual ~DebuggerEngine();
const DebuggerRunParameters &runParameters() const;
......@@ -320,12 +320,14 @@ public:
virtual void resetLocation();
virtual void gotoLocation(const Internal::Location &location);
Q_SLOT virtual void quitDebugger(); // called by DebuggerRunControl
virtual void exitDebugger(); // called by DebuggerRunControl
virtual void abortDebugger(); // called by DebuggerPlugin
virtual void updateViews();
void updateViews();
bool isSlaveEngine() const;
bool isMasterEngine() const;
DebuggerEngine *masterEngine() const;
virtual DebuggerEngine *activeEngine() { return this; }
virtual DebuggerEngine *cppEngine() { return 0; }
virtual bool canDisplayTooltip() const;
......@@ -398,7 +400,6 @@ protected:
virtual void resetInferior() {}
virtual void detachDebugger();
virtual void exitDebugger();
virtual void executeStep();
virtual void executeStepOut();
virtual void executeNext();
......@@ -436,7 +437,7 @@ protected:
bool isStateDebugging() const;
void setStateDebugging(bool on);
static void validateExecutable(DebuggerRunParameters *sp);
void validateExecutable();
virtual void setupSlaveInferior();
virtual void setupSlaveEngine();
......@@ -478,7 +479,6 @@ private:
QPointer<DebuggerEngine> m_engine;
};
DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QStringList *errors);
ProjectExplorer::RunControl *createAndScheduleRun(const DebuggerRunParameters &rp, ProjectExplorer::Kit *kit);
} // namespace Internal
......
This diff is collapsed.
......@@ -73,15 +73,15 @@ enum { debug = 0 };
namespace Debugger {
namespace Internal {
DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *error);
const auto DebugRunMode = ProjectExplorer::Constants::DEBUG_RUN_MODE;
const auto DebugRunModeWithBreakOnMain = ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN;
DebuggerEngine *createGdbEngine(const DebuggerRunParameters &rp);
DebuggerEngine *createPdbEngine(const DebuggerRunParameters &rp);
DebuggerEngine *createQmlEngine(const DebuggerRunParameters &rp);
DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &rp, QStringList *error);
DebuggerEngine *createLldbEngine(const DebuggerRunParameters &rp);
DebuggerEngine *createCdbEngine(QStringList *error, DebuggerStartMode sm);
DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode sm);
DebuggerEngine *createPdbEngine();
DebuggerEngine *createQmlEngine(bool useTerminal);
DebuggerEngine *createQmlCppEngine(DebuggerEngine *cppEngine, bool useTerminal);
DebuggerEngine *createLldbEngine();
} // namespace Internal
......@@ -154,6 +154,7 @@ void DebuggerRunTool::start()
}
appendMessage(tr("Debugging starts") + QLatin1Char('\n'), NormalMessageFormat);
Internal::runControlStarted(this);
engine->start();
}
......@@ -175,7 +176,7 @@ void DebuggerRunTool::notifyEngineRemoteSetupFinished(const RemoteSetupResult &r
void DebuggerRunTool::stop()
{
m_engine->quitDebugger();
m_engine->exitDebugger();
}
void DebuggerRunTool::onTargetFailure()
......@@ -190,12 +191,19 @@ void DebuggerRunTool::onTargetFailure()
void DebuggerRunTool::debuggingFinished()
{
Internal::runControlFinished(this);
appendMessage(tr("Debugging has finished"), NormalMessageFormat);
reportStopped();
}
DebuggerStartParameters &DebuggerRunTool::startParameters()
DebuggerRunParameters &DebuggerRunTool::runParameters()
{
return m_runParameters;
}
const DebuggerRunParameters &DebuggerRunTool::runParameters() const
{
return m_engine->runParameters();
return m_runParameters;
}
int DebuggerRunTool::portsUsedByDebugger() const
......@@ -232,35 +240,46 @@ void DebuggerRunTool::abortDebugger()
namespace Internal {
// Re-used for Combined C++/QML engine.
DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QStringList *errors)
DebuggerEngine *createEngine(DebuggerEngineType cppEngineType,
DebuggerEngineType et,
DebuggerStartMode sm,
bool useTerminal,
QStringList *errors)
{
DebuggerEngine *engine = nullptr;
switch (et) {
case GdbEngineType:
engine = createGdbEngine(rp);
engine = createGdbEngine(useTerminal, sm);
break;
case CdbEngineType:
engine = createCdbEngine(rp, errors);
engine = createCdbEngine(errors, sm);
break;
case PdbEngineType:
engine = createPdbEngine(rp);
engine = createPdbEngine();
break;
case QmlEngineType:
engine = createQmlEngine(rp);
engine = createQmlEngine(useTerminal);
break;
case LldbEngineType:
engine = createLldbEngine(rp);
engine = createLldbEngine();
break;
case QmlCppEngineType:
engine = createQmlCppEngine(rp, errors);
case QmlCppEngineType: {
DebuggerEngine *cppEngine = createEngine(cppEngineType, cppEngineType, sm, useTerminal, errors);
if (cppEngine) {
engine = createQmlCppEngine(cppEngine, useTerminal);
} else {
errors->append(DebuggerPlugin::tr("The slave debugging engine required for combined "
"QML/C++-Debugging could not be created: %1"));
}
break;
}
default:
errors->append(DebuggerPlugin::tr("Unknown debugger type \"%1\"")
.arg(engineTypeName(et)));
}
if (!engine)
errors->append(DebuggerPlugin::tr("Unable to create a debugger engine of the type \"%1\"").
arg(engineTypeName(rp.masterEngineType)));
arg(engineTypeName(et)));
return engine;
}
......@@ -518,11 +537,10 @@ void DebuggerRunTool::setRunParameters(const DebuggerRunParameters &rp, QString
return;
}
DebuggerRunParameters m_rp = rp;
m_runParameters = rp;
runControl()->setDisplayName(m_rp.displayName);
// QML and/or mixed are not prepared for it.
runControl()->setSupportsReRunning(!(m_rp.languages & QmlLanguage));
runControl()->setSupportsReRunning(!(rp.languages & QmlLanguage));
runControl()->setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL_TOOLBAR);
runControl()->setPromptToStop([](bool *optionalPrompt) {
......@@ -535,25 +553,40 @@ void DebuggerRunTool::setRunParameters(const DebuggerRunParameters &rp, QString
QString(), QString(), optionalPrompt);
});
if (Internal::fixupParameters(m_rp, runControl(), m_errors)) {
m_engine = createEngine(m_rp.masterEngineType, m_rp, &m_errors);
if (Internal::fixupParameters(m_runParameters, runControl(), m_errors)) {
m_engine = createEngine(m_runParameters.cppEngineType,
m_runParameters.masterEngineType,
m_runParameters.startMode,
m_runParameters.useTerminal,
&m_errors);
if (!m_engine) {
QString msg = m_errors.join('\n');
if (errorMessage)
*errorMessage = msg;
return;
}
Utils::globalMacroExpander()->registerFileVariables(
"DebuggedExecutable", tr("Debugged executable"),
[this] { return m_runParameters.inferior.executable; }
);
}
runControl()->setDisplayName(m_runParameters.displayName);
m_engine->setRunTool(this);
}
DebuggerEngine *DebuggerRunTool::activeEngine() const
{
return m_engine ? m_engine->activeEngine() : nullptr;
}
void DebuggerRunTool::appendSolibSearchPath(const QString &str)
{
QString path = str;
DebuggerStartParameters &sp = startParameters();
path.replace("%{sysroot}", sp.sysRoot);
sp.solibSearchPath.append(path);
path.replace("%{sysroot}", m_runParameters.sysRoot);
m_runParameters.solibSearchPath.append(path);
}
DebuggerRunTool::~DebuggerRunTool()
......@@ -567,12 +600,6 @@ DebuggerRunTool::~DebuggerRunTool()
}
}
void DebuggerRunTool::onFinished()
{
appendMessage(tr("Debugging has finished"), NormalMessageFormat);
runControlFinished(m_engine);
}
void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
{
if (channel == ConsoleOutput)
......@@ -783,7 +810,7 @@ void GdbServerRunner::start()
m_gdbServer.start(r, device());
}
void GdbServerRunner::onFinished()
void GdbServerRunner::stop()
{
m_gdbServer.stop();
}
......
......@@ -58,12 +58,12 @@ public:
QString *errorMessage = nullptr); // FIXME: Don't use.
Internal::DebuggerEngine *engine() const { return m_engine; }
Internal::DebuggerEngine *activeEngine() const;
void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1);
void start() override;
void stop() override;
void onFinished() override;
void startFailed();
void onTargetFailure();
......@@ -75,7 +75,8 @@ public:
void abortDebugger();
void debuggingFinished();
DebuggerStartParameters &startParameters(); // Used in Boot2Qt.
Internal::DebuggerRunParameters &runParameters();
const Internal::DebuggerRunParameters &runParameters() const;
bool isCppDebugging() const { return m_isCppDebugging; }
bool isQmlDebugging() const { return m_isQmlDebugging; }
......@@ -91,6 +92,7 @@ signals:
private:
Internal::DebuggerEngine *m_engine = nullptr; // Master engine
Internal::DebuggerRunParameters m_runParameters;
QStringList m_errors;
const bool m_isCppDebugging;
const bool m_isQmlDebugging;
......@@ -132,7 +134,7 @@ public:
private:
void start() override;
void onFinished() override;
void stop() override;
ProjectExplorer::ApplicationLauncher m_gdbServer;
};
......
......@@ -35,8 +35,8 @@
namespace Debugger {
namespace Internal {
GdbAttachEngine::GdbAttachEngine(const DebuggerRunParameters &startParameters)
: GdbEngine(startParameters)
GdbAttachEngine::GdbAttachEngine(bool useTerminal)
: GdbEngine(useTerminal)
{
}
......
......@@ -41,7 +41,7 @@ class GdbAttachEngine : public GdbEngine
Q_OBJECT
public:
explicit GdbAttachEngine(const DebuggerRunParameters &runParameters);
explicit GdbAttachEngine(bool useTerminal);
private:
void setupEngine() override;
......
......@@ -54,9 +54,8 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
GdbCoreEngine::GdbCoreEngine(const DebuggerRunParameters &startParameters)
: GdbEngine(startParameters),
m_coreUnpackProcess(0)
GdbCoreEngine::GdbCoreEngine(bool useTerminal)
: GdbEngine(useTerminal)
{}
GdbCoreEngine::~GdbCoreEngine()
......
......@@ -37,7 +37,7 @@ class GdbCoreEngine : public GdbEngine
Q_OBJECT
public:
explicit GdbCoreEngine(const DebuggerRunParameters &runParameters);
explicit GdbCoreEngine(bool useTerminal);
~GdbCoreEngine() override;
struct CoreInfo
......@@ -70,7 +70,7 @@ private:
QString m_executable;
QString m_coreName;
QString m_tempCoreName;
QProcess *m_coreUnpackProcess;
QProcess *m_coreUnpackProcess = nullptr;
QFile m_tempCoreFile;
};
......
......@@ -204,8 +204,7 @@ private:
//
///////////////////////////////////////////////////////////////////////
GdbEngine::GdbEngine(const DebuggerRunParameters &startParameters)
: DebuggerEngine(startParameters)
GdbEngine::GdbEngine(bool useTerminal)
{
setObjectName("GdbEngine");
......@@ -222,7 +221,7 @@ GdbEngine::GdbEngine(const DebuggerRunParameters &startParameters)
m_pendingBreakpointRequests = 0;
m_commandsDoneCallback = 0;
m_stackNeeded = false;
m_terminalTrap = startParameters.useTerminal;
m_terminalTrap = useTerminal;
m_systemDumpersLoaded = false;
m_rerunPending = false;
m_inUpdateLocals = false;
......@@ -4355,20 +4354,20 @@ void GdbEngine::debugLastCommand()
// Factory
//
DebuggerEngine *createGdbEngine(const DebuggerRunParameters &rp)
DebuggerEngine *createGdbEngine(bool useTerminal, DebuggerStartMode sm)