forked from qt-creator/qt-creator
Add support for Boot2Qt
A plugin for communication with Boot2Qt devices. Task-number: QTCREATORBUG-21808 Change-Id: I61f4a9451c2fe8ff4e1108e07db2e72e8c613c43 Reviewed-by: Kari Oikarinen <kari.oikarinen@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
223
src/plugins/boot2qt/qdbdevicedebugsupport.cpp
Normal file
223
src/plugins/boot2qt/qdbdevicedebugsupport.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 "qdbdevicedebugsupport.h"
|
||||
|
||||
#include "qdbconstants.h"
|
||||
#include "qdbdevice.h"
|
||||
#include "qdbrunconfiguration.h"
|
||||
|
||||
#include <debugger/debuggerruncontrol.h>
|
||||
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/url.h>
|
||||
|
||||
using namespace Debugger;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
using namespace Qdb::Internal;
|
||||
|
||||
namespace Qdb {
|
||||
|
||||
class QdbDeviceInferiorRunner : public RunWorker
|
||||
{
|
||||
public:
|
||||
QdbDeviceInferiorRunner(RunControl *runControl,
|
||||
bool usePerf, bool useGdbServer, bool useQmlServer,
|
||||
QmlDebug::QmlDebugServicesPreset qmlServices)
|
||||
: RunWorker(runControl),
|
||||
m_usePerf(usePerf), m_useGdbServer(useGdbServer), m_useQmlServer(useQmlServer),
|
||||
m_qmlServices(qmlServices)
|
||||
{
|
||||
setId("QdbDebuggeeRunner");
|
||||
|
||||
connect(&m_launcher, &ApplicationLauncher::remoteProcessStarted,
|
||||
this, &RunWorker::reportStarted);
|
||||
connect(&m_launcher, &ApplicationLauncher::finished,
|
||||
this, &RunWorker::reportStopped);
|
||||
connect(&m_launcher, &ApplicationLauncher::appendMessage,
|
||||
this, &RunWorker::appendMessage);
|
||||
connect(&m_launcher, &ApplicationLauncher::remoteStdout,
|
||||
this, [this](const QString &out) { appendMessage(out, StdOutFormat); });
|
||||
connect(&m_launcher, &ApplicationLauncher::remoteStderr,
|
||||
this, [this](const QString &out) { appendMessage(out, StdErrFormat); });
|
||||
|
||||
m_portsGatherer = new GdbServerPortsGatherer(runControl);
|
||||
m_portsGatherer->setUseGdbServer(useGdbServer || usePerf);
|
||||
m_portsGatherer->setUseQmlServer(useQmlServer);
|
||||
addStartDependency(m_portsGatherer);
|
||||
}
|
||||
|
||||
Port perfPort() const { return m_portsGatherer->gdbServerPort(); }
|
||||
QUrl gdbServer() const { return m_portsGatherer->gdbServer(); }
|
||||
Port qmlServerPort() const { return m_portsGatherer->qmlServerPort(); }
|
||||
QUrl qmlServer() const { return m_portsGatherer->qmlServer(); }
|
||||
|
||||
void start() override
|
||||
{
|
||||
const int perfPort = m_portsGatherer->gdbServerPort().number();
|
||||
const int gdbServerPort = m_portsGatherer->gdbServerPort().number();
|
||||
const int qmlServerPort = m_portsGatherer->qmlServerPort().number();
|
||||
|
||||
int lowerPort = 0;
|
||||
int upperPort = 0;
|
||||
|
||||
Runnable r = runnable();
|
||||
|
||||
QString args;
|
||||
if (m_useGdbServer) {
|
||||
args.append(" --debug-gdb");
|
||||
lowerPort = upperPort = gdbServerPort;
|
||||
}
|
||||
if (m_useQmlServer) {
|
||||
args.append(" --debug-qml --qml-debug-services ");
|
||||
args.append(QmlDebug::qmlDebugServices(m_qmlServices));
|
||||
lowerPort = upperPort = qmlServerPort;
|
||||
}
|
||||
if (m_useGdbServer && m_useQmlServer) {
|
||||
if (gdbServerPort + 1 != qmlServerPort) {
|
||||
reportFailure("Need adjacent free ports for combined C++/QML debugging");
|
||||
return;
|
||||
}
|
||||
lowerPort = gdbServerPort;
|
||||
upperPort = qmlServerPort;
|
||||
}
|
||||
if (m_usePerf) {
|
||||
if (auto perfSettings = runControl()->settings("Analyzer.Perf.Settings")) {
|
||||
QStringList perfRecordArgs = perfSettings
|
||||
->property("perfRecordArguments").toStringList();
|
||||
args.append(QString::fromLatin1(" --profile-perf %1").arg(
|
||||
Utils::transform(perfRecordArgs, [](QString arg) {
|
||||
return arg.replace(',', ",,");
|
||||
}).join(',')));
|
||||
}
|
||||
lowerPort = upperPort = perfPort;
|
||||
}
|
||||
args.append(QString(" --port-range %1-%2 ").arg(lowerPort).arg(upperPort));
|
||||
args.append(r.executable);
|
||||
args.append(" ");
|
||||
args.append(r.commandLineArguments);
|
||||
|
||||
r.commandLineArguments = args;
|
||||
r.executable = Constants::AppcontrollerFilepath;
|
||||
|
||||
m_launcher.start(r, device());
|
||||
}
|
||||
|
||||
void stop() override { m_launcher.stop(); }
|
||||
|
||||
private:
|
||||
Debugger::GdbServerPortsGatherer *m_portsGatherer = nullptr;
|
||||
bool m_usePerf;
|
||||
bool m_useGdbServer;
|
||||
bool m_useQmlServer;
|
||||
QmlDebug::QmlDebugServicesPreset m_qmlServices;
|
||||
ApplicationLauncher m_launcher;
|
||||
};
|
||||
|
||||
|
||||
// QdbDeviceDebugSupport
|
||||
|
||||
QdbDeviceDebugSupport::QdbDeviceDebugSupport(RunControl *runControl)
|
||||
: Debugger::DebuggerRunTool(runControl)
|
||||
{
|
||||
setId("QdbDeviceDebugSupport");
|
||||
|
||||
m_debuggee = new QdbDeviceInferiorRunner(runControl, false, isCppDebugging(), isQmlDebugging(),
|
||||
QmlDebug::QmlDebuggerServices);
|
||||
addStartDependency(m_debuggee);
|
||||
|
||||
m_debuggee->addStopDependency(this);
|
||||
}
|
||||
|
||||
void QdbDeviceDebugSupport::start()
|
||||
{
|
||||
setStartMode(Debugger::AttachToRemoteServer);
|
||||
setCloseMode(KillAndExitMonitorAtClose);
|
||||
setRemoteChannel(m_debuggee->gdbServer());
|
||||
setQmlServer(m_debuggee->qmlServer());
|
||||
setUseContinueInsteadOfRun(true);
|
||||
setContinueAfterAttach(true);
|
||||
addSolibSearchDir("%{sysroot}/system/lib");
|
||||
|
||||
DebuggerRunTool::start();
|
||||
}
|
||||
|
||||
void QdbDeviceDebugSupport::stop()
|
||||
{
|
||||
// Do nothing unusual. The launcher will die as result of (gdb) kill.
|
||||
DebuggerRunTool::stop();
|
||||
}
|
||||
|
||||
|
||||
// QdbDeviceQmlProfilerSupport
|
||||
|
||||
QdbDeviceQmlToolingSupport::QdbDeviceQmlToolingSupport(RunControl *runControl,
|
||||
QmlDebug::QmlDebugServicesPreset services)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
setId("QdbDeviceQmlToolingSupport");
|
||||
|
||||
m_runner = new QdbDeviceInferiorRunner(runControl, false, false, true, services);
|
||||
addStartDependency(m_runner);
|
||||
addStopDependency(m_runner);
|
||||
|
||||
m_worker = runControl->createWorker(runControl->runMode());
|
||||
m_worker->addStartDependency(this);
|
||||
addStopDependency(m_worker);
|
||||
}
|
||||
|
||||
void QdbDeviceQmlToolingSupport::start()
|
||||
{
|
||||
m_worker->recordData("QmlServerUrl", m_runner->qmlServer());
|
||||
reportStarted();
|
||||
}
|
||||
|
||||
// QdbDevicePerfProfilerSupport
|
||||
|
||||
QdbDevicePerfProfilerSupport::QdbDevicePerfProfilerSupport(RunControl *runControl)
|
||||
: RunWorker(runControl)
|
||||
{
|
||||
setId("QdbDevicePerfProfilerSupport");
|
||||
|
||||
m_profilee = new QdbDeviceInferiorRunner(runControl, true, false, false,
|
||||
QmlDebug::NoQmlDebugServices);
|
||||
addStartDependency(m_profilee);
|
||||
addStopDependency(m_profilee);
|
||||
}
|
||||
|
||||
void QdbDevicePerfProfilerSupport::start()
|
||||
{
|
||||
QUrl url;
|
||||
url.setScheme(Utils::urlTcpScheme());
|
||||
url.setHost(device()->sshParameters().host());
|
||||
url.setPort(m_profilee->perfPort().number());
|
||||
runControl()->setProperty("PerfConnection", url);
|
||||
reportStarted();
|
||||
}
|
||||
|
||||
} // namespace Qdb
|
||||
Reference in New Issue
Block a user