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>
This commit is contained in:
hjk
2017-05-09 10:25:11 +02:00
parent 9b93d5a330
commit 89f02cba2c
56 changed files with 1270 additions and 1843 deletions

View File

@@ -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;
};

View File

@@ -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());

View File

@@ -34,7 +34,7 @@
namespace Android {
namespace Internal {
class AndroidAnalyzeSupport : public ProjectExplorer::ToolRunner
class AndroidAnalyzeSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT

View File

@@ -40,6 +40,7 @@ struct ANDROID_EXPORT AndroidRunnable
QVector<QStringList> afterFinishADBCommands;
QString deviceSerialNumber;
QString displayName() const { return packageName; }
static void *staticTypeId;
};

View File

@@ -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();

View File

@@ -47,7 +47,7 @@ struct AnalyzeUnit {
};
typedef QList<AnalyzeUnit> AnalyzeUnits;
class ClangStaticAnalyzerToolRunner : public ProjectExplorer::ToolRunner
class ClangStaticAnalyzerToolRunner : public ProjectExplorer::RunWorker
{
Q_OBJECT

View File

@@ -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"),

View File

@@ -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

View File

@@ -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))

View File

@@ -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,

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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))
{

View File

@@ -34,7 +34,7 @@ namespace Internal {
class IosRunner;
class IosAnalyzeSupport : public ProjectExplorer::ToolRunner
class IosAnalyzeSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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);

File diff suppressed because it is too large Load Diff

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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 );

View File

@@ -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);

View File

@@ -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);

View File

@@ -49,6 +49,8 @@ public:
explicit QmlProfilerTool(QObject *parent);
~QmlProfilerTool();
static QmlProfilerTool *instance();
ProjectExplorer::RunControl *createRunControl(ProjectExplorer::RunConfiguration *runConfiguration = 0);
void finalizeRunControl(QmlProfilerRunControl *runControl);

View File

@@ -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);

View File

