Debugger: Dissolve DebugServerPortsGatherer

Use a suitable amount of individual SubChannelProviders instead.

Remove the lumping of the perf channel and gdb/lldb channel in the
users.

Change-Id: I47d449e933799e1a10df4801dfbe99653f168f56
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2024-09-30 12:12:59 +02:00
parent a26119b920
commit b187d5ffd8
5 changed files with 159 additions and 176 deletions

View File

@@ -34,7 +34,6 @@ public:
bool usePerf, bool useGdbServer, bool useQmlServer, bool usePerf, bool useGdbServer, bool useQmlServer,
QmlDebug::QmlDebugServicesPreset qmlServices) QmlDebug::QmlDebugServicesPreset qmlServices)
: RunWorker(runControl), : RunWorker(runControl),
m_usePerf(usePerf), m_useGdbServer(useGdbServer), m_useQmlServer(useQmlServer),
m_qmlServices(qmlServices) m_qmlServices(qmlServices)
{ {
setId("QdbDebuggeeRunner"); setId("QdbDebuggeeRunner");
@@ -49,52 +48,54 @@ public:
appendMessage(m_launcher.readAllStandardError(), StdErrFormat); appendMessage(m_launcher.readAllStandardError(), StdErrFormat);
}); });
m_portsGatherer = new DebugServerPortsGatherer(runControl); if (useGdbServer) {
m_portsGatherer->setUseGdbServer(useGdbServer || usePerf); m_debugChannelProvider = new SubChannelProvider(runControl);
m_portsGatherer->setUseQmlServer(useQmlServer); addStartDependency(m_debugChannelProvider);
addStartDependency(m_portsGatherer);
} }
QUrl perfServer() const { return m_portsGatherer->gdbServer(); } if (useQmlServer) {
QUrl gdbServer() const { return m_portsGatherer->gdbServer(); } m_qmlChannelProvider = new SubChannelProvider(runControl);
QUrl qmlServer() const { return m_portsGatherer->qmlServer(); } addStartDependency(m_qmlChannelProvider);
}
if (usePerf) {
m_perfChannelProvider = new SubChannelProvider(runControl);
addStartDependency(m_perfChannelProvider);
}
}
void start() override void start() override
{ {
const int perfPort = m_portsGatherer->gdbServer().port();
const int gdbServerPort = m_portsGatherer->gdbServer().port();
const int qmlServerPort = m_portsGatherer->qmlServer().port();
int lowerPort = 0; int lowerPort = 0;
int upperPort = 0; int upperPort = 0;
CommandLine cmd; CommandLine cmd;
cmd.setExecutable(device()->filePath(Constants::AppcontrollerFilepath)); cmd.setExecutable(device()->filePath(Constants::AppcontrollerFilepath));
if (m_useGdbServer) { if (m_debugChannelProvider) {
cmd.addArg("--debug-gdb"); cmd.addArg("--debug-gdb");
lowerPort = upperPort = gdbServerPort; lowerPort = upperPort = m_debugChannelProvider->channel().port();
} }
if (m_useQmlServer) { if (m_qmlChannelProvider) {
cmd.addArg("--debug-qml"); cmd.addArg("--debug-qml");
cmd.addArg("--qml-debug-services"); cmd.addArg("--qml-debug-services");
cmd.addArg(QmlDebug::qmlDebugServices(m_qmlServices)); cmd.addArg(QmlDebug::qmlDebugServices(m_qmlServices));
lowerPort = upperPort = qmlServerPort; lowerPort = upperPort = m_qmlChannelProvider->channel().port();
} }
if (m_useGdbServer && m_useQmlServer) { if (m_debugChannelProvider && m_qmlChannelProvider) {
if (gdbServerPort + 1 != qmlServerPort) { lowerPort = m_debugChannelProvider->channel().port();
upperPort = m_qmlChannelProvider->channel().port();
if (lowerPort + 1 != upperPort) {
reportFailure("Need adjacent free ports for combined C++/QML debugging"); reportFailure("Need adjacent free ports for combined C++/QML debugging");
return; return;
} }
lowerPort = gdbServerPort;
upperPort = qmlServerPort;
} }
if (m_usePerf) { if (m_perfChannelProvider) {
const Store perfArgs = runControl()->settingsData(PerfProfiler::Constants::PerfSettingsId); const Store perfArgs = runControl()->settingsData(PerfProfiler::Constants::PerfSettingsId);
const QString recordArgs = perfArgs[PerfProfiler::Constants::PerfRecordArgsId].toString(); const QString recordArgs = perfArgs[PerfProfiler::Constants::PerfRecordArgsId].toString();
cmd.addArg("--profile-perf"); cmd.addArg("--profile-perf");
cmd.addArgs(recordArgs, CommandLine::Raw); cmd.addArgs(recordArgs, CommandLine::Raw);
lowerPort = upperPort = perfPort; lowerPort = upperPort = m_perfChannelProvider->channel().port();
} }
cmd.addArg("--port-range"); cmd.addArg("--port-range");
cmd.addArg(QString("%1-%2").arg(lowerPort).arg(upperPort)); cmd.addArg(QString("%1-%2").arg(lowerPort).arg(upperPort));
@@ -109,10 +110,14 @@ public:
void stop() override { m_launcher.close(); } void stop() override { m_launcher.close(); }
private: private:
Debugger::DebugServerPortsGatherer *m_portsGatherer = nullptr; friend class QdbDeviceDebugSupport;
bool m_usePerf; friend class QdbDeviceQmlProfilerSupport;
bool m_useGdbServer; friend class QdbDeviceQmlToolingSupport;
bool m_useQmlServer; friend class QdbDevicePerfProfilerSupport;
Debugger::SubChannelProvider *m_debugChannelProvider = nullptr;
Debugger::SubChannelProvider *m_qmlChannelProvider = nullptr;
Debugger::SubChannelProvider *m_perfChannelProvider = nullptr;
QmlDebug::QmlDebugServicesPreset m_qmlServices; QmlDebug::QmlDebugServicesPreset m_qmlServices;
Process m_launcher; Process m_launcher;
}; };
@@ -167,8 +172,10 @@ void QdbDeviceDebugSupport::start()
{ {
setStartMode(Debugger::AttachToRemoteServer); setStartMode(Debugger::AttachToRemoteServer);
setCloseMode(KillAndExitMonitorAtClose); setCloseMode(KillAndExitMonitorAtClose);
setRemoteChannel(m_debuggee->gdbServer()); if (SubChannelProvider *provider = m_debuggee->m_debugChannelProvider)
setQmlServer(m_debuggee->qmlServer()); setRemoteChannel(provider->channel());
if (SubChannelProvider *provider = m_debuggee->m_qmlChannelProvider)
setQmlServer(provider->channel());
setUseContinueInsteadOfRun(true); setUseContinueInsteadOfRun(true);
setContinueAfterAttach(true); setContinueAfterAttach(true);
addSolibSearchDir("%{sysroot}/system/lib"); addSolibSearchDir("%{sysroot}/system/lib");
@@ -214,7 +221,8 @@ QdbDeviceQmlToolingSupport::QdbDeviceQmlToolingSupport(RunControl *runControl)
void QdbDeviceQmlToolingSupport::start() void QdbDeviceQmlToolingSupport::start()
{ {
m_worker->recordData("QmlServerUrl", m_runner->qmlServer()); QTC_ASSERT(m_runner->m_qmlChannelProvider, reportFailure({}));
m_worker->recordData("QmlServerUrl", m_runner->m_qmlChannelProvider->channel());
reportStarted(); reportStarted();
} }
@@ -244,7 +252,8 @@ QdbDevicePerfProfilerSupport::QdbDevicePerfProfilerSupport(RunControl *runContro
void QdbDevicePerfProfilerSupport::start() void QdbDevicePerfProfilerSupport::start()
{ {
runControl()->setProperty("PerfConnection", m_profilee->perfServer()); QTC_ASSERT(m_profilee->m_perfChannelProvider, reportFailure({}));
runControl()->setProperty("PerfConnection", m_profilee->m_perfChannelProvider->channel());
reportStarted(); reportStarted();
} }

View File

@@ -156,7 +156,8 @@ class DebuggerRunToolPrivate
{ {
public: public:
QPointer<CoreUnpacker> coreUnpacker; QPointer<CoreUnpacker> coreUnpacker;
QPointer<DebugServerPortsGatherer> portsGatherer; QPointer<SubChannelProvider> debugChannelProvider;
QPointer<SubChannelProvider> qmlChannelProvider;
bool addQmlServerInferiorCommandLineArgumentIfNeeded = false; bool addQmlServerInferiorCommandLineArgumentIfNeeded = false;
int snapshotCounter = 0; int snapshotCounter = 0;
int engineStartsNeeded = 0; int engineStartsNeeded = 0;
@@ -463,9 +464,11 @@ void DebuggerRunTool::continueAfterTerminalStart()
{ {
TaskHub::clearTasks(Constants::TASK_CATEGORY_DEBUGGER_RUNTIME); TaskHub::clearTasks(Constants::TASK_CATEGORY_DEBUGGER_RUNTIME);
if (d->portsGatherer) { if (d->debugChannelProvider)
setRemoteChannel(d->portsGatherer->gdbServer()); setRemoteChannel(d->debugChannelProvider->channel());
setQmlServer(d->portsGatherer->qmlServer());
if (d->qmlChannelProvider) {
setQmlServer(d->qmlChannelProvider->channel());
if (d->addQmlServerInferiorCommandLineArgumentIfNeeded if (d->addQmlServerInferiorCommandLineArgumentIfNeeded
&& m_runParameters.isQmlDebugging && m_runParameters.isQmlDebugging
&& m_runParameters.isCppDebugging()) { && m_runParameters.isCppDebugging()) {
@@ -755,17 +758,39 @@ bool DebuggerRunTool::isQmlDebugging() const
void DebuggerRunTool::setUsePortsGatherer(bool useCpp, bool useQml) void DebuggerRunTool::setUsePortsGatherer(bool useCpp, bool useQml)
{ {
QTC_ASSERT(!d->portsGatherer, reportFailure(); return);
runControl()->enablePortsGatherer(); runControl()->enablePortsGatherer();
d->portsGatherer = new DebugServerPortsGatherer(runControl()); if (useCpp) {
d->portsGatherer->setUseGdbServer(useCpp); QTC_ASSERT(!d->debugChannelProvider, reportFailure(); return);
d->portsGatherer->setUseQmlServer(useQml); d->debugChannelProvider = new SubChannelProvider(runControl());
addStartDependency(d->portsGatherer); addStartDependency(d->debugChannelProvider);
}
if (useQml) {
QTC_ASSERT(!d->qmlChannelProvider, reportFailure(); return);
d->qmlChannelProvider = new SubChannelProvider(runControl());
addStartDependency(d->qmlChannelProvider);
}
} }
DebugServerPortsGatherer *DebuggerRunTool::portsGatherer() const SubChannelProvider *DebuggerRunTool::debugChannelProvider() const
{ {
return d->portsGatherer; return d->debugChannelProvider;
}
QUrl DebuggerRunTool::debugChannel() const
{
QTC_ASSERT(d->debugChannelProvider, return {});
return d->debugChannelProvider->channel();
}
SubChannelProvider *DebuggerRunTool::qmlChannelProvider() const
{
return d->qmlChannelProvider;
}
QUrl DebuggerRunTool::qmlChannel() const
{
QTC_ASSERT(d->qmlChannelProvider, return {});
return d->qmlChannelProvider->channel();
} }
void DebuggerRunTool::setSolibSearchPath(const Utils::FilePaths &list) void DebuggerRunTool::setSolibSearchPath(const Utils::FilePaths &list)
@@ -1022,50 +1047,6 @@ void DebuggerRunTool::showMessage(const QString &msg, int channel, int timeout)
} }
} }
namespace Internal {
/*!
\class Debugger::SubChannelProvider
\internal
This is a helper RunWorker implementation to either use or not
use port forwarding for one SubChannel in the ChannelProvider
implementation.
By default it is assumed that no forwarding is needed, i.e.
end points provided by the shared endpoint resource provider
are directly accessible.
*/
class SubChannelProvider : public RunWorker
{
public:
SubChannelProvider(RunControl *runControl)
: RunWorker(runControl)
{
setId("SubChannelProvider");
}
void start() final
{
m_channel.setScheme(urlTcpScheme());
if (device()->extraData(RemoteLinux::Constants::SshForwardDebugServerPort).toBool())
m_channel.setHost("localhost");
else
m_channel.setHost(device()->toolControlChannel(IDevice::ControlChannelHint()).host());
m_channel.setPort(runControl()->findEndPoint().port());
reportStarted();
}
QUrl channel() const { return m_channel; }
private:
QUrl m_channel;
};
} // Internal
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// //
// Externally visible helper. // Externally visible helper.
@@ -1073,21 +1054,23 @@ private:
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/*! /*!
\class Debugger::DebugServerPortsGatherer \class Debugger::SubChannelProvider
\internal The class implements a \c RunWorker to provide a url
indicating usable connection end
The class implements a \c RunWorker to provide
to provide a set of urls indicating usable connection end
points for 'server-using' tools (typically one, like plain points for 'server-using' tools (typically one, like plain
gdbserver and the Qml tooling, but two for mixed debugging). gdbserver and the Qml tooling, but two for mixed debugging).
Urls can describe local or tcp servers that are directly Urls can describe local or tcp servers that are directly
accessible to the host tools. accessible to the host tools.
By default it is assumed that no forwarding is needed, i.e.
end points provided by the shared endpoint resource provider
are directly accessible.
The tool implementations can assume that any needed port The tool implementations can assume that any needed port
forwarding setup is setup and handled transparently by forwarding setup is setup and handled transparently by
a \c DebugServerPortsGatherer instance. a \c SubChannelProvider instance.
If there are multiple subchannels needed that need to share a If there are multiple subchannels needed that need to share a
common set of resources on the remote side, a device implementation common set of resources on the remote side, a device implementation
@@ -1102,28 +1085,21 @@ private:
forwarding. forwarding.
*/ */
DebugServerPortsGatherer::DebugServerPortsGatherer(RunControl *runControl) SubChannelProvider::SubChannelProvider(RunControl *runControl)
: RunWorker(runControl) : RunWorker(runControl)
{ {
setId("DebugServerPortsGatherer"); setId("SubChannelProvider");
m_gdbChannelProvider = new Internal::SubChannelProvider(runControl);
addStartDependency(m_gdbChannelProvider);
m_qmlChannelProvider = new Internal::SubChannelProvider(runControl);
addStartDependency(m_qmlChannelProvider);
} }
DebugServerPortsGatherer::~DebugServerPortsGatherer() = default; void SubChannelProvider::start()
QUrl DebugServerPortsGatherer::gdbServer() const
{ {
return m_gdbChannelProvider->channel(); m_channel.setScheme(urlTcpScheme());
} if (device()->extraData(RemoteLinux::Constants::SshForwardDebugServerPort).toBool())
m_channel.setHost("localhost");
QUrl DebugServerPortsGatherer::qmlServer() const else
{ m_channel.setHost(device()->toolControlChannel(IDevice::ControlChannelHint()).host());
return m_qmlChannelProvider->channel(); m_channel.setPort(runControl()->findEndPoint().port());
reportStarted();
} }
void DebuggerRunTool::startDebugServerIfNeededAndContinueStartup() void DebuggerRunTool::startDebugServerIfNeededAndContinueStartup()
@@ -1135,19 +1111,14 @@ void DebuggerRunTool::startDebugServerIfNeededAndContinueStartup()
// FIXME: Indentation intentionally wrong to keep diff in gerrit small. Will fix later. // FIXME: Indentation intentionally wrong to keep diff in gerrit small. Will fix later.
QTC_ASSERT(portsGatherer(), reportFailure(); return);
const bool isQmlDebugging = portsGatherer()->useQmlServer();
const bool isCppDebugging = portsGatherer()->useGdbServer();
CommandLine commandLine = m_runParameters.inferior.command; CommandLine commandLine = m_runParameters.inferior.command;
CommandLine cmd; CommandLine cmd;
if (isQmlDebugging && !isCppDebugging) { if (d->qmlChannelProvider && !d->debugChannelProvider) {
// FIXME: Case should not happen? // FIXME: Case should not happen?
cmd.setExecutable(commandLine.executable()); cmd.setExecutable(commandLine.executable());
cmd.addArg(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, cmd.addArg(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
portsGatherer()->qmlServer())); d->qmlChannelProvider->channel()));
cmd.addArgs(commandLine.arguments(), CommandLine::Raw); cmd.addArgs(commandLine.arguments(), CommandLine::Raw);
} else { } else {
cmd.setExecutable(device()->debugServerPath()); cmd.setExecutable(device()->debugServerPath());
@@ -1191,14 +1162,15 @@ void DebuggerRunTool::startDebugServerIfNeededAndContinueStartup()
} }
} }
} }
QTC_ASSERT(d->debugChannelProvider, reportFailure({}));
if (cmd.executable().baseName().contains("lldb-server")) { if (cmd.executable().baseName().contains("lldb-server")) {
cmd.addArg("platform"); cmd.addArg("platform");
cmd.addArg("--listen"); cmd.addArg("--listen");
cmd.addArg(QString("*:%1").arg(portsGatherer()->gdbServer().port())); cmd.addArg(QString("*:%1").arg(d->debugChannelProvider->channel().port()));
cmd.addArg("--server"); cmd.addArg("--server");
} else if (cmd.executable().baseName() == "debugserver") { } else if (cmd.executable().baseName() == "debugserver") {
const QString ipAndPort("`echo $SSH_CLIENT | cut -d ' ' -f 1`:%1"); const QString ipAndPort("`echo $SSH_CLIENT | cut -d ' ' -f 1`:%1");
cmd.addArgs(ipAndPort.arg(portsGatherer()->gdbServer().port()), CommandLine::Raw); cmd.addArgs(ipAndPort.arg(d->debugChannelProvider->channel().port()), CommandLine::Raw);
if (d->serverAttachPid.isValid()) if (d->serverAttachPid.isValid())
cmd.addArgs({"--attach", QString::number(d->serverAttachPid.pid())}); cmd.addArgs({"--attach", QString::number(d->serverAttachPid.pid())});
@@ -1211,7 +1183,7 @@ void DebuggerRunTool::startDebugServerIfNeededAndContinueStartup()
if (d->serverAttachPid.isValid()) if (d->serverAttachPid.isValid())
cmd.addArg("--attach"); cmd.addArg("--attach");
const auto port = portsGatherer()->gdbServer().port(); const auto port = d->debugChannelProvider->channel().port();
cmd.addArg(QString(":%1").arg(port)); cmd.addArg(QString(":%1").arg(port));
if (device()->extraData(RemoteLinux::Constants::SshForwardDebugServerPort).toBool()) { if (device()->extraData(RemoteLinux::Constants::SshForwardDebugServerPort).toBool()) {

View File

@@ -15,12 +15,9 @@
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal { class DebuggerRunToolPrivate; }
class DebuggerRunToolPrivate;
class SubChannelProvider;
}
class DebugServerPortsGatherer; class SubChannelProvider;
class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker class DEBUGGER_EXPORT DebuggerRunTool : public ProjectExplorer::RunWorker
{ {
@@ -85,12 +82,17 @@ public:
Internal::DebuggerRunParameters &runParameters() { return m_runParameters; } Internal::DebuggerRunParameters &runParameters() { return m_runParameters; }
QUrl debugChannel() const;
SubChannelProvider *debugChannelProvider() const;
QUrl qmlChannel() const;
SubChannelProvider *qmlChannelProvider() const;
protected: protected:
bool isCppDebugging() const; bool isCppDebugging() const;
bool isQmlDebugging() const; bool isQmlDebugging() const;
void setUsePortsGatherer(bool useCpp, bool useQml); void setUsePortsGatherer(bool useCpp, bool useQml);
DebugServerPortsGatherer *portsGatherer() const;
void addSolibSearchDir(const QString &str); void addSolibSearchDir(const QString &str);
void addQmlServerInferiorCommandLineArgumentIfNeeded(); void addQmlServerInferiorCommandLineArgumentIfNeeded();
@@ -127,25 +129,17 @@ private:
Internal::DebuggerRunParameters m_runParameters; Internal::DebuggerRunParameters m_runParameters;
}; };
class DEBUGGER_EXPORT DebugServerPortsGatherer : public ProjectExplorer::RunWorker class DEBUGGER_EXPORT SubChannelProvider : public ProjectExplorer::RunWorker
{ {
public: public:
explicit DebugServerPortsGatherer(ProjectExplorer::RunControl *runControl); explicit SubChannelProvider(ProjectExplorer::RunControl *runControl);
~DebugServerPortsGatherer() override;
void setUseGdbServer(bool useIt) { m_useGdbServer = useIt; } void start() final;
bool useGdbServer() const { return m_useGdbServer; }
QUrl gdbServer() const;
void setUseQmlServer(bool useIt) { m_useQmlServer = useIt; } QUrl channel() const { return m_channel; }
bool useQmlServer() const { return m_useQmlServer; }
QUrl qmlServer() const;
private: private:
bool m_useGdbServer = false; QUrl m_channel;
bool m_useQmlServer = false;
Internal::SubChannelProvider *m_gdbChannelProvider;
Internal::SubChannelProvider *m_qmlChannelProvider;
}; };
class DebuggerRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory class DebuggerRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory

View File

@@ -76,26 +76,25 @@ static QStringList searchPaths(Kit *kit)
class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
{ {
public: public:
QnxDebuggeeRunner(RunControl *runControl, DebugServerPortsGatherer *portsGatherer) QnxDebuggeeRunner(RunControl *runControl, DebuggerRunTool *debugger)
: SimpleTargetRunner(runControl) : SimpleTargetRunner(runControl)
{ {
setId("QnxDebuggeeRunner"); setId("QnxDebuggeeRunner");
setStartModifier([this, portsGatherer] { setStartModifier([this, debugger] {
CommandLine cmd = commandLine(); CommandLine cmd = commandLine();
QStringList arguments; QStringList arguments;
if (portsGatherer->useGdbServer()) { if (SubChannelProvider *provider = debugger->debugChannelProvider()) {
int pdebugPort = portsGatherer->gdbServer().port(); int pdebugPort = provider->channel().port();
cmd.setExecutable(device()->filePath(QNX_DEBUG_EXECUTABLE)); cmd.setExecutable(device()->filePath(QNX_DEBUG_EXECUTABLE));
arguments.append(QString::number(pdebugPort)); arguments.append(QString::number(pdebugPort));
} }
if (portsGatherer->useQmlServer()) { if (SubChannelProvider *provider = debugger->qmlChannelProvider()) {
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
portsGatherer->qmlServer())); provider->channel()));
} }
cmd.setArguments(ProcessArgs::joinArgs(arguments)); cmd.setArguments(ProcessArgs::joinArgs(arguments));
setCommandLine(cmd); setCommandLine(cmd);
}); });
} }
}; };
@@ -114,8 +113,7 @@ public:
setUsePortsGatherer(isCppDebugging(), isQmlDebugging()); setUsePortsGatherer(isCppDebugging(), isQmlDebugging());
auto debuggeeRunner = new QnxDebuggeeRunner(runControl, portsGatherer()); auto debuggeeRunner = new QnxDebuggeeRunner(runControl, this);
debuggeeRunner->addStartDependency(portsGatherer());
auto slog2InfoRunner = new Slog2InfoRunner(runControl); auto slog2InfoRunner = new Slog2InfoRunner(runControl);
debuggeeRunner->addStartDependency(slog2InfoRunner); debuggeeRunner->addStartDependency(slog2InfoRunner);
@@ -175,14 +173,13 @@ private:
class PDebugRunner : public ProjectExplorer::SimpleTargetRunner class PDebugRunner : public ProjectExplorer::SimpleTargetRunner
{ {
public: public:
PDebugRunner(RunControl *runControl, DebugServerPortsGatherer *portsGatherer) PDebugRunner(RunControl *runControl, DebuggerRunTool *debugger)
: SimpleTargetRunner(runControl) : SimpleTargetRunner(runControl)
{ {
setId("PDebugRunner"); setId("PDebugRunner");
addStartDependency(portsGatherer);
setStartModifier([this, portsGatherer] { setStartModifier([this, debugger] {
const int pdebugPort = portsGatherer->gdbServer().port(); const int pdebugPort = debugger->debugChannel().port();
setCommandLine({QNX_DEBUG_EXECUTABLE, {QString::number(pdebugPort)}}); setCommandLine({QNX_DEBUG_EXECUTABLE, {QString::number(pdebugPort)}});
}); });
} }
@@ -199,7 +196,7 @@ public:
setUseCtrlCStub(true); setUseCtrlCStub(true);
if (isCppDebugging()) { if (isCppDebugging()) {
auto pdebugRunner = new PDebugRunner(runControl, portsGatherer()); auto pdebugRunner = new PDebugRunner(runControl, this);
addStartDependency(pdebugRunner); addStartDependency(pdebugRunner);
} }
} }

