aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2017-05-09 10:25:11 +0200
committerhjk <hjk@qt.io>2017-05-15 14:35:03 +0000
commit89f02cba2ca65f84d99b0b35f555da024f3e2234 (patch)
tree408bd4b2da13e00227697f871cefbf1ea9c4ab98
parent9b93d5a330a4898d12ce99414a51d1bd6cda51ec (diff)
ProjectExplorer: Split Target and ToolRunners into smaller tasks
This increases re-usability of activities like 'port gathering', and makes their use less dependent on actual device implementations. Change-Id: I017cb74874f2b38c487ba2d03906a675d5618647 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r--src/libs/utils/port.h7
-rw-r--r--src/plugins/android/androidanalyzesupport.cpp5
-rw-r--r--src/plugins/android/androidanalyzesupport.h2
-rw-r--r--src/plugins/android/androidrunnable.h1
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp5
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h2
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp2
-rw-r--r--src/plugins/debugger/analyzer/analyzermanager.h7
-rw-r--r--src/plugins/debugger/debuggerengine.cpp29
-rw-r--r--src/plugins/debugger/debuggerengine.h3
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp14
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp124
-rw-r--r--src/plugins/debugger/debuggerruncontrol.h51
-rw-r--r--src/plugins/ios/iosanalyzesupport.cpp2
-rw-r--r--src/plugins/ios/iosanalyzesupport.h2
-rw-r--r--src/plugins/ios/iosrunfactories.cpp7
-rw-r--r--src/plugins/projectexplorer/appoutputpane.cpp9
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp36
-rw-r--r--src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h26
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.h6
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp746
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h189
-rw-r--r--src/plugins/projectexplorer/runnables.h2
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp7
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrol.h5
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp5
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.cpp20
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.h2
-rw-r--r--src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp12
-rw-r--r--src/plugins/qnx/qnx.pro4
-rw-r--r--src/plugins/qnx/qnx.qbs4
-rw-r--r--src/plugins/qnx/qnxabstractrunsupport.cpp124
-rw-r--r--src/plugins/qnx/qnxabstractrunsupport.h91
-rw-r--r--src/plugins/qnx/qnxanalyzesupport.cpp141
-rw-r--r--src/plugins/qnx/qnxanalyzesupport.h27
-rw-r--r--src/plugins/qnx/qnxattachdebugsupport.cpp6
-rw-r--r--src/plugins/qnx/qnxdebugsupport.cpp217
-rw-r--r--src/plugins/qnx/qnxdebugsupport.h42
-rw-r--r--src/plugins/qnx/qnxruncontrol.cpp72
-rw-r--r--src/plugins/qnx/qnxruncontrol.h50
-rw-r--r--src/plugins/qnx/qnxruncontrolfactory.cpp60
-rw-r--r--src/plugins/qnx/slog2inforunner.cpp43
-rw-r--r--src/plugins/qnx/slog2inforunner.h27
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp139
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxrunsupport.h30
-rw-r--r--src/plugins/remotelinux/remotelinuxanalyzesupport.cpp382
-rw-r--r--src/plugins/remotelinux/remotelinuxanalyzesupport.h121
-rw-r--r--src/plugins/remotelinux/remotelinuxdebugsupport.cpp98
-rw-r--r--src/plugins/remotelinux/remotelinuxdebugsupport.h11
-rw-r--r--src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp40
-rw-r--r--src/plugins/valgrind/callgrindtool.cpp10
-rw-r--r--src/plugins/valgrind/memchecktool.cpp28
-rw-r--r--src/plugins/valgrind/valgrindengine.cpp6
-rw-r--r--src/plugins/valgrind/valgrindengine.h2
-rw-r--r--src/plugins/winrt/winrtdebugsupport.cpp2
-rw-r--r--src/plugins/winrt/winrtdebugsupport.h2
56 files changed, 1267 insertions, 1840 deletions
diff --git a/src/libs/utils/port.h b/src/libs/utils/port.h
index c05c8b2d38..e668c46265 100644
--- a/src/libs/utils/port.h
+++ b/src/libs/utils/port.h
@@ -27,8 +27,11 @@
#include "utils_global.h"
#include "qtcassert.h"
-#include <limits>
+
#include <QMetaType>
+#include <QString>
+
+#include <limits>
namespace Utils {
@@ -50,6 +53,8 @@ public:
quint16 number() const { QTC_ASSERT(isValid(), return 0); return quint16(m_port); }
bool isValid() const { return m_port != -1; }
+ QString toString() const { return QString::number(m_port); }
+
private:
int m_port;
};
diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp
index bf5579c867..4ee0463489 100644
--- a/src/plugins/android/androidanalyzesupport.cpp
+++ b/src/plugins/android/androidanalyzesupport.cpp
@@ -48,7 +48,8 @@ namespace Internal {
RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(RunConfiguration *runConfig, Core::Id runMode)
{
- RunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, runMode);
+ auto runControl = new RunControl(runConfig, runMode);
+ runControl->createWorker(runMode);
QTC_ASSERT(runControl, return 0);
AnalyzerConnection connection;
if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
@@ -64,7 +65,7 @@ RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(RunConfiguration *run
}
AndroidAnalyzeSupport::AndroidAnalyzeSupport(RunControl *runControl)
- : ToolRunner(runControl)
+ : RunWorker(runControl)
{
auto runner = new AndroidRunner(this, runControl->runConfiguration(), runControl->runMode());
diff --git a/src/plugins/android/androidanalyzesupport.h b/src/plugins/android/androidanalyzesupport.h
index 887796153d..6c96fc658a 100644
--- a/src/plugins/android/androidanalyzesupport.h
+++ b/src/plugins/android/androidanalyzesupport.h
@@ -34,7 +34,7 @@
namespace Android {
namespace Internal {
-class AndroidAnalyzeSupport : public ProjectExplorer::ToolRunner
+class AndroidAnalyzeSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT
diff --git a/src/plugins/android/androidrunnable.h b/src/plugins/android/androidrunnable.h
index c6ff742112..0c1a894250 100644
--- a/src/plugins/android/androidrunnable.h
+++ b/src/plugins/android/androidrunnable.h
@@ -40,6 +40,7 @@ struct ANDROID_EXPORT AndroidRunnable
QVector<QStringList> afterFinishADBCommands;
QString deviceSerialNumber;
+ QString displayName() const { return packageName; }
static void *staticTypeId;
};
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
index 37721ec772..43fdf32bc0 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
@@ -71,8 +71,9 @@ namespace Internal {
ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runControl,
QString *errorMessage)
- : ToolRunner(runControl)
+ : RunWorker(runControl)
{
+ setDisplayName("ClangStaticAnalyzerRunner");
runControl->setDisplayName(tr("Clang Static Analyzer"));
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
runControl->setSupportsReRunning(false);
@@ -585,7 +586,7 @@ void ClangStaticAnalyzerToolRunner::start()
return;
}
- reportSuccess();
+ reportStarted();
while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty())
analyzeNextFile();
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
index 28d7600493..3c6b4267d7 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
@@ -47,7 +47,7 @@ struct AnalyzeUnit {
};
typedef QList<AnalyzeUnit> AnalyzeUnits;
-class ClangStaticAnalyzerToolRunner : public ProjectExplorer::ToolRunner
+class ClangStaticAnalyzerToolRunner : public ProjectExplorer::RunWorker
{
Q_OBJECT
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
index e1e7c2adef..c8f1f6c8ba 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
@@ -145,7 +145,7 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool()
{{ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical}}
));
- Debugger::registerAction(Constants::CLANGSTATICANALYZER_RUN_MODE, {});
+ //Debugger::registerAction(Constants::CLANGSTATICANALYZER_RUN_MODE, {});
action = new QAction(tr("Clang Static Analyzer"), this);
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, "ClangStaticAnalyzer.Action"),
diff --git a/src/plugins/debugger/analyzer/analyzermanager.h b/src/plugins/debugger/analyzer/analyzermanager.h
index 3558a79646..9a3dedd9d9 100644
--- a/src/plugins/debugger/analyzer/analyzermanager.h
+++ b/src/plugins/debugger/analyzer/analyzermanager.h
@@ -59,16 +59,12 @@ enum ToolMode {
//AnyMode = DebugMode | ProfileMode | ReleaseMode
};
-using RunControlCreator = std::function<ProjectExplorer::RunControl *
- (ProjectExplorer::RunConfiguration *runConfiguration, Core::Id runMode)>;
-
// FIXME: Merge with something sensible.
DEBUGGER_EXPORT bool wantRunTool(ToolMode toolMode, const QString &toolName);
DEBUGGER_EXPORT void showCannotStartDialog(const QString &toolName);
DEBUGGER_EXPORT ProjectExplorer::RunConfiguration *startupRunConfiguration();
// Register a tool for a given start mode.
-DEBUGGER_EXPORT void registerAction(Core::Id runMode, const RunControlCreator &runControlCreator);
DEBUGGER_EXPORT void registerPerspective(const QByteArray &perspectiveId, const Utils::Perspective *perspective);
DEBUGGER_EXPORT void registerToolbar(const QByteArray &perspectiveId, const Utils::ToolbarDescription &desc);
@@ -85,7 +81,4 @@ DEBUGGER_EXPORT void showPermanentStatusMessage(const QString &message);
DEBUGGER_EXPORT QAction *createStartAction();
DEBUGGER_EXPORT QAction *createStopAction();
-DEBUGGER_EXPORT ProjectExplorer::RunControl *createAnalyzerRunControl(
- ProjectExplorer::RunConfiguration *runConfiguration, Core::Id runMode);
-
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index d99a2cdec0..31a3997dd5 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -561,7 +561,7 @@ void DebuggerEngine::setRunTool(DebuggerRunTool *runTool)
d->m_runTool = runTool;
}
-void DebuggerEngine::prepare()
+void DebuggerEngine::start()
{
QTC_ASSERT(d->m_runTool, notifyEngineSetupFailed(); return);
@@ -602,25 +602,7 @@ void DebuggerEngine::prepare()
}
d->queueSetupEngine();
-}
-
-void DebuggerEngine::start()
-{
- Internal::runControlStarted(this);
-
- // We might get a synchronous startFailed() notification on Windows,
- // when launching the process fails. Emit a proper finished() sequence.
- //runControl()->reportApplicationStart();
-
- showMessage("QUEUE: SETUP INFERIOR");
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
-// if (isMasterEngine())
- d->queueSetupInferior();
-}
-
-void DebuggerEngine::startDebugger()
-{
- d->queueRunEngine();
}
void DebuggerEngine::resetLocation()
@@ -822,7 +804,9 @@ void DebuggerEngine::notifyEngineSetupOk()
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state());
setState(EngineSetupOk);
- runTool()->reportSuccess();
+
+ Internal::runControlStarted(this);
+ d->queueSetupInferior();
}
void DebuggerEngine::setupSlaveInferior()
@@ -1313,6 +1297,11 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
DebuggerToolTipManager::registerEngine(this);
}
+ if (state == InferiorUnrunnable || state == InferiorRunOk) {
+ if (isMasterEngine() && runTool())
+ runTool()->reportStarted();
+ }
+
if (state == DebuggerFinished) {
// Give up ownership on claimed breakpoints.
foreach (Breakpoint bp, breakHandler()->engineBreakpoints(this))
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index 75a1174af9..aa927b89dd 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -202,11 +202,8 @@ public:
virtual void setRunTool(DebuggerRunTool *runTool);
DebuggerRunTool *runTool() const;
- void prepare();
void start();
- void startDebugger();
-
enum {
// Remove need to qualify each use.
NeedsTemporaryStop = DebuggerCommand::NeedsTemporaryStop,
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index c712f8246b..5af6473faf 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -973,7 +973,6 @@ public:
QPointer<QWidget> m_modeWindow;
QPointer<DebugMode> m_mode;
- QHash<Id, RunControlCreator> m_runControlCreators;
ActionContainer *m_menu = 0;
// DockWidgetEventFilter m_resizeEventFilter;
@@ -3527,11 +3526,6 @@ bool wantRunTool(ToolMode toolMode, const QString &toolName)
return true;
}
-void registerAction(Id runMode, const RunControlCreator &runControlCreator)
-{
- dd->m_runControlCreators.insert(runMode, runControlCreator);
-}
-
void registerToolbar(const QByteArray &perspectiveId, const ToolbarDescription &desc)
{
auto toolbar = new QWidget;
@@ -3605,14 +3599,6 @@ void showPermanentStatusMessage(const QString &message)
dd->m_mainWindow->showStatusMessage(message, -1);
}
-RunControl *createAnalyzerRunControl(RunConfiguration *runConfiguration, Id runMode)
-{
- RunControlCreator rcc = dd->m_runControlCreators.value(runMode);
- if (rcc)
- return rcc(runConfiguration, runMode);
- return nullptr;
-}
-
namespace Internal {
static bool s_testRun = false;
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index 9e62606f36..2e5f42db98 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -109,19 +109,15 @@ static QLatin1String engineTypeName(DebuggerEngineType et)
return QLatin1String("No engine");
}
-void DebuggerRunTool::prepare()
+void DebuggerRunTool::start()
{
Debugger::Internal::saveModeToRestore();
Debugger::selectPerspective(Debugger::Constants::CppPerspectiveId);
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO);
TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
- m_engine->prepare();
-}
-
-void DebuggerRunTool::start()
-{
DebuggerEngine *engine = m_engine;
+
QTC_ASSERT(engine, return);
const DebuggerRunParameters &rp = engine->runParameters();
// User canceled input dialog asking for executable when working on library project.
@@ -177,11 +173,6 @@ void DebuggerRunTool::notifyEngineRemoteSetupFinished(const RemoteSetupResult &r
m_engine->notifyEngineRemoteSetupFinished(result);
}
-void DebuggerRunTool::setRemoteParameters(const RemoteSetupResult &result)
-{
- m_engine->setRemoteParameters(result);
-}
-
void DebuggerRunTool::stop()
{
m_engine->quitDebugger();
@@ -199,7 +190,7 @@ void DebuggerRunTool::onTargetFailure()
void DebuggerRunTool::debuggingFinished()
{
- runControl()->reportApplicationStop();
+ reportStopped();
}
DebuggerStartParameters &DebuggerRunTool::startParameters()
@@ -495,10 +486,11 @@ static DebuggerRunConfigurationAspect *debuggerAspect(const RunControl *runContr
/// DebuggerRunTool
DebuggerRunTool::DebuggerRunTool(RunControl *runControl)
- : ToolRunner(runControl),
+ : RunWorker(runControl),
m_isCppDebugging(debuggerAspect(runControl)->useCppDebugger()),
m_isQmlDebugging(debuggerAspect(runControl)->useQmlDebugger())
{
+ setDisplayName("DebuggerRunTool");
}
DebuggerRunTool::DebuggerRunTool(RunControl *runControl, const DebuggerStartParameters &sp, QString *errorMessage)
@@ -577,7 +569,7 @@ DebuggerRunTool::~DebuggerRunTool()
void DebuggerRunTool::onFinished()
{
- appendMessage(tr("Debugging has finished") + '\n', NormalMessageFormat);
+ appendMessage(tr("Debugging has finished"), NormalMessageFormat);
runControlFinished(m_engine);
}
@@ -619,8 +611,9 @@ public:
QTC_ASSERT(runConfig, return 0);
QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0);
+ DebuggerStartParameters sp;
auto runControl = new RunControl(runConfig, mode);
- (void) new DebuggerRunTool(runControl, DebuggerStartParameters(), errorMessage);
+ (void) new DebuggerRunTool(runControl, sp, errorMessage);
return runControl;
}
@@ -690,10 +683,109 @@ RunControl *createAndScheduleRun(const DebuggerRunParameters &rp, Kit *kit)
QTC_ASSERT(runConfig, return nullptr);
auto runControl = new RunControl(runConfig, DebugRunMode);
(void) new DebuggerRunTool(runControl, rp);
- QTC_ASSERT(runControl, return nullptr);
ProjectExplorerPlugin::startRunControl(runControl);
return runControl;
}
} // Internal
+
+// GdbServerPortGatherer
+
+GdbServerPortsGatherer::GdbServerPortsGatherer(RunControl *runControl)
+ : RunWorker(runControl)
+{
+}
+
+GdbServerPortsGatherer::~GdbServerPortsGatherer()
+{
+}
+
+void GdbServerPortsGatherer::start()
+{
+ appendMessage(tr("Checking available ports..."), NormalMessageFormat);
+ connect(&m_portsGatherer, &DeviceUsedPortsGatherer::error, this, [this](const QString &msg) {
+ reportFailure(msg);
+ });
+ connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [this] {
+ Utils::PortList portList = device()->freePorts();
+ appendMessage(tr("Found %1 free ports").arg(portList.count()), NormalMessageFormat);
+ if (m_useGdbServer) {
+ m_gdbServerPort = m_portsGatherer.getNextFreePort(&portList);
+ if (!m_gdbServerPort.isValid()) {
+ reportFailure(tr("Not enough free ports on device for C++ debugging."));
+ return;
+ }
+ }
+ if (m_useQmlServer) {
+ m_qmlServerPort = m_portsGatherer.getNextFreePort(&portList);
+ if (!m_qmlServerPort.isValid()) {
+ reportFailure(tr("Not enough free ports on device for QML debugging."));
+ return;
+ }
+ }
+ reportStarted();
+ });
+ m_portsGatherer.start(device());
+}
+
+
+// GdbServerRunner
+
+GdbServerRunner::GdbServerRunner(RunControl *runControl)
+ : RunWorker(runControl)
+{
+ setDisplayName("GdbServerRunner");
+}
+
+GdbServerRunner::~GdbServerRunner()
+{
+}
+
+void GdbServerRunner::start()
+{
+ auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
+ QTC_ASSERT(portsGatherer, reportFailure(); return);
+
+ StandardRunnable r = runnable().as<StandardRunnable>();
+ QStringList args = QtcProcess::splitArgs(r.commandLineArguments, OsTypeLinux);
+ QString command;
+
+ const bool isQmlDebugging = portsGatherer->useQmlServer();
+ const bool isCppDebugging = portsGatherer->useGdbServer();
+
+ if (isQmlDebugging) {
+ args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
+ portsGatherer->qmlServerPort()));
+ }
+
+ if (isQmlDebugging && !isCppDebugging) {
+ command = r.executable;
+ } else {
+ command = device()->debugServerPath();
+ if (command.isEmpty())
+ command = "gdbserver";
+ args.clear();
+ args.append(QString("--multi"));
+ args.append(QString(":%1").arg(portsGatherer->gdbServerPort().number()));
+ }
+ r.executable = command;
+ r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
+
+ connect(&m_gdbServer, &ApplicationLauncher::error, this, [this] {
+ reportFailure(tr("GDBserver start failed"));
+ });
+ connect(&m_gdbServer, &ApplicationLauncher::remoteProcessStarted, this, [this] {
+ appendMessage(tr("GDBserver started") + '\n', NormalMessageFormat);
+ reportStarted();
+ });
+
+ appendMessage(tr("Starting GDBserver...") + '\n', NormalMessageFormat);
+ m_gdbServer.start(r, device());
+}
+
+void GdbServerRunner::onFinished()
+{
+ m_gdbServer.stop();
+}
+
} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h
index fef388cc91..29c5a7e545 100644
--- a/src/plugins/debugger/debuggerruncontrol.h
+++ b/src/plugins/debugger/debuggerruncontrol.h
@@ -30,13 +30,14 @@
#include "debuggerengine.h"
#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
namespace Debugger {
class RemoteSetupResult;
class DebuggerStartParameters;
-class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::ToolRunner
+class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker
{
Q_OBJECT
@@ -60,16 +61,14 @@ public:
void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1);
- void prepare() override;
void start() override;
void stop() override;
- void onTargetFailure() override;
void onFinished() override;
void startFailed();
+ void onTargetFailure();
void notifyEngineRemoteServerRunning(const QByteArray &msg, int pid);
void notifyEngineRemoteSetupFinished(const RemoteSetupResult &result);
- void setRemoteParameters(const RemoteSetupResult &result);
void notifyInferiorIll();
Q_SLOT void notifyInferiorExited();
void quitDebugger();
@@ -97,4 +96,48 @@ private:
const bool m_isQmlDebugging;
};
+class DEBUGGER_EXPORT GdbServerPortsGatherer : public ProjectExplorer::RunWorker
+{
+ Q_OBJECT
+
+public:
+ explicit GdbServerPortsGatherer(ProjectExplorer::RunControl *runControl);
+ ~GdbServerPortsGatherer();
+
+ void setUseGdbServer(bool useIt) { m_useGdbServer = useIt; }
+ bool useGdbServer() const { return m_useGdbServer; }
+ Utils::Port gdbServerPort() const { return m_gdbServerPort; }
+
+ void setUseQmlServer(bool useIt) { m_useQmlServer = useIt; }
+ bool useQmlServer() const { return m_useQmlServer; }
+ Utils::Port qmlServerPort() const { return m_qmlServerPort; }
+
+private:
+ void start();
+
+ ProjectExplorer::DeviceUsedPortsGatherer m_portsGatherer;
+ bool m_useGdbServer = false;
+ bool m_useQmlServer = false;
+ Utils::Port m_gdbServerPort;
+ Utils::Port m_qmlServerPort;
+};
+
+class DEBUGGER_EXPORT GdbServerRunner : public ProjectExplorer::RunWorker
+{
+ Q_OBJECT
+
+public:
+ explicit GdbServerRunner(ProjectExplorer::RunControl *runControl);
+ ~GdbServerRunner();
+
+private:
+ void start() override;
+ void onFinished() override;
+
+ ProjectExplorer::ApplicationLauncher m_gdbServer;
+};
+
+extern DEBUGGER_EXPORT const char GdbServerRunnerWorkerId[];
+extern DEBUGGER_EXPORT const char GdbServerPortGathererWorkerId[];
+
} // namespace Debugger
diff --git a/src/plugins/ios/iosanalyzesupport.cpp b/src/plugins/ios/iosanalyzesupport.cpp
index 5bdb9a2da7..795da9d1aa 100644
--- a/src/plugins/ios/iosanalyzesupport.cpp
+++ b/src/plugins/ios/iosanalyzesupport.cpp
@@ -32,7 +32,7 @@ namespace Ios {
namespace Internal {
IosAnalyzeSupport::IosAnalyzeSupport(RunControl *runControl, bool cppDebug, bool qmlDebug)
- : ToolRunner(runControl),
+ : RunWorker(runControl),
m_runner(new IosRunner(this, runControl, cppDebug, qmlDebug ? QmlDebug::QmlProfilerServices :
QmlDebug::NoQmlDebugServices))
{
diff --git a/src/plugins/ios/iosanalyzesupport.h b/src/plugins/ios/iosanalyzesupport.h
index 6c3677d1a7..2b621034ea 100644
--- a/src/plugins/ios/iosanalyzesupport.h
+++ b/src/plugins/ios/iosanalyzesupport.h
@@ -34,7 +34,7 @@ namespace Internal {
class IosRunner;
-class IosAnalyzeSupport : public ProjectExplorer::ToolRunner
+class IosAnalyzeSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT
diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp
index b331fdb9f4..5571258d63 100644
--- a/src/plugins/ios/iosrunfactories.cpp
+++ b/src/plugins/ios/iosrunfactories.cpp
@@ -184,11 +184,8 @@ RunControl *IosRunControlFactory::create(RunConfiguration *runConfig,
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE)
res = new Ios::Internal::IosRunControl(rc);
else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
- RunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
- QTC_ASSERT(runControl, return 0);
- IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
- if (device.isNull())
- return 0;
+ auto runControl = new RunControl(runConfig, mode);
+ runControl->createWorker(mode);
auto iosRunConfig = qobject_cast<IosRunConfiguration *>(runConfig);
StandardRunnable runnable;
runnable.executable = iosRunConfig->localExecutable().toUserOutput();
diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp
index 3757a0e7b7..ce5511e910 100644
--- a/src/plugins/projectexplorer/appoutputpane.cpp
+++ b/src/plugins/projectexplorer/appoutputpane.cpp
@@ -525,11 +525,16 @@ void AppOutputPane::attachToRunControl()
void AppOutputPane::stopRunControl()
{
const int index = currentIndex();
- QTC_ASSERT(index != -1 && m_runControlTabs.at(index).runControl->isRunning(), return);
-
+ QTC_ASSERT(index != -1, return);
RunControl *rc = m_runControlTabs.at(index).runControl;
+ QTC_ASSERT(rc, return);
+
if (rc->isRunning() && optionallyPromptToStop(rc))
rc->initiateStop();
+ else if (rc->isStarting()) {
+ QTC_CHECK(false);
+ rc->initiateStop();
+ }
if (debug)
qDebug() << "OutputPane::stopRunControl " << rc;
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
index 60f4a39ca7..c5396677e8 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.cpp
@@ -190,4 +190,40 @@ void DeviceUsedPortsGatherer::handleRemoteStdErr()
d->remoteStderr += d->process->readAllStandardError();
}
+// PortGatherer
+
+PortsGatherer::PortsGatherer(RunControl *runControl)
+ : RunWorker(runControl)
+{
+ setDisplayName("PortGatherer");
+}
+
+PortsGatherer::~PortsGatherer()
+{
+}
+
+void PortsGatherer::start()
+{
+ appendMessage(tr("Checking available ports...") + '\n', NormalMessageFormat);
+ connect(&m_portsGatherer, &DeviceUsedPortsGatherer::error, this, [this](const QString &msg) {
+ reportFailure(msg);
+ });
+ connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [this] {
+ m_portList = device()->freePorts();
+ appendMessage(tr("Found %1 free ports").arg(m_portList.count()) + '\n', NormalMessageFormat);
+ reportStarted();
+ });
+ m_portsGatherer.start(device());
+}
+
+Port PortsGatherer::findPort()
+{
+ return m_portsGatherer.getNextFreePort(&m_portList);
+}
+
+void PortsGatherer::stop()
+{
+ m_portsGatherer.stop();
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
index e326557469..c298b6fbd0 100644
--- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
+++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h
@@ -27,10 +27,9 @@
#include "idevice.h"
-namespace Utils {
-class Port;
-class PortList;
-} // namespace Utils
+#include <projectexplorer/runconfiguration.h>
+
+#include <utils/portlist.h>
namespace ProjectExplorer {
namespace Internal { class DeviceUsedPortsGathererPrivate; }
@@ -64,4 +63,23 @@ private:
Internal::DeviceUsedPortsGathererPrivate * const d;
};
+class PROJECTEXPLORER_EXPORT PortsGatherer : public RunWorker
+{
+ Q_OBJECT
+
+public:
+ explicit PortsGatherer(RunControl *runControl);
+ ~PortsGatherer() override;
+
+ Utils::Port findPort();
+
+protected:
+ void start() override;
+ void stop() override;
+
+private:
+ DeviceUsedPortsGatherer m_portsGatherer;
+ Utils::PortList m_portList;
+};
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index a48962c674..a93a029821 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -35,6 +35,8 @@
#include <QSharedPointer>
#include <QVariantMap>
+#include <functional>
+
QT_BEGIN_NAMESPACE
class QWidget;
QT_END_NAMESPACE
@@ -54,6 +56,8 @@ class Connection;
class DeviceProcess;
class DeviceProcessList;
class Kit;
+class RunControl;
+class RunWorker;
namespace Internal { class IDevicePrivate; }
@@ -162,6 +166,8 @@ public:
virtual DeviceProcessSignalOperation::Ptr signalOperation() const = 0;
virtual DeviceEnvironmentFetcher::Ptr environmentFetcher() const;
+ virtual std::function<RunWorker *(RunControl *)> workerCreator(Core::Id) const { return {}; }
+
enum DeviceState { DeviceReadyToUse, DeviceConnected, DeviceDisconnected, DeviceStateUnknown };
DeviceState deviceState() const;
void setDeviceState(const DeviceState state);
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index a7d75c38e9..219cc5baff 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -48,6 +48,8 @@
#include <QDir>
#include <QPushButton>
#include <QTimer>
+#include <QLoggingCategory>
+#include <QSettings>
#ifdef Q_OS_OSX
#include <ApplicationServices/ApplicationServices.h>
@@ -60,7 +62,9 @@
using namespace Utils;
using namespace ProjectExplorer::Internal;
-const bool debugStates = false;
+namespace {
+Q_LOGGING_CATEGORY(statesLog, "qtc.projectmanager.states")
+}
namespace ProjectExplorer {
@@ -506,6 +510,70 @@ IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect(RunCon
namespace Internal {
+enum class RunWorkerState
+{
+ Initialized, Starting, Running, Stopping, Done, Failed
+};
+
+//static QString stateName(RunWorkerState s)
+//{
+//# define SN(x) case x: return QLatin1String(#x);
+// switch (s) {
+// SN(RunWorkerState::Initialized)
+// SN(RunWorkerState::Starting)
+// SN(RunWorkerState::Running)
+// SN(RunWorkerState::Stopping)
+// SN(RunWorkerState::Done)
+// SN(RunWorkerState::Failed)
+// }
+// return QLatin1String("<unknown>");
+//# undef SN
+//}
+
+class RunWorkerPrivate : public QObject
+{
+public:
+ RunWorkerPrivate(RunWorker *runWorker, RunControl *runControl);
+
+ bool canStart() const;
+ void timerEvent(QTimerEvent *ev) override;
+
+ RunWorker *q;
+ RunWorkerState state = RunWorkerState::Initialized;
+ RunControl *runControl;
+ QList<RunWorker *> dependencies;
+ QString displayName;
+
+ QVariantMap data;
+ int startWatchdogInterval = 0;
+ int startWatchdogTimerId = -1;
+ int stopWatchdogInterval = 0; // 5000;
+ int stopWatchdogTimerId = -1;
+};
+
+enum class RunControlState
+{
+ Initialized, // Default value after creation.
+ Starting, // Actual process/tool starts.
+ Running, // All good and running.
+ Stopping, // initiateStop() was called, stop application/tool
+ Stopped, // all good, but stopped. Can possibly be re-started
+};
+
+static QString stateName(RunControlState s)
+{
+# define SN(x) case x: return QLatin1String(#x);
+ switch (s) {
+ SN(RunControlState::Initialized)
+ SN(RunControlState::Starting)
+ SN(RunControlState::Running)
+ SN(RunControlState::Stopping)
+ SN(RunControlState::Stopped)
+ }
+ return QLatin1String("<unknown>");
+# undef SN
+}
+
class RunControlPrivate : public QObject
{
public:
@@ -524,63 +592,30 @@ public:
~RunControlPrivate()
{
- QTC_CHECK(state == State::Stopped || state == State::Initialized);
- delete targetRunner;
- delete toolRunner;
+ QTC_CHECK(state == RunControlState::Stopped || state == RunControlState::Initialized);
+ qDeleteAll(m_workers);
delete outputFormatter;
}
- enum class State {
- Initialized, // Default value after creation.
- TargetPreparing, // initiateStart() was called, target boots up, connects, etc
- ToolPreparing, // Target is acessible, tool boots
- TargetStarting, // Late corrections on the target side after tool is available.
- ToolStarting, // Actual process/tool starts.
- Running, // All good and running.
- ToolStopping, // initiateStop() was called, stop application/tool
- TargetStopping, // Potential clean up on target, set idle state, etc.
- Stopped, // all good, but stopped. Can possibly be re-started
- };
- Q_ENUM(State)
-
- void checkState(State expectedState);
- void setState(State state);
+ Q_ENUM(RunControlState)
+
+ void checkState(RunControlState expectedState);
+ void setState(RunControlState state);
void debugMessage(const QString &msg);
- QString stateName(State s) const;
void initiateStart();
-
- void onTargetPrepared();
- void onTargetPrepareFailed(const QString &msg);
-
- void onToolPrepared();
- void onToolPrepareFailed(const QString &msg);
-
- void onTargetStarted();
- void onTargetStartFailed(const QString &msg);
-
- void onToolStarted();
- void onToolStartFailed(const QString &msg);
-
+ void continueStart();
void initiateStop();
- void onToolStopped();
- void onToolStopFailed(const QString &msg);
+ void continueStop();
- void onTargetStopped();
- void onTargetStopFailed(const QString &msg);
-
- void onToolFailed(const QString &msg);
- void onToolSuccess();
-
- void onTargetFailed(const QString &msg);
- void onTargetSuccess();
-
- void handleFailure();
+ void onWorkerStarted(RunWorker *worker);
+ void onWorkerStopped(RunWorker *worker);
+ void onWorkerFailed(RunWorker *worker, const QString &msg);
void showError(const QString &msg);
- static bool isAllowedTransition(State from, State to);
+ static bool isAllowedTransition(RunControlState from, RunControlState to);
RunControl *q;
QString displayName;
@@ -591,17 +626,17 @@ public:
Utils::Icon icon;
const QPointer<RunConfiguration> runConfiguration; // Not owned.
QPointer<Project> project; // Not owned.
- QPointer<TargetRunner> targetRunner; // Owned. QPointer as "extra safety" for now.
- QPointer<ToolRunner> toolRunner; // Owned. QPointer as "extra safety" for now.
Utils::OutputFormatter *outputFormatter = nullptr;
std::function<bool(bool*)> promptToStop;
// A handle to the actual application process.
Utils::ProcessHandle applicationProcessHandle;
- State state = State::Initialized;
+ RunControlState state = RunControlState::Initialized;
bool supportsReRunning = true;
+ QList<QPointer<RunWorker>> m_workers;
+
#ifdef Q_OS_OSX
// This is used to bring apps in the foreground on Mac
int foregroundCount;
@@ -615,8 +650,6 @@ using namespace Internal;
RunControl::RunControl(RunConfiguration *runConfiguration, Core::Id mode) :
d(new RunControlPrivate(this, runConfiguration, mode))
{
- (void) new TargetRunner(this);
- (void) new ToolRunner(this);
#ifdef WITH_JOURNALD
JournaldWatcher::instance()->subscribe(this, [this](const JournaldWatcher::LogEntry &entry) {
if (entry.value("_MACHINE_ID") != JournaldWatcher::instance()->machineId())
@@ -667,204 +700,178 @@ void RunControl::stop()
d->initiateStop();
}
-void RunControlPrivate::initiateStart()
-{
- checkState(State::Initialized);
- setState(State::TargetPreparing);
- debugMessage("Queue: Prepare target runner");
- QTimer::singleShot(0, targetRunner, [this](){ targetRunner->prepare(); });
-}
-
-void RunControlPrivate::onTargetPrepared()
-{
- checkState(State::TargetPreparing);
- setState(State::ToolPreparing);
- debugMessage("Queue: Prepare tool runner");
- QTimer::singleShot(0, toolRunner, [this](){ toolRunner->prepare(); });
-}
-
-void RunControlPrivate::onTargetPrepareFailed(const QString &msg)
-{
- checkState(State::TargetPreparing);
- toolRunner->onTargetFailure();
- showError(msg);
- setState(State::Stopped);
-}
-
-void RunControlPrivate::onToolPrepared()
-{
- checkState(State::ToolPreparing);
- setState(State::TargetStarting);
- debugMessage("Queue: Start target runner");
- QTimer::singleShot(0, targetRunner, [this](){ targetRunner->start(); });
-}
+using WorkerCreators = QHash<Core::Id, RunControl::WorkerCreator>;
-void RunControlPrivate::onToolPrepareFailed(const QString &msg)
+static WorkerCreators &theWorkerCreators()
{
- checkState(State::ToolPreparing);
- targetRunner->onToolFailure();
- showError(msg);
- setState(State::Stopped);
+ static WorkerCreators creators;
+ return creators;
}
-void RunControlPrivate::onTargetStarted()
+void RunControl::registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator)
{
- checkState(State::TargetStarting);
- setState(State::ToolStarting);
- debugMessage("Queue: Start tool runner");
- QTimer::singleShot(0, toolRunner, [this](){ toolRunner->start(); });
+ theWorkerCreators().insert(id, workerCreator);
+ auto keys = theWorkerCreators().keys();
+ Q_UNUSED(keys);
}
-void RunControlPrivate::onTargetStartFailed(const QString &msg)
+QList<QPointer<RunWorker> > RunControl::workers() const
{
- checkState(State::TargetStarting);
- toolRunner->onTargetFailure();
- showError(msg);
- setState(State::Stopped);
+ return d->m_workers;
}
-void RunControlPrivate::onToolStarted()
+RunWorker *RunControl::createWorker(Core::Id id)
{
- checkState(State::ToolStarting);
- setState(State::Running);
+ auto keys = theWorkerCreators().keys();
+ Q_UNUSED(keys);
+ RunWorkerCreator creator = theWorkerCreators().value(id);
+ if (creator)
+ return creator(this);
+ creator = device()->workerCreator(id);
+ if (creator)
+ return creator(this);
+ return nullptr;
}
-void RunControlPrivate::onToolStartFailed(const QString &msg)
+void RunControlPrivate::initiateStart()
{
- checkState(State::ToolStarting);
- targetRunner->onToolFailure();
- showError(msg);
- setState(State::Stopped);
+ checkState(RunControlState::Initialized);
+ setState(RunControlState::Starting);
+ debugMessage("Queue: Starting");
+
+ continueStart();
+}
+
+void RunControlPrivate::continueStart()
+{
+ checkState(RunControlState::Starting);
+ bool allDone = true;
+ debugMessage("Looking for next worker");
+ for (RunWorker *worker : m_workers) {
+ if (worker) {
+ debugMessage(" Examining worker " + worker->displayName());
+ switch (worker->d->state) {
+ case RunWorkerState::Initialized:
+ debugMessage(" " + worker->displayName() + " is not done yet.");
+ if (worker->d->canStart()) {
+ debugMessage("Starting " + worker->displayName());
+ worker->d->state = RunWorkerState::Starting;
+ QTimer::singleShot(0, worker, &RunWorker::initiateStart);
+ return;
+ }
+ allDone = false;
+ debugMessage(" " + worker->displayName() + " cannot start.");
+ break;
+ case RunWorkerState::Starting:
+ debugMessage(" " + worker->displayName() + " currently starting");
+ allDone = false;
+ break;
+ case RunWorkerState::Running:
+ debugMessage(" " + worker->displayName() + " currently running");
+ break;
+ case RunWorkerState::Stopping:
+ debugMessage(" " + worker->displayName() + " currently stopping");
+ continue;
+ case RunWorkerState::Failed:
+ // Should not happen.
+ debugMessage(" " + worker->displayName() + " failed before");
+ QTC_CHECK(false);
+ //setState(RunControlState::Stopped);
+ break;
+ case RunWorkerState::Done:
+ debugMessage(" " + worker->displayName() + " was done before");
+ break;
+ }
+ } else {
+ debugMessage("Found unknown deleted worker while starting");
+ }
+ }
+ if (allDone)
+ setState(RunControlState::Running);
}
void RunControlPrivate::initiateStop()
{
- checkState(State::Running);
- setState(State::ToolStopping);
- debugMessage("Queue: Stop tool runner");
- QTimer::singleShot(0, toolRunner, [this](){ toolRunner->stop(); });
-}
-
-void RunControlPrivate::onToolStopped()
-{
- toolRunner->onStop();
- debugMessage("Tool stopped");
- checkState(State::ToolStopping);
- setState(State::TargetStopping);
- debugMessage("Queue: Stop target runner");
- QTimer::singleShot(0, targetRunner, [this](){ targetRunner->stop(); });
-}
-
-void RunControlPrivate::onToolStopFailed(const QString &msg)
-{
- checkState(State::ToolStopping);
- targetRunner->onToolFailure();
- debugMessage("Tool stop failed");
- showError(msg);
- setState(State::Stopped);
-}
-
-void RunControlPrivate::onTargetStopped()
-{
- targetRunner->onStop();
- debugMessage("Target stopped");
- checkState(State::TargetStopping);
- setState(State::Stopped);
-}
-
-void RunControlPrivate::onTargetStopFailed(const QString &msg)
-{
- debugMessage("Target stop failed");
- checkState(State::TargetStopping);
- toolRunner->onTargetFailure();
- showError(msg);
- setState(State::Stopped);
-}
-
-void RunControlPrivate::onTargetFailed(const QString &msg)
-{
- debugMessage("Target operation failed");
- if (state == State::TargetPreparing) {
- onTargetPrepareFailed(msg);
- } else if (state == State::TargetStarting) {
- onTargetStartFailed(msg);
- } else if (state == State::TargetStopping) {
- onTargetStopFailed(msg);
- } else {
- showError(msg);
- showError(RunControl::tr("Unexpected state: %1").arg(int(state)));
- setState(State::Stopped);
+ checkState(RunControlState::Running);
+ setState(RunControlState::Stopping);
+ debugMessage("Queue: Stopping");
+
+ continueStop();
+}
+
+void RunControlPrivate::continueStop()
+{
+ debugMessage("Continue Stopping");
+ checkState(RunControlState::Stopping);
+ for (RunWorker *worker : m_workers) {
+ if (worker) {
+ debugMessage(" Examining worker " + worker->displayName());
+ switch (worker->d->state) {
+ case RunWorkerState::Initialized:
+ debugMessage(" " + worker->displayName() + " was Initialized, setting to Done");
+ worker->d->state = RunWorkerState::Done;
+ break;
+ case RunWorkerState::Stopping:
+ debugMessage(" " + worker->displayName() + " was already Stopping. Keeping it that way");
+ break;
+ case RunWorkerState::Starting:
+ worker->d->state = RunWorkerState::Stopping;
+ debugMessage(" " + worker->displayName() + " was Starting, queuing stop");
+ QTimer::singleShot(0, worker, &RunWorker::initiateStop);
+ return; // Sic.
+ case RunWorkerState::Running:
+ debugMessage(" " + worker->displayName() + " was Running, queuing stop");
+ worker->d->state = RunWorkerState::Stopping;
+ QTimer::singleShot(0, worker, &RunWorker::initiateStop);
+ return; // Sic.
+ case RunWorkerState::Done:
+ debugMessage(" " + worker->displayName() + " was Done. Good.");
+ break;
+ case RunWorkerState::Failed:
+ debugMessage(" " + worker->displayName() + " was Failed. Good");
+ break;
+ }
+ } else {
+ debugMessage("Found unknown deleted worker");
+ }
}
+ debugMessage("All workers stopped. Set runControl to Stopped");
+ setState(RunControlState::Stopped);
}
-void RunControlPrivate::onTargetSuccess()
+void RunControlPrivate::onWorkerStarted(RunWorker *worker)
{
- 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);
- }
-}
+ worker->d->state = RunWorkerState::Running;
-void RunControlPrivate::onToolFailed(const QString &msg)
-{
- debugMessage("Tool operation failed");
- if (state == State::ToolPreparing) {
- onToolPrepareFailed(msg);
- } else if (state == State::ToolStarting) {
- onToolStartFailed(msg);
- } else if (state == State::ToolStopping) {
- onToolStartFailed(msg);
- } else {
- showError(msg);
- showError(RunControl::tr("Unexpected state: %1").arg(int(state)));
- setState(State::Stopped);
+ if (state == RunControlState::Starting) {
+ debugMessage(worker->displayName() + " start succeeded");
+ continueStart();
+ return;
}
+ showError(tr("Unexpected run control state %1 when worker %2 started")
+ .arg(stateName(state))
+ .arg(worker->displayName()));
+ //setState(RunControlState::Stopped);
}
-void RunControlPrivate::onToolSuccess()
+void RunControlPrivate::onWorkerFailed(RunWorker *worker, const QString &msg)
{
- 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);
- }
-}
+ worker->d->state = RunWorkerState::Failed;
+ showError(msg);
+ setState(RunControlState::Stopped);
+}
-void RunControlPrivate::handleFailure()
+void RunControlPrivate::onWorkerStopped(RunWorker *worker)
{
- switch (state) {
- case State::Initialized:
- case State::TargetPreparing:
- case State::ToolPreparing:
- case State::TargetStarting:
- case State::ToolStarting:
- case State::Running:
- case State::ToolStopping:
- case State::TargetStopping:
- case State::Stopped:
- setState(State::Stopped);
- break;
- }
+ debugMessage(worker->displayName() + " stopped.");
+ continueStop();
}
void RunControlPrivate::showError(const QString &msg)
{
if (!msg.isEmpty())
- q->appendMessage(msg, ErrorMessageFormat);
+ q->appendMessage(msg + '\n', ErrorMessageFormat);
}
Utils::OutputFormatter *RunControl::outputFormatter() const
@@ -897,28 +904,6 @@ void RunControl::setConnection(const Connection &connection)
d->connection = connection;
}
-ToolRunner *RunControl::toolRunner() const
-{
- return d->toolRunner;
-}
-
-void RunControl::setToolRunner(ToolRunner *tool)
-{
- delete d->toolRunner;
- d->toolRunner = tool;
-}
-
-TargetRunner *RunControl::targetRunner() const
-{
- return d->targetRunner;
-}
-
-void RunControl::setTargetRunner(TargetRunner *runner)
-{
- delete d->targetRunner;
- d->targetRunner = runner;
-}
-
QString RunControl::displayName() const
{
return d->displayName;
@@ -1028,7 +1013,17 @@ void RunControl::setSupportsReRunning(bool reRunningSupported)
bool RunControl::isRunning() const
{
- return d->state == RunControlPrivate::State::Running;
+ return d->state == RunControlState::Running;
+}
+
+bool RunControl::isStarting() const
+{
+ return d->state == RunControlState::Starting;
+}
+
+bool RunControl::isStopping() const
+{
+ return d->state == RunControlState::Stopping;
}
/*!
@@ -1066,61 +1061,36 @@ bool RunControl::showPromptToStopDialog(const QString &title,
return close;
}
-bool RunControlPrivate::isAllowedTransition(State from, State to)
+bool RunControlPrivate::isAllowedTransition(RunControlState from, RunControlState to)
{
switch (from) {
- case State::Initialized:
- return to == State::TargetPreparing;
- case State::TargetPreparing:
- return to == State::ToolPreparing;
- case State::ToolPreparing:
- return to == State::TargetStarting;
- case State::TargetStarting:
- return to == State::ToolStarting;
- case State::ToolStarting:
- return to == State::Running;
- case State::Running:
- return to == State::ToolStopping
- || to == State::Stopped;
- case State::ToolStopping:
- return to == State::TargetStopping;
- case State::TargetStopping:
- return to == State::Stopped;
- case State::Stopped:
+ case RunControlState::Initialized:
+ return to == RunControlState::Starting;
+ case RunControlState::Starting:
+ return to == RunControlState::Running;
+ case RunControlState::Running:
+ return to == RunControlState::Stopping
+ || to == RunControlState::Stopped;
+ case RunControlState::Stopping:
+ return to == RunControlState::Stopped;
+ case RunControlState::Stopped:
return false;
}
- qDebug() << "UNKNOWN DEBUGGER STATE:" << from;
return false;
}
-void RunControlPrivate::checkState(State expectedState)
+void RunControlPrivate::checkState(RunControlState expectedState)
{
if (state != expectedState)
- qDebug() << "Unexpected state " << expectedState << " have: " << state;
+ qDebug() << "Unexpected run control state " << stateName(expectedState)
+ << " have: " << stateName(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(RunControlState newState)
{
if (!isAllowedTransition(state, newState))
- qDebug() << "Invalid run state transition from " << state << " to " << newState;
+ qDebug() << "Invalid run control state transition from " << stateName(state)
+ << " to " << stateName(newState);
state = newState;
@@ -1128,14 +1098,15 @@ void RunControlPrivate::setState(State newState)
// Extra reporting.
switch (state) {
- case State::Running:
+ case RunControlState::Running:
emit q->started();
break;
- case State::Stopped:
+ case RunControlState::Stopped:
q->setApplicationProcessHandle(Utils::ProcessHandle());
- toolRunner->onFinished();
- targetRunner->onFinished();
- state = State::Initialized; // Reset for potential re-running.
+ foreach (auto worker, m_workers)
+ if (worker)
+ worker->onFinished();
+ //state = RunControlState::Initialized; // Reset for potential re-running.
emit q->finished();
break;
default:
@@ -1145,8 +1116,8 @@ void RunControlPrivate::setState(State newState)
void RunControlPrivate::debugMessage(const QString &msg)
{
- if (debugStates)
- q->appendMessage(msg + '\n', Utils::DebugFormat);
+ //q->appendMessage(msg + '\n', Utils::DebugFormat);
+ qCDebug(statesLog()) << msg;
}
/*!
@@ -1166,20 +1137,12 @@ void RunControl::bringApplicationToForeground()
void RunControl::reportApplicationStart()
{
- // QTC_CHECK(false); FIXME: Legacy, ToolRunner should emit started() instead.
- d->onToolStarted();
- emit started();
+ QTC_CHECK(false);// FIXME: Legacy
}
void RunControl::reportApplicationStop()
{
- // QTC_CHECK(false); FIXME: Legacy, ToolRunner should emit stopped() instead.
- if (d->state == RunControlPrivate::State::Stopped) {
- // FIXME: Currently various tool implementations call reportApplicationStop()
- // multiple times. Fix it there and then add a soft assert here.
- return;
- }
- d->onTargetStopped();
+ QTC_CHECK(false);// FIXME: Legacy
}
void RunControl::bringApplicationToForegroundInternal()
@@ -1222,8 +1185,9 @@ static bool isSynchronousLauncher(RunControl *runControl)
// SimpleTargetRunner
SimpleTargetRunner::SimpleTargetRunner(RunControl *runControl)
- : TargetRunner(runControl)
+ : RunWorker(runControl)
{
+ setDisplayName("SimpleTargetRunner");
}
void SimpleTargetRunner::start()
@@ -1231,11 +1195,13 @@ void SimpleTargetRunner::start()
m_launcher.disconnect(this);
Runnable r = runControl()->runnable();
+ QString msg = RunControl::tr("Starting %1...").arg(r.displayName());
+ appendMessage(msg, Utils::NormalMessageFormat);
if (isSynchronousLauncher(runControl())) {
connect(&m_launcher, &ApplicationLauncher::appendMessage,
- this, &TargetRunner::appendMessage);
+ this, &SimpleTargetRunner::appendMessage);
connect(&m_launcher, &ApplicationLauncher::processStarted,
this, &SimpleTargetRunner::onProcessStarted);
connect(&m_launcher, &ApplicationLauncher::processExited,
@@ -1249,15 +1215,15 @@ void SimpleTargetRunner::start()
reportFailure(RunControl::tr("Executable %1 does not exist.")
.arg(QDir::toNativeSeparators(executable)));
} else {
- QString msg = RunControl::tr("Starting %1...").arg(QDir::toNativeSeparators(executable)) + '\n';
- appendMessage(msg, Utils::NormalMessageFormat);
m_launcher.start(r);
}
} else {
connect(&m_launcher, &ApplicationLauncher::reportError,
- this, &TargetRunner::reportFailure);
+ this, [this](const QString &msg) {
+ reportFailure(msg);
+ });
connect(&m_launcher, &ApplicationLauncher::remoteStderr,
this, [this](const QByteArray &output) {
@@ -1272,12 +1238,29 @@ void SimpleTargetRunner::start()
connect(&m_launcher, &ApplicationLauncher::finished,
this, [this] {
m_launcher.disconnect(this);
- reportSuccess();
+ reportStopped();
+ });
+
+ connect(&m_launcher, &ApplicationLauncher::processStarted,
+ this, [this] {
+ appendMessage("Application launcher started", Utils::NormalMessageFormat);
+// reportStarted();
+ });
+
+ connect(&m_launcher, &ApplicationLauncher::processExited,
+ this, [this] {
+ m_launcher.disconnect(this);
+ reportStopped();
+ });
+
+ connect(&m_launcher, &ApplicationLauncher::remoteProcessStarted,
+ this, [this] {
+ reportStarted();
});
connect(&m_launcher, &ApplicationLauncher::reportProgress,
this, [this](const QString &progressString) {
- appendMessage(progressString + '\n', Utils::NormalMessageFormat);
+ appendMessage(progressString, Utils::NormalMessageFormat);
});
m_launcher.start(r, runControl()->device());
@@ -1294,145 +1277,190 @@ void SimpleTargetRunner::onProcessStarted()
// Console processes only know their pid after being started
runControl()->setApplicationProcessHandle(m_launcher.applicationPID());
runControl()->bringApplicationToForeground();
- reportSuccess();
+ reportStarted();
}
void SimpleTargetRunner::onProcessFinished(int exitCode, QProcess::ExitStatus status)
{
QString msg;
- QString exe = runControl()->runnable().as<StandardRunnable>().executable;
if (status == QProcess::CrashExit)
- msg = tr("%1 crashed.").arg(QDir::toNativeSeparators(exe));
+ msg = tr("%1 crashed.");
else
- msg = tr("%1 exited with code %2").arg(QDir::toNativeSeparators(exe)).arg(exitCode);
- appendMessage(msg + '\n', Utils::NormalMessageFormat);
+ msg = tr("%2 exited with code %1").arg(exitCode);
+ appendMessage(msg.arg(runnable().displayName()), Utils::NormalMessageFormat);
reportStopped();
}
+void RunControl::reportFailure(const QString &msg)
+{
+ d->showError(msg);
+ d->setState(RunControlState::Stopped);
+}
-// TargetRunner
+// RunWorkerPrivate
-TargetRunner::TargetRunner(RunControl *runControl)
- : m_runControl(runControl)
+RunWorkerPrivate::RunWorkerPrivate(RunWorker *runWorker, RunControl *runControl)
+ : q(runWorker), runControl(runControl)
{
- runControl->setTargetRunner(this);
+ runControl->d->m_workers.append(runWorker);
}
-TargetRunner::~TargetRunner()
+bool RunWorkerPrivate::canStart() const
{
+ if (state != RunWorkerState::Initialized)
+ return false;
+ for (RunWorker *worker : dependencies) {
+ QTC_ASSERT(worker, return true);
+ if (worker->d->state != RunWorkerState::Done
+ && worker->d->state != RunWorkerState::Running)
+ return false;
+ }
+ return true;
}
-RunControl *TargetRunner::runControl() const
+void RunWorkerPrivate::timerEvent(QTimerEvent *ev)
{
- return m_runControl;
+ if (ev->timerId() == startWatchdogTimerId) {
+ q->reportFailure(tr("Worker start timed out"));
+ return;
+ }
+ if (ev->timerId() == stopWatchdogTimerId) {
+ q->reportFailure(tr("Worker stop timed out"));
+ return;
+ }
}
-void TargetRunner::appendMessage(const QString &msg, OutputFormat format)
+// RunWorker
+
+RunWorker::RunWorker(RunControl *runControl)
+ : d(new RunWorkerPrivate(this, runControl))
{
- m_runControl->appendMessage(msg, format);
}
-IDevice::ConstPtr TargetRunner::device() const
+RunWorker::~RunWorker()
{
- return m_runControl->device();
+ delete d;
}
-void TargetRunner::prepare()
+void RunWorker::initiateStart()
{
- reportSuccess(); // By default nothing to do, all is fine.
+ if (d->startWatchdogInterval != 0)
+ d->startWatchdogTimerId = d->startTimer(d->startWatchdogInterval);
+
+ start();
}
-void TargetRunner::start()
+void RunWorker::reportStarted()
{
- reportSuccess();
+ if (d->startWatchdogInterval != 0)
+ d->killTimer(d->startWatchdogTimerId);
+ d->runControl->d->onWorkerStarted(this);
+ emit started();
}
-void TargetRunner::stop()
+void RunWorker::initiateStop()
{
- reportSuccess(); // By default all is fine.
+ if (d->stopWatchdogInterval != 0)
+ d->stopWatchdogTimerId = d->startTimer(d->stopWatchdogInterval);
+
+ d->runControl->d->debugMessage("Initiate stop for " + displayName());
+ stop();
}
-void TargetRunner::reportStopped()
+void RunWorker::reportStopped()
{
- m_runControl->d->onTargetStopped();
+ if (d->stopWatchdogInterval != 0)
+ d->killTimer(d->stopWatchdogTimerId);
+ d->runControl->d->onWorkerStopped(this);
+ emit stopped();
}
-void TargetRunner::reportSuccess()
+void RunWorker::reportFailure(const QString &msg)
{
- m_runControl->d->onTargetSuccess();
+ d->runControl->d->onWorkerFailed(this, msg);
}
-void TargetRunner::reportFailure(const QString &msg)
+void RunWorker::appendMessage(const QString &msg, OutputFormat format)
{
- m_runControl->d->onTargetFailed(msg);
+ if (msg.endsWith('\n'))
+ d->runControl->appendMessage(msg, format);
+ else
+ d->runControl->appendMessage(msg + '\n', format);
}
-// ToolRunner
+IDevice::ConstPtr RunWorker::device() const
+{
+ return d->runControl->device();
+}
-ToolRunner::ToolRunner(RunControl *runControl)
- : m_runControl(runControl)
+const Runnable &RunWorker::runnable() const
{
- if (runControl)
- runControl->setToolRunner(this);
+ return d->runControl->runnable();
}
-ToolRunner::~ToolRunner()
+const Connection &RunWorker::connection() const
{
+ return d->runControl->connection();
}
-RunControl *ToolRunner::runControl() const
+Core::Id RunWorker::runMode() const
{
- return m_runControl;
+ return d->runControl->runMode();
}
-void ToolRunner::appendMessage(const QString &msg, OutputFormat format)
+void RunWorker::addDependency(RunWorker *dependency)
{
- m_runControl->appendMessage(msg, format);
+ d->dependencies.append(dependency);
}
-IDevice::ConstPtr ToolRunner::device() const
+RunControl *RunWorker::runControl() const
{
- return m_runControl->device();
+ return d->runControl;
}
-const Runnable &ToolRunner::runnable() const
+QString RunWorker::displayName() const
{
- return m_runControl->runnable();
+ return d->displayName;
}
-const Connection &ToolRunner::connection() const
+void RunWorker::setDisplayName(const QString &displayName)
{
- return m_runControl->connection();
+ d->displayName = displayName;
}
-void ToolRunner::prepare()
+void RunWorker::setStartTimeout(int ms)
{
- reportSuccess();
+ d->startWatchdogInterval = ms;
}
-void ToolRunner::start()
+void RunWorker::setStopTimeout(int ms)
{
- reportSuccess();
+ d->stopWatchdogInterval = ms;
}
-void ToolRunner::stop()
+void RunWorker::reportData(int channel, const QVariant &data)
{
- reportSuccess();
+ emit dataReported(channel, data);
}
-void ToolRunner::reportStopped()
+void RunWorker::recordData(const QString &channel, const QVariant &data)
{
- m_runControl->d->onToolStopped();
+ d->data[channel] = data;
}
-void ToolRunner::reportSuccess()
+QVariant RunWorker::recordedData(const QString &channel)
{
- m_runControl->d->onToolSuccess();
+ return d->data[channel];
}
-void ToolRunner::reportFailure(const QString &msg)
+void RunWorker::start()
{
- m_runControl->d->onToolFailed(msg);
+ reportStarted();
+}
+
+void RunWorker::stop()
+{
+ reportStopped();
}
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index 368e95978f..17f14e6457 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -51,11 +51,10 @@ class RunConfiguration;
class RunConfigWidget;
class RunControl;
class Target;
-class TargetRunner;
-class ToolRunner;
namespace Internal {
class RunControlPrivate;
+class RunWorkerPrivate;
class SimpleRunControlPrivate;
} // Internal
@@ -148,6 +147,7 @@ class PROJECTEXPLORER_EXPORT Runnable
virtual ~Concept() {}
virtual Concept *clone() const = 0;
virtual bool canReUseOutputPane(const std::unique_ptr<Concept> &other) const = 0;
+ virtual QString displayName() const = 0;
virtual void *typeId() const = 0;
};
@@ -168,6 +168,8 @@ class PROJECTEXPLORER_EXPORT Runnable
return m_data == that->m_data;
}
+ QString displayName() const override { return m_data.displayName(); }
+
void *typeId() const override { return T::staticTypeId; }
T m_data;
@@ -190,6 +192,7 @@ public:
}
bool canReUseOutputPane(const Runnable &other) const;
+ QString displayName() const { return d->displayName(); }
private:
std::unique_ptr<Concept> d;
@@ -351,6 +354,61 @@ signals:
void displayNameChanged(const QString &);
};
+class PROJECTEXPLORER_EXPORT RunWorker : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit RunWorker(RunControl *runControl);
+ ~RunWorker() override;
+
+ RunControl *runControl() const;
+
+ void addDependency(RunWorker *dependency);
+
+ QString displayName() const;
+ void setDisplayName(const QString &displayName);
+
+ void setStartTimeout(int ms);
+ void setStopTimeout(int ms);
+
+ void reportData(int channel, const QVariant &data);
+
+ void recordData(const QString &channel, const QVariant &data);
+ QVariant recordedData(const QString &channel);
+
+ // Part of read-only interface of RunControl for convenience.
+ void appendMessage(const QString &msg, Utils::OutputFormat format);
+ IDevice::ConstPtr device() const;
+ const Runnable &runnable() const;
+ const Connection &connection() const;
+ Core::Id runMode() const;
+
+ // States
+ void initiateStart();
+ void reportStarted();
+
+ void initiateStop();
+ void reportStopped();
+
+ void reportFailure(const QString &msg = QString());
+
+signals:
+ void dataReported(int channel, const QVariant &data);
+ void started();
+ void stopped();
+
+protected:
+ void virtual start();
+ void virtual stop();
+ void virtual onFinished() {}
+
+private:
+ friend class Internal::RunControlPrivate;
+ friend class Internal::RunWorkerPrivate;
+ Internal::RunWorkerPrivate *d;
+};
+
/**
* A RunControl controls the running of an application or tool
* on a target device. It controls start and stop, and handles
@@ -380,6 +438,8 @@ public:
void setDisplayName(const QString &displayName);
bool isRunning() const;
+ bool isStarting() const;
+ bool isStopping() const;
void setIcon(const Utils::Icon &icon);
Utils::Icon icon() const;
@@ -402,12 +462,6 @@ public:
const Connection &connection() const;
void setConnection(const Connection &connection);
- ToolRunner *toolRunner() const;
- void setToolRunner(ToolRunner *tool);
-
- TargetRunner *targetRunner() const;
- void setTargetRunner(TargetRunner *tool);
-
virtual void appendMessage(const QString &msg, Utils::OutputFormat format);
virtual void bringApplicationToForeground();
@@ -415,8 +469,9 @@ public:
virtual void notifyRemoteSetupFailed(const QString &) {} // Same.
virtual void notifyRemoteFinished() {} // Same.
- void reportApplicationStart(); // Call this when the application starts to run
- void reportApplicationStop(); // Call this when the application has stopped for any reason
+ void reportApplicationStart(); // FIXME: Don't use
+ void reportApplicationStop(); // FIXME: Don't use
+ void reportFailure(const QString &msg = QString());
static bool showPromptToStopDialog(const QString &title, const QString &text,
const QString &stopButtonText = QString(),
@@ -426,6 +481,25 @@ public:
virtual void start();
virtual void stop();
+ using WorkerCreator = std::function<RunWorker *(RunControl *)>;
+ static void registerWorkerCreator(Core::Id id, const WorkerCreator &workerCreator);
+ RunWorker *workerById(Core::Id id) const;
+ QList<QPointer<RunWorker>> workers() const;
+
+ template <class T> T *worker() const {
+ for (const QPointer<RunWorker> &worker : workers()) {
+ if (worker) {
+ if (auto res = qobject_cast<T *>(worker.data()))
+ return res;
+ }
+ }
+ return nullptr;
+ }
+
+ using RunWorkerCreator = std::function<RunWorker *(RunControl *)>;
+ static void registerRunWorkerCreator(Core::Id id, const RunWorkerCreator &creator);
+ RunWorker *createWorker(Core::Id id);
+
signals:
void appendMessageRequested(ProjectExplorer::RunControl *runControl,
const QString &msg, Utils::OutputFormat format);
@@ -436,114 +510,29 @@ signals:
void applicationProcessHandleChanged(QPrivateSignal); // Use setApplicationProcessHandle
private:
- friend class Internal::RunControlPrivate;
- friend class TargetRunner;
- friend class ToolRunner;
+ friend class RunWorker;
+ friend class Internal::RunWorkerPrivate;
void bringApplicationToForegroundInternal();
Internal::RunControlPrivate *d;
};
-/**
- * A base for target-specific additions to the RunControl.
- */
-
-class PROJECTEXPLORER_EXPORT TargetRunner : public QObject
-{
- Q_OBJECT
-
-public:
- explicit TargetRunner(RunControl *runControl);
- ~TargetRunner() override;
-
- RunControl *runControl() const;
- void appendMessage(const QString &msg, Utils::OutputFormat format);
- IDevice::ConstPtr device() const;
-
- // Preparation phase.
- virtual void prepare(); // Initiate setup. Needs to report result.
- // Startup phase.
- virtual void start(); // Initiates start. Needs to report result.
- // Stopping phase.
- virtual void stop(); // Initiates stop. Needs to report result.
-
- //
- void reportStopped();
- // Generic success report, proceed to next stage.
- void reportSuccess();
- // Generic error, start ramp down.
- void reportFailure(const QString &msg = QString());
-
- // Customization points. No reporting required nor wanted.
- virtual void onStop() {}
- virtual void onToolFailure() {}
- virtual void onTargetFailure() {}
- virtual void onFinished() {}
-
-private:
- QPointer<RunControl> m_runControl;
-};
-
-/**
- * A base for tool-specific additions to RunControl.
- */
-
-class PROJECTEXPLORER_EXPORT ToolRunner : public QObject
-{
- Q_OBJECT
-
-public:
- explicit ToolRunner(RunControl *runControl);
- ~ToolRunner() override;
-
- RunControl *runControl() const;
-
- // Part of read-only interface of RunControl for convenience.
- void appendMessage(const QString &msg, Utils::OutputFormat format);
- IDevice::ConstPtr device() const;
- const Runnable &runnable() const;
- const Connection &connection() const;
-
- // Preparation phase.
- virtual void prepare(); // Initiates preparation, needs to report success or failure.
- // Start phase.
- virtual void start();
- // Stop phase.
- virtual void stop();
-
- //
- void reportStopped();
- // Generic success report, proceed to next stage.
- void reportSuccess();
- // Generic error, start ramp down.
- void reportFailure(const QString &msg = QString());
-
- // Customization points. No reporting required nor wanted.
- virtual void onStop() {}
- virtual void onToolFailure() {}
- virtual void onTargetFailure() {}
- virtual void onFinished() {}
-
-private:
- QPointer<RunControl> m_runControl;
-};
/**
* A simple TargetRunner for cases where a plain ApplicationLauncher is
* sufficient for running purposes.
*/
-class PROJECTEXPLORER_EXPORT SimpleTargetRunner : public TargetRunner
+class PROJECTEXPLORER_EXPORT SimpleTargetRunner : public RunWorker
{
public:
explicit SimpleTargetRunner(RunControl *runControl);
- ApplicationLauncher *applicationLauncher() { return &m_launcher; }
-
-private:
+protected:
void start() override;
void stop() override;
+private:
void onProcessStarted();
void onProcessFinished(int exitCode, QProcess::ExitStatus status);
diff --git a/src/plugins/projectexplorer/runnables.h b/src/plugins/projectexplorer/runnables.h
index 088a6a872d..3d286a8b83 100644
--- a/src/plugins/projectexplorer/runnables.h
+++ b/src/plugins/projectexplorer/runnables.h
@@ -32,6 +32,7 @@
#include <utils/environment.h>
+#include <QDir>
#include <QUrl>
namespace ProjectExplorer {
@@ -46,6 +47,7 @@ public:
ApplicationLauncher::Mode runMode = ApplicationLauncher::Gui;
IDevice::ConstPtr device; // Override the kit's device. Keep unset by default.
+ QString displayName() const { return QDir::toNativeSeparators(executable); }
static void *staticTypeId;
};
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
index aa2af74b79..bc537fbb78 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp
@@ -67,7 +67,6 @@ namespace QmlProfiler {
class QmlProfilerRunControl::QmlProfilerRunControlPrivate
{
public:
- Internal::QmlProfilerTool *m_tool = 0;
QmlProfilerStateManager *m_profilerState = 0;
QTimer m_noDebugOutputTimer;
};
@@ -76,15 +75,13 @@ public:
// QmlProfilerRunControl
//
-QmlProfilerRunControl::QmlProfilerRunControl(RunConfiguration *runConfiguration,
- Internal::QmlProfilerTool *tool)
+QmlProfilerRunControl::QmlProfilerRunControl(RunConfiguration *runConfiguration)
: RunControl(runConfiguration, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE)
, d(new QmlProfilerRunControlPrivate)
{
setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
setSupportsReRunning(false);
- d->m_tool = tool;
// Only wait 4 seconds for the 'Waiting for connection' on application output, then just try to connect
// (application output might be redirected / blocked)
d->m_noDebugOutputTimer.setSingleShot(true);
@@ -104,7 +101,7 @@ QmlProfilerRunControl::~QmlProfilerRunControl()
void QmlProfilerRunControl::start()
{
reportApplicationStart();
- d->m_tool->finalizeRunControl(this);
+ Internal::QmlProfilerTool::instance()->finalizeRunControl(this);
QTC_ASSERT(d->m_profilerState, reportApplicationStop(); return);
QTC_ASSERT(connection().is<AnalyzerConnection>(), reportApplicationStop(); return);
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
index 69686a1e35..9ece8c5067 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h
@@ -32,15 +32,12 @@
namespace QmlProfiler {
-namespace Internal { class QmlProfilerTool; }
-
class QmlProfilerRunControl : public ProjectExplorer::RunControl
{
Q_OBJECT
public:
- QmlProfilerRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
- Internal::QmlProfilerTool *tool);
+ QmlProfilerRunControl(ProjectExplorer::RunConfiguration *runConfiguration);
~QmlProfilerRunControl() override;
void registerProfilerStateManager( QmlProfilerStateManager *profilerState );
diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp
index e489c3b5aa..577564f3d2 100644
--- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp
@@ -92,10 +92,7 @@ RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfigurat
connection.analyzerPort = LocalQmlProfilerRunner::findFreePort(connection.analyzerHost);
}
- auto runControl = qobject_cast<QmlProfilerRunControl *>
- (Debugger::createAnalyzerRunControl(runConfiguration, mode));
- QTC_ASSERT(runControl, return 0);
-
+ auto runControl = new QmlProfilerRunControl(runConfiguration);
runControl->setRunnable(runnable);
runControl->setConnection(connection);
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp
index dc7b580a62..09d884e4d1 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -127,9 +127,12 @@ public:
bool m_toolBusy = false;
};
+static QmlProfilerTool *s_instance;
+
QmlProfilerTool::QmlProfilerTool(QObject *parent)
: QObject(parent), d(new QmlProfilerToolPrivate)
{
+ s_instance = this;
setObjectName(QLatin1String("QmlProfilerTool"));
d->m_profilerState = new QmlProfilerStateManager(this);
@@ -244,8 +247,9 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
// is available, then we can populate the file finder
d->m_profilerModelManager->populateFileFinder();
- auto runControlCreator = [this](RunConfiguration *runConfiguration, Core::Id) {
- return createRunControl(runConfiguration);
+ auto runWorkerCreator = [this](RunControl *runControl) {
+// return createRunControl(runConfiguration);
+ return nullptr; // FIXME
};
QString description = tr("The QML Profiler can be used to find performance "
@@ -254,7 +258,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_startAction = Debugger::createStartAction();
d->m_stopAction = Debugger::createStopAction();
- Debugger::registerAction(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runControlCreator);
+ RunControl::registerWorkerCreator(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runWorkerCreator);
act = new QAction(tr("QML Profiler"), this);
act->setToolTip(description);
menu->addAction(ActionManager::registerAction(act, "QmlProfiler.Local"),
@@ -270,7 +274,6 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
act->setEnabled(d->m_startAction->isEnabled());
});
- Debugger::registerAction(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, runControlCreator);
act = new QAction(tr("QML Profiler (External)"), this);
act->setToolTip(description);
menu->addAction(ActionManager::registerAction(act, "QmlProfiler.Remote"),
@@ -305,6 +308,11 @@ QmlProfilerTool::~QmlProfilerTool()
delete d;
}
+QmlProfilerTool *QmlProfilerTool::instance()
+{
+ return s_instance;
+}
+
void QmlProfilerTool::updateRunActions()
{
if (d->m_toolBusy) {
@@ -336,11 +344,11 @@ RunControl *QmlProfilerTool::createRunControl(RunConfiguration *runConfiguration
}
}
- auto runControl = new QmlProfilerRunControl(runConfiguration, this);
+ auto runControl = new QmlProfilerRunControl(runConfiguration);
connect(runControl, &RunControl::finished, this, [this, runControl] {
d->m_toolBusy = false;
updateRunActions();
- disconnect(d->m_stopAction, &QAction::triggered, runControl, &QmlProfilerRunControl::stop);
+ disconnect(d->m_stopAction, &QAction::triggered, runControl, &RunControl::stop);
});
connect(d->m_stopAction, &QAction::triggered, runControl, &QmlProfilerRunControl::stop);
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h
index 85715f8120..c9600051b3 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.h
+++ b/src/plugins/qmlprofiler/qmlprofilertool.h
@@ -49,6 +49,8 @@ public:
explicit QmlProfilerTool(QObject *parent);
~QmlProfilerTool();
+ static QmlProfilerTool *instance();
+
ProjectExplorer::RunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration = 0);
void finalizeRunControl(QmlProfilerRunControl *runControl);
diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
index c7ef5f1b4e..2171f45f60 100644
--- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
+++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp
@@ -24,6 +24,9 @@
****************************************************************************/
#include "localqmlprofilerrunner_test.h"
+
+#include "../qmlprofilerruncontrol.h"
+
#include <debugger/analyzer/analyzermanager.h>
#include <debugger/analyzer/analyzerstartparameters.h>
#include <QtTest>
@@ -57,8 +60,7 @@ void LocalQmlProfilerRunnerTest::testRunner()
// should not be used anywhere but cannot be empty
configuration.socket = connection.analyzerSocket = QString("invalid");
- rc = Debugger::createAnalyzerRunControl(
- nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
+ rc = new QmlProfilerRunControl(nullptr);
rc->setConnection(connection);
auto runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner(runner);
@@ -79,8 +81,7 @@ void LocalQmlProfilerRunnerTest::testRunner1()
configuration.debuggee.commandLineArguments = QString("-test QmlProfiler,");
delete rc;
- rc = Debugger::createAnalyzerRunControl(
- nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
+ rc = new QmlProfilerRunControl(nullptr);
rc->setConnection(connection);
auto runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner(runner);
@@ -100,8 +101,7 @@ void LocalQmlProfilerRunnerTest::testRunner2()
connection.analyzerSocket.clear();
configuration.port = connection.analyzerPort =
LocalQmlProfilerRunner::findFreePort(connection.analyzerHost);
- rc = Debugger::createAnalyzerRunControl(
- nullptr, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE);
+ rc = new QmlProfilerRunControl(nullptr);
rc->setConnection(connection);
auto runner = new LocalQmlProfilerRunner(configuration, rc);
connectRunner(runner);
diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro
index 64874c929a..b50f4b27fb 100644
--- a/src/plugins/qnx/qnx.pro
+++ b/src/plugins/qnx/qnx.pro
@@ -9,13 +9,11 @@ SOURCES += qnxplugin.cpp \
qnxdevicewizard.cpp \
qnxrunconfiguration.cpp \
qnxruncontrolfactory.cpp \
- qnxabstractrunsupport.cpp \
qnxanalyzesupport.cpp \
qnxdebugsupport.cpp \
qnxdeploystepfactory.cpp \
qnxdeployconfigurationfactory.cpp \
qnxrunconfigurationfactory.cpp \
- qnxruncontrol.cpp \
qnxqtversionfactory.cpp \
qnxqtversion.cpp \
qnxdeployconfiguration.cpp \
@@ -44,13 +42,11 @@ HEADERS += qnxplugin.h\
qnxdevicewizard.h \
qnxrunconfiguration.h \
qnxruncontrolfactory.h \
- qnxabstractrunsupport.h \
qnxanalyzesupport.h \
qnxdebugsupport.h \
qnxdeploystepfactory.h \
qnxdeployconfigurationfactory.h \
qnxrunconfigurationfactory.h \
- qnxruncontrol.h \
qnxqtversionfactory.h \
qnxqtversion.h \
qnxdeployconfiguration.h \
diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs
index d57a93259b..eee52f0f5d 100644
--- a/src/plugins/qnx/qnx.qbs
+++ b/src/plugins/qnx/qnx.qbs
@@ -33,8 +33,6 @@ QtcPlugin {
"qnxconstants.h",
"qnxconfiguration.cpp",
"qnxconfiguration.h",
- "qnxabstractrunsupport.cpp",
- "qnxabstractrunsupport.h",
"qnxanalyzesupport.cpp",
"qnxanalyzesupport.h",
"qnxdebugsupport.cpp",
@@ -78,8 +76,6 @@ QtcPlugin {
"qnxrunconfiguration.h",
"qnxrunconfigurationfactory.cpp",
"qnxrunconfigurationfactory.h",
- "qnxruncontrol.cpp",
- "qnxruncontrol.h",
"qnxruncontrolfactory.cpp",
"qnxruncontrolfactory.h",
"qnxutils.cpp",
diff --git a/src/plugins/qnx/qnxabstractrunsupport.cpp b/src/plugins/qnx/qnxabstractrunsupport.cpp
deleted file mode 100644
index 52d2110bb4..0000000000
--- a/src/plugins/qnx/qnxabstractrunsupport.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qnxabstractrunsupport.h"
-#include "qnxrunconfiguration.h"
-
-#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/target.h>
-#include <utils/portlist.h>
-#include <utils/qtcassert.h>
-
-using namespace ProjectExplorer;
-using namespace RemoteLinux;
-
-namespace Qnx {
-namespace Internal {
-
-QnxAbstractRunSupport::QnxAbstractRunSupport(RunControl *runControl)
- : ToolRunner(runControl)
- , m_state(Inactive)
-{
- m_launcher = new ApplicationLauncher(this);
- m_portsGatherer = new DeviceUsedPortsGatherer(this);
-
- connect(m_portsGatherer, &DeviceUsedPortsGatherer::error,
- this, &QnxAbstractRunSupport::handleError);
- connect(m_portsGatherer, &DeviceUsedPortsGatherer::portListReady,
- this, &QnxAbstractRunSupport::handlePortListReady);
-}
-
-void QnxAbstractRunSupport::handleAdapterSetupRequested()
-{
- QTC_ASSERT(m_state == Inactive, return);
-
- m_state = GatheringPorts;
- m_portsGatherer->start(m_device);
-}
-
-void QnxAbstractRunSupport::handlePortListReady()
-{
- QTC_ASSERT(m_state == GatheringPorts, return);
- m_portList = device()->freePorts();
- startExecution();
-}
-
-void QnxAbstractRunSupport::handleRemoteProcessStarted()
-{
- m_state = Running;
-}
-
-void QnxAbstractRunSupport::handleRemoteProcessFinished(bool)
-{
-}
-
-void QnxAbstractRunSupport::setFinished()
-{
- if (m_state != GatheringPorts && m_state != Inactive)
- m_launcher->stop();
-
- m_state = Inactive;
-}
-
-QnxAbstractRunSupport::State QnxAbstractRunSupport::state() const
-{
- return m_state;
-}
-
-void QnxAbstractRunSupport::setState(QnxAbstractRunSupport::State state)
-{
- m_state = state;
-}
-
-ApplicationLauncher *QnxAbstractRunSupport::appRunner() const
-{
- return m_launcher;
-}
-
-void QnxAbstractRunSupport::handleProgressReport(const QString &)
-{
-}
-
-void QnxAbstractRunSupport::handleRemoteOutput(const QByteArray &)
-{
-}
-
-void QnxAbstractRunSupport::handleError(const QString &)
-{
-}
-
-bool QnxAbstractRunSupport::setPort(Utils::Port &port)
-{
- port = m_portsGatherer->getNextFreePort(&m_portList);
- if (!port.isValid()) {
- handleError(tr("Not enough free ports on device for debugging."));
- return false;
- }
- return true;
-}
-
-} // namespace Internal
-} // namespace Qnx
diff --git a/src/plugins/qnx/qnxabstractrunsupport.h b/src/plugins/qnx/qnxabstractrunsupport.h
deleted file mode 100644
index f0e9a58c5b..0000000000
--- a/src/plugins/qnx/qnxabstractrunsupport.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <projectexplorer/devicesupport/idevice.h>
-#include <projectexplorer/runconfiguration.h>
-
-#include <utils/environment.h>
-#include <utils/portlist.h>
-
-#include <QObject>
-#include <QString>
-
-namespace ProjectExplorer {
-class ApplicationLauncher;
-class DeviceUsedPortsGatherer;
-}
-
-namespace Qnx {
-namespace Internal {
-
-class QnxAbstractRunSupport : public ProjectExplorer::ToolRunner
-{
- Q_OBJECT
-protected:
- enum State {
- Inactive,
- GatheringPorts,
- StartingRemoteProcess,
- Running
- };
-
-public:
- explicit QnxAbstractRunSupport(ProjectExplorer::RunControl *runControl);
-
-protected:
- bool setPort(Utils::Port &port);
- virtual void startExecution() = 0;
-
- void setFinished();
-
- State state() const;
- void setState(State state);
-
- ProjectExplorer::ApplicationLauncher *appRunner() const;
-
-public slots:
- virtual void handleAdapterSetupRequested();
-
- virtual void handleRemoteProcessStarted();
- virtual void handleRemoteProcessFinished(bool);
- virtual void handleProgressReport(const QString &progressOutput);
- virtual void handleRemoteOutput(const QByteArray &output);
- virtual void handleError(const QString &);
-
-private slots:
- void handlePortListReady();
-
-private:
- ProjectExplorer::DeviceUsedPortsGatherer * m_portsGatherer;
- Utils::PortList m_portList;
- ProjectExplorer::IDevice::ConstPtr m_device;
- ProjectExplorer::ApplicationLauncher *m_launcher;
- State m_state;
-};
-
-} // namespace Internal
-} // namespace Qnx
diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp
index 59ee41810d..5215010790 100644
--- a/src/plugins/qnx/qnxanalyzesupport.cpp
+++ b/src/plugins/qnx/qnxanalyzesupport.cpp
@@ -29,12 +29,15 @@
#include "qnxrunconfiguration.h"
#include "slog2inforunner.h"
+#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
+#include <qmldebug/qmloutputparser.h>
using namespace ProjectExplorer;
using namespace Utils;
@@ -42,122 +45,64 @@ using namespace Utils;
namespace Qnx {
namespace Internal {
-QnxAnalyzeSupport::QnxAnalyzeSupport(RunControl *runControl)
- : QnxAbstractRunSupport(runControl)
- , m_runnable(runControl->runnable().as<StandardRunnable>())
- , m_qmlPort(-1)
+class QnxAnalyzeeRunner : public ProjectExplorer::SimpleTargetRunner
{
- const ApplicationLauncher *runner = appRunner();
- connect(runner, &ApplicationLauncher::reportError,
- this, &QnxAnalyzeSupport::handleError);
- connect(runner, &ApplicationLauncher::remoteProcessStarted,
- this, &QnxAbstractRunSupport::handleRemoteProcessStarted);
- connect(runner, &ApplicationLauncher::finished,
- this, &QnxAnalyzeSupport::handleRemoteProcessFinished);
- connect(runner, &ApplicationLauncher::reportProgress,
- this, &QnxAnalyzeSupport::handleProgressReport);
- connect(runner, &ApplicationLauncher::remoteStdout,
- this, &QnxAnalyzeSupport::handleRemoteOutput);
- connect(runner, &ApplicationLauncher::remoteStderr,
- this, &QnxAnalyzeSupport::handleRemoteOutput);
-
- connect(runControl, &RunControl::starting,
- this, &QnxAnalyzeSupport::handleAdapterSetupRequested);
- connect(runControl, &RunControl::finished,
- this, &QnxAnalyzeSupport::setFinished);
-
- connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
- this, &QnxAnalyzeSupport::remoteIsRunning);
-
- IDevice::ConstPtr dev = DeviceKitInformation::device(runControl->runConfiguration()->target()->kit());
- QnxDevice::ConstPtr qnxDevice = dev.dynamicCast<const QnxDevice>();
-
- auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
- const QString applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
- m_slog2Info = new Slog2InfoRunner(applicationId, qnxDevice, this);
- connect(m_slog2Info, &Slog2InfoRunner::output,
- this, &QnxAnalyzeSupport::showMessage);
- connect(runner, &ApplicationLauncher::remoteProcessStarted,
- m_slog2Info, &Slog2InfoRunner::start);
- if (qnxDevice->qnxVersion() > 0x060500)
- connect(m_slog2Info, &Slog2InfoRunner::commandMissing,
- this, &QnxAnalyzeSupport::printMissingWarning);
-}
+public:
+ QnxAnalyzeeRunner(ProjectExplorer::RunControl *runControl)
+ : SimpleTargetRunner(runControl)
+ {
+ setDisplayName("QnxAnalyzeeRunner");
+ }
-void QnxAnalyzeSupport::handleAdapterSetupRequested()
-{
- QTC_ASSERT(state() == Inactive, return);
+private:
+ void start() override
+ {
+ auto portsGatherer = runControl()->worker<PortsGatherer>();
+ Utils::Port port = portsGatherer->findPort();
- showMessage(tr("Preparing remote side...") + QLatin1Char('\n'), NormalMessageFormat);
- QnxAbstractRunSupport::handleAdapterSetupRequested();
-}
+ auto r = runnable().as<StandardRunnable>();
+ if (!r.commandLineArguments.isEmpty())
+ r.commandLineArguments += ' ';
+ r.commandLineArguments +=
+ QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, port);
-void QnxAnalyzeSupport::startExecution()
-{
- if (state() == Inactive)
- return;
+ runControl()->setRunnable(r);
- if (!setPort(m_qmlPort) && !m_qmlPort.isValid())
- return;
+ SimpleTargetRunner::start();
+ }
+};
- setState(StartingRemoteProcess);
- StandardRunnable r = m_runnable;
- if (!r.commandLineArguments.isEmpty())
- r.commandLineArguments += QLatin1Char(' ');
- r.commandLineArguments += QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices,
- m_qmlPort);
- appRunner()->start(r, device());
-}
+// QnxDebugSupport
-void QnxAnalyzeSupport::handleRemoteProcessFinished(bool success)
+QnxAnalyzeSupport::QnxAnalyzeSupport(RunControl *runControl)
+ : RunWorker(runControl)
{
- if (!success)
- showMessage(tr("The %1 process closed unexpectedly.").arg(m_runnable.executable),
- NormalMessageFormat);
- runControl()->notifyRemoteFinished();
+ setDisplayName("QnxAnalyzeSupport");
+ appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
- m_slog2Info->stop();
-}
+ auto portsGatherer = new PortsGatherer(runControl);
-void QnxAnalyzeSupport::handleProgressReport(const QString &progressOutput)
-{
- showMessage(progressOutput + QLatin1Char('\n'), NormalMessageFormat);
-}
+ auto debuggeeRunner = new QnxAnalyzeeRunner(runControl);
+ debuggeeRunner->addDependency(portsGatherer);
-void QnxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
-{
- QTC_ASSERT(state() == Inactive || state() == Running, return);
+ auto slog2InfoRunner = new Slog2InfoRunner(runControl);
+ slog2InfoRunner->addDependency(debuggeeRunner);
- showMessage(QString::fromUtf8(output), StdOutFormat);
-}
-
-void QnxAnalyzeSupport::handleError(const QString &error)
-{
- if (state() == Running) {
- showMessage(error, ErrorMessageFormat);
- } else if (state() != Inactive) {
- showMessage(tr("Initial setup failed: %1").arg(error), NormalMessageFormat);
- setFinished();
- }
-}
+ addDependency(slog2InfoRunner);
-void QnxAnalyzeSupport::remoteIsRunning()
-{
- runControl()->notifyRemoteSetupDone(m_qmlPort);
-}
+ // QmlDebug::QmlOutputParser m_outputParser;
+ // FIXME: m_outputParser needs to be fed with application output
+ // connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
+ // this, &QnxAnalyzeSupport::remoteIsRunning);
-void QnxAnalyzeSupport::showMessage(const QString &msg, OutputFormat format)
-{
- if (state() != Inactive)
- runControl()->appendMessage(msg, format);
- m_outputParser.processOutput(msg);
+ // m_outputParser.processOutput(msg);
}
-void QnxAnalyzeSupport::printMissingWarning()
+void QnxAnalyzeSupport::start()
{
- showMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."),
- ErrorMessageFormat);
+ // runControl()->notifyRemoteSetupDone(m_qmlPort);
+ reportStarted();
}
} // namespace Internal
diff --git a/src/plugins/qnx/qnxanalyzesupport.h b/src/plugins/qnx/qnxanalyzesupport.h
index bd665c8436..cb049866f8 100644
--- a/src/plugins/qnx/qnxanalyzesupport.h
+++ b/src/plugins/qnx/qnxanalyzesupport.h
@@ -25,18 +25,14 @@
#pragma once
-#include "qnxabstractrunsupport.h"
-
-#include <projectexplorer/runnables.h>
-#include <utils/outputformat.h>
-#include <qmldebug/qmloutputparser.h>
+#include <projectexplorer/runconfiguration.h>
namespace Qnx {
namespace Internal {
class Slog2InfoRunner;
-class QnxAnalyzeSupport : public QnxAbstractRunSupport
+class QnxAnalyzeSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT
@@ -44,24 +40,7 @@ public:
explicit QnxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
private:
- void handleAdapterSetupRequested() override;
-
- void handleRemoteProcessFinished(bool success) override;
- void handleProgressReport(const QString &progressOutput) override;
- void handleRemoteOutput(const QByteArray &output) override;
- void handleError(const QString &error) override;
-
- void showMessage(const QString &, Utils::OutputFormat);
- void printMissingWarning();
-
- void remoteIsRunning();
- void startExecution() override;
-
- ProjectExplorer::StandardRunnable m_runnable;
- QmlDebug::QmlOutputParser m_outputParser;
- Utils::Port m_qmlPort;
-
- Slog2InfoRunner *m_slog2Info;
+ void start() override;
};
} // namespace Internal
diff --git a/src/plugins/qnx/qnxattachdebugsupport.cpp b/src/plugins/qnx/qnxattachdebugsupport.cpp
index 2a0d57531d..5319b14d80 100644
--- a/src/plugins/qnx/qnxattachdebugsupport.cpp
+++ b/src/plugins/qnx/qnxattachdebugsupport.cpp
@@ -146,9 +146,9 @@ void QnxAttachDebugSupport::attachToProcess()
stopPDebug();
return;
}
- connect(qobject_cast<Debugger::DebuggerRunTool *>(runControl->toolRunner()),
- &Debugger::DebuggerRunTool::stateChanged,
- this, &QnxAttachDebugSupport::handleDebuggerStateChanged);
+// connect(qobject_cast<Debugger::DebuggerRunTool *>(runControl->toolRunner()),
+// &Debugger::DebuggerRunTool::stateChanged,
+// this, &QnxAttachDebugSupport::handleDebuggerStateChanged);
ProjectExplorerPlugin::startRunControl(runControl);
}
diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp
index 5099c2224f..f86c20647c 100644
--- a/src/plugins/qnx/qnxdebugsupport.cpp
+++ b/src/plugins/qnx/qnxdebugsupport.cpp
@@ -28,182 +28,123 @@
#include "qnxdevice.h"
#include "qnxrunconfiguration.h"
#include "slog2inforunner.h"
+#include "qnxqtversion.h"
+#include "qnxutils.h"
-#include <debugger/debuggerrunconfigurationaspect.h>
#include <debugger/debuggerruncontrol.h>
-#include <debugger/debuggerstartparameters.h>
+
+#include <projectexplorer/applicationlauncher.h>
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
+
+#include <qmldebug/qmldebugcommandlinearguments.h>
+#include <qtsupport/qtkitinformation.h>
+
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
-#include <qmldebug/qmldebugcommandlinearguments.h>
+using namespace Debugger;
using namespace ProjectExplorer;
namespace Qnx {
namespace Internal {
-QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
- : QnxAbstractRunSupport(runControl)
-{
- auto runConfig = runControl->runConfiguration();
- m_useCppDebugger = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>()->useCppDebugger();
- m_useQmlDebugger = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>()->useQmlDebugger();
- m_runnable = runConfig->runnable().as<StandardRunnable>();
-
- const ApplicationLauncher *runner = appRunner();
- connect(runner, &ApplicationLauncher::reportError, this, &QnxDebugSupport::handleError);
- connect(runner, &ApplicationLauncher::remoteProcessStarted, this, &QnxDebugSupport::handleRemoteProcessStarted);
- connect(runner, &ApplicationLauncher::finished, this, &QnxDebugSupport::handleRemoteProcessFinished);
- connect(runner, &ApplicationLauncher::reportProgress, this, &QnxDebugSupport::handleProgressReport);
- connect(runner, &ApplicationLauncher::remoteStdout, this, &QnxDebugSupport::handleRemoteOutput);
- connect(runner, &ApplicationLauncher::remoteStderr, this, &QnxDebugSupport::handleRemoteOutput);
-
- connect(toolRunner(), &Debugger::DebuggerRunTool::requestRemoteSetup,
- this, &QnxDebugSupport::handleAdapterSetupRequested);
- connect(runControl, &RunControl::finished,
- this, &QnxDebugSupport::handleDebuggingFinished);
-
- auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
- const QString applicationId = Utils::FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
- IDevice::ConstPtr dev = DeviceKitInformation::device(runConfig->target()->kit());
- QnxDevice::ConstPtr qnxDevice = dev.dynamicCast<const QnxDevice>();
-
- m_slog2Info = new Slog2InfoRunner(applicationId, qnxDevice, this);
- connect(m_slog2Info, &Slog2InfoRunner::output, this, &QnxDebugSupport::handleApplicationOutput);
- connect(runner, &ApplicationLauncher::remoteProcessStarted, m_slog2Info, &Slog2InfoRunner::start);
- if (qnxDevice->qnxVersion() > 0x060500)
- connect(m_slog2Info, &Slog2InfoRunner::commandMissing, this, &QnxDebugSupport::printMissingWarning);
-}
+// QnxDebuggeeRunner
-void QnxDebugSupport::handleAdapterSetupRequested()
+class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
{
- QTC_ASSERT(state() == Inactive, return);
-
- toolRunner()->showMessage(tr("Preparing remote side...") + '\n', Debugger::AppStuff);
- QnxAbstractRunSupport::handleAdapterSetupRequested();
-}
+public:
+ QnxDebuggeeRunner(ProjectExplorer::RunControl *runControl)
+ : SimpleTargetRunner(runControl)
+ {
+ setDisplayName("QnxDebuggeeRunner");
+ }
-void QnxDebugSupport::startExecution()
-{
- if (state() == Inactive)
- return;
-
- if (m_useCppDebugger && !setPort(m_pdebugPort))
- return;
- if (m_useQmlDebugger && !setPort(m_qmlPort))
- return;
-
- setState(StartingRemoteProcess);
-
- StandardRunnable r = m_runnable;
- QStringList arguments;
- if (m_useCppDebugger)
- arguments << QString::number(m_pdebugPort.number());
- else {
- if (m_useQmlDebugger) {
+private:
+ void start() override
+ {
+ auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
+
+ StandardRunnable r = runnable().as<StandardRunnable>();
+ QStringList arguments;
+ if (portsGatherer->useGdbServer()) {
+ Utils::Port pdebugPort = portsGatherer->gdbServerPort();
+ r.executable = Constants::QNX_DEBUG_EXECUTABLE;
+ arguments.append(pdebugPort.toString());
+ }
+ if (portsGatherer->useQmlServer()) {
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
- m_qmlPort));
+ portsGatherer->qmlServerPort()));
}
arguments.append(Utils::QtcProcess::splitArgs(r.commandLineArguments));
- }
+ r.commandLineArguments = Utils::QtcProcess::joinArgs(arguments);
- r.executable = processExecutable();
- r.commandLineArguments = Utils::QtcProcess::joinArgs(arguments);
- r.environment = m_runnable.environment;
- r.workingDirectory = m_runnable.workingDirectory;
- appRunner()->start(r, device());
-}
+ SimpleTargetRunner::start();
+ }
+};
-void QnxDebugSupport::handleRemoteProcessStarted()
-{
- QnxAbstractRunSupport::handleRemoteProcessStarted();
- Debugger::RemoteSetupResult result;
- result.success = true;
- result.gdbServerPort = m_pdebugPort;
- result.qmlServerPort = m_qmlPort;
- toolRunner()->notifyEngineRemoteSetupFinished(result);
-}
-void QnxDebugSupport::handleRemoteProcessFinished(bool success)
-{
- if (state() == Inactive)
- return;
-
- if (state() == Running) {
- if (!success)
- toolRunner()->notifyInferiorIll();
-
- } else {
- Debugger::RemoteSetupResult result;
- result.success = false;
- result.reason = tr("The %1 process closed unexpectedly.").arg(processExecutable());
- toolRunner()->notifyEngineRemoteSetupFinished(result);
- }
-}
+// QnxDebugSupport
-void QnxDebugSupport::handleDebuggingFinished()
+QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
+ : DebuggerRunTool(runControl)
{
- // setFinished() will kill "pdebug", but we also have to kill
- // the inferior process, as invoking "kill" in gdb doesn't work
- // on QNX gdb
- setFinished();
- m_slog2Info->stop();
- killInferiorProcess();
-}
+ setDisplayName("QnxDebugSupport");
+ appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
-QString QnxDebugSupport::processExecutable() const
-{
- return m_useCppDebugger? QLatin1String(Constants::QNX_DEBUG_EXECUTABLE) : m_runnable.executable;
-}
+ auto portsGatherer = new GdbServerPortsGatherer(runControl);
+ portsGatherer->setUseGdbServer(isCppDebugging());
+ portsGatherer->setUseQmlServer(isQmlDebugging());
-void QnxDebugSupport::killInferiorProcess()
-{
- device()->signalOperation()->killProcess(m_runnable.executable);
-}
+ auto debuggeeRunner = new QnxDebuggeeRunner(runControl);
+ debuggeeRunner->addDependency(portsGatherer);
-void QnxDebugSupport::handleProgressReport(const QString &progressOutput)
-{
- toolRunner()->showMessage(progressOutput + QLatin1Char('\n'), Debugger::AppStuff);
-}
+ auto slog2InfoRunner = new Slog2InfoRunner(runControl);
+ slog2InfoRunner->addDependency(debuggeeRunner);
-void QnxDebugSupport::handleRemoteOutput(const QByteArray &output)
-{
- QTC_ASSERT(state() == Inactive || state() == Running, return);
- toolRunner()->showMessage(QString::fromUtf8(output), Debugger::AppOutput);
+ addDependency(slog2InfoRunner);
}
-void QnxDebugSupport::handleError(const QString &error)
+void QnxDebugSupport::start()
{
- if (state() == Running) {
- toolRunner()->showMessage(error, Debugger::AppError);
- toolRunner()->notifyInferiorIll();
- } else if (state() != Inactive) {
- setFinished();
- Debugger::RemoteSetupResult result;
- result.success = false;
- result.reason = tr("Initial setup failed: %1").arg(error);
- toolRunner()->notifyEngineRemoteSetupFinished(result);
+ auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
+ Utils::Port pdebugPort = portsGatherer->gdbServerPort();
+
+ auto runConfig = qobject_cast<QnxRunConfiguration *>(runControl()->runConfiguration());
+ QTC_ASSERT(runConfig, return);
+ Target *target = runConfig->target();
+ Kit *k = target->kit();
+
+ DebuggerStartParameters params;
+ params.startMode = AttachToRemoteServer;
+ params.useCtrlCStub = true;
+ params.inferior.executable = runConfig->remoteExecutableFilePath();
+ params.symbolFile = runConfig->localExecutableFilePath();
+ params.remoteChannel = QString("%1:%2").arg(device()->sshParameters().host).arg(pdebugPort.number());
+ params.closeMode = KillAtClose;
+ params.inferior.commandLineArguments = runConfig->arguments();
+
+ if (isQmlDebugging()) {
+ params.qmlServer.host = device()->sshParameters().host;
+ params.qmlServer.port = portsGatherer->qmlServerPort();
+ params.inferior.commandLineArguments.replace("%qml_port%", params.qmlServer.port.toString());
}
-}
-void QnxDebugSupport::printMissingWarning()
-{
- toolRunner()->showMessage(tr("Warning: \"slog2info\" is not found "
- "on the device, debug output not available."), Debugger::AppError);
-}
+ auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k));
+ if (qtVersion)
+ params.solibSearchPath = QnxUtils::searchPaths(qtVersion);
-void QnxDebugSupport::handleApplicationOutput(const QString &msg, Utils::OutputFormat outputFormat)
-{
- Q_UNUSED(outputFormat);
- toolRunner()->showMessage(msg, Debugger::AppOutput);
+ reportStarted();
}
-Debugger::DebuggerRunTool *QnxDebugSupport::toolRunner()
+void QnxDebugSupport::stop()
{
- return qobject_cast<Debugger::DebuggerRunTool *>(runControl()->toolRunner());
+ // We have to kill the inferior process, as invoking "kill" in
+ // gdb doesn't work on QNX gdb.
+ auto stdRunnable = runnable().as<StandardRunnable>();
+ device()->signalOperation()->killProcess(stdRunnable.executable);
}
} // namespace Internal
diff --git a/src/plugins/qnx/qnxdebugsupport.h b/src/plugins/qnx/qnxdebugsupport.h
index 5e198a2469..e408f703f3 100644
--- a/src/plugins/qnx/qnxdebugsupport.h
+++ b/src/plugins/qnx/qnxdebugsupport.h
@@ -25,55 +25,21 @@
#pragma once
-#include "qnxabstractrunsupport.h"
-
-#include <projectexplorer/runnables.h>
-
-#include <utils/outputformat.h>
-
-namespace Debugger { class DebuggerRunTool; }
+#include <debugger/debuggerruncontrol.h>
namespace Qnx {
namespace Internal {
-class Slog2InfoRunner;
-
-class QnxDebugSupport : public QnxAbstractRunSupport
+class QnxDebugSupport : public Debugger::DebuggerRunTool
{
Q_OBJECT
public:
explicit QnxDebugSupport(ProjectExplorer::RunControl *runControl);
- void handleDebuggingFinished();
-
private:
- void handleAdapterSetupRequested() override;
-
- void handleRemoteProcessStarted() override;
- void handleRemoteProcessFinished(bool success) override;
- void handleProgressReport(const QString &progressOutput) override;
- void handleRemoteOutput(const QByteArray &output) override;
- void handleError(const QString &error) override;
-
- void printMissingWarning();
- void handleApplicationOutput(const QString &msg, Utils::OutputFormat outputFormat);
-
- void startExecution() override;
-
- Debugger::DebuggerRunTool *toolRunner();
- QString processExecutable() const;
-
- void killInferiorProcess();
-
- ProjectExplorer::StandardRunnable m_runnable;
- Slog2InfoRunner *m_slog2Info;
-
- Utils::Port m_pdebugPort;
- Utils::Port m_qmlPort;
-
- bool m_useCppDebugger;
- bool m_useQmlDebugger;
+ void start() override;
+ void stop() override;
};
} // namespace Internal
diff --git a/src/plugins/qnx/qnxruncontrol.cpp b/src/plugins/qnx/qnxruncontrol.cpp
deleted file mode 100644
index 926274c501..0000000000
--- a/src/plugins/qnx/qnxruncontrol.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
-** Contact: KDAB (info@kdab.com)
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qnxruncontrol.h"
-#include "qnxdevice.h"
-#include "qnxrunconfiguration.h"
-#include "slog2inforunner.h"
-
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/runconfiguration.h>
-#include <projectexplorer/target.h>
-
-using namespace ProjectExplorer;
-using namespace Utils;
-
-namespace Qnx {
-namespace Internal {
-
-QnxRunControl::QnxRunControl(RunConfiguration *runConfig)
- : RunControl(runConfig, ProjectExplorer::Constants::NORMAL_RUN_MODE)
- , m_slog2Info(0)
-{
- IDevice::ConstPtr dev = DeviceKitInformation::device(runConfig->target()->kit());
- QnxDevice::ConstPtr qnxDevice = dev.dynamicCast<const QnxDevice>();
-
- QnxRunConfiguration *qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runConfig);
- QTC_CHECK(qnxRunConfig);
-
- const QString applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
- m_slog2Info = new Slog2InfoRunner(applicationId, qnxDevice, this);
- connect(m_slog2Info, &Slog2InfoRunner::output,
- this, static_cast<void(RunControl::*)(const QString &, OutputFormat)>(&RunControl::appendMessage));
- connect(this, &RunControl::started, m_slog2Info, &Slog2InfoRunner::start);
- if (qnxDevice->qnxVersion() > 0x060500)
- connect(m_slog2Info, &Slog2InfoRunner::commandMissing, this, &QnxRunControl::printMissingWarning);
-}
-
-void QnxRunControl::stop()
-{
- m_slog2Info->stop();
- RunControl::stop();
-}
-
-void QnxRunControl::printMissingWarning()
-{
- appendMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."), ErrorMessageFormat);
-}
-
-} // namespace Internal
-} // namespace Qnx
diff --git a/src/plugins/qnx/qnxruncontrol.h b/src/plugins/qnx/qnxruncontrol.h
deleted file mode 100644
index a447682101..0000000000
--- a/src/plugins/qnx/qnxruncontrol.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
-** Contact: KDAB (info@kdab.com)
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <projectexplorer/runconfiguration.h>
-
-namespace Qnx {
-namespace Internal {
-
-class Slog2InfoRunner;
-
-class QnxRunControl : public ProjectExplorer::RunControl
-{
- Q_OBJECT
-public:
- explicit QnxRunControl(ProjectExplorer::RunConfiguration *runConfig);
-
- void stop() override;
-
-private:
- void printMissingWarning();
-
- Slog2InfoRunner *m_slog2Info;
-};
-
-} // namespace Internal
-} // namespace Qnx
diff --git a/src/plugins/qnx/qnxruncontrolfactory.cpp b/src/plugins/qnx/qnxruncontrolfactory.cpp
index 36dfe09766..a1e6019802 100644
--- a/src/plugins/qnx/qnxruncontrolfactory.cpp
+++ b/src/plugins/qnx/qnxruncontrolfactory.cpp
@@ -30,7 +30,7 @@
#include "qnxdevice.h"
#include "qnxanalyzesupport.h"
#include "qnxqtversion.h"
-#include "qnxruncontrol.h"
+#include "slog2inforunner.h"
#include "qnxutils.h"
#include <debugger/debuggerruncontrol.h>
@@ -53,38 +53,6 @@ using namespace ProjectExplorer;
namespace Qnx {
namespace Internal {
-static DebuggerStartParameters createDebuggerStartParameters(QnxRunConfiguration *runConfig)
-{
- DebuggerStartParameters params;
- Target *target = runConfig->target();
- Kit *k = target->kit();
-
- const IDevice::ConstPtr device = DeviceKitInformation::device(k);
- if (device.isNull())
- return params;
-
- params.startMode = AttachToRemoteServer;
- params.useCtrlCStub = true;
- params.inferior.executable = runConfig->remoteExecutableFilePath();
- params.symbolFile = runConfig->localExecutableFilePath();
- params.remoteChannel = device->sshParameters().host + QLatin1String(":-1");
- params.remoteSetupNeeded = true;
- params.closeMode = KillAtClose;
- params.inferior.commandLineArguments = runConfig->arguments();
-
- auto aspect = runConfig->extraAspect<DebuggerRunConfigurationAspect>();
- if (aspect->useQmlDebugger()) {
- params.qmlServer.host = device->sshParameters().host;
- params.qmlServer.port = Utils::Port(); // QML port is handed out later
- }
-
- auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k));
- if (qtVersion)
- params.solibSearchPath = QnxUtils::searchPaths(qtVersion);
-
- return params;
-}
-
QnxRunControlFactory::QnxRunControlFactory(QObject *parent)
: IRunControlFactory(parent)
{
@@ -108,48 +76,28 @@ bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id m
if (dev.isNull())
return false;
- if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE
- || mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
- auto aspect = runConfiguration->extraAspect<DebuggerRunConfigurationAspect>();
- int portsUsed = aspect ? aspect->portsUsedByDebugger() : 0;
- return portsUsed <= dev->freePorts().count();
- }
-
return true;
}
RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *)
{
QTC_ASSERT(canRun(runConfig, mode), return 0);
- auto rc = qobject_cast<QnxRunConfiguration *>(runConfig);
- QTC_ASSERT(rc, return 0);
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
- auto runControl = new QnxRunControl(rc);
+ auto runControl = new RunControl(runConfig, mode);
(void) new SimpleTargetRunner(runControl);
return runControl;
}
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE) {
- const DebuggerStartParameters params = createDebuggerStartParameters(rc);
auto runControl = new RunControl(runConfig, mode);
- // (void) new DebuggerRunTool(runControl, params, errorMessage); FIXME
(void) new QnxDebugSupport(runControl);
return runControl;
}
if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
- Kit *kit = runConfig->target()->kit();
- const IDevice::ConstPtr device = DeviceKitInformation::device(kit);
- if (device.isNull())
- return 0;
- RunControl *runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
- QTC_ASSERT(runControl, return 0);
- AnalyzerConnection connection;
- connection.connParams = device->sshParameters();
- connection.analyzerHost = connection.connParams.host;
- connection.analyzerPort = Utils::Port(connection.connParams.port);
- runControl->setConnection(connection);
+ RunControl *runControl = new RunControl(runConfig, mode);
+ runControl->createWorker(mode);
(void) new QnxAnalyzeSupport(runControl);
return runControl;
}
diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp
index 7b5f0f38bf..3bde0d4301 100644
--- a/src/plugins/qnx/slog2inforunner.cpp
+++ b/src/plugins/qnx/slog2inforunner.cpp
@@ -25,7 +25,9 @@
#include "slog2inforunner.h"
+#include "qnxdevice.h"
#include "qnxdeviceprocess.h"
+#include "qnxrunconfiguration.h"
#include <projectexplorer/runnables.h>
#include <utils/qtcassert.h>
@@ -33,28 +35,33 @@
#include <QRegExp>
using namespace ProjectExplorer;
+using namespace Utils;
namespace Qnx {
namespace Internal {
-Slog2InfoRunner::Slog2InfoRunner(const QString &applicationId,
- const RemoteLinux::LinuxDevice::ConstPtr &device, QObject *parent)
- : QObject(parent)
- , m_applicationId(applicationId)
- , m_found(false)
- , m_currentLogs(false)
+Slog2InfoRunner::Slog2InfoRunner(RunControl *runControl)
+ : RunWorker(runControl)
{
+ auto qnxRunConfig = qobject_cast<QnxRunConfiguration *>(runControl->runConfiguration());
+ QTC_ASSERT(qnxRunConfig, return);
+ m_applicationId = FileName::fromString(qnxRunConfig->remoteExecutableFilePath()).fileName();
+}
+
+void Slog2InfoRunner::printMissingWarning()
+{
+ appendMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."), ErrorMessageFormat);
// See QTCREATORBUG-10712 for details.
// We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info.
m_applicationId.truncate(63);
- m_testProcess = new QnxDeviceProcess(device, this);
+ m_testProcess = new QnxDeviceProcess(device(), this);
connect(m_testProcess, &DeviceProcess::finished, this, &Slog2InfoRunner::handleTestProcessCompleted);
- m_launchDateTimeProcess = new SshDeviceProcess(device, this);
+ m_launchDateTimeProcess = new SshDeviceProcess(device(), this);
connect(m_launchDateTimeProcess, &DeviceProcess::finished, this, &Slog2InfoRunner::launchSlog2Info);
- m_logProcess = new QnxDeviceProcess(device, this);
+ m_logProcess = new QnxDeviceProcess(device(), this);
connect(m_logProcess, &DeviceProcess::readyReadStandardOutput, this, &Slog2InfoRunner::readLogStandardOutput);
connect(m_logProcess, &DeviceProcess::readyReadStandardError, this, &Slog2InfoRunner::readLogStandardError);
connect(m_logProcess, &DeviceProcess::error, this, &Slog2InfoRunner::handleLogError);
@@ -88,10 +95,14 @@ bool Slog2InfoRunner::commandFound() const
void Slog2InfoRunner::handleTestProcessCompleted()
{
m_found = (m_testProcess->exitCode() == 0);
- if (m_found)
+ if (m_found) {
readLaunchTime();
- else
- emit commandMissing();
+ } else {
+ QnxDevice::ConstPtr qnxDevice = device().dynamicCast<const QnxDevice>();
+ if (qnxDevice->qnxVersion() > 0x060500) {
+ printMissingWarning();
+ }
+ }
}
void Slog2InfoRunner::readLaunchTime()
@@ -174,18 +185,18 @@ void Slog2InfoRunner::processLogLine(const QString &line)
if (bufferName == QLatin1String("default") && bufferId == 8900)
return;
- emit output(regexp.cap(6).trimmed() + QLatin1Char('\n'), Utils::StdOutFormat);
+ appendMessage(regexp.cap(6).trimmed() + '\n', Utils::StdOutFormat);
}
void Slog2InfoRunner::readLogStandardError()
{
- const QString message = QString::fromLatin1(m_logProcess->readAllStandardError());
- emit output(message, Utils::StdErrFormat);
+ appendMessage(QString::fromLatin1(m_logProcess->readAllStandardError()), Utils::StdErrFormat);
}
void Slog2InfoRunner::handleLogError()
{
- emit output(tr("Cannot show slog2info output. Error: %1").arg(m_logProcess->errorString()), Utils::StdErrFormat);
+ appendMessage(tr("Cannot show slog2info output. Error: %1")
+ .arg(m_logProcess->errorString()), Utils::StdErrFormat);
}
} // namespace Internal
diff --git a/src/plugins/qnx/slog2inforunner.h b/src/plugins/qnx/slog2inforunner.h
index 4e08b5f950..048915baac 100644
--- a/src/plugins/qnx/slog2inforunner.h
+++ b/src/plugins/qnx/slog2inforunner.h
@@ -27,6 +27,7 @@
#include <QObject>
+#include <projectexplorer/runconfiguration.h>
#include <remotelinux/linuxdevice.h>
#include <utils/outputformat.h>
@@ -38,26 +39,23 @@ namespace ProjectExplorer { class SshDeviceProcess; }
namespace Qnx {
namespace Internal {
-class Slog2InfoRunner : public QObject
+class Slog2InfoRunner : public ProjectExplorer::RunWorker
{
Q_OBJECT
public:
- explicit Slog2InfoRunner(const QString &applicationId, const RemoteLinux::LinuxDevice::ConstPtr &device, QObject *parent = 0);
+ explicit Slog2InfoRunner(ProjectExplorer::RunControl *runControl);
- void stop();
+ void start() override;
+ void stop() override;
bool commandFound() const;
-public slots:
- void start();
-
signals:
void commandMissing();
void started();
void finished();
- void output(const QString &msg, Utils::OutputFormat format);
-private slots:
+private:
void handleTestProcessCompleted();
void launchSlog2Info();
@@ -65,22 +63,21 @@ private slots:
void readLogStandardError();
void handleLogError();
-private:
+ void printMissingWarning();
void readLaunchTime();
void processLog(bool force);
void processLogLine(const QString &line);
QString m_applicationId;
- bool m_found;
-
QDateTime m_launchDateTime;
- bool m_currentLogs;
+ bool m_found = false;
+ bool m_currentLogs = false;
QString m_remainingData;
- ProjectExplorer::SshDeviceProcess *m_launchDateTimeProcess;
- ProjectExplorer::SshDeviceProcess *m_testProcess;
- ProjectExplorer::SshDeviceProcess *m_logProcess;
+ ProjectExplorer::SshDeviceProcess *m_launchDateTimeProcess = nullptr;
+ ProjectExplorer::SshDeviceProcess *m_testProcess = nullptr;
+ ProjectExplorer::SshDeviceProcess *m_logProcess = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp b/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp
index 4dc313d5e6..15521b8ddb 100644
--- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp
+++ b/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp
@@ -25,89 +25,34 @@
#include "abstractremotelinuxrunsupport.h"
-#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
#include <utils/environment.h>
#include <utils/portlist.h>
+#include <utils/qtcprocess.h>
+
+#include <qmldebug/qmldebugcommandlinearguments.h>
using namespace ProjectExplorer;
using namespace Utils;
namespace RemoteLinux {
-namespace Internal {
-
-class AbstractRemoteLinuxRunSupportPrivate
-{
-public:
- ApplicationLauncher launcher;
- DeviceUsedPortsGatherer portsGatherer;
- ApplicationLauncher fifoCreator;
- PortList portList;
- QString fifo;
- bool usesFifo = false;
-};
-
-} // namespace Internal
-
-using namespace Internal;
-
-AbstractRemoteLinuxRunSupport::AbstractRemoteLinuxRunSupport(RunControl *runControl)
- : TargetRunner(runControl),
- d(new AbstractRemoteLinuxRunSupportPrivate)
-{
-}
-AbstractRemoteLinuxRunSupport::~AbstractRemoteLinuxRunSupport()
-{
- delete d;
-}
-
-ApplicationLauncher *AbstractRemoteLinuxRunSupport::applicationLauncher()
-{
- return &d->launcher;
-}
-
-void AbstractRemoteLinuxRunSupport::setUsesFifo(bool on)
-{
- d->usesFifo = on;
-}
-
-Port AbstractRemoteLinuxRunSupport::findPort() const
-{
- return d->portsGatherer.getNextFreePort(&d->portList);
-}
-
-QString AbstractRemoteLinuxRunSupport::fifo() const
-{
- return d->fifo;
-}
+// FifoGatherer
-void AbstractRemoteLinuxRunSupport::prepare()
+FifoGatherer::FifoGatherer(RunControl *runControl)
+ : RunWorker(runControl)
{
- if (d->usesFifo)
- createRemoteFifo();
- else
- startPortsGathering();
+ setDisplayName("FifoGatherer");
}
-void AbstractRemoteLinuxRunSupport::startPortsGathering()
+FifoGatherer::~FifoGatherer()
{
- appendMessage(tr("Checking available ports...") + '\n', NormalMessageFormat);
- connect(&d->portsGatherer, &DeviceUsedPortsGatherer::error, this, [&](const QString &msg) {
- reportFailure(msg);
- });
- connect(&d->portsGatherer, &DeviceUsedPortsGatherer::portListReady, this, [&] {
- d->portList = device()->freePorts();
- //appendMessage(tr("Found %1 free ports").arg(d->portList.count()), NormalMessageFormat);
- reportSuccess();
- });
- d->portsGatherer.start(device());
}
-void AbstractRemoteLinuxRunSupport::createRemoteFifo()
+void FifoGatherer::start()
{
appendMessage(tr("Creating remote socket...") + '\n', NormalMessageFormat);
@@ -120,77 +65,35 @@ void AbstractRemoteLinuxRunSupport::createRemoteFifo()
QSharedPointer<QByteArray> output(new QByteArray);
QSharedPointer<QByteArray> errors(new QByteArray);
- connect(&d->fifoCreator, &ApplicationLauncher::finished,
+ connect(&m_fifoCreator, &ApplicationLauncher::finished,
this, [this, output, errors](bool success) {
if (!success) {
reportFailure(QString("Failed to create fifo: %1").arg(QLatin1String(*errors)));
} else {
- d->fifo = QString::fromLatin1(*output);
- //appendMessage(tr("Created fifo").arg(d->fifo), NormalMessageFormat);
- reportSuccess();
+ m_fifo = QString::fromLatin1(*output);
+ appendMessage(tr("Created fifo: %1").arg(m_fifo), NormalMessageFormat);
+ reportStarted();
}
});
- connect(&d->fifoCreator, &ApplicationLauncher::remoteStdout,
+ connect(&m_fifoCreator, &ApplicationLauncher::remoteStdout,
this, [output](const QByteArray &data) {
output->append(data);
});
- connect(&d->fifoCreator, &ApplicationLauncher::remoteStderr,
- this, [errors](const QByteArray &data) {
- errors->append(data);
+ connect(&m_fifoCreator, &ApplicationLauncher::remoteStderr,
+ this, [this, errors](const QByteArray &) {
+ reportFailure();
+// errors->append(data);
});
- d->fifoCreator.start(r, device());
-}
-
-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);
+ m_fifoCreator.start(r, device());
}
-void AbstractRemoteLinuxRunSupport::handleAppRunnerFinished(bool success)
+void FifoGatherer::onFinished()
{
- success ? reportStopped() : reportFailure();
+ m_fifoCreator.stop();
}
-void AbstractRemoteLinuxRunSupport::handleAppRunnerError(const QString &error)
-{
- reportFailure(error);
-}
-
-void AbstractRemoteLinuxRunSupport::handleRemoteOutput(const QByteArray &output)
-{
- appendMessage(QString::fromUtf8(output), StdOutFormat);
-}
-
-void AbstractRemoteLinuxRunSupport::handleRemoteErrorOutput(const QByteArray &output)
-{
- appendMessage(QString::fromUtf8(output), StdErrFormat);
-}
-
-void AbstractRemoteLinuxRunSupport::handleProgressReport(const QString &progressOutput)
-{
- appendMessage(progressOutput + '\n', LogMessageFormat);
-}
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h b/src/plugins/remotelinux/abstractremotelinuxrunsupport.h
index a914d48ea7..2a6be032bc 100644
--- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h
+++ b/src/plugins/remotelinux/abstractremotelinuxrunsupport.h
@@ -27,46 +27,28 @@
#include "remotelinux_export.h"
-#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/runconfiguration.h>
-#include <utils/port.h>
-
namespace RemoteLinux {
-namespace Internal { class AbstractRemoteLinuxRunSupportPrivate; }
-
-class REMOTELINUX_EXPORT AbstractRemoteLinuxRunSupport : public ProjectExplorer::TargetRunner
+class REMOTELINUX_EXPORT FifoGatherer : public ProjectExplorer::RunWorker
{
Q_OBJECT
public:
- explicit AbstractRemoteLinuxRunSupport(ProjectExplorer::RunControl *runControl);
- ~AbstractRemoteLinuxRunSupport();
-
- ProjectExplorer::ApplicationLauncher *applicationLauncher();
+ explicit FifoGatherer(ProjectExplorer::RunControl *runControl);
+ ~FifoGatherer();
- void setUsesFifo(bool on);
-
- Utils::Port findPort() const;
- QString fifo() const;
+ QString fifo() const { return m_fifo; }
private:
- void prepare() override;
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;
+ ProjectExplorer::ApplicationLauncher m_fifoCreator;
+ QString m_fifo;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
index 4652734e2f..a2519b7b67 100644
--- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp
@@ -1,210 +1,172 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "remotelinuxanalyzesupport.h"
-
-#include "remotelinuxrunconfiguration.h"
-
-#include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/project.h>
-#include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/kitinformation.h>
-#include <projectexplorer/runnables.h>
-
-#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
-#include <qmldebug/qmloutputparser.h>
-#include <qmldebug/qmldebugcommandlinearguments.h>
-
-#include <QPointer>
-
-using namespace QSsh;
-using namespace ProjectExplorer;
-using namespace Utils;
-
-namespace RemoteLinux {
-namespace Internal {
-
-class RemoteLinuxAnalyzeSupportPrivate
-{
-public:
- RemoteLinuxAnalyzeSupportPrivate(RunControl *runControl)
- {
- if (runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
- usesFifo = true;
- RunConfiguration *runConfiguration = runControl->runConfiguration();
- QTC_ASSERT(runConfiguration, return);
- IRunConfigurationAspect *perfAspect =
- runConfiguration->extraAspect("Analyzer.Perf.Settings");
- QTC_ASSERT(perfAspect, return);
- perfRecordArguments =
- perfAspect->currentSettings()->property("perfRecordArguments").toStringList()
- .join(' ');
- }
- }
-
- Utils::Port qmlPort;
- QString remoteFifo;
- QString perfRecordArguments;
-
- ApplicationLauncher outputGatherer;
- QmlDebug::QmlOutputParser outputParser;
- bool usesFifo = false;
-};
-
-} // namespace Internal
-
-using namespace Internal;
-
-RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RunControl *runControl)
- : ToolRunner(runControl),
- d(new RemoteLinuxAnalyzeSupportPrivate(runControl))
-{
- connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
- this, &RemoteLinuxAnalyzeSupport::remoteIsRunning);
- targetRunner()->setUsesFifo(runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE);
-}
-
-RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
-{
- delete d;
-}
-
-void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
-{
- appendMessage(msg, format);
- d->outputParser.processOutput(msg);
-}
-
-void RemoteLinuxAnalyzeSupport::start()
-{
- const Core::Id runMode = runControl()->runMode();
- if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
- d->qmlPort = targetRunner()->findPort();
- if (!d->qmlPort.isValid()) {
- reportFailure(tr("Not enough free ports on device for profiling."));
- return;
- }
- } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
- d->remoteFifo = targetRunner()->fifo();
- if (d->remoteFifo.isEmpty()) {
- reportFailure(tr("FIFO for profiling data could not be created."));
- return;
- }
- }
-
- ApplicationLauncher *runner = targetRunner()->applicationLauncher();
- connect(runner, &ApplicationLauncher::remoteStderr,
- this, &RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput);
- connect(runner, &ApplicationLauncher::remoteStdout,
- this, &RemoteLinuxAnalyzeSupport::handleRemoteOutput);
- connect(runner, &ApplicationLauncher::remoteProcessStarted,
- this, &RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted);
- connect(runner, &ApplicationLauncher::finished,
- this, &RemoteLinuxAnalyzeSupport::handleAppRunnerFinished);
- connect(runner, &ApplicationLauncher::reportProgress,
- this, &RemoteLinuxAnalyzeSupport::handleProgressReport);
- connect(runner, &ApplicationLauncher::reportError,
- this, &RemoteLinuxAnalyzeSupport::handleAppRunnerError);
-
- auto r = runControl()->runnable().as<StandardRunnable>();
-
- if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
- if (!r.commandLineArguments.isEmpty())
- r.commandLineArguments.append(QLatin1Char(' '));
- r.commandLineArguments += QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices,
- d->qmlPort);
- } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
- r.commandLineArguments = QLatin1String("-c 'perf record -o - ") + d->perfRecordArguments
- + QLatin1String(" -- ") + r.executable + QLatin1String(" ")
- + r.commandLineArguments + QLatin1String(" > ") + d->remoteFifo
- + QLatin1String("'");
- r.executable = QLatin1String("sh");
-
- connect(&d->outputGatherer, SIGNAL(remoteStdout(QByteArray)),
- runControl(), SIGNAL(analyzePerfOutput(QByteArray)));
- connect(&d->outputGatherer, SIGNAL(finished(bool)),
- runControl(), SIGNAL(perfFinished()));
-
- StandardRunnable outputRunner;
- outputRunner.executable = QLatin1String("sh");
- outputRunner.commandLineArguments =
- QString::fromLatin1("-c 'cat %1 && rm -r `dirname %1`'").arg(d->remoteFifo);
- d->outputGatherer.start(outputRunner, device());
- remoteIsRunning();
- }
- runner->start(r, device());
-}
-
-void RemoteLinuxAnalyzeSupport::handleAppRunnerError(const QString &error)
-{
- showMessage(error, Utils::ErrorMessageFormat);
- reportFailure(error);
-}
-
-void RemoteLinuxAnalyzeSupport::handleAppRunnerFinished(bool success)
-{
- // reset needs to be called first to ensure that the correct state is set.
- if (!success)
- showMessage(tr("Failure running remote process."), Utils::NormalMessageFormat);
- runControl()->notifyRemoteFinished();
-}
-
-void RemoteLinuxAnalyzeSupport::remoteIsRunning()
-{
- runControl()->notifyRemoteSetupDone(d->qmlPort);
-}
-
-AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const
-{
- return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
-}
-
-void RemoteLinuxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
-{
- showMessage(QString::fromUtf8(output), Utils::StdOutFormat);
-}
-
-void RemoteLinuxAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output)
-{
- showMessage(QString::fromUtf8(output), Utils::StdErrFormat);
-}
-
-void RemoteLinuxAnalyzeSupport::handleProgressReport(const QString &progressOutput)
-{
- showMessage(progressOutput + QLatin1Char('\n'), Utils::NormalMessageFormat);
-}
-
-void RemoteLinuxAnalyzeSupport::handleAdapterSetupFailed(const QString &error)
-{
- showMessage(tr("Initial setup failed: %1").arg(error), Utils::NormalMessageFormat);
-}
-
-void RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted()
-{
-}
-
-} // namespace RemoteLinux
+///****************************************************************************
+//**
+//** Copyright (C) 2016 The Qt Company Ltd.
+//** Contact: https://www.qt.io/licensing/
+//**
+//** This file is part of Qt Creator.
+//**
+//** Commercial License Usage
+//** Licensees holding valid commercial Qt licenses may use this file in
+//** accordance with the commercial license agreement provided with the
+//** Software or, alternatively, in accordance with the terms contained in
+//** a written agreement between you and The Qt Company. For licensing terms
+//** and conditions see https://www.qt.io/terms-conditions. For further
+//** information use the contact form at https://www.qt.io/contact-us.
+//**
+//** GNU General Public License Usage
+//** Alternatively, this file may be used under the terms of the GNU
+//** General Public License version 3 as published by the Free Software
+//** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+//** included in the packaging of this file. Please review the following
+//** information to ensure the GNU General Public License requirements will
+//** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+//**
+//****************************************************************************/
+
+//#include "remotelinuxanalyzesupport.h"
+
+//#include "remotelinuxrunconfiguration.h"
+
+//#include <projectexplorer/buildconfiguration.h>
+//#include <projectexplorer/project.h>
+//#include <projectexplorer/target.h>
+//#include <projectexplorer/toolchain.h>
+//#include <projectexplorer/kitinformation.h>
+//#include <projectexplorer/runnables.h>
+
+//#include <utils/qtcassert.h>
+//#include <utils/qtcprocess.h>
+//#include <qmldebug/qmloutputparser.h>
+//#include <qmldebug/qmldebugcommandlinearguments.h>
+
+//#include <QPointer>
+
+//using namespace QSsh;
+//using namespace ProjectExplorer;
+//using namespace Utils;
+
+//namespace RemoteLinux {
+//namespace Internal {
+
+//const char RemoteLinuxAnalyzeSupportWorkerId[] = "RemoteLinux.AnalyzeSupportWorker";
+
+//class RemoteLinuxAnalyzeSupportPrivate
+//{
+//public:
+// RemoteLinuxAnalyzeSupportPrivate(RunControl *runControl)
+// {
+// bool isPerf = runControl->runMode() == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE;
+// needFifo = isPerf;
+// if (needFifo) {
+// RunConfiguration *runConfiguration = runControl->runConfiguration();
+// QTC_ASSERT(runConfiguration, return);
+// IRunConfigurationAspect *perfAspect =
+// runConfiguration->extraAspect("Analyzer.Perf.Settings");
+// QTC_ASSERT(perfAspect, return);
+// perfRecordArguments =
+// perfAspect->currentSettings()->property("perfRecordArguments").toStringList()
+// .join(' ');
+// }
+// }
+
+// Utils::Port qmlPort;
+// QString remoteFifo;
+// QString perfRecordArguments;
+
+// ApplicationLauncher outputGatherer;
+// QmlDebug::QmlOutputParser outputParser;
+// bool needFifo = false;
+// bool needPort = false;
+//};
+
+//} // namespace Internal
+
+//using namespace Internal;
+
+//RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RunControl *runControl)
+// : ToolRunner(runControl),
+// d(new RemoteLinuxAnalyzeSupportPrivate(runControl))
+//{
+// setId(RemoteLinuxAnalyzeSupportWorkerId);
+
+// connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
+// this, &RemoteLinuxAnalyzeSupport::remoteIsRunning);
+
+// if (d->needFifo)
+// addDependency(FifoCreatorWorkerId);
+// if (d->needPort)
+// addDependency(PortsGathererWorkerId);
+//}
+
+//RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
+//{
+// delete d;
+//}
+
+////void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
+////{
+//// appendMessage(msg, format);
+//// d->outputParser.processOutput(msg);
+////}
+
+//void RemoteLinuxAnalyzeSupport::start()
+//{
+// if (d->needPort) {
+// RunWorker *worker = qobject_cast<PortsGatherer>();
+// QTC_ASSERT(worker, reportFailure(); return);
+// runControl()->worker(PortsGathererWorkerId)->result();
+// d->qmlPort = targetRunner()->findPort();
+// if (!d->qmlPort.isValid()) {
+// reportFailure(tr("Not enough free ports on device for profiling."));
+// return;
+// }
+// } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
+// d->remoteFifo = targetRunner()->fifo();
+// if (d->remoteFifo.isEmpty()) {
+// reportFailure(tr("FIFO for profiling data could not be created."));
+// return;
+// }
+// }
+
+// ApplicationLauncher *runner = targetRunner()->applicationLauncher();
+
+// auto r = runControl()->runnable().as<StandardRunnable>();
+
+// if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
+// if (!r.commandLineArguments.isEmpty())
+// r.commandLineArguments.append(QLatin1Char(' '));
+// r.commandLineArguments += QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices,
+// d->qmlPort);
+// } else if (runMode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
+// r.commandLineArguments = QLatin1String("-c 'perf record -o - ") + d->perfRecordArguments
+// + QLatin1String(" -- ") + r.executable + QLatin1String(" ")
+// + r.commandLineArguments + QLatin1String(" > ") + d->remoteFifo
+// + QLatin1String("'");
+// r.executable = QLatin1String("sh");
+
+// connect(&d->outputGatherer, SIGNAL(remoteStdout(QByteArray)),
+// runControl(), SIGNAL(analyzePerfOutput(QByteArray)));
+// connect(&d->outputGatherer, SIGNAL(finished(bool)),
+// runControl(), SIGNAL(perfFinished()));
+
+// StandardRunnable outputRunner;
+// outputRunner.executable = QLatin1String("sh");
+// outputRunner.commandLineArguments =
+// QString::fromLatin1("-c 'cat %1 && rm -r `dirname %1`'").arg(d->remoteFifo);
+// d->outputGatherer.start(outputRunner, device());
+// remoteIsRunning();
+// }
+// runner->start(r, device());
+//}
+
+//void RemoteLinuxAnalyzeSupport::remoteIsRunning()
+//{
+// runControl()->notifyRemoteSetupDone(d->qmlPort);
+//}
+
+//AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const
+//{
+// return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
+//}
+
+//} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.h b/src/plugins/remotelinux/remotelinuxanalyzesupport.h
index f125deba91..e1cefa6f97 100644
--- a/src/plugins/remotelinux/remotelinuxanalyzesupport.h
+++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.h
@@ -1,67 +1,54 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "abstractremotelinuxrunsupport.h"
-
-#include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/runconfiguration.h>
-
-#include <utils/outputformat.h>
-
-namespace RemoteLinux {
-
-namespace Internal { class RemoteLinuxAnalyzeSupportPrivate; }
-
-class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public ProjectExplorer::ToolRunner
-{
- Q_OBJECT
-public:
- RemoteLinuxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
- ~RemoteLinuxAnalyzeSupport() override;
-
-private:
- void start() override;
- void handleAdapterSetupFailed(const QString &error);
-
- void handleRemoteSetupRequested();
- void handleAppRunnerError(const QString &error);
- void handleRemoteOutput(const QByteArray &output);
- void handleRemoteErrorOutput(const QByteArray &output);
- void handleAppRunnerFinished(bool success);
- void handleProgressReport(const QString &progressOutput);
-
- void handleRemoteProcessStarted();
-
- void remoteIsRunning();
- AbstractRemoteLinuxRunSupport *targetRunner() const;
-
- void showMessage(const QString &, Utils::OutputFormat);
-
- Internal::RemoteLinuxAnalyzeSupportPrivate * const d;
-};
-
-} // namespace RemoteLinux
+///****************************************************************************
+//**
+//** Copyright (C) 2016 The Qt Company Ltd.
+//** Contact: https://www.qt.io/licensing/
+//**
+//** This file is part of Qt Creator.
+//**
+//** Commercial License Usage
+//** Licensees holding valid commercial Qt licenses may use this file in
+//** accordance with the commercial license agreement provided with the
+//** Software or, alternatively, in accordance with the terms contained in
+//** a written agreement between you and The Qt Company. For licensing terms
+//** and conditions see https://www.qt.io/terms-conditions. For further
+//** information use the contact form at https://www.qt.io/contact-us.
+//**
+//** GNU General Public License Usage
+//** Alternatively, this file may be used under the terms of the GNU
+//** General Public License version 3 as published by the Free Software
+//** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+//** included in the packaging of this file. Please review the following
+//** information to ensure the GNU General Public License requirements will
+//** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+//**
+//****************************************************************************/
+
+//#pragma once
+
+//#include "abstractremotelinuxrunsupport.h"
+
+//#include <projectexplorer/projectexplorerconstants.h>
+//#include <projectexplorer/runconfiguration.h>
+
+//#include <utils/outputformat.h>
+
+//namespace RemoteLinux {
+
+//namespace Internal { class RemoteLinuxAnalyzeSupportPrivate; }
+
+//class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public ProjectExplorer::RunWorker
+//{
+// Q_OBJECT
+//public:
+// RemoteLinuxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
+// ~RemoteLinuxAnalyzeSupport() override;
+
+//private:
+// void start() override;
+
+// void remoteIsRunning();
+
+// Internal::RemoteLinuxAnalyzeSupportPrivate * const d;
+//};
+
+//} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
index 9bcdc5b207..331b5c3ad3 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp
@@ -47,10 +47,35 @@ using namespace Utils;
namespace RemoteLinux {
-LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString *errorMessage)
+LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl)
: DebuggerRunTool(runControl)
{
- RunConfiguration *runConfig = runControl->runConfiguration();
+ setDisplayName("DebugSupport");
+
+ auto portsGatherer = new GdbServerPortsGatherer(runControl);
+ portsGatherer->setUseGdbServer(isCppDebugging());
+ portsGatherer->setUseQmlServer(isQmlDebugging());
+
+ auto gdbServer = new GdbServerRunner(runControl);
+ gdbServer->addDependency(portsGatherer);
+
+ addDependency(gdbServer);
+}
+
+LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
+{
+}
+
+void LinuxDeviceDebugSupport::start()
+{
+ auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
+ QTC_ASSERT(portsGatherer, reportFailure(); return);
+
+ const QString host = device()->sshParameters().host;
+ const Port gdbServerPort = portsGatherer->gdbServerPort();
+ const Port qmlServerPort = portsGatherer->qmlServerPort();
+
+ RunConfiguration *runConfig = runControl()->runConfiguration();
QString symbolFile;
if (auto rlrc = qobject_cast<RemoteLinuxRunConfiguration *>(runConfig))
@@ -58,7 +83,7 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString
if (auto rlrc = qobject_cast<Internal::RemoteLinuxCustomRunConfiguration *>(runConfig))
symbolFile = rlrc->localExecutableFilePath();
if (symbolFile.isEmpty()) {
- *errorMessage = tr("Cannot debug: Local executable is not set.");
+// *errorMessage = tr("Cannot debug: Local executable is not set.");
return;
}
@@ -68,8 +93,10 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString
params.remoteSetupNeeded = false;
if (isQmlDebugging()) {
- params.qmlServer.host = device()->sshParameters().host;
- params.qmlServer.port = Utils::Port(); // port is selected later on
+ params.qmlServer.host = host;
+ params.qmlServer.port = qmlServerPort;
+ params.inferior.commandLineArguments.replace("%qml_port%",
+ QString::number(qmlServerPort.number()));
}
if (isCppDebugging()) {
Runnable r = runnable();
@@ -83,69 +110,14 @@ LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl, QString
params.inferior.commandLineArguments.prepend(
QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices));
}
- params.remoteChannel = device()->sshParameters().host + ":-1";
+
+ params.remoteChannel = QString("%1:%2").arg(host).arg(gdbServerPort.number());
params.symbolFile = symbolFile;
}
setStartParameters(params);
-}
-LinuxDeviceDebugSupport::~LinuxDeviceDebugSupport()
-{
-}
-
-void LinuxDeviceDebugSupport::prepare()
-{
- auto targetRunner = qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
-
- if (isCppDebugging()) {
- m_gdbServerPort = targetRunner->findPort();
- if (!m_gdbServerPort.isValid()) {
- reportFailure(tr("Not enough free ports on device for C++ debugging."));
- return;
- }
- }
- if (isQmlDebugging()) {
- m_qmlPort = targetRunner->findPort();
- if (!m_qmlPort.isValid()) {
- reportFailure(tr("Not enough free ports on device for QML debugging."));
- return;
- }
- }
-
- runControl()->setRunnable(realRunnable());
-
- RemoteSetupResult result;
- result.success = true;
- result.gdbServerPort = m_gdbServerPort;
- result.qmlServerPort = m_qmlPort;
- setRemoteParameters(result);
-
- DebuggerRunTool::prepare();
-}
-
-Runnable LinuxDeviceDebugSupport::realRunnable() const
-{
- StandardRunnable r = runControl()->runnable().as<StandardRunnable>();
- QStringList args = QtcProcess::splitArgs(r.commandLineArguments, OsTypeLinux);
- QString command;
-
- if (isQmlDebugging())
- args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, m_qmlPort));
-
- if (isQmlDebugging() && !isCppDebugging()) {
- command = r.executable;
- } else {
- command = device()->debugServerPath();
- if (command.isEmpty())
- command = QLatin1String("gdbserver");
- args.clear();
- args.append(QString::fromLatin1("--multi"));
- args.append(QString::fromLatin1(":%1").arg(m_gdbServerPort.number()));
- }
- r.executable = command;
- r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
- return r;
+ DebuggerRunTool::start();
}
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.h b/src/plugins/remotelinux/remotelinuxdebugsupport.h
index 7473f05593..d670be1b3a 100644
--- a/src/plugins/remotelinux/remotelinuxdebugsupport.h
+++ b/src/plugins/remotelinux/remotelinuxdebugsupport.h
@@ -36,18 +36,11 @@ class REMOTELINUX_EXPORT LinuxDeviceDebugSupport : public Debugger::DebuggerRunT
Q_OBJECT
public:
- LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl,
- QString *errorMessage = nullptr);
+ LinuxDeviceDebugSupport(ProjectExplorer::RunControl *runControl);
~LinuxDeviceDebugSupport() override;
-protected:
- virtual ProjectExplorer::Runnable realRunnable() const;
-
private:
- void prepare() override;
-
- Utils::Port m_gdbServerPort;
- Utils::Port m_qmlPort;
+ void start() override;
};
} // namespace RemoteLinux
diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
index 978bb9aa90..76911168e8 100644
--- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
+++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp
@@ -30,18 +30,12 @@
#include "remotelinuxcustomrunconfiguration.h"
#include "remotelinuxrunconfiguration.h"
-#include <debugger/analyzer/analyzermanager.h>
-#include <debugger/analyzer/analyzerstartparameters.h>
-
#include <debugger/debuggerruncontrol.h>
-#include <debugger/debuggerrunconfigurationaspect.h>
-#include <debugger/debuggerstartparameters.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/target.h>
-
#include <utils/portlist.h>
#include <utils/qtcassert.h>
@@ -62,7 +56,8 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Co
&& mode != ProjectExplorer::Constants::DEBUG_RUN_MODE
&& mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN
&& mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE
- && mode != ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
+// && mode != ProjectExplorer::Constants::PERFPROFILER_RUN_MODE
+ ) {
return false;
}
@@ -73,34 +68,37 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Co
}
RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode,
- QString *errorMessage)
+ QString *)
{
QTC_ASSERT(canRun(runConfig, mode), return 0);
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
auto runControl = new RunControl(runConfig, mode);
- (void) new AbstractRemoteLinuxRunSupport(runControl);
+ (void) new SimpleTargetRunner(runControl);
return runControl;
}
if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE
|| mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) {
auto runControl = new RunControl(runConfig, mode);
- (void) new AbstractRemoteLinuxRunSupport(runControl);
- (void) new LinuxDeviceDebugSupport(runControl, errorMessage);
+ (void) new LinuxDeviceDebugSupport(runControl);
return runControl;
}
- if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE ||
- mode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE) {
- auto runControl = Debugger::createAnalyzerRunControl(runConfig, mode);
- AnalyzerConnection connection;
- connection.connParams =
- DeviceKitInformation::device(runConfig->target()->kit())->sshParameters();
- connection.analyzerHost = connection.connParams.host;
- runControl->setConnection(connection);
- (void) new AbstractRemoteLinuxRunSupport(runControl);
- (void) new RemoteLinuxAnalyzeSupport(runControl);
+ if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE
+// || mode == ProjectExplorer::Constants::PERFPROFILER_RUN_MODE
+ ) {
+ auto runControl = new RunControl(runConfig, mode);
+ runControl->createWorker(mode);
+// AnalyzerConnection connection;
+// connection.connParams =
+// DeviceKitInformation::device(runConfig->target()->kit())->sshParameters();
+// connection.analyzerHost = connection.connParams.host;
+// runControl->setConnection(connection);
+// (void) new SimpleTargetRunner(runControl);
+// (void) new PortsGatherer(runControl);
+// (void) new FifoGatherer(runControl);
+// (void) new RemoteLinuxAnalyzeSupport(runControl);
return runControl;
}
diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp
index 01aac21877..7137659025 100644
--- a/src/plugins/valgrind/callgrindtool.cpp
+++ b/src/plugins/valgrind/callgrindtool.cpp
@@ -255,14 +255,11 @@ CallgrindTool::CallgrindTool(QObject *parent)
QString toolTip = tr("Valgrind Function Profiler uses the "
"Callgrind tool to record function calls when a program runs.");
- auto rcc = [this](RunConfiguration *runConfiguration, Id mode) {
- auto runControl = new RunControl(runConfiguration, mode);
- (void) createRunTool(runControl);
- return runControl;
- };
+ RunControl::registerWorkerCreator(CALLGRIND_RUN_MODE, [this](RunControl *runControl) {
+ return createRunTool(runControl);
+ });
if (!Utils::HostOsInfo::isWindowsHost()) {
- Debugger::registerAction(CALLGRIND_RUN_MODE, rcc);
auto action = new QAction(tr("Valgrind Function Profiler"), this);
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, CallgrindLocalActionId),
@@ -279,7 +276,6 @@ CallgrindTool::CallgrindTool(QObject *parent)
});
}
- Debugger::registerAction(CALLGRIND_RUN_MODE, rcc);
auto action = new QAction(tr("Valgrind Function Profiler (External Application)"), this);
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, CallgrindRemoteActionId),
diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp
index 4c8d421a6c..f452a845df 100644
--- a/src/plugins/valgrind/memchecktool.cpp
+++ b/src/plugins/valgrind/memchecktool.cpp
@@ -244,7 +244,7 @@ class MemcheckTool : public QObject
public:
MemcheckTool(QObject *parent);
- RunControl *createRunControl(RunConfiguration *runConfiguration, Core::Id runMode);
+ RunWorker *createRunWorker(RunControl *runControl);
private:
void updateRunActions();
@@ -395,8 +395,10 @@ MemcheckTool::MemcheckTool(QObject *parent)
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
QString toolTip = tr("Valgrind Analyze Memory uses the Memcheck tool to find memory leaks.");
+ RunControl::registerWorkerCreator(MEMCHECK_RUN_MODE, std::bind(&MemcheckTool::createRunWorker, this, _1));
+ RunControl::registerWorkerCreator(MEMCHECK_WITH_GDB_RUN_MODE, std::bind(&MemcheckTool::createRunWorker, this, _1));
+
if (!Utils::HostOsInfo::isWindowsHost()) {
- Debugger::registerAction(MEMCHECK_RUN_MODE, std::bind(&MemcheckTool::createRunControl, this, _1, _2));
action = new QAction(this);
action->setText(tr("Valgrind Memory Analyzer"));
action->setToolTip(toolTip);
@@ -414,7 +416,6 @@ MemcheckTool::MemcheckTool(QObject *parent)
action->setEnabled(m_startAction->isEnabled());
});
- Debugger::registerAction(MEMCHECK_WITH_GDB_RUN_MODE, std::bind(&MemcheckTool::createRunControl, this, _1, _2));
action = new QAction(this);
action->setText(tr("Valgrind Memory Analyzer with GDB"));
action->setToolTip(tr("Valgrind Analyze Memory with GDB uses the "
@@ -435,7 +436,6 @@ MemcheckTool::MemcheckTool(QObject *parent)
});
}
- Debugger::registerAction(MEMCHECK_RUN_MODE, std::bind(&MemcheckTool::createRunControl, this, _1, _2));
action = new QAction(this);
action->setText(tr("Valgrind Memory Analyzer (External Application)"));
action->setToolTip(toolTip);
@@ -452,8 +452,8 @@ MemcheckTool::MemcheckTool(QObject *parent)
return;
TaskHub::clearTasks(Debugger::Constants::ANALYZERTASK_ID);
Debugger::selectPerspective(MemcheckPerspectiveId);
- RunControl *rc = createRunControl(runConfig, MEMCHECK_RUN_MODE);
- QTC_ASSERT(rc, return);
+ RunControl *rc = new RunControl(runConfig, MEMCHECK_RUN_MODE);
+ rc->createWorker(MEMCHECK_RUN_MODE);
const auto runnable = dlg.runnable();
rc->setRunnable(runnable);
AnalyzerConnection connection;
@@ -560,14 +560,14 @@ void MemcheckTool::maybeActiveRunConfigurationChanged()
updateFromSettings();
}
-RunControl *MemcheckTool::createRunControl(RunConfiguration *runConfiguration, Core::Id runMode)
+RunWorker *MemcheckTool::createRunWorker(RunControl *runControl)
{
- m_errorModel.setRelevantFrameFinder(makeFrameFinder(runConfiguration
- ? runConfiguration->target()->project()->files(Project::AllFiles) : QStringList()));
+ RunConfiguration *runConfig = runControl->runConfiguration();
+ m_errorModel.setRelevantFrameFinder(makeFrameFinder(runConfig
+ ? runConfig->target()->project()->files(Project::AllFiles) : QStringList()));
- auto runControl = new RunControl(runConfiguration, runMode);
MemcheckToolRunner *runTool = 0;
- if (runMode == MEMCHECK_RUN_MODE)
+ if (runControl->runMode() == MEMCHECK_RUN_MODE)
runTool = new MemcheckToolRunner(runControl);
else
runTool = new MemcheckWithGdbToolRunner(runControl);
@@ -583,7 +583,7 @@ RunControl *MemcheckTool::createRunControl(RunConfiguration *runConfiguration, C
m_toolBusy = true;
updateRunActions();
- return runControl;
+ return runTool;
}
void MemcheckTool::engineStarting(const MemcheckToolRunner *runTool)
@@ -739,7 +739,9 @@ public:
RunControl *create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) override
{
Q_UNUSED(errorMessage);
- return m_tool->createRunControl(runConfiguration, mode);
+ auto runControl = new RunControl(runConfiguration, mode);
+ runControl->createWorker(mode);
+ return runControl;
}
// Do not create an aspect, let the Callgrind tool create one and use that, too.
diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp
index a10e709b3a..c2df034ecf 100644
--- a/src/plugins/valgrind/valgrindengine.cpp
+++ b/src/plugins/valgrind/valgrindengine.cpp
@@ -54,7 +54,7 @@ namespace Valgrind {
namespace Internal {
ValgrindToolRunner::ValgrindToolRunner(RunControl *runControl)
- : ToolRunner(runControl)
+ : RunWorker(runControl)
{
runControl->setIcon(ProjectExplorer::Icons::ANALYZER_START_SMALL_TOOLBAR);
runControl->setSupportsReRunning(false);
@@ -102,7 +102,7 @@ void ValgrindToolRunner::start()
return;
}
- reportSuccess();
+ reportStarted();
}
void ValgrindToolRunner::stop()
@@ -160,7 +160,7 @@ void ValgrindToolRunner::runnerFinished()
disconnect(runner(), &ValgrindRunner::finished,
this, &ValgrindToolRunner::runnerFinished);
- reportSuccess();
+ reportStarted();
}
void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputFormat format)
diff --git a/src/plugins/valgrind/valgrindengine.h b/src/plugins/valgrind/valgrindengine.h
index 874fdf284c..6a41d68000 100644
--- a/src/plugins/valgrind/valgrindengine.h
+++ b/src/plugins/valgrind/valgrindengine.h
@@ -37,7 +37,7 @@
namespace Valgrind {
namespace Internal {
-class ValgrindToolRunner : public ProjectExplorer::ToolRunner
+class ValgrindToolRunner : public ProjectExplorer::RunWorker
{
Q_OBJECT
diff --git a/src/plugins/winrt/winrtdebugsupport.cpp b/src/plugins/winrt/winrtdebugsupport.cpp
index a3f31072a1..1cb2c6b124 100644
--- a/src/plugins/winrt/winrtdebugsupport.cpp
+++ b/src/plugins/winrt/winrtdebugsupport.cpp
@@ -49,7 +49,7 @@ namespace Internal {
using namespace ProjectExplorer;
WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl, WinRtRunnerHelper *runner)
- : ToolRunner(runControl)
+ : RunWorker(runControl)
, m_runner(runner)
{
connect(runControl, &RunControl::finished, this, &WinRtDebugSupport::finish);
diff --git a/src/plugins/winrt/winrtdebugsupport.h b/src/plugins/winrt/winrtdebugsupport.h
index 630463d44c..177e8157c1 100644
--- a/src/plugins/winrt/winrtdebugsupport.h
+++ b/src/plugins/winrt/winrtdebugsupport.h
@@ -35,7 +35,7 @@ namespace Internal {
class WinRtRunConfiguration;
class WinRtRunnerHelper;
-class WinRtDebugSupport : public ProjectExplorer::ToolRunner
+class WinRtDebugSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT
public: