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/remotelinux | |
parent | ac59e2be40e3d18a83ad110f60efa5f62c56e085 (diff) |
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/remotelinux')
7 files changed, 164 insertions, 378 deletions
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; } |