View File

@@ -101,7 +101,6 @@ public:
bool usePerf, bool useGdbServer, bool useQmlServer, bool usePerf, bool useGdbServer, bool useQmlServer,
QmlDebug::QmlDebugServicesPreset qmlServices) QmlDebug::QmlDebugServicesPreset qmlServices)
: SimpleTargetRunner(runControl), : SimpleTargetRunner(runControl),
m_usePerf(usePerf), m_useGdbServer(useGdbServer), m_useQmlServer(useQmlServer),
m_qmlServices(qmlServices) m_qmlServices(qmlServices)
{ {
setId(AppManager::Constants::DEBUG_LAUNCHER_ID); setId(AppManager::Constants::DEBUG_LAUNCHER_ID);
@@ -110,12 +109,19 @@ public:
if (usePerf) { if (usePerf) {
suppressDefaultStdOutHandling(); suppressDefaultStdOutHandling();
runControl->setProperty("PerfProcess", QVariant::fromValue(process())); runControl->setProperty("PerfProcess", QVariant::fromValue(process()));
m_perfChannelProvider = new Debugger::SubChannelProvider(runControl);
addStartDependency(m_perfChannelProvider);
} }
m_portsGatherer = new Debugger::DebugServerPortsGatherer(runControl); if (useGdbServer) {
m_portsGatherer->setUseGdbServer(useGdbServer || usePerf); m_debugChannelProvider = new Debugger::SubChannelProvider(runControl);
m_portsGatherer->setUseQmlServer(useQmlServer); addStartDependency(m_debugChannelProvider);
addStartDependency(m_portsGatherer); }
if (useQmlServer) {
m_qmlChannelProvider = new Debugger::SubChannelProvider(runControl);
addStartDependency(m_qmlChannelProvider);
}
setStartModifier([this, runControl] { setStartModifier([this, runControl] {
FilePath controller = runControl->aspectData<AppManagerControllerAspect>()->filePath; FilePath controller = runControl->aspectData<AppManagerControllerAspect>()->filePath;
@@ -128,30 +134,28 @@ public:
envVars = envAspect->environment.toStringList(); envVars = envAspect->environment.toStringList();
envVars.replaceInStrings(" ", "\\ "); envVars.replaceInStrings(" ", "\\ ");
const int gdbServerPort = m_portsGatherer->gdbServer().port();
const int qmlServerPort = m_portsGatherer->qmlServer().port();
CommandLine cmd{controller}; CommandLine cmd{controller};
if (!instanceId.isEmpty()) if (!instanceId.isEmpty())
cmd.addArgs({"--instance-id", instanceId}); cmd.addArgs({"--instance-id", instanceId});
cmd.addArg("debug-application"); cmd.addArg("debug-application");
if (m_useGdbServer || m_useQmlServer) { if (m_debugChannelProvider || m_qmlChannelProvider) {
QStringList debugArgs; QStringList debugArgs;
debugArgs.append(envVars.join(' ')); debugArgs.append(envVars.join(' '));
if (m_useGdbServer) { if (m_debugChannelProvider) {
debugArgs.append(QString("gdbserver :%1").arg(gdbServerPort)); debugArgs.append(QString("gdbserver :%1").arg(m_debugChannelProvider->channel().port()));
} }
if (m_useQmlServer) { if (m_qmlChannelProvider) {
debugArgs.append(QString("%program% %1 %arguments%") const QString qmlArgs =
.arg(qmlDebugCommandLineArguments(m_qmlServices, qmlDebugCommandLineArguments(m_qmlServices,
QString("port:%1").arg(qmlServerPort), QString("port:%1").arg(m_qmlChannelProvider->channel().port()),
true))); true);
debugArgs.append(QString("%program% %1 %arguments%") .arg(qmlArgs));
} }
cmd.addArg(debugArgs.join(' ')); cmd.addArg(debugArgs.join(' '));
} }
if (m_usePerf) { if (m_perfChannelProvider) {
const Store perfArgs = runControl->settingsData(PerfProfiler::Constants::PerfSettingsId); const Store perfArgs = runControl->settingsData(PerfProfiler::Constants::PerfSettingsId);
const QString recordArgs = perfArgs[PerfProfiler::Constants::PerfRecordArgsId].toString(); const QString recordArgs = perfArgs[PerfProfiler::Constants::PerfRecordArgsId].toString();
cmd.addArg(QString("perf record %1 -o - --").arg(recordArgs)); cmd.addArg(QString("perf record %1 -o - --").arg(recordArgs));
@@ -177,15 +181,22 @@ public:
}); });
} }
QUrl perfServer() const { return m_portsGatherer->gdbServer(); } QUrl gdbServer() const
QUrl gdbServer() const { return m_portsGatherer->gdbServer(); } {
QUrl qmlServer() const { return m_portsGatherer->qmlServer(); } QTC_ASSERT(m_debugChannelProvider, return {});
return m_debugChannelProvider->channel();
}
QUrl qmlServer() const
{
QTC_ASSERT(m_qmlChannelProvider, return {});
return m_qmlChannelProvider->channel();
}
private: private:
Debugger::DebugServerPortsGatherer *m_portsGatherer = nullptr; Debugger::SubChannelProvider *m_debugChannelProvider = nullptr;
bool m_usePerf; Debugger::SubChannelProvider *m_qmlChannelProvider = nullptr;
bool m_useGdbServer; Debugger::SubChannelProvider *m_perfChannelProvider = nullptr;
bool m_useQmlServer;
QmlDebug::QmlDebugServicesPreset m_qmlServices; QmlDebug::QmlDebugServicesPreset m_qmlServices;
}; };