diff options
author | hjk <hjk@qt.io> | 2017-05-04 12:12:27 +0200 |
---|---|---|
committer | hjk <hjk@qt.io> | 2017-05-05 11:17:49 +0000 |
commit | 2a46b1521daa4d65cffd2b7fb00e68b4eec31f30 (patch) | |
tree | 59006139dc404c7f6e8ac94e39bd6011bad71857 /src/plugins | |
parent | ac59e2be40e3d18a83ad110f60efa5f62c56e085 (diff) | |
download | qt-creator-2a46b1521daa4d65cffd2b7fb00e68b4eec31f30.tar.gz |
ProjectExplorer/Debugger/RL: Make run control state transitions more uniform
Forward all tool and target activities to run control, and initiate
further state transitions (only) from there. Also, make sure
tool/target's on finished() triggered on all finishing code paths.
After that, the base state handling is sufficient to handle remote linux
running and debugging.
Change-Id: I0150ef249c9ad0b7b8ac7192be6dc860c9ca8fc5
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/debugger/debuggerengine.cpp | 52 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.h | 2 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerruncontrol.cpp | 30 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerruncontrol.h | 5 | ||||
-rw-r--r-- | src/plugins/projectexplorer/runconfiguration.cpp | 214 | ||||
-rw-r--r-- | src/plugins/projectexplorer/runconfiguration.h | 30 | ||||
-rw-r--r-- | src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp | 121 | ||||
-rw-r--r-- | src/plugins/remotelinux/abstractremotelinuxrunsupport.h | 35 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxanalyzesupport.cpp | 83 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxanalyzesupport.h | 3 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxdebugsupport.cpp | 221 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxdebugsupport.h | 23 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp | 56 | ||||
-rw-r--r-- | src/plugins/valgrind/valgrindengine.cpp | 4 |
14 files changed, 382 insertions, 497 deletions
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index a636bbdfc6..d99a2cdec0 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -674,6 +674,7 @@ void DebuggerEngine::handleStartFailed() // Called from RunControl. void DebuggerEngine::handleFinished() { + setState(DebuggerFinished); showMessage("HANDLE RUNCONTROL FINISHED"); d->m_runTool.clear(); d->m_progress.setProgressValue(1000); @@ -821,7 +822,7 @@ void DebuggerEngine::notifyEngineSetupOk() QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state()); setState(EngineSetupOk); - runTool()->reportPrepared(); + runTool()->reportSuccess(); } void DebuggerEngine::setupSlaveInferior() @@ -907,7 +908,7 @@ void DebuggerEngine::notifyEngineRequestRemoteSetup() << "remoteSetupState" << d->remoteSetupState()); d->setRemoteSetupState(RemoteSetupRequested); - runTool()->requestRemoteSetup(); + runTool()->doRemoteSetup(); } void DebuggerEngine::notifyEngineRemoteServerRunning(const QString &, int /*pid*/) @@ -915,6 +916,30 @@ void DebuggerEngine::notifyEngineRemoteServerRunning(const QString &, int /*pid* showMessage("NOTE: REMOTE SERVER RUNNING IN MULTIMODE"); } +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())); + + if (result.gdbServerPort.isValid()) { + QString &rc = d->m_runParameters.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) { + // e.g. iOS Simulator + runParameters().attachPID = ProcessHandle(result.inferiorPid); + } + + if (result.qmlServerPort.isValid()) { + d->m_runParameters.qmlServer.port = result.qmlServerPort; + d->m_runParameters.inferior.commandLineArguments.replace("%qml_port%", + QString::number(result.qmlServerPort.number())); + } +} + void DebuggerEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &result) { QTC_ASSERT(state() == EngineSetupRequested @@ -926,30 +951,9 @@ void DebuggerEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &re qDebug() << this << "remoteSetupState" << d->remoteSetupState()); if (result.success) { - showMessage(QString("NOTE: REMOTE SETUP DONE: GDB SERVER PORT: %1 QML PORT %2") - .arg(result.gdbServerPort.number()).arg(result.qmlServerPort.number())); - if (d->remoteSetupState() != RemoteSetupCancelled) d->setRemoteSetupState(RemoteSetupSucceeded); - - if (result.gdbServerPort.isValid()) { - QString &rc = d->m_runParameters.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) { - // e.g. iOS Simulator - runParameters().attachPID = ProcessHandle(result.inferiorPid); - } - - if (result.qmlServerPort.isValid()) { - d->m_runParameters.qmlServer.port = result.qmlServerPort; - d->m_runParameters.inferior.commandLineArguments.replace("%qml_port%", - QString::number(result.qmlServerPort.number())); - } - + setRemoteParameters(result); } else { d->setRemoteSetupState(RemoteSetupFailed); showMessage("NOTE: REMOTE SETUP FAILED: " + result.reason); diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 2eb56d7092..75a1174af9 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -381,6 +381,8 @@ protected: void notifyDebuggerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus, const QString &backendName); + void setRemoteParameters(const RemoteSetupResult &result); + protected: virtual void notifyInferiorShutdownOk(); virtual void notifyInferiorShutdownFailed(); diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 38775f4b25..9e62606f36 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -52,8 +52,10 @@ #include <utils/checkablemessagebox.h> #include <utils/fileutils.h> +#include <utils/portlist.h> #include <utils/qtcassert.h> #include <utils/qtcprocess.h> + #include <coreplugin/icore.h> #include <coreplugin/coreconstants.h> #include <qmldebug/qmldebugcommandlinearguments.h> @@ -126,9 +128,7 @@ void DebuggerRunTool::start() if (rp.startMode == StartInternal && rp.inferior.executable.isEmpty() && rp.interpreter.isEmpty()) { - appendMessage(tr("No executable specified.") + QLatin1Char('\n'), ErrorMessageFormat); - runControl()->reportApplicationStart(); - runControl()->reportApplicationStop(); + reportFailure(tr("No executable specified.") + '\n'); return; } @@ -177,6 +177,11 @@ void DebuggerRunTool::notifyEngineRemoteSetupFinished(const RemoteSetupResult &r m_engine->notifyEngineRemoteSetupFinished(result); } +void DebuggerRunTool::setRemoteParameters(const RemoteSetupResult &result) +{ + m_engine->setRemoteParameters(result); +} + void DebuggerRunTool::stop() { m_engine->quitDebugger(); @@ -202,6 +207,11 @@ DebuggerStartParameters &DebuggerRunTool::startParameters() return m_engine->runParameters(); } +int DebuggerRunTool::portsUsedByDebugger() const +{ + return isCppDebugging() + isQmlDebugging(); +} + void DebuggerRunTool::notifyInferiorIll() { m_engine->notifyInferiorIll(); @@ -510,6 +520,12 @@ void DebuggerRunTool::setStartParameters(const DebuggerStartParameters &sp, QStr void DebuggerRunTool::setRunParameters(const DebuggerRunParameters &rp, QString *errorMessage) { + int portsUsed = portsUsedByDebugger(); + if (portsUsed > device()->freePorts().count()) { + *errorMessage = tr("Cannot debug: Not enough free ports available."); + return; + } + DebuggerRunParameters m_rp = rp; runControl()->setDisplayName(m_rp.displayName); @@ -540,6 +556,14 @@ void DebuggerRunTool::setRunParameters(const DebuggerRunParameters &rp, QString m_engine->setRunTool(this); } +void DebuggerRunTool::appendSolibSearchPath(const QString &str) +{ + QString path = str; + DebuggerStartParameters &sp = startParameters(); + path.replace("%{sysroot}", sp.sysRoot); + sp.solibSearchPath.append(path); +} + DebuggerRunTool::~DebuggerRunTool() { disconnect(); diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 65e13e9cf0..fef388cc91 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -69,6 +69,7 @@ public: void startFailed(); void notifyEngineRemoteServerRunning(const QByteArray &msg, int pid); void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result); + void setRemoteParameters(const RemoteSetupResult &result); void notifyInferiorIll(); Q_SLOT void notifyInferiorExited(); void quitDebugger(); @@ -79,6 +80,10 @@ public: bool isCppDebugging() const { return m_isCppDebugging; } bool isQmlDebugging() const { return m_isQmlDebugging; } + int portsUsedByDebugger() const; + + virtual void doRemoteSetup() { emit requestRemoteSetup(); } + void appendSolibSearchPath(const QString &str); signals: void stateChanged(Debugger::DebuggerState state); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 5215de6324..9f6b6e3205 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -60,6 +60,8 @@ using namespace Utils; using namespace ProjectExplorer::Internal; +const bool debugStates = false; + namespace ProjectExplorer { /////////////////////////////////////////////////////////////////////// @@ -522,7 +524,7 @@ public: ~RunControlPrivate() { - QTC_CHECK(state == State::Stopped); + QTC_CHECK(state == State::Stopped || state == State::Initialized); delete targetRunner; delete toolRunner; delete outputFormatter; @@ -544,6 +546,9 @@ public: void checkState(State expectedState); void setState(State state); + void debugMessage(const QString &msg); + QString stateName(State s) const; + void initiateStart(); void onTargetPrepared(); @@ -560,10 +565,17 @@ public: void initiateStop(); void onToolStopped(); + void onToolStopFailed(const QString &msg); + void onTargetStopped(); + void onTargetStopFailed(const QString &msg); void onToolFailed(const QString &msg); + void onToolSuccess(); + void onTargetFailed(const QString &msg); + void onTargetSuccess(); + void handleFailure(); void showError(const QString &msg); @@ -659,14 +671,16 @@ void RunControlPrivate::initiateStart() { checkState(State::Initialized); setState(State::TargetPreparing); - targetRunner->prepare(); + debugMessage("Queue: Prepare target runner"); + QTimer::singleShot(0, targetRunner, &TargetRunner::prepare); } void RunControlPrivate::onTargetPrepared() { checkState(State::TargetPreparing); setState(State::ToolPreparing); - toolRunner->prepare(); + debugMessage("Queue: Prepare tool runner"); + QTimer::singleShot(0, toolRunner, &ToolRunner::prepare); } void RunControlPrivate::onTargetPrepareFailed(const QString &msg) @@ -681,7 +695,8 @@ void RunControlPrivate::onToolPrepared() { checkState(State::ToolPreparing); setState(State::TargetStarting); - targetRunner->start(); + debugMessage("Queue: Start target runner"); + QTimer::singleShot(0, targetRunner, &TargetRunner::start); } void RunControlPrivate::onToolPrepareFailed(const QString &msg) @@ -696,7 +711,8 @@ void RunControlPrivate::onTargetStarted() { checkState(State::TargetStarting); setState(State::ToolStarting); - toolRunner->start(); + debugMessage("Queue: Start tool runner"); + QTimer::singleShot(0, toolRunner, &ToolRunner::start); } void RunControlPrivate::onTargetStartFailed(const QString &msg) @@ -725,54 +741,109 @@ void RunControlPrivate::initiateStop() { checkState(State::Running); setState(State::ToolStopping); - toolRunner->stop(); + debugMessage("Queue: Stop tool runner"); + QTimer::singleShot(0, toolRunner, &ToolRunner::stop); } void RunControlPrivate::onToolStopped() { toolRunner->onStop(); + debugMessage("Tool stopped"); checkState(State::ToolStopping); setState(State::TargetStopping); - targetRunner->stop(); + debugMessage("Queue: Stop target runner"); + QTimer::singleShot(0, targetRunner, &TargetRunner::stop); +} + +void RunControlPrivate::onToolStopFailed(const QString &msg) +{ + checkState(State::ToolStopping); + targetRunner->onToolFailure(); + debugMessage("Tool stop failed"); + showError(msg); + setState(State::Stopped); } void RunControlPrivate::onTargetStopped() { + targetRunner->onStop(); + debugMessage("Target stopped"); checkState(State::TargetStopping); setState(State::Stopped); - QTC_CHECK(applicationProcessHandle.isValid()); - q->setApplicationProcessHandle(Utils::ProcessHandle()); +} - toolRunner->onFinished(); - targetRunner->onFinished(); +void RunControlPrivate::onTargetStopFailed(const QString &msg) +{ + debugMessage("Target stop failed"); + checkState(State::TargetStopping); + toolRunner->onTargetFailure(); + showError(msg); + setState(State::Stopped); } void RunControlPrivate::onTargetFailed(const QString &msg) { + debugMessage("Target operation failed"); if (state == State::TargetPreparing) { onTargetPrepareFailed(msg); } else if (state == State::TargetStarting) { onTargetStartFailed(msg); + } else if (state == State::TargetStopping) { + onTargetStopFailed(msg); } else { showError(msg); -// showError(RunControl::tr("Unexpected state: %1").arg(int(state))); + showError(RunControl::tr("Unexpected state: %1").arg(int(state))); + setState(State::Stopped); + } +} + +void RunControlPrivate::onTargetSuccess() +{ + debugMessage("Target operation successful"); + if (state == State::TargetPreparing) { + onTargetPrepared(); + } else if (state == State::TargetStarting) { + onTargetStarted(); + } else if (state == State::TargetStopping) { + onTargetStopped(); + } else { + showError(RunControl::tr("Unexpected state: %1").arg(int(state))); setState(State::Stopped); } } void RunControlPrivate::onToolFailed(const QString &msg) { + debugMessage("Tool operation failed"); if (state == State::ToolPreparing) { onToolPrepareFailed(msg); } else if (state == State::ToolStarting) { onToolStartFailed(msg); + } else if (state == State::ToolStopping) { + onToolStartFailed(msg); } else { showError(msg); -// showError(RunControl::tr("Unexpected state: %1").arg(int(state))); + showError(RunControl::tr("Unexpected state: %1").arg(int(state))); + setState(State::Stopped); + } +} + +void RunControlPrivate::onToolSuccess() +{ + debugMessage("Tool operation successful"); + if (state == State::ToolPreparing) { + onToolPrepared(); + } else if (state == State::ToolStarting) { + onToolStarted(); + } else if (state == State::ToolStopping) { + onToolStopped(); + } else { + showError(RunControl::tr("Unexpected state: %1").arg(int(state))); setState(State::Stopped); } } + void RunControlPrivate::handleFailure() { switch (state) { @@ -1028,6 +1099,24 @@ void RunControlPrivate::checkState(State expectedState) qDebug() << "Unexpected state " << expectedState << " have: " << state; } +QString RunControlPrivate::stateName(State s) const +{ +# define SN(x) case x: return QLatin1String(#x); + switch (s) { + SN(State::Initialized) + SN(State::TargetPreparing) + SN(State::ToolPreparing) + SN(State::TargetStarting) + SN(State::ToolStarting) + SN(State::Running) + SN(State::ToolStopping) + SN(State::TargetStopping) + SN(State::Stopped) + } + return QLatin1String("<unknown>"); +# undef SN +} + void RunControlPrivate::setState(State newState) { if (!isAllowedTransition(state, newState)) @@ -1035,20 +1124,32 @@ void RunControlPrivate::setState(State newState) state = newState; + debugMessage("Entering state " + stateName(newState)); + // Extra reporting. switch (state) { case State::Running: emit q->started(); break; case State::Stopped: - emit q->finished(); + QTC_CHECK(applicationProcessHandle.isValid()); + q->setApplicationProcessHandle(Utils::ProcessHandle()); + toolRunner->onFinished(); + targetRunner->onFinished(); state = State::Initialized; // Reset for potential re-running. + emit q->finished(); break; default: break; } } +void RunControlPrivate::debugMessage(const QString &msg) +{ + if (debugStates) + q->appendMessage(msg + '\n', Utils::DebugFormat); +} + /*! Brings the application determined by this RunControl's \c applicationProcessHandle to the foreground. @@ -1079,8 +1180,7 @@ void RunControl::reportApplicationStop() // multiple times. Fix it there and then add a soft assert here. return; } - d->onToolStopped(); - emit finished(); + d->onTargetStopped(); } void RunControl::bringApplicationToForegroundInternal() @@ -1145,9 +1245,9 @@ void SimpleTargetRunner::start() QTC_ASSERT(r.is<StandardRunnable>(), return); const QString executable = r.as<StandardRunnable>().executable; if (executable.isEmpty()) { - reportStartFailed(RunControl::tr("No executable specified.")); + reportFailure(RunControl::tr("No executable specified.")); } else if (!QFileInfo::exists(executable)) { - reportStartFailed(RunControl::tr("Executable %1 does not exist.") + reportFailure(RunControl::tr("Executable %1 does not exist.") .arg(QDir::toNativeSeparators(executable))); } else { QString msg = RunControl::tr("Starting %1...").arg(QDir::toNativeSeparators(executable)) + '\n'; @@ -1173,7 +1273,7 @@ void SimpleTargetRunner::start() connect(&m_launcher, &ApplicationLauncher::finished, this, [this] { m_launcher.disconnect(this); - reportStopped(); + reportSuccess(); }); connect(&m_launcher, &ApplicationLauncher::reportProgress, @@ -1195,7 +1295,7 @@ void SimpleTargetRunner::onProcessStarted() // Console processes only know their pid after being started runControl()->setApplicationProcessHandle(m_launcher.applicationPID()); runControl()->bringApplicationToForeground(); - reportStarted(); + reportSuccess(); } void SimpleTargetRunner::onProcessFinished(int exitCode, QProcess::ExitStatus status) @@ -1219,6 +1319,10 @@ TargetRunner::TargetRunner(RunControl *runControl) runControl->setTargetRunner(this); } +TargetRunner::~TargetRunner() +{ +} + RunControl *TargetRunner::runControl() const { return m_runControl; @@ -1236,46 +1340,27 @@ IDevice::ConstPtr TargetRunner::device() const void TargetRunner::prepare() { - reportPrepared(); // By default nothing to do, all is fine. -} - -void TargetRunner::reportPrepareFailed(const QString &msg) -{ - m_runControl->d->onTargetPrepareFailed(msg); -} - -void TargetRunner::reportPrepared() -{ - QTC_ASSERT(m_runControl, return); - m_runControl->d->onTargetPrepared(); + reportSuccess(); // By default nothing to do, all is fine. } void TargetRunner::start() { - reportStarted(); -} - -void TargetRunner::reportStartFailed(const QString &msg) -{ - m_runControl->d->onTargetStartFailed(msg); + reportSuccess(); } void TargetRunner::stop() { - reportStopped(); // By default all is fine. + reportSuccess(); // By default all is fine. } -void TargetRunner::reportStarted() +void TargetRunner::reportStopped() { - QTC_ASSERT(m_runControl, return); - m_runControl->d->onTargetStarted(); + m_runControl->d->onTargetStopped(); } -void TargetRunner::reportStopped() +void TargetRunner::reportSuccess() { - QTC_ASSERT(m_runControl, return); - onStop(); - m_runControl->d->onTargetStopped(); + m_runControl->d->onTargetSuccess(); } void TargetRunner::reportFailure(const QString &msg) @@ -1292,6 +1377,10 @@ ToolRunner::ToolRunner(RunControl *runControl) runControl->setToolRunner(this); } +ToolRunner::~ToolRunner() +{ +} + RunControl *ToolRunner::runControl() const { return m_runControl; @@ -1319,46 +1408,27 @@ const Connection &ToolRunner::connection() const void ToolRunner::prepare() { - reportPrepared(); -} - -void ToolRunner::reportPrepared() -{ - m_runControl->d->onToolPrepared(); + reportSuccess(); } void ToolRunner::start() { - reportStarted(); -} - -void ToolRunner::reportStartFailed(const QString &msg) -{ - QTC_CHECK(m_runControl->d->state == RunControlPrivate::State::ToolStarting); - m_runControl->d->targetRunner->onToolFailure(); - reportFailure(msg); -} - -void ToolRunner::reportStarted() -{ - m_runControl->d->onToolStarted(); + reportSuccess(); } void ToolRunner::stop() { - reportStopped(); + reportSuccess(); } -void ToolRunner::reportStopFailed(const QString &msg) +void ToolRunner::reportStopped() { - QTC_CHECK(m_runControl->d->state == RunControlPrivate::State::ToolStopping); - m_runControl->d->targetRunner->onToolFailure(); - reportFailure(msg); + m_runControl->d->onToolStopped(); } -void ToolRunner::reportStopped() +void ToolRunner::reportSuccess() { - m_runControl->d->onToolStopped(); + m_runControl->d->onToolSuccess(); } void ToolRunner::reportFailure(const QString &msg) diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index cc7298ac98..dab5a3b965 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -454,6 +454,7 @@ class PROJECTEXPLORER_EXPORT TargetRunner : public QObject public: explicit TargetRunner(RunControl *runControl); + ~TargetRunner() override; RunControl *runControl() const; void appendMessage(const QString &msg, Utils::OutputFormat format); @@ -461,20 +462,16 @@ public: // Preparation phase. virtual void prepare(); // Initiate setup. Needs to report result. - void reportPrepareFailed(const QString &msg = QString()); - void reportPrepared(); - // Startup phase. virtual void start(); // Initiates start. Needs to report result. - void reportStartFailed(const QString &msg = QString()); - void reportStarted(); - // Stopping phase. virtual void stop(); // Initiates stop. Needs to report result. - void reportStopFailed(const QString &msg = QString()); - void reportStopped(); - // Generic error in uncertain state. + // + void reportStopped(); + // Generic success report, proceed to next stage. + void reportSuccess(); + // Generic error, start ramp down. void reportFailure(const QString &msg = QString()); // Customization points. No reporting required nor wanted. @@ -497,6 +494,7 @@ class PROJECTEXPLORER_EXPORT ToolRunner : public QObject public: explicit ToolRunner(RunControl *runControl); + ~ToolRunner() override; RunControl *runControl() const; @@ -508,20 +506,16 @@ public: // Preparation phase. virtual void prepare(); // Initiates preparation, needs to report success or failure. - void reportPrepareFailed(const QString &msg = QString()); - void reportPrepared(); - // Start phase. virtual void start(); - void reportStartFailed(const QString &msg = QString()); - void reportStarted(); - // Stop phase. virtual void stop(); - void reportStopFailed(const QString &msg = QString()); - void reportStopped(); - // Generic error in uncertain state. + // + void reportStopped(); + // Generic success report, proceed to next stage. + void reportSuccess(); + // Generic error, start ramp down. void reportFailure(const QString &msg = QString()); // Customization points. No reporting required nor wanted. diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp b/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp index dd410d505a..4dc313d5e6 100644 --- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp +++ b/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp @@ -34,6 +34,7 @@ #include <utils/portlist.h> using namespace ProjectExplorer; +using namespace Utils; namespace RemoteLinux { namespace Internal { @@ -42,11 +43,11 @@ class AbstractRemoteLinuxRunSupportPrivate { public: ApplicationLauncher launcher; - AbstractRemoteLinuxRunSupport::State state = AbstractRemoteLinuxRunSupport::Inactive; DeviceUsedPortsGatherer portsGatherer; ApplicationLauncher fifoCreator; - Utils::PortList portList; + PortList portList; QString fifo; + bool usesFifo = false; }; } // namespace Internal @@ -61,7 +62,6 @@ AbstractRemoteLinuxRunSupport::AbstractRemoteLinuxRunSupport(RunControl *runCont AbstractRemoteLinuxRunSupport::~AbstractRemoteLinuxRunSupport() { - setFinished(); delete d; } @@ -70,42 +70,12 @@ ApplicationLauncher *AbstractRemoteLinuxRunSupport::applicationLauncher() return &d->launcher; } -void AbstractRemoteLinuxRunSupport::setState(AbstractRemoteLinuxRunSupport::State state) +void AbstractRemoteLinuxRunSupport::setUsesFifo(bool on) { - d->state = state; + d->usesFifo = on; } -AbstractRemoteLinuxRunSupport::State AbstractRemoteLinuxRunSupport::state() const -{ - return d->state; -} - -void AbstractRemoteLinuxRunSupport::handleResourcesError(const QString &message) -{ - QTC_ASSERT(d->state == GatheringResources, return); - setFinished(); - reset(); - emit adapterSetupFailed(message); -} - -void AbstractRemoteLinuxRunSupport::handleResourcesAvailable() -{ - QTC_ASSERT(d->state == GatheringResources, return); - - d->portList = device()->freePorts(); - emit executionStartRequested(); -} - -void AbstractRemoteLinuxRunSupport::setFinished() -{ - if (d->state == Inactive) - return; - if (d->state == Running) - applicationLauncher()->stop(); - d->state = Inactive; -} - -Utils::Port AbstractRemoteLinuxRunSupport::findPort() const +Port AbstractRemoteLinuxRunSupport::findPort() const { return d->portsGatherer.getNextFreePort(&d->portList); } @@ -115,21 +85,31 @@ QString AbstractRemoteLinuxRunSupport::fifo() const return d->fifo; } +void AbstractRemoteLinuxRunSupport::prepare() +{ + if (d->usesFifo) + createRemoteFifo(); + else + startPortsGathering(); +} + void AbstractRemoteLinuxRunSupport::startPortsGathering() { - QTC_ASSERT(d->state == Inactive, return); - d->state = GatheringResources; - connect(&d->portsGatherer, &DeviceUsedPortsGatherer::error, - this, &AbstractRemoteLinuxRunSupport::handleResourcesError); - connect(&d->portsGatherer, &DeviceUsedPortsGatherer::portListReady, - this, &AbstractRemoteLinuxRunSupport::handleResourcesAvailable); + appendMessage(tr("Checking available ports...") + '\n', NormalMessageFormat); + connect(&d->portsGatherer, &DeviceUsedPortsGatherer::error, this, [&](const QString &msg) { + reportFailure(msg); + }); + connect(&d->portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [&] { + d->portList = device()->freePorts(); + //appendMessage(tr("Found %1 free ports").arg(d->portList.count()), NormalMessageFormat); + reportSuccess(); + }); d->portsGatherer.start(device()); } void AbstractRemoteLinuxRunSupport::createRemoteFifo() { - QTC_ASSERT(d->state == Inactive, return); - d->state = GatheringResources; + appendMessage(tr("Creating remote socket...") + '\n', NormalMessageFormat); StandardRunnable r; r.executable = QLatin1String("/bin/sh"); @@ -143,10 +123,11 @@ void AbstractRemoteLinuxRunSupport::createRemoteFifo() connect(&d->fifoCreator, &ApplicationLauncher::finished, this, [this, output, errors](bool success) { if (!success) { - handleResourcesError(QString("Failed to create fifo: %1").arg(QLatin1String(*errors))); + reportFailure(QString("Failed to create fifo: %1").arg(QLatin1String(*errors))); } else { d->fifo = QString::fromLatin1(*output); - handleResourcesAvailable(); + //appendMessage(tr("Created fifo").arg(d->fifo), NormalMessageFormat); + reportSuccess(); } }); @@ -163,11 +144,53 @@ void AbstractRemoteLinuxRunSupport::createRemoteFifo() d->fifoCreator.start(r, device()); } -void AbstractRemoteLinuxRunSupport::reset() +void AbstractRemoteLinuxRunSupport::start() { + connect(&d->launcher, &ApplicationLauncher::remoteStderr, + this, &AbstractRemoteLinuxRunSupport::handleRemoteErrorOutput); + connect(&d->launcher, &ApplicationLauncher::remoteStdout, + this, &AbstractRemoteLinuxRunSupport::handleRemoteOutput); + connect(&d->launcher, &ApplicationLauncher::finished, + this, &AbstractRemoteLinuxRunSupport::handleAppRunnerFinished); + connect(&d->launcher, &ApplicationLauncher::reportProgress, + this, &AbstractRemoteLinuxRunSupport::handleProgressReport); + connect(&d->launcher, &ApplicationLauncher::reportError, + this, &AbstractRemoteLinuxRunSupport::handleAppRunnerError); + connect(&d->launcher, &ApplicationLauncher::remoteProcessStarted, + this, &TargetRunner::reportSuccess); + d->launcher.start(runControl()->runnable(), device()); +} + +void AbstractRemoteLinuxRunSupport::onFinished() +{ + d->launcher.disconnect(this); + d->launcher.stop(); d->portsGatherer.disconnect(this); - applicationLauncher()->disconnect(this); - d->state = Inactive; +} + +void AbstractRemoteLinuxRunSupport::handleAppRunnerFinished(bool success) +{ + success ? reportStopped() : reportFailure(); +} + +void AbstractRemoteLinuxRunSupport::handleAppRunnerError(const QString &error) +{ + reportFailure(error); +} + +void AbstractRemoteLinuxRunSupport::handleRemoteOutput(const QByteArray &output) +{ + appendMessage(QString::fromUtf8(output), StdOutFormat); +} + +void AbstractRemoteLinuxRunSupport::handleRemoteErrorOutput(const QByteArray &output) +{ + appendMessage(QString::fromUtf8(output), StdErrFormat); +} + +void AbstractRemoteLinuxRunSupport::handleProgressReport(const QString &progressOutput) +{ + appendMessage(progressOutput + '\n', LogMessageFormat); } } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h b/src/plugins/remotelinux/abstractremotelinuxrunsupport.h index 9502972dfa..a914d48ea7 100644 --- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h +++ b/src/plugins/remotelinux/abstractremotelinuxrunsupport.h @@ -41,39 +41,30 @@ class REMOTELINUX_EXPORT AbstractRemoteLinuxRunSupport : public ProjectExplorer: Q_OBJECT public: - enum State - { - Inactive, - GatheringResources, - StartingRunner, - Running - }; - explicit AbstractRemoteLinuxRunSupport(ProjectExplorer::RunControl *runControl); ~AbstractRemoteLinuxRunSupport(); ProjectExplorer::ApplicationLauncher *applicationLauncher(); - void setState(State state); - State state() const; - - void setFinished(); + void setUsesFifo(bool on); - void startPortsGathering(); Utils::Port findPort() const; - - void createRemoteFifo(); QString fifo() const; - void reset(); +private: + void prepare() override; + void start() override; + void onFinished() override; -signals: - void adapterSetupFailed(const QString &error); - void executionStartRequested(); + void createRemoteFifo(); + void startPortsGathering(); -private: - void handleResourcesError(const QString &message); - void handleResourcesAvailable(); + void handleAppRunnerError(const QString &error); + void handleRemoteOutput(const QByteArray &output); + void handleRemoteErrorOutput(const QByteArray &output); + void handleAppRunnerFinished(bool success); + void handleProgressReport(const QString &progressOutput); + void handleAdapterSetupDone(); Internal::AbstractRemoteLinuxRunSupportPrivate * const d; }; diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp index 9349f432fe..4652734e2f 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp @@ -53,16 +53,17 @@ class RemoteLinuxAnalyzeSupportPrivate public: RemoteLinuxAnalyzeSupportPrivate(RunControl *runControl) { - if (runControl->runMode() != ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) - return; - RunConfiguration *runConfiguration = runControl->runConfiguration(); - QTC_ASSERT(runConfiguration, return); - IRunConfigurationAspect *perfAspect = - runConfiguration->extraAspect("Analyzer.Perf.Settings"); - QTC_ASSERT(perfAspect, return); - perfRecordArguments = - perfAspect->currentSettings()->property("perfRecordArguments").toStringList() - .join(' '); + if (runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) { + usesFifo = true; + RunConfiguration *runConfiguration = runControl->runConfiguration(); + QTC_ASSERT(runConfiguration, return); + IRunConfigurationAspect *perfAspect = + runConfiguration->extraAspect("Analyzer.Perf.Settings"); + QTC_ASSERT(perfAspect, return); + perfRecordArguments = + perfAspect->currentSettings()->property("perfRecordArguments").toStringList() + .join(' '); + } } Utils::Port qmlPort; @@ -71,6 +72,7 @@ public: ApplicationLauncher outputGatherer; QmlDebug::QmlOutputParser outputParser; + bool usesFifo = false; }; } // namespace Internal @@ -81,19 +83,9 @@ RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RunControl *runControl) : ToolRunner(runControl), d(new RemoteLinuxAnalyzeSupportPrivate(runControl)) { - connect(runControl, &RunControl::starting, - this, &RemoteLinuxAnalyzeSupport::handleRemoteSetupRequested); connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort, this, &RemoteLinuxAnalyzeSupport::remoteIsRunning); - connect(runControl, &RunControl::finished, - this, &RemoteLinuxAnalyzeSupport::handleProfilingFinished); - - connect(qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl->targetRunner()), - &AbstractRemoteLinuxRunSupport::executionStartRequested, - this, &RemoteLinuxAnalyzeSupport::startExecution); - connect(qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl->targetRunner()), - &AbstractRemoteLinuxRunSupport::adapterSetupFailed, - this, &RemoteLinuxAnalyzeSupport::handleAdapterSetupFailed); + targetRunner()->setUsesFifo(runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE); } RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport() @@ -103,48 +95,27 @@ RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport() void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format) { - if (targetRunner()->state() != AbstractRemoteLinuxRunSupport::Inactive) - appendMessage(msg, format); + appendMessage(msg, format); d->outputParser.processOutput(msg); } -void RemoteLinuxAnalyzeSupport::handleRemoteSetupRequested() -{ - QTC_ASSERT(targetRunner()->state() == AbstractRemoteLinuxRunSupport::Inactive, return); - - const Core::Id runMode = runControl()->runMode(); - if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { - showMessage(tr("Checking available ports...") + QLatin1Char('\n'), - Utils::NormalMessageFormat); - targetRunner()->startPortsGathering(); - } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) { - showMessage(tr("Creating remote socket...") + QLatin1Char('\n'), - Utils::NormalMessageFormat); - targetRunner()->createRemoteFifo(); - } -} - -void RemoteLinuxAnalyzeSupport::startExecution() +void RemoteLinuxAnalyzeSupport::start() { - QTC_ASSERT(targetRunner()->state() == AbstractRemoteLinuxRunSupport::GatheringResources, return); - const Core::Id runMode = runControl()->runMode(); if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { d->qmlPort = targetRunner()->findPort(); if (!d->qmlPort.isValid()) { - handleAdapterSetupFailed(tr("Not enough free ports on device for profiling.")); + reportFailure(tr("Not enough free ports on device for profiling.")); return; } } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) { d->remoteFifo = targetRunner()->fifo(); if (d->remoteFifo.isEmpty()) { - handleAdapterSetupFailed(tr("FIFO for profiling data could not be created.")); + reportFailure(tr("FIFO for profiling data could not be created.")); return; } } - targetRunner()->setState(AbstractRemoteLinuxRunSupport::StartingRunner); - ApplicationLauncher *runner = targetRunner()->applicationLauncher(); connect(runner, &ApplicationLauncher::remoteStderr, this, &RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput); @@ -190,26 +161,18 @@ void RemoteLinuxAnalyzeSupport::startExecution() void RemoteLinuxAnalyzeSupport::handleAppRunnerError(const QString &error) { - if (targetRunner()->state() == AbstractRemoteLinuxRunSupport::Running) - showMessage(error, Utils::ErrorMessageFormat); - else if (targetRunner()->state() != AbstractRemoteLinuxRunSupport::Inactive) - handleAdapterSetupFailed(error); + showMessage(error, Utils::ErrorMessageFormat); + reportFailure(error); } void RemoteLinuxAnalyzeSupport::handleAppRunnerFinished(bool success) { // reset needs to be called first to ensure that the correct state is set. - targetRunner()->reset(); if (!success) showMessage(tr("Failure running remote process."), Utils::NormalMessageFormat); runControl()->notifyRemoteFinished(); } -void RemoteLinuxAnalyzeSupport::handleProfilingFinished() -{ - targetRunner()->setFinished(); -} - void RemoteLinuxAnalyzeSupport::remoteIsRunning() { runControl()->notifyRemoteSetupDone(d->qmlPort); @@ -222,16 +185,11 @@ AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const void RemoteLinuxAnalyzeSupport::handleRemoteOutput(const QByteArray &output) { - QTC_ASSERT(targetRunner()->state() == AbstractRemoteLinuxRunSupport::Inactive - || targetRunner()->state() == AbstractRemoteLinuxRunSupport::Running, return); - showMessage(QString::fromUtf8(output), Utils::StdOutFormat); } void RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output) { - QTC_ASSERT(targetRunner()->state() != AbstractRemoteLinuxRunSupport::GatheringResources, return); - showMessage(QString::fromUtf8(output), Utils::StdErrFormat); } @@ -247,9 +205,6 @@ void RemoteLinuxAnalyzeSupport::handleAdapterSetupFailed(const QString &error) void RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted() { - QTC_ASSERT(targetRunner()->state() == AbstractRemoteLinuxRunSupport::StartingRunner, return); - - targetRunner()->setState(AbstractRemoteLinuxRunSupport::Running); } } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.h b/src/plugins/remotelinux/remotelinuxanalyzesupport.h index 2cea6c380c..f125deba91 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.h +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.h @@ -44,7 +44,7 @@ public: ~RemoteLinuxAnalyzeSupport() override; private: - void startExecution(); + void start() override; void handleAdapterSetupFailed(const QString &error); void handleRemoteSetupRequested(); @@ -55,7 +55,6 @@ private: void handleProgressReport(const QString &progressOutput); void handleRemoteProcessStarted(); - void handleProfilingFinished(); void remoteIsRunning(); AbstractRemoteLinuxRunSupport *targetRunner() const; diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index 7acc63af8c..9bcdc5b207 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -25,10 +25,10 @@ #include "remotelinuxdebugsupport.h" +#include "remotelinuxcustomrunconfiguration.h" #include "remotelinuxrunconfiguration.h" #include <debugger/debuggerruncontrol.h> -#include <debugger/debuggerstartparameters.h> #include <projectexplorer/buildconfiguration.h> #include <projectexplorer/project.h> @@ -41,109 +41,87 @@ #include <utils/qtcassert.h> #include <utils/qtcprocess.h> -#include <QPointer> - -using namespace QSsh; using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; namespace RemoteLinux { -namespace Internal { -class LinuxDeviceDebugSupportPrivate +LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString *errorMessage) + : DebuggerRunTool(runControl) { -public: - QByteArray gdbserverOutput; - Port gdbServerPort; - Port qmlPort; -}; + RunConfiguration *runConfig = runControl->runConfiguration(); -} // namespace Internal + QString symbolFile; + if (auto rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig)) + symbolFile = rlrc->localExecutableFilePath(); + if (auto rlrc = qobject_cast<Internal::RemoteLinuxCustomRunConfiguration *>(runConfig)) + symbolFile = rlrc->localExecutableFilePath(); + if (symbolFile.isEmpty()) { + *errorMessage = tr("Cannot debug: Local executable is not set."); + return; + } -using namespace Internal; + DebuggerStartParameters params; + params.startMode = AttachToRemoteServer; + params.closeMode = KillAndExitMonitorAtClose; + params.remoteSetupNeeded = false; -LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, - const Debugger::DebuggerStartParameters &sp, - QString *errorMessage) - : DebuggerRunTool(runControl, sp, errorMessage), - d(new LinuxDeviceDebugSupportPrivate) -{ - connect(this, &DebuggerRunTool::requestRemoteSetup, - this, &LinuxDeviceDebugSupport::handleRemoteSetupRequested); - connect(runControl, &RunControl::finished, - this, &LinuxDeviceDebugSupport::handleDebuggingFinished); + if (isQmlDebugging()) { + params.qmlServer.host = device()->sshParameters().host; + params.qmlServer.port = Utils::Port(); // port is selected later on + } + if (isCppDebugging()) { + Runnable r = runnable(); + QTC_ASSERT(r.is<StandardRunnable>(), return); + auto stdRunnable = r.as<StandardRunnable>(); + params.useExtendedRemote = true; + params.inferior.executable = stdRunnable.executable; + params.inferior.commandLineArguments = stdRunnable.commandLineArguments; + if (isQmlDebugging()) { + params.inferior.commandLineArguments.prepend(' '); + params.inferior.commandLineArguments.prepend( + QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices)); + } + params.remoteChannel = device()->sshParameters().host + ":-1"; + params.symbolFile = symbolFile; + } - connect(qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl->targetRunner()), - &AbstractRemoteLinuxRunSupport::executionStartRequested, - this, &LinuxDeviceDebugSupport::startExecution); - connect(qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl->targetRunner()), - &AbstractRemoteLinuxRunSupport::adapterSetupFailed, - this, &LinuxDeviceDebugSupport::handleAdapterSetupFailed); + setStartParameters(params); } LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport() { - delete d; -} - -AbstractRemoteLinuxRunSupport *LinuxDeviceDebugSupport::targetRunner() const -{ - return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner()); } -AbstractRemoteLinuxRunSupport::State LinuxDeviceDebugSupport::state() const +void LinuxDeviceDebugSupport::prepare() { - AbstractRemoteLinuxRunSupport *runner = targetRunner(); - return runner ? runner->state() : AbstractRemoteLinuxRunSupport::Inactive; -} - -void LinuxDeviceDebugSupport::handleRemoteSetupRequested() -{ - QTC_ASSERT(state() == AbstractRemoteLinuxRunSupport::Inactive, return); - - showMessage(tr("Checking available ports...") + QLatin1Char('\n'), LogStatus); - targetRunner()->startPortsGathering(); -} - -void LinuxDeviceDebugSupport::startExecution() -{ - QTC_ASSERT(state() == AbstractRemoteLinuxRunSupport::GatheringResources, return); + auto targetRunner = qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner()); if (isCppDebugging()) { - d->gdbServerPort = targetRunner()->findPort(); - if (!d->gdbServerPort.isValid()) { - handleAdapterSetupFailed(tr("Not enough free ports on device for C++ debugging.")); + m_gdbServerPort = targetRunner->findPort(); + if (!m_gdbServerPort.isValid()) { + reportFailure(tr("Not enough free ports on device for C++ debugging.")); return; } } if (isQmlDebugging()) { - d->qmlPort = targetRunner()->findPort(); - if (!d->qmlPort.isValid()) { - handleAdapterSetupFailed(tr("Not enough free ports on device for QML debugging.")); + m_qmlPort = targetRunner->findPort(); + if (!m_qmlPort.isValid()) { + reportFailure(tr("Not enough free ports on device for QML debugging.")); return; } } - targetRunner()->setState(AbstractRemoteLinuxRunSupport::StartingRunner); - d->gdbserverOutput.clear(); + runControl()->setRunnable(realRunnable()); - ApplicationLauncher *launcher = targetRunner()->applicationLauncher(); - connect(launcher, &ApplicationLauncher::remoteStderr, - this, &LinuxDeviceDebugSupport::handleRemoteErrorOutput); - connect(launcher, &ApplicationLauncher::remoteStdout, - this, &LinuxDeviceDebugSupport::handleRemoteOutput); - connect(launcher, &ApplicationLauncher::finished, - this, &LinuxDeviceDebugSupport::handleAppRunnerFinished); - connect(launcher, &ApplicationLauncher::reportProgress, - this, &LinuxDeviceDebugSupport::handleProgressReport); - connect(launcher, &ApplicationLauncher::reportError, - this, &LinuxDeviceDebugSupport::handleAppRunnerError); - if (isQmlDebugging() && !isCppDebugging()) - connect(launcher, &ApplicationLauncher::remoteProcessStarted, - this, &LinuxDeviceDebugSupport::handleRemoteProcessStarted); + RemoteSetupResult result; + result.success = true; + result.gdbServerPort = m_gdbServerPort; + result.qmlServerPort = m_qmlPort; + setRemoteParameters(result); - launcher->start(realRunnable(), device()); + DebuggerRunTool::prepare(); } Runnable LinuxDeviceDebugSupport::realRunnable() const @@ -153,7 +131,7 @@ Runnable LinuxDeviceDebugSupport::realRunnable() const QString command; if (isQmlDebugging()) - args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, d->qmlPort)); + args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, m_qmlPort)); if (isQmlDebugging() && !isCppDebugging()) { command = r.executable; @@ -163,102 +141,11 @@ Runnable LinuxDeviceDebugSupport::realRunnable() const command = QLatin1String("gdbserver"); args.clear(); args.append(QString::fromLatin1("--multi")); - args.append(QString::fromLatin1(":%1").arg(d->gdbServerPort.number())); + args.append(QString::fromLatin1(":%1").arg(m_gdbServerPort.number())); } r.executable = command; r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux); return r; } -void LinuxDeviceDebugSupport::handleAppRunnerError(const QString &error) -{ - if (state() == AbstractRemoteLinuxRunSupport::Running) { - showMessage(error, AppError); - notifyInferiorIll(); - } else if (state() != AbstractRemoteLinuxRunSupport::Inactive) { - handleAdapterSetupFailed(error); - } -} - -void LinuxDeviceDebugSupport::handleAppRunnerFinished(bool success) -{ - if (state() == AbstractRemoteLinuxRunSupport::Inactive) - return; - - if (state() == AbstractRemoteLinuxRunSupport::Running) { - // The QML engine does not realize on its own that the application has finished. - if (isQmlDebugging() && !isCppDebugging()) - quitDebugger(); - else if (!success) - notifyInferiorIll(); - - } else if (state() == AbstractRemoteLinuxRunSupport::StartingRunner) { - RemoteSetupResult result; - result.success = false; - result.reason = tr("Debugging failed."); - notifyEngineRemoteSetupFinished(result); - } - targetRunner()->reset(); -} - -void LinuxDeviceDebugSupport::handleDebuggingFinished() -{ - targetRunner()->setFinished(); - targetRunner()->reset(); -} - -void LinuxDeviceDebugSupport::handleRemoteOutput(const QByteArray &output) -{ - QTC_ASSERT(state() == AbstractRemoteLinuxRunSupport::Inactive - || state() == AbstractRemoteLinuxRunSupport::Running, return); - - showMessage(QString::fromUtf8(output), AppOutput); -} - -void LinuxDeviceDebugSupport::handleRemoteErrorOutput(const QByteArray &output) -{ - QTC_ASSERT(state() != AbstractRemoteLinuxRunSupport::GatheringResources, return); - - showMessage(QString::fromUtf8(output), AppError); - if (state() == AbstractRemoteLinuxRunSupport::StartingRunner && isCppDebugging()) { - d->gdbserverOutput += output; - if (d->gdbserverOutput.contains("Listening on port")) { - handleAdapterSetupDone(); - d->gdbserverOutput.clear(); - } - } -} - -void LinuxDeviceDebugSupport::handleProgressReport(const QString &progressOutput) -{ - showMessage(progressOutput + QLatin1Char('\n'), LogStatus); -} - -void LinuxDeviceDebugSupport::handleAdapterSetupFailed(const QString &error) -{ - RemoteSetupResult result; - result.success = false; - result.reason = tr("Initial setup failed: %1").arg(error); - notifyEngineRemoteSetupFinished(result); -} - -void LinuxDeviceDebugSupport::handleAdapterSetupDone() -{ - targetRunner()->setState(AbstractRemoteLinuxRunSupport::Running); - - RemoteSetupResult result; - result.success = true; - result.gdbServerPort = d->gdbServerPort; - result.qmlServerPort = d->qmlPort; - notifyEngineRemoteSetupFinished(result); -} - -void LinuxDeviceDebugSupport::handleRemoteProcessStarted() -{ - QTC_ASSERT(isQmlDebugging() && !isCppDebugging(), return); - QTC_ASSERT(state() == AbstractRemoteLinuxRunSupport::StartingRunner, return); - - handleAdapterSetupDone(); -} - } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.h b/src/plugins/remotelinux/remotelinuxdebugsupport.h index 17a35be297..7473f05593 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.h +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.h @@ -31,15 +31,12 @@ namespace RemoteLinux { -namespace Internal { class LinuxDeviceDebugSupportPrivate; } - class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public Debugger::DebuggerRunTool { Q_OBJECT public: LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl, - const Debugger::DebuggerStartParameters &sp, QString *errorMessage = nullptr); ~LinuxDeviceDebugSupport() override; @@ -47,24 +44,10 @@ protected: virtual ProjectExplorer::Runnable realRunnable() const; private: - void startExecution(); - void handleAdapterSetupFailed(const QString &error); - - void handleRemoteSetupRequested(); - void handleAppRunnerError(const QString &error); - void handleRemoteOutput(const QByteArray &output); - void handleRemoteErrorOutput(const QByteArray &output); - void handleAppRunnerFinished(bool success); - void handleProgressReport(const QString &progressOutput); - - void handleRemoteProcessStarted(); - void handleAdapterSetupDone(); - void handleDebuggingFinished(); - - AbstractRemoteLinuxRunSupport *targetRunner() const; - AbstractRemoteLinuxRunSupport::State state() const; + void prepare() override; - Internal::LinuxDeviceDebugSupportPrivate * const d; + Utils::Port m_gdbServerPort; + Utils::Port m_qmlPort; }; } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp index af07e1828f..978bb9aa90 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp @@ -41,7 +41,6 @@ #include <projectexplorer/runnables.h> #include <projectexplorer/target.h> -#include <qmldebug/qmldebugcommandlinearguments.h> #include <utils/portlist.h> #include <utils/qtcassert.h> @@ -68,7 +67,6 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Co } const Core::Id id = runConfiguration->id(); - QTC_ASSERT(runConfiguration->extraAspect<DebuggerRunConfigurationAspect>(), return false); return runConfiguration->isEnabled() && (id == RemoteLinuxCustomRunConfiguration::runConfigId() || id.name().startsWith(RemoteLinuxRunConfiguration::IdPrefix)); @@ -81,65 +79,15 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Co if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) { auto runControl = new RunControl(runConfig, mode); - (void) new SimpleTargetRunner(runControl); + (void) new AbstractRemoteLinuxRunSupport(runControl); return runControl; } - const auto rcRunnable = runConfig->runnable(); - QTC_ASSERT(rcRunnable.is<StandardRunnable>(), return 0); - const auto stdRunnable = rcRunnable.as<StandardRunnable>(); - if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) { - IDevice::ConstPtr dev = DeviceKitInformation::device(runConfig->target()->kit()); - if (!dev) { - *errorMessage = tr("Cannot debug: Kit has no device."); - return 0; - } - - auto aspect = runConfig->extraAspect<DebuggerRunConfigurationAspect>(); - QTC_ASSERT(aspect, return 0); - - int portsUsed = aspect->portsUsedByDebugger(); - if (portsUsed > dev->freePorts().count()) { - *errorMessage = tr("Cannot debug: Not enough free ports available."); - return 0; - } - - QString symbolFile; - if (auto rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig)) - symbolFile = rlrc->localExecutableFilePath(); - if (auto rlrc = qobject_cast<RemoteLinuxCustomRunConfiguration *>(runConfig)) - symbolFile = rlrc->localExecutableFilePath(); - if (symbolFile.isEmpty()) { - *errorMessage = tr("Cannot debug: Local executable is not set."); - return 0; - } - - DebuggerStartParameters params; - params.startMode = AttachToRemoteServer; - params.closeMode = KillAndExitMonitorAtClose; - params.remoteSetupNeeded = true; - - if (aspect->useQmlDebugger()) { - params.qmlServer.host = dev->sshParameters().host; - params.qmlServer.port = Utils::Port(); // port is selected later on - } - if (aspect->useCppDebugger()) { - params.useExtendedRemote = true; - params.inferior.executable = stdRunnable.executable; - params.inferior.commandLineArguments = stdRunnable.commandLineArguments; - if (aspect->useQmlDebugger()) { - params.inferior.commandLineArguments.prepend(QLatin1Char(' ')); - params.inferior.commandLineArguments.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices)); - } - params.remoteChannel = dev->sshParameters().host + QLatin1String(":-1"); - params.symbolFile = symbolFile; - } - auto runControl = new RunControl(runConfig, mode); (void) new AbstractRemoteLinuxRunSupport(runControl); - (void) new LinuxDeviceDebugSupport(runControl, params, errorMessage); + (void) new LinuxDeviceDebugSupport(runControl, errorMessage); return runControl; } diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index 090c02e6b5..a10e709b3a 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -102,7 +102,7 @@ void ValgrindToolRunner::start() return; } - reportStarted(); + reportSuccess(); } void ValgrindToolRunner::stop() @@ -160,7 +160,7 @@ void ValgrindToolRunner::runnerFinished() disconnect(runner(), &ValgrindRunner::finished, this, &ValgrindToolRunner::runnerFinished); - reportStopped(); + reportSuccess(); } void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputFormat format) |