@@ -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 \

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
void QnxAnalyzeSupport::handleAdapterSetupRequested()
{
QTC_ASSERT(state() == Inactive, return);
showMessage(tr("Preparing remote side...") + QLatin1Char('\n'), NormalMessageFormat);
QnxAbstractRunSupport::handleAdapterSetupRequested();
}
void QnxAnalyzeSupport::startExecution()
{
if (state() == Inactive)
return;
if (!setPort(m_qmlPort) && !m_qmlPort.isValid())
return;
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());
}
void QnxAnalyzeSupport::handleRemoteProcessFinished(bool success)
{
if (!success)
showMessage(tr("The %1 process closed unexpectedly.").arg(m_runnable.executable),
NormalMessageFormat);
runControl()->notifyRemoteFinished();
m_slog2Info->stop();
}
void QnxAnalyzeSupport::handleProgressReport(const QString &progressOutput)
{
showMessage(progressOutput + QLatin1Char('\n'), NormalMessageFormat);
}
void QnxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
{
QTC_ASSERT(state() == Inactive || state() == Running, return);
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();
public:
QnxAnalyzeeRunner(ProjectExplorer::RunControl *runControl)
: SimpleTargetRunner(runControl)
{
setDisplayName("QnxAnalyzeeRunner");
}
private:
void start() override
{
auto portsGatherer = runControl()->worker<PortsGatherer>();
Utils::Port port = portsGatherer->findPort();
auto r = runnable().as<StandardRunnable>();
if (!r.commandLineArguments.isEmpty())
r.commandLineArguments += ' ';
r.commandLineArguments +=
QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, port);
runControl()->setRunnable(r);
SimpleTargetRunner::start();
}
};
// QnxDebugSupport
QnxAnalyzeSupport::QnxAnalyzeSupport(RunControl *runControl)
: RunWorker(runControl)
{
setDisplayName("QnxAnalyzeSupport");
appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
auto portsGatherer = new PortsGatherer(runControl);
auto debuggeeRunner = new QnxAnalyzeeRunner(runControl);
debuggeeRunner->addDependency(portsGatherer);
auto slog2InfoRunner = new Slog2InfoRunner(runControl);
slog2InfoRunner->addDependency(debuggeeRunner);
addDependency(slog2InfoRunner);
// QmlDebug::QmlOutputParser m_outputParser;
// FIXME: m_outputParser needs to be fed with application output
// connect(&m_outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
// this, &QnxAnalyzeSupport::remoteIsRunning);
// m_outputParser.processOutput(msg);
}
void QnxAnalyzeSupport::remoteIsRunning()
void QnxAnalyzeSupport::start()
{
runControl()->notifyRemoteSetupDone(m_qmlPort);
}
void QnxAnalyzeSupport::showMessage(const QString &msg, OutputFormat format)
{
if (state() != Inactive)
runControl()->appendMessage(msg, format);
m_outputParser.processOutput(msg);
}
void QnxAnalyzeSupport::printMissingWarning()
{
showMessage(tr("Warning: \"slog2info\" is not found on the device, debug output not available."),
ErrorMessageFormat);
// runControl()->notifyRemoteSetupDone(m_qmlPort);
reportStarted();
}
} // namespace Internal

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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)
// QnxDebuggeeRunner
class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
{
auto runConfig = runControl->runConfiguration();
m_useCppDebugger = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>()->useCppDebugger();
m_useQmlDebugger = runConfig->extraAspect<Debugger::DebuggerRunConfigurationAspect>()->useQmlDebugger();
m_runnable = runConfig->runnable().as<StandardRunnable>();
public:
QnxDebuggeeRunner(ProjectExplorer::RunControl *runControl)
: SimpleTargetRunner(runControl)
{
setDisplayName("QnxDebuggeeRunner");
}
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);
private:
void start() override
{
auto portsGatherer = runControl()->worker<GdbServerPortsGatherer>();
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);
}
void QnxDebugSupport::handleAdapterSetupRequested()
{
QTC_ASSERT(state() == Inactive, return);
toolRunner()->showMessage(tr("Preparing remote side...") + '\n', Debugger::AppStuff);
QnxAbstractRunSupport::handleAdapterSetupRequested();
}
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) {
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);
SimpleTargetRunner::start();
}
};
// QnxDebugSupport
QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
: DebuggerRunTool(runControl)
{
setDisplayName("QnxDebugSupport");
appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
auto portsGatherer = new GdbServerPortsGatherer(runControl);
portsGatherer->setUseGdbServer(isCppDebugging());
portsGatherer->setUseQmlServer(isQmlDebugging());
auto debuggeeRunner = new QnxDebuggeeRunner(runControl);
debuggeeRunner->addDependency(portsGatherer);
auto slog2InfoRunner = new Slog2InfoRunner(runControl);
slog2InfoRunner->addDependency(debuggeeRunner);
addDependency(slog2InfoRunner);
}
void QnxDebugSupport::start()
{
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());
}
r.executable = processExecutable();
r.commandLineArguments = Utils::QtcProcess::joinArgs(arguments);
r.environment = m_runnable.environment;
r.workingDirectory = m_runnable.workingDirectory;
appRunner()->start(r, device());
auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k));
if (qtVersion)
params.solibSearchPath = QnxUtils::searchPaths(qtVersion);
reportStarted();
}
void QnxDebugSupport::handleRemoteProcessStarted()
void QnxDebugSupport::stop()
{
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);
}
}
void QnxDebugSupport::handleDebuggingFinished()
{
// 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();
}
QString QnxDebugSupport::processExecutable() const
{
return m_useCppDebugger? QLatin1String(Constants::QNX_DEBUG_EXECUTABLE) : m_runnable.executable;
}
void QnxDebugSupport::killInferiorProcess()
{
device()->signalOperation()->killProcess(m_runnable.executable);
}
void QnxDebugSupport::handleProgressReport(const QString &progressOutput)
{
toolRunner()->showMessage(progressOutput + QLatin1Char('\n'), Debugger::AppStuff);
}
void QnxDebugSupport::handleRemoteOutput(const QByteArray &output)
{
QTC_ASSERT(state() == Inactive || state() == Running, return);
toolRunner()->showMessage(QString::fromUtf8(output), Debugger::AppOutput);
}
void QnxDebugSupport::handleError(const QString &error)
{
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);
}
}
void QnxDebugSupport::printMissingWarning()
{
toolRunner()->showMessage(tr("Warning: \"slog2info\" is not found "
"on the device, debug output not available."), Debugger::AppError);
}
void QnxDebugSupport::handleApplicationOutput(const QString &msg, Utils::OutputFormat outputFormat)
{
Q_UNUSED(outputFormat);
toolRunner()->showMessage(msg, Debugger::AppOutput);
}
Debugger::DebuggerRunTool *QnxDebugSupport::toolRunner()
{
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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
// FifoGatherer
FifoGatherer::FifoGatherer(RunControl *runControl)
: RunWorker(runControl)
{
public:
ApplicationLauncher launcher;
DeviceUsedPortsGatherer portsGatherer;
ApplicationLauncher fifoCreator;
PortList portList;
QString fifo;
bool usesFifo = false;
};
setDisplayName("FifoGatherer");
}
} // namespace Internal
using namespace Internal;
AbstractRemoteLinuxRunSupport::AbstractRemoteLinuxRunSupport(RunControl *runControl)
: TargetRunner(runControl),
d(new AbstractRemoteLinuxRunSupportPrivate)
FifoGatherer::~FifoGatherer()
{
}
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;
}
void AbstractRemoteLinuxRunSupport::prepare()
{
if (d->usesFifo)
createRemoteFifo();
else
startPortsGathering();
}
void AbstractRemoteLinuxRunSupport::startPortsGathering()
{
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());
m_fifoCreator.start(r, device());
}
void AbstractRemoteLinuxRunSupport::start()
void FifoGatherer::onFinished()
{
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());
m_fifoCreator.stop();
}
void AbstractRemoteLinuxRunSupport::onFinished()
{
d->launcher.disconnect(this);
d->launcher.stop();
d->portsGatherer.disconnect(this);
}
void AbstractRemoteLinuxRunSupport::handleAppRunnerFinished(bool success)
{
success ? reportStopped() : reportFailure();
}
void AbstractRemoteLinuxRunSupport::handleAppRunnerError(const QString &error)
{
reportFailure(error);
}
void AbstractRemoteLinuxRunSupport::handleRemoteOutput(const QByteArray &output)
{
appendMessage(QString::fromUtf8(output), StdOutFormat);
}
void AbstractRemoteLinuxRunSupport::handleRemoteErrorOutput(const QByteArray &output)
{
appendMessage(QString::fromUtf8(output), StdErrFormat);
}
void AbstractRemoteLinuxRunSupport::handleProgressReport(const QString &progressOutput)
{
appendMessage(progressOutput + '\n', LogMessageFormat);
}
} // namespace RemoteLinux

