Commit 3d11a27a authored by hjk's avatar hjk

Debugger: Consolidate "Attach to running process"

Change-Id: I78e89a662140f37f5f9719dbbbff070f1e2fbe84
Reviewed-by: Christian Stenger's avatarChristian Stenger <christian.stenger@qt.io>
parent 6a470f0a
...@@ -110,7 +110,6 @@ Project { ...@@ -110,7 +110,6 @@ Project {
files: [ files: [
"gdbengine.cpp", "gdbengine.h", "gdbengine.cpp", "gdbengine.h",
"gdboptionspage.cpp", "gdboptionspage.cpp",
"startgdbserverdialog.cpp", "startgdbserverdialog.h",
] ]
} }
......
...@@ -61,7 +61,6 @@ ...@@ -61,7 +61,6 @@
#include "snapshothandler.h" #include "snapshothandler.h"
#include "threadshandler.h" #include "threadshandler.h"
#include "commonoptionspage.h" #include "commonoptionspage.h"
#include "gdb/startgdbserverdialog.h"
#include "analyzer/analyzerconstants.h" #include "analyzer/analyzerconstants.h"
#include "analyzer/analyzermanager.h" #include "analyzer/analyzermanager.h"
...@@ -735,7 +734,6 @@ public: ...@@ -735,7 +734,6 @@ public:
void updateDebugWithoutDeployMenu(); void updateDebugWithoutDeployMenu();
void startRemoteCdbSession(); void startRemoteCdbSession();
void startRemoteServerAndAttachToProcess();
void attachToRunningApplication(); void attachToRunningApplication();
void attachToUnstartedApplicationDialog(); void attachToUnstartedApplicationDialog();
void attachToQmlPort(); void attachToQmlPort();
...@@ -981,7 +979,6 @@ public: ...@@ -981,7 +979,6 @@ public:
QAction *m_startAction = 0; QAction *m_startAction = 0;
QAction *m_debugWithoutDeployAction = 0; QAction *m_debugWithoutDeployAction = 0;
QAction *m_startAndDebugApplicationAction = 0; QAction *m_startAndDebugApplicationAction = 0;
QAction *m_startRemoteServerAction = 0;
QAction *m_attachToRunningApplication = 0; QAction *m_attachToRunningApplication = 0;
QAction *m_attachToUnstartedApplication = 0; QAction *m_attachToUnstartedApplication = 0;
QAction *m_attachToQmlPortAction = 0; QAction *m_attachToQmlPortAction = 0;
...@@ -1507,10 +1504,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, ...@@ -1507,10 +1504,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
act->setText(tr("Attach to Running Debug Server...")); act->setText(tr("Attach to Running Debug Server..."));
connect(act, &QAction::triggered, this, &StartApplicationDialog::attachToRemoteServer); connect(act, &QAction::triggered, this, &StartApplicationDialog::attachToRemoteServer);
act = m_startRemoteServerAction = new QAction(this);
act->setText(tr("Start Debug Server Attached to Process..."));
connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::startRemoteServerAndAttachToProcess);
act = m_attachToRunningApplication = new QAction(this); act = m_attachToRunningApplication = new QAction(this);
act->setText(tr("Attach to Running Application...")); act->setText(tr("Attach to Running Application..."));
connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRunningApplication); connect(act, &QAction::triggered, this, &DebuggerPluginPrivate::attachToRunningApplication);
...@@ -1584,11 +1577,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, ...@@ -1584,11 +1577,6 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
cmd->setAttribute(Command::CA_Hide); cmd->setAttribute(Command::CA_Hide);
mstart->addAction(cmd, Constants::G_SPECIAL); mstart->addAction(cmd, Constants::G_SPECIAL);
cmd = ActionManager::registerAction(m_startRemoteServerAction,
"Debugger.StartRemoteServer");
cmd->setDescription(tr("Start Gdbserver"));
mstart->addAction(cmd, Constants::G_SPECIAL);
if (m_startRemoteCdbAction) { if (m_startRemoteCdbAction) {
cmd = ActionManager::registerAction(m_startRemoteCdbAction, cmd = ActionManager::registerAction(m_startRemoteCdbAction,
"Debugger.AttachRemoteCdb"); "Debugger.AttachRemoteCdb");
...@@ -1992,30 +1980,48 @@ void DebuggerPluginPrivate::startRemoteCdbSession() ...@@ -1992,30 +1980,48 @@ void DebuggerPluginPrivate::startRemoteCdbSession()
debugger->startRunControl(); debugger->startRunControl();
} }
void DebuggerPluginPrivate::startRemoteServerAndAttachToProcess() class RemoteAttachRunner : public DebuggerRunTool
{ {
auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging); public:
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent()); RemoteAttachRunner(RunControl *runControl, Kit *kit, int pid)
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process")); : DebuggerRunTool(runControl, kit)
dlg->showAllDevices(); {
if (dlg->exec() == QDialog::Rejected) { IDevice::ConstPtr device = DeviceKitInformation::device(kit);
delete dlg; setDisplayName("AttachToRunningProcess");
return;
portsGatherer = new GdbServerPortsGatherer(runControl);
portsGatherer->setUseGdbServer(true);
portsGatherer->setUseQmlServer(false);
portsGatherer->setDevice(device);
auto gdbServer = new GdbServerRunner(runControl, portsGatherer);
gdbServer->setUseMulti(false);
gdbServer->addStartDependency(portsGatherer);
gdbServer->setDevice(device);
gdbServer->setAttachPid(ProcessHandle(pid));
addStartDependency(gdbServer);
setStartMode(AttachToRemoteProcess);
setCloseMode(DetachAtClose);
// setInferiorExecutable(localExecutable);
setUseContinueInsteadOfRun(true);
setContinueAfterAttach(false);
} }
dlg->setAttribute(Qt::WA_DeleteOnClose); void start() final
Kit *kit = kitChooser->currentKit(); {
QTC_ASSERT(kit, return); setRemoteChannel(portsGatherer->gdbServerChannel());
IDevice::ConstPtr device = DeviceKitInformation::device(kit); DebuggerRunTool::start();
QTC_ASSERT(device, return); }
GdbServerStarter *starter = new GdbServerStarter(dlg, true); GdbServerPortsGatherer *portsGatherer;
starter->run(); };
}
void DebuggerPluginPrivate::attachToRunningApplication() void DebuggerPluginPrivate::attachToRunningApplication()
{ {
auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::LocalDebugging); auto kitChooser = new DebuggerKitChooser(DebuggerKitChooser::AnyDebugging);
auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent()); auto dlg = new DeviceProcessesDialog(kitChooser, ICore::dialogParent());
dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process")); dlg->addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
...@@ -2031,11 +2037,14 @@ void DebuggerPluginPrivate::attachToRunningApplication() ...@@ -2031,11 +2037,14 @@ void DebuggerPluginPrivate::attachToRunningApplication()
IDevice::ConstPtr device = DeviceKitInformation::device(kit); IDevice::ConstPtr device = DeviceKitInformation::device(kit);
QTC_ASSERT(device, return); QTC_ASSERT(device, return);
DeviceProcessItem process = dlg->currentProcess();
if (device->type() == PE::DESKTOP_DEVICE_TYPE) { if (device->type() == PE::DESKTOP_DEVICE_TYPE) {
attachToRunningProcess(kit, dlg->currentProcess(), false); attachToRunningProcess(kit, process, false);
} else { } else {
GdbServerStarter *starter = new GdbServerStarter(dlg, true); auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE);
starter->run(); auto debugger = new RemoteAttachRunner(runControl, kit, process.pid);
debugger->startRunControl();
} }
} }
......
...@@ -936,6 +936,8 @@ GdbServerPortsGatherer::GdbServerPortsGatherer(RunControl *runControl) ...@@ -936,6 +936,8 @@ GdbServerPortsGatherer::GdbServerPortsGatherer(RunControl *runControl)
this, &RunWorker::reportFailure); this, &RunWorker::reportFailure);
connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady, connect(&m_portsGatherer, &DeviceUsedPortsGatherer::portListReady,
this, &GdbServerPortsGatherer::handlePortListReady); this, &GdbServerPortsGatherer::handlePortListReady);
m_device = runControl->device();
} }
GdbServerPortsGatherer::~GdbServerPortsGatherer() GdbServerPortsGatherer::~GdbServerPortsGatherer()
...@@ -944,26 +946,31 @@ GdbServerPortsGatherer::~GdbServerPortsGatherer() ...@@ -944,26 +946,31 @@ GdbServerPortsGatherer::~GdbServerPortsGatherer()
QString GdbServerPortsGatherer::gdbServerChannel() const QString GdbServerPortsGatherer::gdbServerChannel() const
{ {
const QString host = device()->sshParameters().host; const QString host = m_device->sshParameters().host;
return QString("%1:%2").arg(host).arg(m_gdbServerPort.number()); return QString("%1:%2").arg(host).arg(m_gdbServerPort.number());
} }
QUrl GdbServerPortsGatherer::qmlServer() const QUrl GdbServerPortsGatherer::qmlServer() const
{ {
QUrl server = device()->toolControlChannel(IDevice::QmlControlChannel); QUrl server = m_device->toolControlChannel(IDevice::QmlControlChannel);
server.setPort(m_qmlServerPort.number()); server.setPort(m_qmlServerPort.number());
return server; return server;
} }
void GdbServerPortsGatherer::setDevice(IDevice::ConstPtr device)
{
m_device = device;
}
void GdbServerPortsGatherer::start() void GdbServerPortsGatherer::start()
{ {
appendMessage(tr("Checking available ports..."), NormalMessageFormat); appendMessage(tr("Checking available ports..."), NormalMessageFormat);
m_portsGatherer.start(device()); m_portsGatherer.start(m_device);
} }
void GdbServerPortsGatherer::handlePortListReady() void GdbServerPortsGatherer::handlePortListReady()
{ {
Utils::PortList portList = device()->freePorts(); Utils::PortList portList = m_device->freePorts();
appendMessage(tr("Found %n free ports.", nullptr, portList.count()), NormalMessageFormat); appendMessage(tr("Found %n free ports.", nullptr, portList.count()), NormalMessageFormat);
if (m_useGdbServer) { if (m_useGdbServer) {
m_gdbServerPort = m_portsGatherer.getNextFreePort(&portList); m_gdbServerPort = m_portsGatherer.getNextFreePort(&portList);
...@@ -989,19 +996,38 @@ GdbServerRunner::GdbServerRunner(RunControl *runControl, GdbServerPortsGatherer ...@@ -989,19 +996,38 @@ GdbServerRunner::GdbServerRunner(RunControl *runControl, GdbServerPortsGatherer
: SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer) : SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
{ {
setDisplayName("GdbServerRunner"); setDisplayName("GdbServerRunner");
if (runControl->runnable().is<StandardRunnable>())
m_runnable = runControl->runnable().as<StandardRunnable>();
} }
GdbServerRunner::~GdbServerRunner() GdbServerRunner::~GdbServerRunner()
{ {
} }
void GdbServerRunner::setRunnable(const StandardRunnable &runnable)
{
m_runnable = runnable;
}
void GdbServerRunner::setUseMulti(bool on)
{
m_useMulti = on;
}
void GdbServerRunner::setAttachPid(ProcessHandle pid)
{
m_pid = pid;
}
void GdbServerRunner::start() void GdbServerRunner::start()
{ {
QTC_ASSERT(m_portsGatherer, reportFailure(); return); QTC_ASSERT(m_portsGatherer, reportFailure(); return);
StandardRunnable r = runnable().as<StandardRunnable>(); StandardRunnable gdbserver;
QStringList args = QtcProcess::splitArgs(r.commandLineArguments, OsTypeLinux); gdbserver.environment = m_runnable.environment;
QString command; gdbserver.workingDirectory = m_runnable.workingDirectory;
QStringList args = QtcProcess::splitArgs(m_runnable.commandLineArguments, OsTypeLinux);
const bool isQmlDebugging = m_portsGatherer->useQmlServer(); const bool isQmlDebugging = m_portsGatherer->useQmlServer();
const bool isCppDebugging = m_portsGatherer->useGdbServer(); const bool isCppDebugging = m_portsGatherer->useGdbServer();
...@@ -1010,21 +1036,24 @@ void GdbServerRunner::start() ...@@ -1010,21 +1036,24 @@ void GdbServerRunner::start()
args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices, args.prepend(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
m_portsGatherer->qmlServerPort())); m_portsGatherer->qmlServerPort()));
} }
if (isQmlDebugging && !isCppDebugging) { if (isQmlDebugging && !isCppDebugging) {
command = r.executable; gdbserver.executable = m_runnable.executable; // FIXME: Case should not happen?
} else { } else {
command = device()->debugServerPath(); gdbserver.executable = device()->debugServerPath();
if (command.isEmpty()) if (gdbserver.executable.isEmpty())
command = "gdbserver"; gdbserver.executable = "gdbserver";
args.clear(); args.clear();
args.append(QString("--multi")); if (m_useMulti)
args.append("--multi");
if (m_pid.isValid())
args.append("--attach");
args.append(QString(":%1").arg(m_portsGatherer->gdbServerPort().number())); args.append(QString(":%1").arg(m_portsGatherer->gdbServerPort().number()));
if (m_pid.isValid())
args.append(QString::number(m_pid.pid()));
} }
r.executable = command; gdbserver.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
r.commandLineArguments = QtcProcess::joinArgs(args, OsTypeLinux);
setRunnable(r); SimpleTargetRunner::setRunnable(gdbserver);
appendMessage(tr("Starting gdbserver..."), NormalMessageFormat); appendMessage(tr("Starting gdbserver..."), NormalMessageFormat);
......
...@@ -161,6 +161,8 @@ public: ...@@ -161,6 +161,8 @@ public:
Utils::Port qmlServerPort() const { return m_qmlServerPort; } Utils::Port qmlServerPort() const { return m_qmlServerPort; }
QUrl qmlServer() const; QUrl qmlServer() const;
void setDevice(ProjectExplorer::IDevice::ConstPtr device);
private: private:
void start() override; void start() override;
void handlePortListReady(); void handlePortListReady();
...@@ -170,6 +172,7 @@ private: ...@@ -170,6 +172,7 @@ private:
bool m_useQmlServer = false; bool m_useQmlServer = false;
Utils::Port m_gdbServerPort; Utils::Port m_gdbServerPort;
Utils::Port m_qmlServerPort; Utils::Port m_qmlServerPort;
ProjectExplorer::IDevice::ConstPtr m_device;
}; };
class DEBUGGER_EXPORT GdbServerRunner : public ProjectExplorer::SimpleTargetRunner class DEBUGGER_EXPORT GdbServerRunner : public ProjectExplorer::SimpleTargetRunner
...@@ -179,12 +182,20 @@ class DEBUGGER_EXPORT GdbServerRunner : public ProjectExplorer::SimpleTargetRunn ...@@ -179,12 +182,20 @@ class DEBUGGER_EXPORT GdbServerRunner : public ProjectExplorer::SimpleTargetRunn
public: public:
explicit GdbServerRunner(ProjectExplorer::RunControl *runControl, explicit GdbServerRunner(ProjectExplorer::RunControl *runControl,
GdbServerPortsGatherer *portsGatherer); GdbServerPortsGatherer *portsGatherer);
~GdbServerRunner(); ~GdbServerRunner();
void setRunnable(const ProjectExplorer::StandardRunnable &runnable);
void setUseMulti(bool on);
void setAttachPid(Utils::ProcessHandle pid);
private: private:
void start() override; void start() override;
GdbServerPortsGatherer *m_portsGatherer; GdbServerPortsGatherer *m_portsGatherer;
ProjectExplorer::StandardRunnable m_runnable;
Utils::ProcessHandle m_pid;
bool m_useMulti = true;
}; };
extern DEBUGGER_EXPORT const char GdbServerRunnerWorkerId[]; extern DEBUGGER_EXPORT const char GdbServerRunnerWorkerId[];
......
HEADERS += \ HEADERS += \
$$PWD/gdbengine.h \ $$PWD/gdbengine.h
$$PWD/startgdbserverdialog.h
SOURCES += \ SOURCES += \
$$PWD/gdbengine.cpp \ $$PWD/gdbengine.cpp \
$$PWD/gdboptionspage.cpp \ $$PWD/gdboptionspage.cpp
$$PWD/startgdbserverdialog.cpp
...@@ -1330,11 +1330,12 @@ void GdbEngine::handleStopResponse(const GdbMi &data) ...@@ -1330,11 +1330,12 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
notifyInferiorStopOk(); notifyInferiorStopOk();
} else if (state() == EngineRunRequested) { } else if (state() == EngineRunRequested) {
// This is gdb 7+'s initial *stopped in response to attach that // This is gdb 7+'s initial *stopped in response to attach that
// appears before the ^done is seen. // appears before the ^done is seen for local setups.
notifyEngineRunAndInferiorStopOk(); notifyEngineRunAndInferiorStopOk();
if (terminal()) if (terminal()) {
continueInferiorInternal(); continueInferiorInternal();
return; return;
}
} else { } else {
QTC_CHECK(false); QTC_CHECK(false);
} }
...@@ -4267,7 +4268,11 @@ void GdbEngine::setupInferior() ...@@ -4267,7 +4268,11 @@ void GdbEngine::setupInferior()
const DebuggerRunParameters &rp = runParameters(); const DebuggerRunParameters &rp = runParameters();
if (isAttachEngine()) { if (rp.startMode == AttachToRemoteProcess) {
notifyInferiorSetupOk();
} else if (isAttachEngine()) {
// Task 254674 does not want to remove them // Task 254674 does not want to remove them
//qq->breakHandler()->removeAllBreakpoints(); //qq->breakHandler()->removeAllBreakpoints();
handleInferiorPrepared(); handleInferiorPrepared();
...@@ -4377,7 +4382,6 @@ void GdbEngine::setupInferior() ...@@ -4377,7 +4382,6 @@ void GdbEngine::setupInferior()
} else if (isPlainEngine()) { } else if (isPlainEngine()) {
setEnvironmentVariables(); setEnvironmentVariables();
const DebuggerRunParameters &rp = runParameters();
if (!rp.inferior.workingDirectory.isEmpty()) if (!rp.inferior.workingDirectory.isEmpty())
runCommand({"cd " + rp.inferior.workingDirectory}); runCommand({"cd " + rp.inferior.workingDirectory});
if (!rp.inferior.commandLineArguments.isEmpty()) { if (!rp.inferior.commandLineArguments.isEmpty()) {
...@@ -4395,9 +4399,18 @@ void GdbEngine::runEngine() ...@@ -4395,9 +4399,18 @@ void GdbEngine::runEngine()
{ {
CHECK_STATE(EngineRunRequested); CHECK_STATE(EngineRunRequested);
if (isAttachEngine()) { const DebuggerRunParameters &rp = runParameters();
if (rp.startMode == AttachToRemoteProcess) {
notifyEngineRunAndInferiorStopOk();
const qint64 pid = runParameters().attachPID.pid(); QString channel = rp.remoteChannel;
runCommand({"target remote " + channel});
} else if (isAttachEngine()) {
const qint64 pid = rp.attachPID.pid();
showStatusMessage(tr("Attaching to process %1.").arg(pid)); showStatusMessage(tr("Attaching to process %1.").arg(pid));
runCommand({"attach " + QString::number(pid), runCommand({"attach " + QString::number(pid),
[this](const DebuggerResponse &r) { handleAttach(r); }}); [this](const DebuggerResponse &r) { handleAttach(r); }});
...@@ -4460,6 +4473,7 @@ void GdbEngine::handleAttach(const DebuggerResponse &response) ...@@ -4460,6 +4473,7 @@ void GdbEngine::handleAttach(const DebuggerResponse &response)
// InferiorStopOk, e.g. for "Attach to running application". // InferiorStopOk, e.g. for "Attach to running application".
// The *stopped came in between sending the 'attach' and // The *stopped came in between sending the 'attach' and
// receiving its '^done'. // receiving its '^done'.
notifyEngineRunAndInferiorStopOk();
if (runParameters().continueAfterAttach) if (runParameters().continueAfterAttach)
continueInferiorInternal(); continueInferiorInternal();
} }
...@@ -4663,6 +4677,7 @@ void GdbEngine::handleSetTargetAsync(const DebuggerResponse &response) ...@@ -4663,6 +4677,7 @@ void GdbEngine::handleSetTargetAsync(const DebuggerResponse &response)
void GdbEngine::callTargetRemote() void GdbEngine::callTargetRemote()
{ {
CHECK_STATE(InferiorSetupRequested);
QString channel = runParameters().remoteChannel; QString channel = runParameters().remoteChannel;
// Don't touch channels with explicitly set protocols. // Don't touch channels with explicitly set protocols.
......
/****************************************************************************
**
** 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 "startgdbserverdialog.h"
#include <debugger/debuggerengine.h>
#include <debugger/debuggermainwindow.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerruncontrol.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagebox.h>
#include <projectexplorer/kitchooser.h>
#include <projectexplorer/devicesupport/deviceprocesslist.h>
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
#include <ssh/sshremoteprocessrunner.h>
#include <utils/portlist.h>
#include <utils/qtcassert.h>
#include <QFileInfo>
using namespace Core;
using namespace ProjectExplorer;
using namespace QSsh;
using namespace Utils;
namespace Debugger {
namespace Internal {
class StartGdbServerDialogPrivate
{
public:
StartGdbServerDialogPrivate() : dialog(0), kit(0) {}
DeviceProcessesDialog *dialog;
bool attachToServer;
DeviceProcessItem process;
Kit *kit;
IDevice::ConstPtr device;
DeviceUsedPortsGatherer gatherer;
SshRemoteProcessRunner runner;
};
GdbServerStarter::GdbServerStarter(DeviceProcessesDialog *dlg, bool attachAfterServerStart)
: QObject(dlg)
{
d = new StartGdbServerDialogPrivate;
d->dialog = dlg;
d->kit = dlg->kitChooser()->currentKit();
d->process = dlg->currentProcess();
d->device = DeviceKitInformation::device(d->kit);
d->attachToServer = attachAfterServerStart;
}
GdbServerStarter::~GdbServerStarter()
{
delete d;
}
void GdbServerStarter::handleRemoteError(const QString &errorMsg)
{
AsynchronousMessageBox::critical(tr("Remote Error"), errorMsg);
}
void GdbServerStarter::portGathererError(const QString &text)
{
logMessage(tr("Could not retrieve list of free ports:"));
logMessage(text);
logMessage(tr("Process aborted"));
}
void GdbServerStarter::run()
{
QTC_ASSERT(d->device, return);
connect(&d->gatherer, &DeviceUsedPortsGatherer::error,
this, &GdbServerStarter::portGathererError);
connect(&d->gatherer, &DeviceUsedPortsGatherer::portListReady,
this, &GdbServerStarter::portListReady);
d->gatherer.start(d->device);
}
void GdbServerStarter::portListReady()
{
PortList ports = d->device->freePorts();
const Port port = d->gatherer.getNextFreePort(&ports);
if (!port.isValid()) {
QTC_ASSERT(false, /**/);
emit logMessage(tr("Process aborted"));
return;
}
connect(&d->runner, &SshRemoteProcessRunner::connectionError,
this, &GdbServerStarter::handleConnectionError);
connect(&d->runner, &SshRemoteProcessRunner::processStarted,
this, &GdbServerStarter::handleProcessStarted);
connect(&d->runner, &SshRemoteProcessRunner::readyReadStandardOutput,
this, &GdbServerStarter::handleProcessOutputAvailable);
connect(&d->runner, &SshRemoteProcessRunner::readyReadStandardError,
this, &GdbServerStarter::handleProcessErrorOutput);
connect(&d->runner, &SshRemoteProcessRunner::processClosed,
this, &GdbServerStarter::handleProcessClosed);
QByteArray gdbServerPath = d->device->debugServerPath().toUtf8();
if (gdbServerPath.isEmpty())
gdbServerPath = "gdbserver";
QByteArray cmd = gdbServerPath + " --attach :"
+ QByteArray::number(port.number()) + ' ' + QByteArray::number(d->process.pid);
logMessage(tr("Running command: %1").arg(QString::fromLatin1(cmd)));
d->runner.run(cmd, d->device->sshParameters());
}
void GdbServerStarter::handleConnectionError()
{
logMessage(tr("Connection error: %1").arg(d->runner.lastConnectionErrorString()));
}
void GdbServerStarter::handleProcessStarted()
{
logMessage(tr("Starting gdbserver..."));
}
void GdbServerStarter::handleProcessOutputAvailable()
{