forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -674,6 +674,7 @@ void DebuggerEngine::handleStartFailed()
|
|||||||
// Called from RunControl.
|
// Called from RunControl.
|
||||||
void DebuggerEngine::handleFinished()
|
void DebuggerEngine::handleFinished()
|
||||||
{
|
{
|
||||||
|
setState(DebuggerFinished);
|
||||||
showMessage("HANDLE RUNCONTROL FINISHED");
|
showMessage("HANDLE RUNCONTROL FINISHED");
|
||||||
d->m_runTool.clear();
|
d->m_runTool.clear();
|
||||||
d->m_progress.setProgressValue(1000);
|
d->m_progress.setProgressValue(1000);
|
||||||
@@ -821,7 +822,7 @@ void DebuggerEngine::notifyEngineSetupOk()
|
|||||||
|
|
||||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
|
||||||
setState(EngineSetupOk);
|
setState(EngineSetupOk);
|
||||||
runTool()->reportPrepared();
|
runTool()->reportSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEngine::setupSlaveInferior()
|
void DebuggerEngine::setupSlaveInferior()
|
||||||
@@ -907,7 +908,7 @@ void DebuggerEngine::notifyEngineRequestRemoteSetup()
|
|||||||
<< "remoteSetupState" << d->remoteSetupState());
|
<< "remoteSetupState" << d->remoteSetupState());
|
||||||
|
|
||||||
d->setRemoteSetupState(RemoteSetupRequested);
|
d->setRemoteSetupState(RemoteSetupRequested);
|
||||||
runTool()->requestRemoteSetup();
|
runTool()->doRemoteSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEngine::notifyEngineRemoteServerRunning(const QString &, int /*pid*/)
|
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");
|
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)
|
void DebuggerEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &result)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == EngineSetupRequested
|
QTC_ASSERT(state() == EngineSetupRequested
|
||||||
@@ -926,30 +951,9 @@ void DebuggerEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &re
|
|||||||
qDebug() << this << "remoteSetupState" << d->remoteSetupState());
|
qDebug() << this << "remoteSetupState" << d->remoteSetupState());
|
||||||
|
|
||||||
if (result.success) {
|
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)
|
if (d->remoteSetupState() != RemoteSetupCancelled)
|
||||||
d->setRemoteSetupState(RemoteSetupSucceeded);
|
d->setRemoteSetupState(RemoteSetupSucceeded);
|
||||||
|
setRemoteParameters(result);
|
||||||
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
d->setRemoteSetupState(RemoteSetupFailed);
|
d->setRemoteSetupState(RemoteSetupFailed);
|
||||||
showMessage("NOTE: REMOTE SETUP FAILED: " + result.reason);
|
showMessage("NOTE: REMOTE SETUP FAILED: " + result.reason);
|
||||||
|
|||||||
@@ -381,6 +381,8 @@ protected:
|
|||||||
void notifyDebuggerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus,
|
void notifyDebuggerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus,
|
||||||
const QString &backendName);
|
const QString &backendName);
|
||||||
|
|
||||||
|
void setRemoteParameters(const RemoteSetupResult &result);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void notifyInferiorShutdownOk();
|
virtual void notifyInferiorShutdownOk();
|
||||||
virtual void notifyInferiorShutdownFailed();
|
virtual void notifyInferiorShutdownFailed();
|
||||||
|
|||||||
@@ -52,8 +52,10 @@
|
|||||||
|
|
||||||
#include <utils/checkablemessagebox.h>
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
#include <utils/portlist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||||
@@ -126,9 +128,7 @@ void DebuggerRunTool::start()
|
|||||||
if (rp.startMode == StartInternal
|
if (rp.startMode == StartInternal
|
||||||
&& rp.inferior.executable.isEmpty()
|
&& rp.inferior.executable.isEmpty()
|
||||||
&& rp.interpreter.isEmpty()) {
|
&& rp.interpreter.isEmpty()) {
|
||||||
appendMessage(tr("No executable specified.") + QLatin1Char('\n'), ErrorMessageFormat);
|
reportFailure(tr("No executable specified.") + '\n');
|
||||||
runControl()->reportApplicationStart();
|
|
||||||
runControl()->reportApplicationStop();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,6 +177,11 @@ void DebuggerRunTool::notifyEngineRemoteSetupFinished(const RemoteSetupResult &r
|
|||||||
m_engine->notifyEngineRemoteSetupFinished(result);
|
m_engine->notifyEngineRemoteSetupFinished(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerRunTool::setRemoteParameters(const RemoteSetupResult &result)
|
||||||
|
{
|
||||||
|
m_engine->setRemoteParameters(result);
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::stop()
|
void DebuggerRunTool::stop()
|
||||||
{
|
{
|
||||||
m_engine->quitDebugger();
|
m_engine->quitDebugger();
|
||||||
@@ -202,6 +207,11 @@ DebuggerStartParameters &DebuggerRunTool::startParameters()
|
|||||||
return m_engine->runParameters();
|
return m_engine->runParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DebuggerRunTool::portsUsedByDebugger() const
|
||||||
|
{
|
||||||
|
return isCppDebugging() + isQmlDebugging();
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerRunTool::notifyInferiorIll()
|
void DebuggerRunTool::notifyInferiorIll()
|
||||||
{
|
{
|
||||||
m_engine->notifyInferiorIll();
|
m_engine->notifyInferiorIll();
|
||||||
@@ -510,6 +520,12 @@ void DebuggerRunTool::setStartParameters(const DebuggerStartParameters &sp, QStr
|
|||||||
|
|
||||||
void DebuggerRunTool::setRunParameters(const DebuggerRunParameters &rp, QString *errorMessage)
|
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;
|
DebuggerRunParameters m_rp = rp;
|
||||||
|
|
||||||
runControl()->setDisplayName(m_rp.displayName);
|
runControl()->setDisplayName(m_rp.displayName);
|
||||||
@@ -540,6 +556,14 @@ void DebuggerRunTool::setRunParameters(const DebuggerRunParameters &rp, QString
|
|||||||
m_engine->setRunTool(this);
|
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()
|
DebuggerRunTool::~DebuggerRunTool()
|
||||||
{
|
{
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public:
|
|||||||
void startFailed();
|
void startFailed();
|
||||||
void notifyEngineRemoteServerRunning(const QByteArray &msg, int pid);
|
void notifyEngineRemoteServerRunning(const QByteArray &msg, int pid);
|
||||||
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
|
||||||
|
void setRemoteParameters(const RemoteSetupResult &result);
|
||||||
void notifyInferiorIll();
|
void notifyInferiorIll();
|
||||||
Q_SLOT void notifyInferiorExited();
|
Q_SLOT void notifyInferiorExited();
|
||||||
void quitDebugger();
|
void quitDebugger();
|
||||||
@@ -79,6 +80,10 @@ public:
|
|||||||
|
|
||||||
bool isCppDebugging() const { return m_isCppDebugging; }
|
bool isCppDebugging() const { return m_isCppDebugging; }
|
||||||
bool isQmlDebugging() const { return m_isQmlDebugging; }
|
bool isQmlDebugging() const { return m_isQmlDebugging; }
|
||||||
|
int portsUsedByDebugger() const;
|
||||||
|
|
||||||
|
virtual void doRemoteSetup() { emit requestRemoteSetup(); }
|
||||||
|
void appendSolibSearchPath(const QString &str);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stateChanged(Debugger::DebuggerState state);
|
void stateChanged(Debugger::DebuggerState state);
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
using namespace ProjectExplorer::Internal;
|
using namespace ProjectExplorer::Internal;
|
||||||
|
|
||||||
|
const bool debugStates = false;
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
@@ -522,7 +524,7 @@ public:
|
|||||||
|
|
||||||
~RunControlPrivate()
|
~RunControlPrivate()
|
||||||
{
|
{
|
||||||
QTC_CHECK(state == State::Stopped);
|
QTC_CHECK(state == State::Stopped || state == State::Initialized);
|
||||||
delete targetRunner;
|
delete targetRunner;
|
||||||
delete toolRunner;
|
delete toolRunner;
|
||||||
delete outputFormatter;
|
delete outputFormatter;
|
||||||
@@ -544,6 +546,9 @@ public:
|
|||||||
void checkState(State expectedState);
|
void checkState(State expectedState);
|
||||||
void setState(State state);
|
void setState(State state);
|
||||||
|
|
||||||
|
void debugMessage(const QString &msg);
|
||||||
|
QString stateName(State s) const;
|
||||||
|
|
||||||
void initiateStart();
|
void initiateStart();
|
||||||
|
|
||||||
void onTargetPrepared();
|
void onTargetPrepared();
|
||||||
@@ -560,10 +565,17 @@ public:
|
|||||||
|
|
||||||
void initiateStop();
|
void initiateStop();
|
||||||
void onToolStopped();
|
void onToolStopped();
|
||||||
|
void onToolStopFailed(const QString &msg);
|
||||||
|
|
||||||
void onTargetStopped();
|
void onTargetStopped();
|
||||||
|
void onTargetStopFailed(const QString &msg);
|
||||||
|
|
||||||
void onToolFailed(const QString &msg);
|
void onToolFailed(const QString &msg);
|
||||||
|
void onToolSuccess();
|
||||||
|
|
||||||
void onTargetFailed(const QString &msg);
|
void onTargetFailed(const QString &msg);
|
||||||
|
void onTargetSuccess();
|
||||||
|
|
||||||
void handleFailure();
|
void handleFailure();
|
||||||
|
|
||||||
void showError(const QString &msg);
|
void showError(const QString &msg);
|
||||||
@@ -659,14 +671,16 @@ void RunControlPrivate::initiateStart()
|
|||||||
{
|
{
|
||||||
checkState(State::Initialized);
|
checkState(State::Initialized);
|
||||||
setState(State::TargetPreparing);
|
setState(State::TargetPreparing);
|
||||||
targetRunner->prepare();
|
debugMessage("Queue: Prepare target runner");
|
||||||
|
QTimer::singleShot(0, targetRunner, &TargetRunner::prepare);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onTargetPrepared()
|
void RunControlPrivate::onTargetPrepared()
|
||||||
{
|
{
|
||||||
checkState(State::TargetPreparing);
|
checkState(State::TargetPreparing);
|
||||||
setState(State::ToolPreparing);
|
setState(State::ToolPreparing);
|
||||||
toolRunner->prepare();
|
debugMessage("Queue: Prepare tool runner");
|
||||||
|
QTimer::singleShot(0, toolRunner, &ToolRunner::prepare);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onTargetPrepareFailed(const QString &msg)
|
void RunControlPrivate::onTargetPrepareFailed(const QString &msg)
|
||||||
@@ -681,7 +695,8 @@ void RunControlPrivate::onToolPrepared()
|
|||||||
{
|
{
|
||||||
checkState(State::ToolPreparing);
|
checkState(State::ToolPreparing);
|
||||||
setState(State::TargetStarting);
|
setState(State::TargetStarting);
|
||||||
targetRunner->start();
|
debugMessage("Queue: Start target runner");
|
||||||
|
QTimer::singleShot(0, targetRunner, &TargetRunner::start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onToolPrepareFailed(const QString &msg)
|
void RunControlPrivate::onToolPrepareFailed(const QString &msg)
|
||||||
@@ -696,7 +711,8 @@ void RunControlPrivate::onTargetStarted()
|
|||||||
{
|
{
|
||||||
checkState(State::TargetStarting);
|
checkState(State::TargetStarting);
|
||||||
setState(State::ToolStarting);
|
setState(State::ToolStarting);
|
||||||
toolRunner->start();
|
debugMessage("Queue: Start tool runner");
|
||||||
|
QTimer::singleShot(0, toolRunner, &ToolRunner::start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onTargetStartFailed(const QString &msg)
|
void RunControlPrivate::onTargetStartFailed(const QString &msg)
|
||||||
@@ -725,54 +741,109 @@ void RunControlPrivate::initiateStop()
|
|||||||
{
|
{
|
||||||
checkState(State::Running);
|
checkState(State::Running);
|
||||||
setState(State::ToolStopping);
|
setState(State::ToolStopping);
|
||||||
toolRunner->stop();
|
debugMessage("Queue: Stop tool runner");
|
||||||
|
QTimer::singleShot(0, toolRunner, &ToolRunner::stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onToolStopped()
|
void RunControlPrivate::onToolStopped()
|
||||||
{
|
{
|
||||||
toolRunner->onStop();
|
toolRunner->onStop();
|
||||||
|
debugMessage("Tool stopped");
|
||||||
checkState(State::ToolStopping);
|
checkState(State::ToolStopping);
|
||||||
setState(State::TargetStopping);
|
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()
|
void RunControlPrivate::onTargetStopped()
|
||||||
{
|
{
|
||||||
|
targetRunner->onStop();
|
||||||
|
debugMessage("Target stopped");
|
||||||
checkState(State::TargetStopping);
|
checkState(State::TargetStopping);
|
||||||
setState(State::Stopped);
|
setState(State::Stopped);
|
||||||
QTC_CHECK(applicationProcessHandle.isValid());
|
}
|
||||||
q->setApplicationProcessHandle(Utils::ProcessHandle());
|
|
||||||
|
|
||||||
toolRunner->onFinished();
|
void RunControlPrivate::onTargetStopFailed(const QString &msg)
|
||||||
targetRunner->onFinished();
|
{
|
||||||
|
debugMessage("Target stop failed");
|
||||||
|
checkState(State::TargetStopping);
|
||||||
|
toolRunner->onTargetFailure();
|
||||||
|
showError(msg);
|
||||||
|
setState(State::Stopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onTargetFailed(const QString &msg)
|
void RunControlPrivate::onTargetFailed(const QString &msg)
|
||||||
{
|
{
|
||||||
|
debugMessage("Target operation failed");
|
||||||
if (state == State::TargetPreparing) {
|
if (state == State::TargetPreparing) {
|
||||||
onTargetPrepareFailed(msg);
|
onTargetPrepareFailed(msg);
|
||||||
} else if (state == State::TargetStarting) {
|
} else if (state == State::TargetStarting) {
|
||||||
onTargetStartFailed(msg);
|
onTargetStartFailed(msg);
|
||||||
|
} else if (state == State::TargetStopping) {
|
||||||
|
onTargetStopFailed(msg);
|
||||||
} else {
|
} else {
|
||||||
showError(msg);
|
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);
|
setState(State::Stopped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onToolFailed(const QString &msg)
|
void RunControlPrivate::onToolFailed(const QString &msg)
|
||||||
{
|
{
|
||||||
|
debugMessage("Tool operation failed");
|
||||||
if (state == State::ToolPreparing) {
|
if (state == State::ToolPreparing) {
|
||||||
onToolPrepareFailed(msg);
|
onToolPrepareFailed(msg);
|
||||||
} else if (state == State::ToolStarting) {
|
} else if (state == State::ToolStarting) {
|
||||||
onToolStartFailed(msg);
|
onToolStartFailed(msg);
|
||||||
|
} else if (state == State::ToolStopping) {
|
||||||
|
onToolStartFailed(msg);
|
||||||
} else {
|
} else {
|
||||||
showError(msg);
|
showError(msg);
|
||||||
// showError(RunControl::tr("Unexpected state: %1").arg(int(state)));
|
showError(RunControl::tr("Unexpected state: %1").arg(int(state)));
|
||||||
setState(State::Stopped);
|
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()
|
void RunControlPrivate::handleFailure()
|
||||||
{
|
{
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@@ -1028,6 +1099,24 @@ void RunControlPrivate::checkState(State expectedState)
|
|||||||
qDebug() << "Unexpected state " << expectedState << " have: " << state;
|
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)
|
void RunControlPrivate::setState(State newState)
|
||||||
{
|
{
|
||||||
if (!isAllowedTransition(state, newState))
|
if (!isAllowedTransition(state, newState))
|
||||||
@@ -1035,20 +1124,32 @@ void RunControlPrivate::setState(State newState)
|
|||||||
|
|
||||||
state = newState;
|
state = newState;
|
||||||
|
|
||||||
|
debugMessage("Entering state " + stateName(newState));
|
||||||
|
|
||||||
// Extra reporting.
|
// Extra reporting.
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case State::Running:
|
case State::Running:
|
||||||
emit q->started();
|
emit q->started();
|
||||||
break;
|
break;
|
||||||
case State::Stopped:
|
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.
|
state = State::Initialized; // Reset for potential re-running.
|
||||||
|
emit q->finished();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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
|
Brings the application determined by this RunControl's \c applicationProcessHandle
|
||||||
to the foreground.
|
to the foreground.
|
||||||
@@ -1079,8 +1180,7 @@ void RunControl::reportApplicationStop()
|
|||||||
// multiple times. Fix it there and then add a soft assert here.
|
// multiple times. Fix it there and then add a soft assert here.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
d->onToolStopped();
|
d->onTargetStopped();
|
||||||
emit finished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControl::bringApplicationToForegroundInternal()
|
void RunControl::bringApplicationToForegroundInternal()
|
||||||
@@ -1145,9 +1245,9 @@ void SimpleTargetRunner::start()
|
|||||||
QTC_ASSERT(r.is<StandardRunnable>(), return);
|
QTC_ASSERT(r.is<StandardRunnable>(), return);
|
||||||
const QString executable = r.as<StandardRunnable>().executable;
|
const QString executable = r.as<StandardRunnable>().executable;
|
||||||
if (executable.isEmpty()) {
|
if (executable.isEmpty()) {
|
||||||
reportStartFailed(RunControl::tr("No executable specified."));
|
reportFailure(RunControl::tr("No executable specified."));
|
||||||
} else if (!QFileInfo::exists(executable)) {
|
} 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)));
|
.arg(QDir::toNativeSeparators(executable)));
|
||||||
} else {
|
} else {
|
||||||
QString msg = RunControl::tr("Starting %1...").arg(QDir::toNativeSeparators(executable)) + '\n';
|
QString msg = RunControl::tr("Starting %1...").arg(QDir::toNativeSeparators(executable)) + '\n';
|
||||||
@@ -1173,7 +1273,7 @@ void SimpleTargetRunner::start()
|
|||||||
connect(&m_launcher, &ApplicationLauncher::finished,
|
connect(&m_launcher, &ApplicationLauncher::finished,
|
||||||
this, [this] {
|
this, [this] {
|
||||||
m_launcher.disconnect(this);
|
m_launcher.disconnect(this);
|
||||||
reportStopped();
|
reportSuccess();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&m_launcher, &ApplicationLauncher::reportProgress,
|
connect(&m_launcher, &ApplicationLauncher::reportProgress,
|
||||||
@@ -1195,7 +1295,7 @@ void SimpleTargetRunner::onProcessStarted()
|
|||||||
// Console processes only know their pid after being started
|
// Console processes only know their pid after being started
|
||||||
runControl()->setApplicationProcessHandle(m_launcher.applicationPID());
|
runControl()->setApplicationProcessHandle(m_launcher.applicationPID());
|
||||||
runControl()->bringApplicationToForeground();
|
runControl()->bringApplicationToForeground();
|
||||||
reportStarted();
|
reportSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleTargetRunner::onProcessFinished(int exitCode, QProcess::ExitStatus status)
|
void SimpleTargetRunner::onProcessFinished(int exitCode, QProcess::ExitStatus status)
|
||||||
@@ -1219,6 +1319,10 @@ TargetRunner::TargetRunner(RunControl *runControl)
|
|||||||
runControl->setTargetRunner(this);
|
runControl->setTargetRunner(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TargetRunner::~TargetRunner()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RunControl *TargetRunner::runControl() const
|
RunControl *TargetRunner::runControl() const
|
||||||
{
|
{
|
||||||
return m_runControl;
|
return m_runControl;
|
||||||
@@ -1236,48 +1340,29 @@ IDevice::ConstPtr TargetRunner::device() const
|
|||||||
|
|
||||||
void TargetRunner::prepare()
|
void TargetRunner::prepare()
|
||||||
{
|
{
|
||||||
reportPrepared(); // By default nothing to do, all is fine.
|
reportSuccess(); // 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TargetRunner::start()
|
void TargetRunner::start()
|
||||||
{
|
{
|
||||||
reportStarted();
|
reportSuccess();
|
||||||
}
|
|
||||||
|
|
||||||
void TargetRunner::reportStartFailed(const QString &msg)
|
|
||||||
{
|
|
||||||
m_runControl->d->onTargetStartFailed(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TargetRunner::stop()
|
void TargetRunner::stop()
|
||||||
{
|
{
|
||||||
reportStopped(); // By default all is fine.
|
reportSuccess(); // By default all is fine.
|
||||||
}
|
|
||||||
|
|
||||||
void TargetRunner::reportStarted()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_runControl, return);
|
|
||||||
m_runControl->d->onTargetStarted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TargetRunner::reportStopped()
|
void TargetRunner::reportStopped()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_runControl, return);
|
|
||||||
onStop();
|
|
||||||
m_runControl->d->onTargetStopped();
|
m_runControl->d->onTargetStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TargetRunner::reportSuccess()
|
||||||
|
{
|
||||||
|
m_runControl->d->onTargetSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
void TargetRunner::reportFailure(const QString &msg)
|
void TargetRunner::reportFailure(const QString &msg)
|
||||||
{
|
{
|
||||||
m_runControl->d->onTargetFailed(msg);
|
m_runControl->d->onTargetFailed(msg);
|
||||||
@@ -1292,6 +1377,10 @@ ToolRunner::ToolRunner(RunControl *runControl)
|
|||||||
runControl->setToolRunner(this);
|
runControl->setToolRunner(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ToolRunner::~ToolRunner()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RunControl *ToolRunner::runControl() const
|
RunControl *ToolRunner::runControl() const
|
||||||
{
|
{
|
||||||
return m_runControl;
|
return m_runControl;
|
||||||
@@ -1319,41 +1408,17 @@ const Connection &ToolRunner::connection() const
|
|||||||
|
|
||||||
void ToolRunner::prepare()
|
void ToolRunner::prepare()
|
||||||
{
|
{
|
||||||
reportPrepared();
|
reportSuccess();
|
||||||
}
|
|
||||||
|
|
||||||
void ToolRunner::reportPrepared()
|
|
||||||
{
|
|
||||||
m_runControl->d->onToolPrepared();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolRunner::start()
|
void ToolRunner::start()
|
||||||
{
|
{
|
||||||
reportStarted();
|
reportSuccess();
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolRunner::stop()
|
void ToolRunner::stop()
|
||||||
{
|
{
|
||||||
reportStopped();
|
reportSuccess();
|
||||||
}
|
|
||||||
|
|
||||||
void ToolRunner::reportStopFailed(const QString &msg)
|
|
||||||
{
|
|
||||||
QTC_CHECK(m_runControl->d->state == RunControlPrivate::State::ToolStopping);
|
|
||||||
m_runControl->d->targetRunner->onToolFailure();
|
|
||||||
reportFailure(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolRunner::reportStopped()
|
void ToolRunner::reportStopped()
|
||||||
@@ -1361,6 +1426,11 @@ void ToolRunner::reportStopped()
|
|||||||
m_runControl->d->onToolStopped();
|
m_runControl->d->onToolStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToolRunner::reportSuccess()
|
||||||
|
{
|
||||||
|
m_runControl->d->onToolSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
void ToolRunner::reportFailure(const QString &msg)
|
void ToolRunner::reportFailure(const QString &msg)
|
||||||
{
|
{
|
||||||
m_runControl->d->onToolFailed(msg);
|
m_runControl->d->onToolFailed(msg);
|
||||||
|
|||||||
@@ -454,6 +454,7 @@ class PROJECTEXPLORER_EXPORT TargetRunner : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TargetRunner(RunControl *runControl);
|
explicit TargetRunner(RunControl *runControl);
|
||||||
|
~TargetRunner() override;
|
||||||
|
|
||||||
RunControl *runControl() const;
|
RunControl *runControl() const;
|
||||||
void appendMessage(const QString &msg, Utils::OutputFormat format);
|
void appendMessage(const QString &msg, Utils::OutputFormat format);
|
||||||
@@ -461,20 +462,16 @@ public:
|
|||||||
|
|
||||||
// Preparation phase.
|
// Preparation phase.
|
||||||
virtual void prepare(); // Initiate setup. Needs to report result.
|
virtual void prepare(); // Initiate setup. Needs to report result.
|
||||||
void reportPrepareFailed(const QString &msg = QString());
|
|
||||||
void reportPrepared();
|
|
||||||
|
|
||||||
// Startup phase.
|
// Startup phase.
|
||||||
virtual void start(); // Initiates start. Needs to report result.
|
virtual void start(); // Initiates start. Needs to report result.
|
||||||
void reportStartFailed(const QString &msg = QString());
|
|
||||||
void reportStarted();
|
|
||||||
|
|
||||||
// Stopping phase.
|
// Stopping phase.
|
||||||
virtual void stop(); // Initiates stop. Needs to report result.
|
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());
|
void reportFailure(const QString &msg = QString());
|
||||||
|
|
||||||
// Customization points. No reporting required nor wanted.
|
// Customization points. No reporting required nor wanted.
|
||||||
@@ -497,6 +494,7 @@ class PROJECTEXPLORER_EXPORT ToolRunner : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ToolRunner(RunControl *runControl);
|
explicit ToolRunner(RunControl *runControl);
|
||||||
|
~ToolRunner() override;
|
||||||
|
|
||||||
RunControl *runControl() const;
|
RunControl *runControl() const;
|
||||||
|
|
||||||
@@ -508,20 +506,16 @@ public:
|
|||||||
|
|
||||||
// Preparation phase.
|
// Preparation phase.
|
||||||
virtual void prepare(); // Initiates preparation, needs to report success or failure.
|
virtual void prepare(); // Initiates preparation, needs to report success or failure.
|
||||||
void reportPrepareFailed(const QString &msg = QString());
|
|
||||||
void reportPrepared();
|
|
||||||
|
|
||||||
// Start phase.
|
// Start phase.
|
||||||
virtual void start();
|
virtual void start();
|
||||||
void reportStartFailed(const QString &msg = QString());
|
|
||||||
void reportStarted();
|
|
||||||
|
|
||||||
// Stop phase.
|
// Stop phase.
|
||||||
virtual void stop();
|
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());
|
void reportFailure(const QString &msg = QString());
|
||||||
|
|
||||||
// Customization points. No reporting required nor wanted.
|
// Customization points. No reporting required nor wanted.
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <utils/portlist.h>
|
#include <utils/portlist.h>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -42,11 +43,11 @@ class AbstractRemoteLinuxRunSupportPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ApplicationLauncher launcher;
|
ApplicationLauncher launcher;
|
||||||
AbstractRemoteLinuxRunSupport::State state = AbstractRemoteLinuxRunSupport::Inactive;
|
|
||||||
DeviceUsedPortsGatherer portsGatherer;
|
DeviceUsedPortsGatherer portsGatherer;
|
||||||
ApplicationLauncher fifoCreator;
|
ApplicationLauncher fifoCreator;
|
||||||
Utils::PortList portList;
|
PortList portList;
|
||||||
QString fifo;
|
QString fifo;
|
||||||
|
bool usesFifo = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -61,7 +62,6 @@ AbstractRemoteLinuxRunSupport::AbstractRemoteLinuxRunSupport(RunControl *runCont
|
|||||||
|
|
||||||
AbstractRemoteLinuxRunSupport::~AbstractRemoteLinuxRunSupport()
|
AbstractRemoteLinuxRunSupport::~AbstractRemoteLinuxRunSupport()
|
||||||
{
|
{
|
||||||
setFinished();
|
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,42 +70,12 @@ ApplicationLauncher *AbstractRemoteLinuxRunSupport::applicationLauncher()
|
|||||||
return &d->launcher;
|
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
|
Port AbstractRemoteLinuxRunSupport::findPort() 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
|
|
||||||
{
|
{
|
||||||
return d->portsGatherer.getNextFreePort(&d->portList);
|
return d->portsGatherer.getNextFreePort(&d->portList);
|
||||||
}
|
}
|
||||||
@@ -115,21 +85,31 @@ QString AbstractRemoteLinuxRunSupport::fifo() const
|
|||||||
return d->fifo;
|
return d->fifo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractRemoteLinuxRunSupport::prepare()
|
||||||
|
{
|
||||||
|
if (d->usesFifo)
|
||||||
|
createRemoteFifo();
|
||||||
|
else
|
||||||
|
startPortsGathering();
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunSupport::startPortsGathering()
|
void AbstractRemoteLinuxRunSupport::startPortsGathering()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->state == Inactive, return);
|
appendMessage(tr("Checking available ports...") + '\n', NormalMessageFormat);
|
||||||
d->state = GatheringResources;
|
connect(&d->portsGatherer, &DeviceUsedPortsGatherer::error, this, [&](const QString &msg) {
|
||||||
connect(&d->portsGatherer, &DeviceUsedPortsGatherer::error,
|
reportFailure(msg);
|
||||||
this, &AbstractRemoteLinuxRunSupport::handleResourcesError);
|
});
|
||||||
connect(&d->portsGatherer, &DeviceUsedPortsGatherer::portListReady,
|
connect(&d->portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [&] {
|
||||||
this, &AbstractRemoteLinuxRunSupport::handleResourcesAvailable);
|
d->portList = device()->freePorts();
|
||||||
|
//appendMessage(tr("Found %1 free ports").arg(d->portList.count()), NormalMessageFormat);
|
||||||
|
reportSuccess();
|
||||||
|
});
|
||||||
d->portsGatherer.start(device());
|
d->portsGatherer.start(device());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractRemoteLinuxRunSupport::createRemoteFifo()
|
void AbstractRemoteLinuxRunSupport::createRemoteFifo()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->state == Inactive, return);
|
appendMessage(tr("Creating remote socket...") + '\n', NormalMessageFormat);
|
||||||
d->state = GatheringResources;
|
|
||||||
|
|
||||||
StandardRunnable r;
|
StandardRunnable r;
|
||||||
r.executable = QLatin1String("/bin/sh");
|
r.executable = QLatin1String("/bin/sh");
|
||||||
@@ -143,10 +123,11 @@ void AbstractRemoteLinuxRunSupport::createRemoteFifo()
|
|||||||
connect(&d->fifoCreator, &ApplicationLauncher::finished,
|
connect(&d->fifoCreator, &ApplicationLauncher::finished,
|
||||||
this, [this, output, errors](bool success) {
|
this, [this, output, errors](bool success) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
handleResourcesError(QString("Failed to create fifo: %1").arg(QLatin1String(*errors)));
|
reportFailure(QString("Failed to create fifo: %1").arg(QLatin1String(*errors)));
|
||||||
} else {
|
} else {
|
||||||
d->fifo = QString::fromLatin1(*output);
|
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());
|
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);
|
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
|
} // namespace RemoteLinux
|
||||||
|
|||||||
@@ -41,39 +41,30 @@ class REMOTELINUX_EXPORT AbstractRemoteLinuxRunSupport : public ProjectExplorer:
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum State
|
|
||||||
{
|
|
||||||
Inactive,
|
|
||||||
GatheringResources,
|
|
||||||
StartingRunner,
|
|
||||||
Running
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit AbstractRemoteLinuxRunSupport(ProjectExplorer::RunControl *runControl);
|
explicit AbstractRemoteLinuxRunSupport(ProjectExplorer::RunControl *runControl);
|
||||||
~AbstractRemoteLinuxRunSupport();
|
~AbstractRemoteLinuxRunSupport();
|
||||||
|
|
||||||
ProjectExplorer::ApplicationLauncher *applicationLauncher();
|
ProjectExplorer::ApplicationLauncher *applicationLauncher();
|
||||||
|
|
||||||
void setState(State state);
|
void setUsesFifo(bool on);
|
||||||
State state() const;
|
|
||||||
|
|
||||||
void setFinished();
|
|
||||||
|
|
||||||
void startPortsGathering();
|
|
||||||
Utils::Port findPort() const;
|
Utils::Port findPort() const;
|
||||||
|
|
||||||
void createRemoteFifo();
|
|
||||||
QString fifo() const;
|
QString fifo() const;
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void adapterSetupFailed(const QString &error);
|
|
||||||
void executionStartRequested();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleResourcesError(const QString &message);
|
void prepare() override;
|
||||||
void handleResourcesAvailable();
|
void start() override;
|
||||||
|
void onFinished() override;
|
||||||
|
|
||||||
|
void createRemoteFifo();
|
||||||
|
void startPortsGathering();
|
||||||
|
|
||||||
|
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;
|
Internal::AbstractRemoteLinuxRunSupportPrivate * const d;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -53,16 +53,17 @@ class RemoteLinuxAnalyzeSupportPrivate
|
|||||||
public:
|
public:
|
||||||
RemoteLinuxAnalyzeSupportPrivate(RunControl *runControl)
|
RemoteLinuxAnalyzeSupportPrivate(RunControl *runControl)
|
||||||
{
|
{
|
||||||
if (runControl->runMode() != ProjectExplorer::Constants::PERFPROFILER_RUN_MODE)
|
if (runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||||
return;
|
usesFifo = true;
|
||||||
RunConfiguration *runConfiguration = runControl->runConfiguration();
|
RunConfiguration *runConfiguration = runControl->runConfiguration();
|
||||||
QTC_ASSERT(runConfiguration, return);
|
QTC_ASSERT(runConfiguration, return);
|
||||||
IRunConfigurationAspect *perfAspect =
|
IRunConfigurationAspect *perfAspect =
|
||||||
runConfiguration->extraAspect("Analyzer.Perf.Settings");
|
runConfiguration->extraAspect("Analyzer.Perf.Settings");
|
||||||
QTC_ASSERT(perfAspect, return);
|
QTC_ASSERT(perfAspect, return);
|
||||||
perfRecordArguments =
|
perfRecordArguments =
|
||||||
perfAspect->currentSettings()->property("perfRecordArguments").toStringList()
|
perfAspect->currentSettings()->property("perfRecordArguments").toStringList()
|
||||||
.join(' ');
|
.join(' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Port qmlPort;
|
Utils::Port qmlPort;
|
||||||
@@ -71,6 +72,7 @@ public:
|
|||||||
|
|
||||||
ApplicationLauncher outputGatherer;
|
ApplicationLauncher outputGatherer;
|
||||||
QmlDebug::QmlOutputParser outputParser;
|
QmlDebug::QmlOutputParser outputParser;
|
||||||
|
bool usesFifo = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -81,19 +83,9 @@ RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RunControl *runControl)
|
|||||||
: ToolRunner(runControl),
|
: ToolRunner(runControl),
|
||||||
d(new RemoteLinuxAnalyzeSupportPrivate(runControl))
|
d(new RemoteLinuxAnalyzeSupportPrivate(runControl))
|
||||||
{
|
{
|
||||||
connect(runControl, &RunControl::starting,
|
|
||||||
this, &RemoteLinuxAnalyzeSupport::handleRemoteSetupRequested);
|
|
||||||
connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
|
connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
|
||||||
this, &RemoteLinuxAnalyzeSupport::remoteIsRunning);
|
this, &RemoteLinuxAnalyzeSupport::remoteIsRunning);
|
||||||
connect(runControl, &RunControl::finished,
|
targetRunner()->setUsesFifo(runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
|
RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
|
||||||
@@ -103,48 +95,27 @@ RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
|
|||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
|
void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
|
||||||
{
|
{
|
||||||
if (targetRunner()->state() != AbstractRemoteLinuxRunSupport::Inactive)
|
appendMessage(msg, format);
|
||||||
appendMessage(msg, format);
|
|
||||||
d->outputParser.processOutput(msg);
|
d->outputParser.processOutput(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::handleRemoteSetupRequested()
|
void RemoteLinuxAnalyzeSupport::start()
|
||||||
{
|
{
|
||||||
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()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(targetRunner()->state() == AbstractRemoteLinuxRunSupport::GatheringResources, return);
|
|
||||||
|
|
||||||
const Core::Id runMode = runControl()->runMode();
|
const Core::Id runMode = runControl()->runMode();
|
||||||
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
||||||
d->qmlPort = targetRunner()->findPort();
|
d->qmlPort = targetRunner()->findPort();
|
||||||
if (!d->qmlPort.isValid()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
} else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
} else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
|
||||||
d->remoteFifo = targetRunner()->fifo();
|
d->remoteFifo = targetRunner()->fifo();
|
||||||
if (d->remoteFifo.isEmpty()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
targetRunner()->setState(AbstractRemoteLinuxRunSupport::StartingRunner);
|
|
||||||
|
|
||||||
ApplicationLauncher *runner = targetRunner()->applicationLauncher();
|
ApplicationLauncher *runner = targetRunner()->applicationLauncher();
|
||||||
connect(runner, &ApplicationLauncher::remoteStderr,
|
connect(runner, &ApplicationLauncher::remoteStderr,
|
||||||
this, &RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput);
|
this, &RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput);
|
||||||
@@ -190,26 +161,18 @@ void RemoteLinuxAnalyzeSupport::startExecution()
|
|||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::handleAppRunnerError(const QString &error)
|
void RemoteLinuxAnalyzeSupport::handleAppRunnerError(const QString &error)
|
||||||
{
|
{
|
||||||
if (targetRunner()->state() == AbstractRemoteLinuxRunSupport::Running)
|
showMessage(error, Utils::ErrorMessageFormat);
|
||||||
showMessage(error, Utils::ErrorMessageFormat);
|
reportFailure(error);
|
||||||
else if (targetRunner()->state() != AbstractRemoteLinuxRunSupport::Inactive)
|
|
||||||
handleAdapterSetupFailed(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::handleAppRunnerFinished(bool success)
|
void RemoteLinuxAnalyzeSupport::handleAppRunnerFinished(bool success)
|
||||||
{
|
{
|
||||||
// reset needs to be called first to ensure that the correct state is set.
|
// reset needs to be called first to ensure that the correct state is set.
|
||||||
targetRunner()->reset();
|
|
||||||
if (!success)
|
if (!success)
|
||||||
showMessage(tr("Failure running remote process."), Utils::NormalMessageFormat);
|
showMessage(tr("Failure running remote process."), Utils::NormalMessageFormat);
|
||||||
runControl()->notifyRemoteFinished();
|
runControl()->notifyRemoteFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::handleProfilingFinished()
|
|
||||||
{
|
|
||||||
targetRunner()->setFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::remoteIsRunning()
|
void RemoteLinuxAnalyzeSupport::remoteIsRunning()
|
||||||
{
|
{
|
||||||
runControl()->notifyRemoteSetupDone(d->qmlPort);
|
runControl()->notifyRemoteSetupDone(d->qmlPort);
|
||||||
@@ -222,16 +185,11 @@ AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const
|
|||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
|
void RemoteLinuxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(targetRunner()->state() == AbstractRemoteLinuxRunSupport::Inactive
|
|
||||||
|| targetRunner()->state() == AbstractRemoteLinuxRunSupport::Running, return);
|
|
||||||
|
|
||||||
showMessage(QString::fromUtf8(output), Utils::StdOutFormat);
|
showMessage(QString::fromUtf8(output), Utils::StdOutFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output)
|
void RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(targetRunner()->state() != AbstractRemoteLinuxRunSupport::GatheringResources, return);
|
|
||||||
|
|
||||||
showMessage(QString::fromUtf8(output), Utils::StdErrFormat);
|
showMessage(QString::fromUtf8(output), Utils::StdErrFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,9 +205,6 @@ void RemoteLinuxAnalyzeSupport::handleAdapterSetupFailed(const QString &error)
|
|||||||
|
|
||||||
void RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted()
|
void RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(targetRunner()->state() == AbstractRemoteLinuxRunSupport::StartingRunner, return);
|
|
||||||
|
|
||||||
targetRunner()->setState(AbstractRemoteLinuxRunSupport::Running);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
~RemoteLinuxAnalyzeSupport() override;
|
~RemoteLinuxAnalyzeSupport() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startExecution();
|
void start() override;
|
||||||
void handleAdapterSetupFailed(const QString &error);
|
void handleAdapterSetupFailed(const QString &error);
|
||||||
|
|
||||||
void handleRemoteSetupRequested();
|
void handleRemoteSetupRequested();
|
||||||
@@ -55,7 +55,6 @@ private:
|
|||||||
void handleProgressReport(const QString &progressOutput);
|
void handleProgressReport(const QString &progressOutput);
|
||||||
|
|
||||||
void handleRemoteProcessStarted();
|
void handleRemoteProcessStarted();
|
||||||
void handleProfilingFinished();
|
|
||||||
|
|
||||||
void remoteIsRunning();
|
void remoteIsRunning();
|
||||||
AbstractRemoteLinuxRunSupport *targetRunner() const;
|
AbstractRemoteLinuxRunSupport *targetRunner() const;
|
||||||
|
|||||||
@@ -25,10 +25,10 @@
|
|||||||
|
|
||||||
#include "remotelinuxdebugsupport.h"
|
#include "remotelinuxdebugsupport.h"
|
||||||
|
|
||||||
|
#include "remotelinuxcustomrunconfiguration.h"
|
||||||
#include "remotelinuxrunconfiguration.h"
|
#include "remotelinuxrunconfiguration.h"
|
||||||
|
|
||||||
#include <debugger/debuggerruncontrol.h>
|
#include <debugger/debuggerruncontrol.h>
|
||||||
#include <debugger/debuggerstartparameters.h>
|
|
||||||
|
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
@@ -41,109 +41,87 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QPointer>
|
|
||||||
|
|
||||||
using namespace QSsh;
|
|
||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class LinuxDeviceDebugSupportPrivate
|
LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString *errorMessage)
|
||||||
|
: DebuggerRunTool(runControl)
|
||||||
{
|
{
|
||||||
public:
|
RunConfiguration *runConfig = runControl->runConfiguration();
|
||||||
QByteArray gdbserverOutput;
|
|
||||||
Port gdbServerPort;
|
|
||||||
Port qmlPort;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // 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,
|
if (isQmlDebugging()) {
|
||||||
const Debugger::DebuggerStartParameters &sp,
|
params.qmlServer.host = device()->sshParameters().host;
|
||||||
QString *errorMessage)
|
params.qmlServer.port = Utils::Port(); // port is selected later on
|
||||||
: DebuggerRunTool(runControl, sp, errorMessage),
|
}
|
||||||
d(new LinuxDeviceDebugSupportPrivate)
|
if (isCppDebugging()) {
|
||||||
{
|
Runnable r = runnable();
|
||||||
connect(this, &DebuggerRunTool::requestRemoteSetup,
|
QTC_ASSERT(r.is<StandardRunnable>(), return);
|
||||||
this, &LinuxDeviceDebugSupport::handleRemoteSetupRequested);
|
auto stdRunnable = r.as<StandardRunnable>();
|
||||||
connect(runControl, &RunControl::finished,
|
params.useExtendedRemote = true;
|
||||||
this, &LinuxDeviceDebugSupport::handleDebuggingFinished);
|
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()),
|
setStartParameters(params);
|
||||||
&AbstractRemoteLinuxRunSupport::executionStartRequested,
|
|
||||||
this, &LinuxDeviceDebugSupport::startExecution);
|
|
||||||
connect(qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl->targetRunner()),
|
|
||||||
&AbstractRemoteLinuxRunSupport::adapterSetupFailed,
|
|
||||||
this, &LinuxDeviceDebugSupport::handleAdapterSetupFailed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
|
LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
|
||||||
{
|
{
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractRemoteLinuxRunSupport *LinuxDeviceDebugSupport::targetRunner() const
|
void LinuxDeviceDebugSupport::prepare()
|
||||||
{
|
{
|
||||||
return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
|
auto targetRunner = qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRemoteLinuxRunSupport::State LinuxDeviceDebugSupport::state() const
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (isCppDebugging()) {
|
if (isCppDebugging()) {
|
||||||
d->gdbServerPort = targetRunner()->findPort();
|
m_gdbServerPort = targetRunner->findPort();
|
||||||
if (!d->gdbServerPort.isValid()) {
|
if (!m_gdbServerPort.isValid()) {
|
||||||
handleAdapterSetupFailed(tr("Not enough free ports on device for C++ debugging."));
|
reportFailure(tr("Not enough free ports on device for C++ debugging."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isQmlDebugging()) {
|
if (isQmlDebugging()) {
|
||||||
d->qmlPort = targetRunner()->findPort();
|
m_qmlPort = targetRunner->findPort();
|
||||||
if (!d->qmlPort.isValid()) {
|
if (!m_qmlPort.isValid()) {
|
||||||
handleAdapterSetupFailed(tr("Not enough free ports on device for QML debugging."));
|
reportFailure(tr("Not enough free ports on device for QML debugging."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
targetRunner()->setState(AbstractRemoteLinuxRunSupport::StartingRunner);
|
runControl()->setRunnable(realRunnable());
|
||||||
d->gdbserverOutput.clear();
|
|
||||||
|
|
||||||
ApplicationLauncher *launcher = targetRunner()->applicationLauncher();
|
RemoteSetupResult result;
|
||||||
connect(launcher, &ApplicationLauncher::remoteStderr,
|
result.success = true;
|
||||||
this, &LinuxDeviceDebugSupport::handleRemoteErrorOutput);
|
result.gdbServerPort = m_gdbServerPort;
|
||||||
connect(launcher, &ApplicationLauncher::remoteStdout,
|
result.qmlServerPort = m_qmlPort;
|
||||||
this, &LinuxDeviceDebugSupport::handleRemoteOutput);
|
setRemoteParameters(result);
|
||||||
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);
|
|
||||||
|
|
||||||
launcher->start(realRunnable(), device());
|
DebuggerRunTool::prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
Runnable LinuxDeviceDebugSupport::realRunnable() const
|
Runnable LinuxDeviceDebugSupport::realRunnable() const
|
||||||
@@ -153,7 +131,7 @@ Runnable LinuxDeviceDebugSupport::realRunnable() const
|
|||||||
QString command;
|
QString command;
|
||||||
|
|
||||||
if (isQmlDebugging())
|
if (isQmlDebugging())
|
||||||
args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, d->qmlPort));
|
args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, m_qmlPort));
|
||||||
|
|
||||||
if (isQmlDebugging() && !isCppDebugging()) {
|
if (isQmlDebugging() && !isCppDebugging()) {
|
||||||
command = r.executable;
|
command = r.executable;
|
||||||
@@ -163,102 +141,11 @@ Runnable LinuxDeviceDebugSupport::realRunnable() const
|
|||||||
command = QLatin1String("gdbserver");
|
command = QLatin1String("gdbserver");
|
||||||
args.clear();
|
args.clear();
|
||||||
args.append(QString::fromLatin1("--multi"));
|
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.executable = command;
|
||||||
r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
|
r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
|
||||||
return r;
|
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
|
} // namespace RemoteLinux
|
||||||
|
|||||||
@@ -31,15 +31,12 @@
|
|||||||
|
|
||||||
namespace RemoteLinux {
|
namespace RemoteLinux {
|
||||||
|
|
||||||
namespace Internal { class LinuxDeviceDebugSupportPrivate; }
|
|
||||||
|
|
||||||
class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public Debugger::DebuggerRunTool
|
class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public Debugger::DebuggerRunTool
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl,
|
LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl,
|
||||||
const Debugger::DebuggerStartParameters &sp,
|
|
||||||
QString *errorMessage = nullptr);
|
QString *errorMessage = nullptr);
|
||||||
~LinuxDeviceDebugSupport() override;
|
~LinuxDeviceDebugSupport() override;
|
||||||
|
|
||||||
@@ -47,24 +44,10 @@ protected:
|
|||||||
virtual ProjectExplorer::Runnable realRunnable() const;
|
virtual ProjectExplorer::Runnable realRunnable() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startExecution();
|
void prepare() override;
|
||||||
void handleAdapterSetupFailed(const QString &error);
|
|
||||||
|
|
||||||
void handleRemoteSetupRequested();
|
Utils::Port m_gdbServerPort;
|
||||||
void handleAppRunnerError(const QString &error);
|
Utils::Port m_qmlPort;
|
||||||
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;
|
|
||||||
|
|
||||||
Internal::LinuxDeviceDebugSupportPrivate * const d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RemoteLinux
|
} // namespace RemoteLinux
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include <projectexplorer/runnables.h>
|
#include <projectexplorer/runnables.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
|
||||||
|
|
||||||
#include <utils/portlist.h>
|
#include <utils/portlist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -68,7 +67,6 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Core::Id id = runConfiguration->id();
|
const Core::Id id = runConfiguration->id();
|
||||||
QTC_ASSERT(runConfiguration->extraAspect<DebuggerRunConfigurationAspect>(), return false);
|
|
||||||
return runConfiguration->isEnabled()
|
return runConfiguration->isEnabled()
|
||||||
&& (id == RemoteLinuxCustomRunConfiguration::runConfigId()
|
&& (id == RemoteLinuxCustomRunConfiguration::runConfigId()
|
||||||
|| id.name().startsWith(RemoteLinuxRunConfiguration::IdPrefix));
|
|| id.name().startsWith(RemoteLinuxRunConfiguration::IdPrefix));
|
||||||
@@ -81,65 +79,15 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Co
|
|||||||
|
|
||||||
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
|
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
|
||||||
auto runControl = new RunControl(runConfig, mode);
|
auto runControl = new RunControl(runConfig, mode);
|
||||||
(void) new SimpleTargetRunner(runControl);
|
(void) new AbstractRemoteLinuxRunSupport(runControl);
|
||||||
return 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
|
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE
|
||||||
|| mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) {
|
|| 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);
|
auto runControl = new RunControl(runConfig, mode);
|
||||||
(void) new AbstractRemoteLinuxRunSupport(runControl);
|
(void) new AbstractRemoteLinuxRunSupport(runControl);
|
||||||
(void) new LinuxDeviceDebugSupport(runControl, params, errorMessage);
|
(void) new LinuxDeviceDebugSupport(runControl, errorMessage);
|
||||||
return runControl;
|
return runControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ void ValgrindToolRunner::start()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reportStarted();
|
reportSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValgrindToolRunner::stop()
|
void ValgrindToolRunner::stop()
|
||||||
@@ -160,7 +160,7 @@ void ValgrindToolRunner::runnerFinished()
|
|||||||
disconnect(runner(), &ValgrindRunner::finished,
|
disconnect(runner(), &ValgrindRunner::finished,
|
||||||
this, &ValgrindToolRunner::runnerFinished);
|
this, &ValgrindToolRunner::runnerFinished);
|
||||||
|
|
||||||
reportStopped();
|
reportSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputFormat format)
|
void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputFormat format)
|
||||||
|
|||||||
Reference in New Issue
Block a user