aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2017-05-04 12:12:27 +0200
committerhjk <hjk@qt.io>2017-05-05 11:17:49 +0000
commit2a46b1521daa4d65cffd2b7fb00e68b4eec31f30 (patch)
tree59006139dc404c7f6e8ac94e39bd6011bad71857 /src/plugins/remotelinux/remotelinuxdebugsupport.cpp
parentac59e2be40e3d18a83ad110f60efa5f62c56e085 (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.cpp221
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