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/remotelinuxdebugsupport.cpp | |
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/remotelinuxdebugsupport.cpp')
-rw-r--r-- | src/plugins/remotelinux/remotelinuxdebugsupport.cpp | 221 |
1 files changed, 54 insertions, 167 deletions
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 |