View File

@@ -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();
explicit FifoGatherer(ProjectExplorer::RunControl *runControl);
~FifoGatherer();
ProjectExplorer::ApplicationLauncher *applicationLauncher();
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

View File

@@ -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.
**
****************************************************************************/
///****************************************************************************
//**
//** 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 "remotelinuxanalyzesupport.h"
#include "remotelinuxrunconfiguration.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 <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 <utils/qtcassert.h>
//#include <utils/qtcprocess.h>
//#include <qmldebug/qmloutputparser.h>
//#include <qmldebug/qmldebugcommandlinearguments.h>
#include <QPointer>
//#include <QPointer>
using namespace QSsh;
using namespace ProjectExplorer;
using namespace Utils;
//using namespace QSsh;
//using namespace ProjectExplorer;
//using namespace Utils;
namespace RemoteLinux {
namespace Internal {
//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(' ');
}
}
//const char RemoteLinuxAnalyzeSupportWorkerId[] = "RemoteLinux.AnalyzeSupportWorker";
Utils::Port qmlPort;
QString remoteFifo;
QString perfRecordArguments;
//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(' ');
// }
// }
ApplicationLauncher outputGatherer;
QmlDebug::QmlOutputParser outputParser;
bool usesFifo = false;
};
// Utils::Port qmlPort;
// QString remoteFifo;
// QString perfRecordArguments;
} // namespace Internal
// ApplicationLauncher outputGatherer;
// QmlDebug::QmlOutputParser outputParser;
// bool needFifo = false;
// bool needPort = false;
//};
using namespace Internal;
//} // 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);
}
//using namespace Internal;
RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
{
delete d;
}
//RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RunControl *runControl)
// : ToolRunner(runControl),
// d(new RemoteLinuxAnalyzeSupportPrivate(runControl))
//{
// setId(RemoteLinuxAnalyzeSupportWorkerId);
void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
{
appendMessage(msg, format);
d->outputParser.processOutput(msg);
}
// connect(&d->outputParser, &QmlDebug::QmlOutputParser::waitingForConnectionOnPort,
// this, &RemoteLinuxAnalyzeSupport::remoteIsRunning);
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;
}
}
// if (d->needFifo)
// addDependency(FifoCreatorWorkerId);
// if (d->needPort)
// addDependency(PortsGathererWorkerId);
//}
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);
//RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport()
//{
// delete d;
//}
auto r = runControl()->runnable().as<StandardRunnable>();
////void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format)
////{
//// appendMessage(msg, format);
//// d->outputParser.processOutput(msg);
////}
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");
//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;
// }
// }
connect(&d->outputGatherer, SIGNAL(remoteStdout(QByteArray)),
runControl(), SIGNAL(analyzePerfOutput(QByteArray)));
connect(&d->outputGatherer, SIGNAL(finished(bool)),
runControl(), SIGNAL(perfFinished()));
// ApplicationLauncher *runner = targetRunner()->applicationLauncher();
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());
}
// auto r = runControl()->runnable().as<StandardRunnable>();
void RemoteLinuxAnalyzeSupport::handleAppRunnerError(const QString &error)
{
showMessage(error, Utils::ErrorMessageFormat);
reportFailure(error);
}
// 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");
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();
}
// connect(&d->outputGatherer, SIGNAL(remoteStdout(QByteArray)),
// runControl(), SIGNAL(analyzePerfOutput(QByteArray)));
// connect(&d->outputGatherer, SIGNAL(finished(bool)),
// runControl(), SIGNAL(perfFinished()));
void RemoteLinuxAnalyzeSupport::remoteIsRunning()
{
runControl()->notifyRemoteSetupDone(d->qmlPort);
}
// 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());
//}
AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const
{
return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
}
//void RemoteLinuxAnalyzeSupport::remoteIsRunning()
//{
// runControl()->notifyRemoteSetupDone(d->qmlPort);
//}
void RemoteLinuxAnalyzeSupport::handleRemoteOutput(const QByteArray &output)
{
showMessage(QString::fromUtf8(output), Utils::StdOutFormat);
}
//AbstractRemoteLinuxRunSupport *RemoteLinuxAnalyzeSupport::targetRunner() const
//{
// return qobject_cast<AbstractRemoteLinuxRunSupport *>(runControl()->targetRunner());
//}
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
//} // namespace RemoteLinux

