forked from qt-creator/qt-creator
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:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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()) {
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user