forked from qt-creator/qt-creator
Qnx: Merge debug support related files
The attach part has not been active for a while, but there's code now easier to reuse. So move participants of a potential solution to a suitable place before attempting to fix functionality. Change-Id: I9a7d4a6637e8ef214c22ee5683103e464109210d Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -23,8 +23,6 @@ SOURCES += qnxplugin.cpp \
|
|||||||
qnxdeviceprocesslist.cpp \
|
qnxdeviceprocesslist.cpp \
|
||||||
qnxtoolchain.cpp \
|
qnxtoolchain.cpp \
|
||||||
slog2inforunner.cpp \
|
slog2inforunner.cpp \
|
||||||
qnxattachdebugsupport.cpp \
|
|
||||||
qnxattachdebugdialog.cpp \
|
|
||||||
qnxconfiguration.cpp \
|
qnxconfiguration.cpp \
|
||||||
qnxsettingswidget.cpp \
|
qnxsettingswidget.cpp \
|
||||||
qnxconfigurationmanager.cpp \
|
qnxconfigurationmanager.cpp \
|
||||||
@@ -55,8 +53,6 @@ HEADERS += qnxplugin.h\
|
|||||||
qnxdeviceprocesslist.h \
|
qnxdeviceprocesslist.h \
|
||||||
qnxtoolchain.h \
|
qnxtoolchain.h \
|
||||||
slog2inforunner.h \
|
slog2inforunner.h \
|
||||||
qnxattachdebugsupport.h \
|
|
||||||
qnxattachdebugdialog.h \
|
|
||||||
qnxconfiguration.h \
|
qnxconfiguration.h \
|
||||||
qnxsettingswidget.h \
|
qnxsettingswidget.h \
|
||||||
qnxconfigurationmanager.h \
|
qnxconfigurationmanager.h \
|
||||||
|
@@ -24,10 +24,6 @@ QtcPlugin {
|
|||||||
"qnxtoolchain.cpp",
|
"qnxtoolchain.cpp",
|
||||||
"qnxtoolchain.h",
|
"qnxtoolchain.h",
|
||||||
"qnx.qrc",
|
"qnx.qrc",
|
||||||
"qnxattachdebugsupport.cpp",
|
|
||||||
"qnxattachdebugsupport.h",
|
|
||||||
"qnxattachdebugdialog.cpp",
|
|
||||||
"qnxattachdebugdialog.h",
|
|
||||||
"qnxbaseqtconfigwidget.cpp",
|
"qnxbaseqtconfigwidget.cpp",
|
||||||
"qnxbaseqtconfigwidget.h",
|
"qnxbaseqtconfigwidget.h",
|
||||||
"qnxconstants.h",
|
"qnxconstants.h",
|
||||||
|
@@ -1,66 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
|
|
||||||
** Contact: 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 "qnxattachdebugdialog.h"
|
|
||||||
|
|
||||||
#include <utils/pathchooser.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
#include <QFormLayout>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
using namespace Qnx;
|
|
||||||
using namespace Qnx::Internal;
|
|
||||||
|
|
||||||
QnxAttachDebugDialog::QnxAttachDebugDialog(ProjectExplorer::KitChooser *kitChooser, QWidget *parent)
|
|
||||||
: ProjectExplorer::DeviceProcessesDialog(kitChooser, parent)
|
|
||||||
{
|
|
||||||
auto sourceLabel = new QLabel(tr("Project source directory:"), this);
|
|
||||||
m_projectSource = new Utils::PathChooser(this);
|
|
||||||
m_projectSource->setExpectedKind(Utils::PathChooser::ExistingDirectory);
|
|
||||||
|
|
||||||
auto binaryLabel = new QLabel(tr("Local executable:"), this);
|
|
||||||
m_localExecutable = new Utils::PathChooser(this);
|
|
||||||
m_localExecutable->setExpectedKind(Utils::PathChooser::File);
|
|
||||||
|
|
||||||
auto formLayout = new QFormLayout;
|
|
||||||
formLayout->addRow(sourceLabel, m_projectSource);
|
|
||||||
formLayout->addRow(binaryLabel, m_localExecutable);
|
|
||||||
|
|
||||||
auto mainLayout = dynamic_cast<QVBoxLayout*>(layout());
|
|
||||||
QTC_ASSERT(mainLayout, return);
|
|
||||||
mainLayout->insertLayout(mainLayout->count() - 2, formLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QnxAttachDebugDialog::projectSource() const
|
|
||||||
{
|
|
||||||
return m_projectSource->path();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QnxAttachDebugDialog::localExecutable() const
|
|
||||||
{
|
|
||||||
return m_localExecutable->path();
|
|
||||||
}
|
|
@@ -1,51 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
|
|
||||||
** Contact: 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/devicesupport/deviceprocessesdialog.h>
|
|
||||||
|
|
||||||
namespace Utils { class PathChooser; }
|
|
||||||
|
|
||||||
namespace Qnx {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class QnxAttachDebugDialog : public ProjectExplorer::DeviceProcessesDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QnxAttachDebugDialog(ProjectExplorer::KitChooser *kitChooser, QWidget *parent = 0);
|
|
||||||
|
|
||||||
QString projectSource() const;
|
|
||||||
QString localExecutable() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Utils::PathChooser *m_projectSource;
|
|
||||||
Utils::PathChooser *m_localExecutable;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Qnx
|
|
@@ -1,172 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
|
|
||||||
** Contact: 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 "qnxattachdebugsupport.h"
|
|
||||||
|
|
||||||
#include "qnxattachdebugdialog.h"
|
|
||||||
#include "qnxconstants.h"
|
|
||||||
#include "qnxqtversion.h"
|
|
||||||
#include "qnxutils.h"
|
|
||||||
|
|
||||||
#include <debugger/debuggerkitinformation.h>
|
|
||||||
#include <debugger/debuggerruncontrol.h>
|
|
||||||
#include <debugger/debuggerstartparameters.h>
|
|
||||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
|
||||||
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
|
|
||||||
#include <projectexplorer/devicesupport/deviceprocesslist.h>
|
|
||||||
#include <projectexplorer/kit.h>
|
|
||||||
#include <projectexplorer/kitchooser.h>
|
|
||||||
#include <projectexplorer/kitinformation.h>
|
|
||||||
#include <projectexplorer/projectexplorer.h>
|
|
||||||
#include <projectexplorer/runnables.h>
|
|
||||||
#include <projectexplorer/toolchain.h>
|
|
||||||
#include <qtsupport/qtkitinformation.h>
|
|
||||||
#include <utils/portlist.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
|
||||||
|
|
||||||
namespace Qnx {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
QnxAttachDebugSupport::QnxAttachDebugSupport(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
m_launcher = new ApplicationLauncher(this);
|
|
||||||
m_portsGatherer = new DeviceUsedPortsGatherer(this);
|
|
||||||
|
|
||||||
connect(m_portsGatherer, &DeviceUsedPortsGatherer::portListReady,
|
|
||||||
this, &QnxAttachDebugSupport::launchPDebug);
|
|
||||||
connect(m_portsGatherer, &DeviceUsedPortsGatherer::error,
|
|
||||||
this, &QnxAttachDebugSupport::handleError);
|
|
||||||
connect(m_launcher, &ApplicationLauncher::remoteProcessStarted,
|
|
||||||
this, &QnxAttachDebugSupport::attachToProcess);
|
|
||||||
connect(m_launcher, &ApplicationLauncher::reportError,
|
|
||||||
this, &QnxAttachDebugSupport::handleError);
|
|
||||||
connect(m_launcher, &ApplicationLauncher::reportProgress,
|
|
||||||
this, &QnxAttachDebugSupport::handleProgressReport);
|
|
||||||
connect(m_launcher, &ApplicationLauncher::remoteStdout,
|
|
||||||
this, &QnxAttachDebugSupport::handleRemoteOutput);
|
|
||||||
connect(m_launcher, &ApplicationLauncher::remoteStderr,
|
|
||||||
this, &QnxAttachDebugSupport::handleRemoteOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::showProcessesDialog()
|
|
||||||
{
|
|
||||||
auto kitChooser = new KitChooser;
|
|
||||||
kitChooser->setKitPredicate([](const Kit *k){
|
|
||||||
return k->isValid() && DeviceTypeKitInformation::deviceTypeId(k) == Core::Id(Constants::QNX_QNX_OS_TYPE);
|
|
||||||
});
|
|
||||||
|
|
||||||
QnxAttachDebugDialog dlg(kitChooser, 0);
|
|
||||||
dlg.addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
|
|
||||||
dlg.showAllDevices();
|
|
||||||
if (dlg.exec() == QDialog::Rejected)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_kit = kitChooser->currentKit();
|
|
||||||
if (!m_kit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_device = DeviceKitInformation::device(m_kit);
|
|
||||||
QTC_ASSERT(m_device, return);
|
|
||||||
m_process = dlg.currentProcess();
|
|
||||||
|
|
||||||
m_projectSourceDirectory = dlg.projectSource();
|
|
||||||
m_localExecutablePath = dlg.localExecutable();
|
|
||||||
|
|
||||||
m_portsGatherer->start(m_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::launchPDebug()
|
|
||||||
{
|
|
||||||
Utils::PortList portList = m_device->freePorts();
|
|
||||||
m_pdebugPort = m_portsGatherer->getNextFreePort(&portList);
|
|
||||||
if (!m_pdebugPort.isValid()) {
|
|
||||||
handleError(tr("No free ports for debugging."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardRunnable r;
|
|
||||||
r.executable = QLatin1String("pdebug");
|
|
||||||
r.commandLineArguments = QString::number(m_pdebugPort.number());
|
|
||||||
m_launcher->start(r, m_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::attachToProcess()
|
|
||||||
{
|
|
||||||
Debugger::DebuggerStartParameters sp;
|
|
||||||
sp.attachPID = Utils::ProcessHandle(m_process.pid);
|
|
||||||
sp.startMode = Debugger::AttachToRemoteServer;
|
|
||||||
sp.closeMode = Debugger::DetachAtClose;
|
|
||||||
sp.remoteChannel = QString("%1:%2").arg(m_device->sshParameters().host).arg(m_pdebugPort.number());
|
|
||||||
sp.displayName = tr("Remote: \"%1\" - Process %2").arg(sp.remoteChannel).arg(m_process.pid);
|
|
||||||
sp.inferior.executable = m_localExecutablePath;
|
|
||||||
sp.useCtrlCStub = true;
|
|
||||||
|
|
||||||
QnxQtVersion *qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(m_kit));
|
|
||||||
if (qtVersion)
|
|
||||||
sp.solibSearchPath = QnxUtils::searchPaths(qtVersion);
|
|
||||||
|
|
||||||
auto runControl = new RunControl(nullptr, ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
|
||||||
auto debugger = new Debugger::DebuggerRunTool(runControl);
|
|
||||||
debugger->setRunParameters(sp);
|
|
||||||
// connect(qobject_cast<Debugger::DebuggerRunTool *>(runControl->toolRunner()),
|
|
||||||
// &Debugger::DebuggerRunTool::stateChanged,
|
|
||||||
// this, &QnxAttachDebugSupport::handleDebuggerStateChanged);
|
|
||||||
debugger->startRunControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::handleDebuggerStateChanged(Debugger::DebuggerState state)
|
|
||||||
{
|
|
||||||
if (state == Debugger::DebuggerFinished)
|
|
||||||
stopPDebug();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::handleError(const QString &message)
|
|
||||||
{
|
|
||||||
if (m_runTool)
|
|
||||||
m_runTool->showMessage(message, Debugger::AppError);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::handleProgressReport(const QString &message)
|
|
||||||
{
|
|
||||||
if (m_runTool)
|
|
||||||
m_runTool->showMessage(message + QLatin1Char('\n'), Debugger::AppStuff);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::handleRemoteOutput(const QString &output)
|
|
||||||
{
|
|
||||||
if (m_runTool)
|
|
||||||
m_runTool->showMessage(output, Debugger::AppOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QnxAttachDebugSupport::stopPDebug()
|
|
||||||
{
|
|
||||||
m_launcher->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Qnx
|
|
@@ -1,81 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
|
|
||||||
** Contact: 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 <debugger/debuggerconstants.h>
|
|
||||||
#include <projectexplorer/devicesupport/deviceprocesslist.h>
|
|
||||||
#include <projectexplorer/devicesupport/idevice.h>
|
|
||||||
#include <utils/port.h>
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
namespace Debugger { class DebuggerRunTool; }
|
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
|
||||||
class ApplicationLauncher;
|
|
||||||
class DeviceUsedPortsGatherer;
|
|
||||||
class Kit;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Qnx {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class QnxAttachDebugSupport : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit QnxAttachDebugSupport(QObject *parent = 0);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void showProcessesDialog();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void launchPDebug();
|
|
||||||
void attachToProcess();
|
|
||||||
|
|
||||||
void handleDebuggerStateChanged(Debugger::DebuggerState state);
|
|
||||||
void handleError(const QString &message);
|
|
||||||
void handleProgressReport(const QString &message);
|
|
||||||
void handleRemoteOutput(const QString &output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void stopPDebug();
|
|
||||||
|
|
||||||
ProjectExplorer::Kit *m_kit = 0;
|
|
||||||
ProjectExplorer::IDevice::ConstPtr m_device;
|
|
||||||
ProjectExplorer::DeviceProcessItem m_process;
|
|
||||||
|
|
||||||
ProjectExplorer::ApplicationLauncher *m_launcher;
|
|
||||||
ProjectExplorer::DeviceUsedPortsGatherer *m_portsGatherer;
|
|
||||||
Debugger::DebuggerRunTool *m_runTool = 0;
|
|
||||||
|
|
||||||
Utils::Port m_pdebugPort;
|
|
||||||
QString m_projectSourceDirectory;
|
|
||||||
QString m_localExecutablePath;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Qnx
|
|
@@ -24,6 +24,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qnxdebugsupport.h"
|
#include "qnxdebugsupport.h"
|
||||||
|
|
||||||
#include "qnxconstants.h"
|
#include "qnxconstants.h"
|
||||||
#include "qnxdevice.h"
|
#include "qnxdevice.h"
|
||||||
#include "qnxrunconfiguration.h"
|
#include "qnxrunconfiguration.h"
|
||||||
@@ -31,26 +32,64 @@
|
|||||||
#include "qnxqtversion.h"
|
#include "qnxqtversion.h"
|
||||||
#include "qnxutils.h"
|
#include "qnxutils.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <debugger/debuggerkitinformation.h>
|
||||||
#include <debugger/debuggerruncontrol.h>
|
#include <debugger/debuggerruncontrol.h>
|
||||||
|
|
||||||
#include <projectexplorer/applicationlauncher.h>
|
#include <projectexplorer/applicationlauncher.h>
|
||||||
|
#include <projectexplorer/devicesupport/deviceprocessesdialog.h>
|
||||||
|
#include <projectexplorer/devicesupport/deviceprocesslist.h>
|
||||||
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
#include <projectexplorer/devicesupport/deviceusedportsgatherer.h>
|
||||||
|
#include <projectexplorer/kit.h>
|
||||||
|
#include <projectexplorer/kitchooser.h>
|
||||||
#include <projectexplorer/kitinformation.h>
|
#include <projectexplorer/kitinformation.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/runnables.h>
|
#include <projectexplorer/runnables.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
#include <projectexplorer/toolchain.h>
|
||||||
|
|
||||||
#include <qmldebug/qmldebugcommandlinearguments.h>
|
#include <qmldebug/qmldebugcommandlinearguments.h>
|
||||||
|
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
|
#include <utils/pathchooser.h>
|
||||||
|
#include <utils/portlist.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
static QStringList searchPaths(Kit *kit)
|
||||||
|
{
|
||||||
|
auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit));
|
||||||
|
if (!qtVersion)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const QDir pluginDir(qtVersion->qmakeProperty("QT_INSTALL_PLUGINS"));
|
||||||
|
const QStringList pluginSubDirs = pluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
|
|
||||||
|
QStringList searchPaths;
|
||||||
|
|
||||||
|
for (const QString &dir : pluginSubDirs)
|
||||||
|
searchPaths << qtVersion->qmakeProperty("QT_INSTALL_PLUGINS") + '/' + dir;
|
||||||
|
|
||||||
|
searchPaths << qtVersion->qmakeProperty("QT_INSTALL_LIBS");
|
||||||
|
searchPaths << qtVersion->qnxTarget() + '/' + qtVersion->cpuDir() + "/lib";
|
||||||
|
searchPaths << qtVersion->qnxTarget() + '/' + qtVersion->cpuDir() + "/usr/lib";
|
||||||
|
|
||||||
|
return searchPaths;
|
||||||
|
}
|
||||||
|
|
||||||
// QnxDebuggeeRunner
|
// QnxDebuggeeRunner
|
||||||
|
|
||||||
class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
|
class QnxDebuggeeRunner : public ProjectExplorer::SimpleTargetRunner
|
||||||
@@ -68,7 +107,7 @@ private:
|
|||||||
StandardRunnable r = runnable().as<StandardRunnable>();
|
StandardRunnable r = runnable().as<StandardRunnable>();
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
if (m_portsGatherer->useGdbServer()) {
|
if (m_portsGatherer->useGdbServer()) {
|
||||||
Utils::Port pdebugPort = m_portsGatherer->gdbServerPort();
|
Port pdebugPort = m_portsGatherer->gdbServerPort();
|
||||||
r.executable = Constants::QNX_DEBUG_EXECUTABLE;
|
r.executable = Constants::QNX_DEBUG_EXECUTABLE;
|
||||||
arguments.append(pdebugPort.toString());
|
arguments.append(pdebugPort.toString());
|
||||||
}
|
}
|
||||||
@@ -76,8 +115,8 @@ private:
|
|||||||
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
|
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
|
||||||
m_portsGatherer->qmlServerPort()));
|
m_portsGatherer->qmlServerPort()));
|
||||||
}
|
}
|
||||||
arguments.append(Utils::QtcProcess::splitArgs(r.commandLineArguments));
|
arguments.append(QtcProcess::splitArgs(r.commandLineArguments));
|
||||||
r.commandLineArguments = Utils::QtcProcess::joinArgs(arguments);
|
r.commandLineArguments = QtcProcess::joinArgs(arguments);
|
||||||
|
|
||||||
setRunnable(r);
|
setRunnable(r);
|
||||||
|
|
||||||
@@ -94,7 +133,7 @@ QnxDebugSupport::QnxDebugSupport(RunControl *runControl)
|
|||||||
: DebuggerRunTool(runControl)
|
: DebuggerRunTool(runControl)
|
||||||
{
|
{
|
||||||
setDisplayName("QnxDebugSupport");
|
setDisplayName("QnxDebugSupport");
|
||||||
appendMessage(tr("Preparing remote side..."), Utils::LogMessageFormat);
|
appendMessage(tr("Preparing remote side..."), LogMessageFormat);
|
||||||
|
|
||||||
m_portsGatherer = new GdbServerPortsGatherer(runControl);
|
m_portsGatherer = new GdbServerPortsGatherer(runControl);
|
||||||
m_portsGatherer->setUseGdbServer(isCppDebugging());
|
m_portsGatherer->setUseGdbServer(isCppDebugging());
|
||||||
@@ -123,14 +162,193 @@ void QnxDebugSupport::start()
|
|||||||
setStartMode(AttachToRemoteServer);
|
setStartMode(AttachToRemoteServer);
|
||||||
setCloseMode(KillAtClose);
|
setCloseMode(KillAtClose);
|
||||||
setUseCtrlCStub(true);
|
setUseCtrlCStub(true);
|
||||||
setSymbolFile(runConfig->localExecutableFilePath());
|
|
||||||
setRemoteChannel(m_portsGatherer->gdbServerChannel());
|
setRemoteChannel(m_portsGatherer->gdbServerChannel());
|
||||||
setQmlServer(m_portsGatherer->qmlServer());
|
setQmlServer(m_portsGatherer->qmlServer());
|
||||||
setInferior(inferior);
|
setInferior(inferior);
|
||||||
|
setSolibSearchPath(searchPaths(k));
|
||||||
|
|
||||||
auto qtVersion = dynamic_cast<QnxQtVersion *>(QtSupport::QtKitInformation::qtVersion(k));
|
DebuggerRunTool::start();
|
||||||
if (qtVersion)
|
}
|
||||||
setSolibSearchPath(QnxUtils::searchPaths(qtVersion));
|
|
||||||
|
|
||||||
|
// QnxAttachDebugDialog
|
||||||
|
|
||||||
|
class QnxAttachDebugDialog : public DeviceProcessesDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QnxAttachDebugDialog(KitChooser *kitChooser)
|
||||||
|
: DeviceProcessesDialog(kitChooser, Core::ICore::dialogParent())
|
||||||
|
{
|
||||||
|
auto sourceLabel = new QLabel(QnxDebugSupport::tr("Project source directory:"), this);
|
||||||
|
m_projectSource = new PathChooser(this);
|
||||||
|
m_projectSource->setExpectedKind(PathChooser::ExistingDirectory);
|
||||||
|
|
||||||
|
auto binaryLabel = new QLabel(QnxDebugSupport::tr("Local executable:"), this);
|
||||||
|
m_localExecutable = new PathChooser(this);
|
||||||
|
m_localExecutable->setExpectedKind(PathChooser::File);
|
||||||
|
|
||||||
|
auto formLayout = new QFormLayout;
|
||||||
|
formLayout->addRow(sourceLabel, m_projectSource);
|
||||||
|
formLayout->addRow(binaryLabel, m_localExecutable);
|
||||||
|
|
||||||
|
auto mainLayout = dynamic_cast<QVBoxLayout*>(layout());
|
||||||
|
QTC_ASSERT(mainLayout, return);
|
||||||
|
mainLayout->insertLayout(mainLayout->count() - 2, formLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString projectSource() const { return m_projectSource->path(); }
|
||||||
|
QString localExecutable() const { return m_localExecutable->path(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PathChooser *m_projectSource;
|
||||||
|
PathChooser *m_localExecutable;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// QnxAttachDebugSupport
|
||||||
|
|
||||||
|
class PDebugRunner : public ProjectExplorer::SimpleTargetRunner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PDebugRunner(RunControl *runControl, GdbServerPortsGatherer *portsGatherer)
|
||||||
|
: SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
|
||||||
|
{
|
||||||
|
setDisplayName("PDebugRunner");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void start() final
|
||||||
|
{
|
||||||
|
StandardRunnable r = runnable().as<StandardRunnable>();
|
||||||
|
QStringList arguments;
|
||||||
|
if (m_portsGatherer->useGdbServer()) {
|
||||||
|
Port pdebugPort = m_portsGatherer->gdbServerPort();
|
||||||
|
r.executable = Constants::QNX_DEBUG_EXECUTABLE;
|
||||||
|
arguments.append(pdebugPort.toString());
|
||||||
|
}
|
||||||
|
if (m_portsGatherer->useQmlServer()) {
|
||||||
|
arguments.append(QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlDebuggerServices,
|
||||||
|
m_portsGatherer->qmlServerPort()));
|
||||||
|
}
|
||||||
|
arguments.append(QtcProcess::splitArgs(r.commandLineArguments));
|
||||||
|
r.commandLineArguments = QtcProcess::joinArgs(arguments);
|
||||||
|
|
||||||
|
setRunnable(r);
|
||||||
|
|
||||||
|
SimpleTargetRunner::start();
|
||||||
|
}
|
||||||
|
|
||||||
|
GdbServerPortsGatherer *m_portsGatherer;
|
||||||
|
};
|
||||||
|
|
||||||
|
QnxAttachDebugSupport::QnxAttachDebugSupport(RunControl *runControl)
|
||||||
|
: DebuggerRunTool(runControl)
|
||||||
|
{
|
||||||
|
setDisplayName("QnxAttachDebugSupport");
|
||||||
|
|
||||||
|
m_portsGatherer = new GdbServerPortsGatherer(runControl);
|
||||||
|
m_portsGatherer->setUseGdbServer(isCppDebugging());
|
||||||
|
m_portsGatherer->setUseQmlServer(isQmlDebugging());
|
||||||
|
|
||||||
|
m_pdebugRunner = new PDebugRunner(runControl, m_portsGatherer);
|
||||||
|
m_pdebugRunner->addStartDependency(m_portsGatherer);
|
||||||
|
|
||||||
|
addStartDependency(m_pdebugRunner);
|
||||||
|
|
||||||
|
// connect(m_launcher, &ApplicationLauncher::remoteProcessStarted,
|
||||||
|
// this, &QnxAttachDebugSupport::attachToProcess);
|
||||||
|
// connect(m_launcher, &ApplicationLauncher::reportError,
|
||||||
|
// this, &QnxAttachDebugSupport::handleError);
|
||||||
|
// connect(m_launcher, &ApplicationLauncher::reportProgress,
|
||||||
|
// this, &QnxAttachDebugSupport::handleProgressReport);
|
||||||
|
// connect(m_launcher, &ApplicationLauncher::remoteStdout,
|
||||||
|
// this, &QnxAttachDebugSupport::handleRemoteOutput);
|
||||||
|
// connect(m_launcher, &ApplicationLauncher::remoteStderr,
|
||||||
|
// this, &QnxAttachDebugSupport::handleRemoteOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QnxAttachDebugSupport::showProcessesDialog()
|
||||||
|
{
|
||||||
|
auto kitChooser = new KitChooser;
|
||||||
|
kitChooser->setKitPredicate([](const Kit *k) {
|
||||||
|
return k->isValid() && DeviceTypeKitInformation::deviceTypeId(k) == Constants::QNX_QNX_OS_TYPE;
|
||||||
|
});
|
||||||
|
|
||||||
|
QnxAttachDebugDialog dlg(kitChooser);
|
||||||
|
dlg.addAcceptButton(DeviceProcessesDialog::tr("&Attach to Process"));
|
||||||
|
dlg.showAllDevices();
|
||||||
|
if (dlg.exec() == QDialog::Rejected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Kit *kit = kitChooser->currentKit();
|
||||||
|
if (!kit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// FIXME: That should be somehow related to the selected kit.
|
||||||
|
auto runConfig = RunConfiguration::startupRunConfiguration();
|
||||||
|
if (!runConfig)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DeviceProcessItem process = dlg.currentProcess();
|
||||||
|
const int pid = process.pid;
|
||||||
|
|
||||||
|
auto runControl = new RunControl(runConfig, ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
||||||
|
auto debugger = new QnxAttachDebugSupport(runControl);
|
||||||
|
debugger->setAttachPid(pid);
|
||||||
|
debugger->setSymbolFile(dlg.localExecutable());
|
||||||
|
// QString projectSourceDirectory = dlg.projectSource();
|
||||||
|
|
||||||
|
// auto runConfig = qobject_cast<QnxRunConfiguration *>(runControl()->runConfiguration());
|
||||||
|
// QTC_ASSERT(runConfig, return);
|
||||||
|
// Target *target = runConfig->target();
|
||||||
|
|
||||||
|
// StandardRunnable inferior;
|
||||||
|
// inferior.executable = runConfig->remoteExecutableFilePath();
|
||||||
|
// inferior.executable = m_localExecutablePath;
|
||||||
|
// inferior.commandLineArguments = runConfig->arguments();
|
||||||
|
|
||||||
|
debugger->setStartMode(AttachToRemoteServer);
|
||||||
|
debugger->setCloseMode(DetachAtClose);
|
||||||
|
debugger->setUseCtrlCStub(true);
|
||||||
|
// setInferior(inferior);
|
||||||
|
// setRunControlName(tr("Remote: \"%1\" - Process %2").arg(remoteChannel).arg(m_process.pid));
|
||||||
|
debugger->setRunControlName(tr("Remote QNX process %1").arg(pid));
|
||||||
|
debugger->setSolibSearchPath(searchPaths(kit));
|
||||||
|
|
||||||
|
(void) new QnxAttachDebugSupport(runControl);
|
||||||
|
ProjectExplorerPlugin::startRunControl(runControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QnxAttachDebugSupport::handleDebuggerStateChanged(Debugger::DebuggerState state)
|
||||||
|
{
|
||||||
|
if (state == Debugger::DebuggerFinished)
|
||||||
|
stopPDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QnxAttachDebugSupport::handleError(const QString &message)
|
||||||
|
{
|
||||||
|
showMessage(message, Debugger::AppError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QnxAttachDebugSupport::handleProgressReport(const QString &message)
|
||||||
|
{
|
||||||
|
showMessage(message, Debugger::AppStuff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QnxAttachDebugSupport::handleRemoteOutput(const QString &output)
|
||||||
|
{
|
||||||
|
showMessage(output, Debugger::AppOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QnxAttachDebugSupport::stopPDebug()
|
||||||
|
{
|
||||||
|
// m_launcher->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QnxAttachDebugSupport::start()
|
||||||
|
{
|
||||||
|
setRemoteChannel(m_portsGatherer->gdbServerChannel());
|
||||||
|
setQmlServer(m_portsGatherer->qmlServer());
|
||||||
|
|
||||||
DebuggerRunTool::start();
|
DebuggerRunTool::start();
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <debugger/debuggerruncontrol.h>
|
#include <debugger/debuggerruncontrol.h>
|
||||||
|
|
||||||
|
#include <utils/port.h>
|
||||||
|
|
||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -43,5 +45,35 @@ private:
|
|||||||
Debugger::GdbServerPortsGatherer *m_portsGatherer;
|
Debugger::GdbServerPortsGatherer *m_portsGatherer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QnxAttachDebugSupport : public Debugger::DebuggerRunTool
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QnxAttachDebugSupport(ProjectExplorer::RunControl *runControl);
|
||||||
|
|
||||||
|
static void showProcessesDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void start() final;
|
||||||
|
|
||||||
|
void launchPDebug();
|
||||||
|
void attachToProcess();
|
||||||
|
|
||||||
|
void handleDebuggerStateChanged(Debugger::DebuggerState state);
|
||||||
|
void handleError(const QString &message);
|
||||||
|
void handleProgressReport(const QString &message);
|
||||||
|
void handleRemoteOutput(const QString &output);
|
||||||
|
|
||||||
|
void stopPDebug();
|
||||||
|
|
||||||
|
Debugger::GdbServerPortsGatherer *m_portsGatherer;
|
||||||
|
ProjectExplorer::SimpleTargetRunner *m_pdebugRunner;
|
||||||
|
|
||||||
|
Utils::Port m_pdebugPort;
|
||||||
|
QString m_projectSourceDirectory;
|
||||||
|
QString m_localExecutablePath;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Qnx
|
} // namespace Qnx
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
#include "qnxplugin.h"
|
#include "qnxplugin.h"
|
||||||
|
|
||||||
#include "qnxanalyzesupport.h"
|
#include "qnxanalyzesupport.h"
|
||||||
#include "qnxattachdebugsupport.h"
|
|
||||||
#include "qnxconfigurationmanager.h"
|
#include "qnxconfigurationmanager.h"
|
||||||
#include "qnxconstants.h"
|
#include "qnxconstants.h"
|
||||||
#include "qnxdebugsupport.h"
|
#include "qnxdebugsupport.h"
|
||||||
@@ -108,12 +107,10 @@ bool QnxPlugin::initialize(const QStringList &arguments, QString *errorString)
|
|||||||
|
|
||||||
void QnxPlugin::extensionsInitialized()
|
void QnxPlugin::extensionsInitialized()
|
||||||
{
|
{
|
||||||
// Debug support
|
// Attach support
|
||||||
QnxAttachDebugSupport *debugSupport = new QnxAttachDebugSupport(this);
|
|
||||||
|
|
||||||
m_attachToQnxApplication = new QAction(this);
|
m_attachToQnxApplication = new QAction(this);
|
||||||
m_attachToQnxApplication->setText(tr("Attach to remote QNX application..."));
|
m_attachToQnxApplication->setText(tr("Attach to remote QNX application..."));
|
||||||
connect(m_attachToQnxApplication, &QAction::triggered, debugSupport, &QnxAttachDebugSupport::showProcessesDialog);
|
connect(m_attachToQnxApplication, &QAction::triggered, this, [] { QnxAttachDebugSupport::showProcessesDialog(); });
|
||||||
|
|
||||||
Core::ActionContainer *mstart = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING);
|
Core::ActionContainer *mstart = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING);
|
||||||
mstart->appendGroup(Constants::QNX_DEBUGGING_GROUP);
|
mstart->appendGroup(Constants::QNX_DEBUGGING_GROUP);
|
||||||
|
@@ -73,27 +73,6 @@ QString QnxUtils::cpuDirShortDescription(const QString &cpuDir)
|
|||||||
return cpuDir;
|
return cpuDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList QnxUtils::searchPaths(QnxQtVersion *qtVersion)
|
|
||||||
{
|
|
||||||
const QDir pluginDir(qtVersion->qmakeProperty("QT_INSTALL_PLUGINS"));
|
|
||||||
const QStringList pluginSubDirs = pluginDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
|
||||||
|
|
||||||
QStringList searchPaths;
|
|
||||||
|
|
||||||
Q_FOREACH (const QString &dir, pluginSubDirs) {
|
|
||||||
searchPaths << qtVersion->qmakeProperty("QT_INSTALL_PLUGINS")
|
|
||||||
+ QLatin1Char('/') + dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
searchPaths << qtVersion->qmakeProperty("QT_INSTALL_LIBS");
|
|
||||||
searchPaths << qtVersion->qnxTarget() + QLatin1Char('/') + qtVersion->cpuDir()
|
|
||||||
+ QLatin1String("/lib");
|
|
||||||
searchPaths << qtVersion->qnxTarget() + QLatin1Char('/') + qtVersion->cpuDir()
|
|
||||||
+ QLatin1String("/usr/lib");
|
|
||||||
|
|
||||||
return searchPaths;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Utils::EnvironmentItem> QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
|
QList<Utils::EnvironmentItem> QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
QList <Utils::EnvironmentItem> items;
|
QList <Utils::EnvironmentItem> items;
|
||||||
|
@@ -70,7 +70,6 @@ class QnxUtils
|
|||||||
public:
|
public:
|
||||||
static QString addQuotes(const QString &string);
|
static QString addQuotes(const QString &string);
|
||||||
static QString cpuDirShortDescription(const QString &cpuDir);
|
static QString cpuDirShortDescription(const QString &cpuDir);
|
||||||
static QStringList searchPaths(Qnx::Internal::QnxQtVersion *qtVersion);
|
|
||||||
static QList<Utils::EnvironmentItem> qnxEnvironmentFromEnvFile(const QString &fileName);
|
static QList<Utils::EnvironmentItem> qnxEnvironmentFromEnvFile(const QString &fileName);
|
||||||
static QString envFilePath(const QString &sdpPath);
|
static QString envFilePath(const QString &sdpPath);
|
||||||
static QString defaultTargetVersion(const QString &sdpPath);
|
static QString defaultTargetVersion(const QString &sdpPath);
|
||||||
|
Reference in New Issue
Block a user