View File

@@ -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.
**
****************************************************************************/
///****************************************************************************
//**
//** 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
//#pragma once
#include "abstractremotelinuxrunsupport.h"
//#include "abstractremotelinuxrunsupport.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/runconfiguration.h>
//#include <projectexplorer/projectexplorerconstants.h>
//#include <projectexplorer/runconfiguration.h>
#include <utils/outputformat.h>
//#include <utils/outputformat.h>
namespace RemoteLinux {
//namespace RemoteLinux {
namespace Internal { class RemoteLinuxAnalyzeSupportPrivate; }
//namespace Internal { class RemoteLinuxAnalyzeSupportPrivate; }
class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public ProjectExplorer::ToolRunner
{
Q_OBJECT
public:
RemoteLinuxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
~RemoteLinuxAnalyzeSupport() override;
//class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public ProjectExplorer::RunWorker
//{
// Q_OBJECT
//public:
// RemoteLinuxAnalyzeSupport(ProjectExplorer::RunControl *runControl);
// ~RemoteLinuxAnalyzeSupport() override;
private:
void start() override;
void handleAdapterSetupFailed(const QString &error);
//private:
// void start() override;
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 remoteIsRunning();
void handleRemoteProcessStarted();
// Internal::RemoteLinuxAnalyzeSupportPrivate * const d;
//};
void remoteIsRunning();
AbstractRemoteLinuxRunSupport *targetRunner() const;
void showMessage(const QString &, Utils::OutputFormat);
Internal::RemoteLinuxAnalyzeSupportPrivate * const d;
};
} // namespace RemoteLinux
//} // namespace RemoteLinux

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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),

View File

@@ -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.

View File

@@ -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)

View File

@@ -37,7 +37,7 @@
namespace Valgrind {
namespace Internal {
class ValgrindToolRunner : public ProjectExplorer::ToolRunner
class ValgrindToolRunner : public ProjectExplorer::RunWorker
{
Q_OBJECT

View File

@@ -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);

View File

@@ -35,7 +35,7 @@ namespace Internal {
class WinRtRunConfiguration;
class WinRtRunnerHelper;
class WinRtDebugSupport : public ProjectExplorer::ToolRunner
class WinRtDebugSupport : public ProjectExplorer::RunWorker
{
Q_OBJECT
public: