Allow GenericGdbServerProvider to execute apps

It's very useful for debugging baremetal apps (e.g. kernels) on qemu.

Change-Id: Ie63759015f146b6a32d664a8bcc5690e5bbe81f6
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
BogDan Vatra
2025-04-04 10:00:09 +03:00
committed by BogDan Vatra
parent 3af3bc918d
commit fc692ef84f
6 changed files with 36 additions and 27 deletions

View File

@@ -91,7 +91,6 @@ private:
static QString defaultInitCommands(); static QString defaultInitCommands();
static QString defaultResetCommands(); static QString defaultResetCommands();
Utils::FilePath m_executableFile = "eblink"; // server execute filename
int m_verboseLevel = 0; // verbose <0..7> Specify generally verbose logging int m_verboseLevel = 0; // verbose <0..7> Specify generally verbose logging
InterfaceType m_interfaceType = SWD; // -I stlink ;swd(default) jtag InterfaceType m_interfaceType = SWD; // -I stlink ;swd(default) jtag
Utils::FilePath m_deviceScript = "stm32-auto.script"; // -D <script> ;Select the device script <>.script Utils::FilePath m_deviceScript = "stm32-auto.script"; // -D <script> ;Select the device script <>.script
@@ -112,6 +111,7 @@ private:
EBlinkGdbServerProvider::EBlinkGdbServerProvider() EBlinkGdbServerProvider::EBlinkGdbServerProvider()
: GdbServerProvider(Constants::GDBSERVER_EBLINK_PROVIDER_ID) : GdbServerProvider(Constants::GDBSERVER_EBLINK_PROVIDER_ID)
{ {
m_executableFile = "eblink"; // server execute filename
setInitCommands(defaultInitCommands()); setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands()); setResetCommands(defaultResetCommands());
setChannel("127.0.0.1", 2331); setChannel("127.0.0.1", 2331);

View File

@@ -35,6 +35,8 @@ const char peripheralDescriptionFileKeyC[] = "PeripheralDescriptionFile";
const char initCommandsKeyC[] = "InitCommands"; const char initCommandsKeyC[] = "InitCommands";
const char resetCommandsKeyC[] = "ResetCommands"; const char resetCommandsKeyC[] = "ResetCommands";
const char useExtendedRemoteKeyC[] = "UseExtendedRemote"; const char useExtendedRemoteKeyC[] = "UseExtendedRemote";
const char executableFileKeyC[] = "ExecutableFile";
const char additionalArgumentsKeyC[] = "AdditionalArguments";
// GdbServerProvider // GdbServerProvider
@@ -96,7 +98,9 @@ void GdbServerProvider::setResetCommands(const QString &cmds)
Utils::CommandLine GdbServerProvider::command() const Utils::CommandLine GdbServerProvider::command() const
{ {
if (m_executableFile.isEmpty())
return {}; return {};
return CommandLine{m_executableFile, m_additionalArguments, CommandLine::Raw};
} }
bool GdbServerProvider::operator==(const IDebugServerProvider &other) const bool GdbServerProvider::operator==(const IDebugServerProvider &other) const
@@ -120,6 +124,8 @@ void GdbServerProvider::toMap(Store &data) const
data.insert(initCommandsKeyC, m_initCommands); data.insert(initCommandsKeyC, m_initCommands);
data.insert(resetCommandsKeyC, m_resetCommands); data.insert(resetCommandsKeyC, m_resetCommands);
data.insert(useExtendedRemoteKeyC, m_useExtendedRemote); data.insert(useExtendedRemoteKeyC, m_useExtendedRemote);
data.insert(executableFileKeyC, m_executableFile.toSettings());
data.insert(additionalArgumentsKeyC, m_additionalArguments);
} }
bool GdbServerProvider::isValid() const bool GdbServerProvider::isValid() const
@@ -158,12 +164,13 @@ Result<> GdbServerProvider::setupDebuggerRunParameters(DebuggerRunParameters &rp
RunWorker *GdbServerProvider::targetRunner(RunControl *runControl) const RunWorker *GdbServerProvider::targetRunner(RunControl *runControl) const
{ {
if (m_startupMode != GdbServerProvider::StartupOnNetwork) const CommandLine cmd = command();
if (m_startupMode != GdbServerProvider::StartupOnNetwork || cmd.isEmpty())
return nullptr; return nullptr;
// Command arguments are in host OS style as the bare metal's GDB servers are launched // Command arguments are in host OS style as the bare metal's GDB servers are launched
// on the host, not on that target. // on the host, not on that target.
return createProcessWorker(runControl, [cmd = command()](Process &process) { return createProcessWorker(runControl, [cmd](Process &process) {
// Baremetal's GDB servers are launched on the host, not on the target. // Baremetal's GDB servers are launched on the host, not on the target.
process.setCommand(cmd.toLocal()); process.setCommand(cmd.toLocal());
}); });
@@ -174,6 +181,8 @@ void GdbServerProvider::fromMap(const Store &data)
IDebugServerProvider::fromMap(data); IDebugServerProvider::fromMap(data);
m_startupMode = static_cast<StartupMode>(data.value(startupModeKeyC).toInt()); m_startupMode = static_cast<StartupMode>(data.value(startupModeKeyC).toInt());
m_peripheralDescriptionFile = FilePath::fromSettings(data.value(peripheralDescriptionFileKeyC)); m_peripheralDescriptionFile = FilePath::fromSettings(data.value(peripheralDescriptionFileKeyC));
m_executableFile = FilePath::fromSettings(data.value(executableFileKeyC));
m_additionalArguments = data.value(additionalArgumentsKeyC).toString();
m_initCommands = data.value(initCommandsKeyC).toString(); m_initCommands = data.value(initCommandsKeyC).toString();
m_resetCommands = data.value(resetCommandsKeyC).toString(); m_resetCommands = data.value(resetCommandsKeyC).toString();
m_useExtendedRemote = data.value(useExtendedRemoteKeyC).toBool(); m_useExtendedRemote = data.value(useExtendedRemoteKeyC).toBool();

View File

@@ -61,6 +61,8 @@ protected:
QString m_initCommands; QString m_initCommands;
QString m_resetCommands; QString m_resetCommands;
bool m_useExtendedRemote = false; bool m_useExtendedRemote = false;
Utils::FilePath m_executableFile;
QString m_additionalArguments;
friend class GdbServerProviderConfigWidget; friend class GdbServerProviderConfigWidget;
}; };

View File

@@ -7,6 +7,7 @@
#include <baremetal/baremetaltr.h> #include <baremetal/baremetaltr.h>
#include <baremetal/debugserverprovidermanager.h> #include <baremetal/debugserverprovidermanager.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/variablechooser.h> #include <utils/variablechooser.h>
@@ -32,6 +33,8 @@ private:
void setFromProvider(); void setFromProvider();
HostWidget *m_hostWidget = nullptr; HostWidget *m_hostWidget = nullptr;
Utils::PathChooser *m_executableFileChooser = nullptr;
QLineEdit *m_additionalArgumentsLineEdit = nullptr;
QCheckBox *m_useExtendedRemoteCheckBox = nullptr; QCheckBox *m_useExtendedRemoteCheckBox = nullptr;
QPlainTextEdit *m_initCommandsTextEdit = nullptr; QPlainTextEdit *m_initCommandsTextEdit = nullptr;
QPlainTextEdit *m_resetCommandsTextEdit = nullptr; QPlainTextEdit *m_resetCommandsTextEdit = nullptr;
@@ -44,12 +47,6 @@ class GenericGdbServerProvider final : public GdbServerProvider
private: private:
GenericGdbServerProvider(); GenericGdbServerProvider();
QSet<StartupMode> supportedStartupModes() const final; QSet<StartupMode> supportedStartupModes() const final;
ProjectExplorer::RunWorker *targetRunner(ProjectExplorer::RunControl *runControl) const final {
Q_UNUSED(runControl)
// Generic Runner assumes GDB Server already running
return nullptr;
}
friend class GenericGdbServerProviderConfigWidget; friend class GenericGdbServerProviderConfigWidget;
friend class GenericGdbServerProviderFactory; friend class GenericGdbServerProviderFactory;
}; };
@@ -59,7 +56,7 @@ private:
GenericGdbServerProvider::GenericGdbServerProvider() GenericGdbServerProvider::GenericGdbServerProvider()
: GdbServerProvider(Constants::GDBSERVER_GENERIC_PROVIDER_ID) : GdbServerProvider(Constants::GDBSERVER_GENERIC_PROVIDER_ID)
{ {
setChannel("localhost", 3333); setChannel("localhost", 1234);
setTypeDisplayName(Tr::tr("Generic")); setTypeDisplayName(Tr::tr("Generic"));
setConfigurationWidgetCreator([this] { return new GenericGdbServerProviderConfigWidget(this); }); setConfigurationWidgetCreator([this] { return new GenericGdbServerProviderConfigWidget(this); });
} }
@@ -89,6 +86,14 @@ GenericGdbServerProviderConfigWidget::GenericGdbServerProviderConfigWidget(
m_hostWidget = new HostWidget(this); m_hostWidget = new HostWidget(this);
m_mainLayout->addRow(Tr::tr("Host:"), m_hostWidget); m_mainLayout->addRow(Tr::tr("Host:"), m_hostWidget);
m_executableFileChooser = new Utils::PathChooser;
m_executableFileChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
m_executableFileChooser->setCommandVersionArguments({"--version"});
m_mainLayout->addRow(Tr::tr("Executable file:"), m_executableFileChooser);
m_additionalArgumentsLineEdit = new QLineEdit(this);
m_mainLayout->addRow(Tr::tr("Additional arguments:"), m_additionalArgumentsLineEdit);
m_useExtendedRemoteCheckBox = new QCheckBox(this); m_useExtendedRemoteCheckBox = new QCheckBox(this);
m_useExtendedRemoteCheckBox->setToolTip(Tr::tr("Use GDB target extended-remote")); m_useExtendedRemoteCheckBox->setToolTip(Tr::tr("Use GDB target extended-remote"));
m_mainLayout->addRow(Tr::tr("Extended mode:"), m_useExtendedRemoteCheckBox); m_mainLayout->addRow(Tr::tr("Extended mode:"), m_useExtendedRemoteCheckBox);
@@ -108,6 +113,10 @@ GenericGdbServerProviderConfigWidget::GenericGdbServerProviderConfigWidget(
connect(m_hostWidget, &HostWidget::dataChanged, connect(m_hostWidget, &HostWidget::dataChanged,
this, &GdbServerProviderConfigWidget::dirty); this, &GdbServerProviderConfigWidget::dirty);
connect(m_executableFileChooser, &Utils::PathChooser::rawPathChanged,
this, &GdbServerProviderConfigWidget::dirty);
connect(m_additionalArgumentsLineEdit, &QLineEdit::textChanged,
this, &GdbServerProviderConfigWidget::dirty);
connect(m_useExtendedRemoteCheckBox, &QCheckBox::stateChanged, connect(m_useExtendedRemoteCheckBox, &QCheckBox::stateChanged,
this, &GdbServerProviderConfigWidget::dirty); this, &GdbServerProviderConfigWidget::dirty);
connect(m_initCommandsTextEdit, &QPlainTextEdit::textChanged, connect(m_initCommandsTextEdit, &QPlainTextEdit::textChanged,
@@ -122,6 +131,8 @@ void GenericGdbServerProviderConfigWidget::apply()
Q_ASSERT(p); Q_ASSERT(p);
p->setChannel(m_hostWidget->channel()); p->setChannel(m_hostWidget->channel());
p->m_executableFile = m_executableFileChooser->filePath();
p->m_additionalArguments = m_additionalArgumentsLineEdit->text();
p->setUseExtendedRemote(m_useExtendedRemoteCheckBox->isChecked()); p->setUseExtendedRemote(m_useExtendedRemoteCheckBox->isChecked());
p->setInitCommands(m_initCommandsTextEdit->toPlainText()); p->setInitCommands(m_initCommandsTextEdit->toPlainText());
p->setResetCommands(m_resetCommandsTextEdit->toPlainText()); p->setResetCommands(m_resetCommandsTextEdit->toPlainText());
@@ -141,6 +152,8 @@ void GenericGdbServerProviderConfigWidget::setFromProvider()
const QSignalBlocker blocker(this); const QSignalBlocker blocker(this);
m_hostWidget->setChannel(p->channel()); m_hostWidget->setChannel(p->channel());
m_executableFileChooser->setFilePath(p->m_executableFile);
m_additionalArgumentsLineEdit->setText(p->m_additionalArguments);
m_useExtendedRemoteCheckBox->setChecked(p->useExtendedRemote()); m_useExtendedRemoteCheckBox->setChecked(p->useExtendedRemote());
m_initCommandsTextEdit->setPlainText(p->initCommands()); m_initCommandsTextEdit->setPlainText(p->initCommands());
m_resetCommandsTextEdit->setPlainText(p->resetCommands()); m_resetCommandsTextEdit->setPlainText(p->resetCommands());

View File

@@ -24,13 +24,11 @@ using namespace Utils;
namespace BareMetal::Internal { namespace BareMetal::Internal {
const char executableFileKeyC[] = "ExecutableFile";
const char jlinkDeviceKeyC[] = "JLinkDevice"; const char jlinkDeviceKeyC[] = "JLinkDevice";
const char jlinkHostInterfaceKeyC[] = "JLinkHostInterface"; const char jlinkHostInterfaceKeyC[] = "JLinkHostInterface";
const char jlinkHostInterfaceIPAddressKeyC[] = "JLinkHostInterfaceIPAddress"; const char jlinkHostInterfaceIPAddressKeyC[] = "JLinkHostInterfaceIPAddress";
const char jlinkTargetInterfaceKeyC[] = "JLinkTargetInterface"; const char jlinkTargetInterfaceKeyC[] = "JLinkTargetInterface";
const char jlinkTargetInterfaceSpeedKeyC[] = "JLinkTargetInterfaceSpeed"; const char jlinkTargetInterfaceSpeedKeyC[] = "JLinkTargetInterfaceSpeed";
const char additionalArgumentsKeyC[] = "AdditionalArguments";
// JLinkGdbServerProviderConfigWidget // JLinkGdbServerProviderConfigWidget
@@ -98,13 +96,11 @@ private:
static QString defaultInitCommands(); static QString defaultInitCommands();
static QString defaultResetCommands(); static QString defaultResetCommands();
FilePath m_executableFile;
QString m_jlinkDevice; QString m_jlinkDevice;
QString m_jlinkHost = {"USB"}; QString m_jlinkHost = {"USB"};
QString m_jlinkHostAddr; QString m_jlinkHostAddr;
QString m_jlinkTargetIface = {"SWD"}; QString m_jlinkTargetIface = {"SWD"};
QString m_jlinkTargetIfaceSpeed = {"12000"}; QString m_jlinkTargetIfaceSpeed = {"12000"};
QString m_additionalArguments;
friend class JLinkGdbServerProviderConfigWidget; friend class JLinkGdbServerProviderConfigWidget;
friend class JLinkGdbServerProviderFactory; friend class JLinkGdbServerProviderFactory;
@@ -197,21 +193,17 @@ bool JLinkGdbServerProvider::isValid() const
void JLinkGdbServerProvider::toMap(Store &data) const void JLinkGdbServerProvider::toMap(Store &data) const
{ {
GdbServerProvider::toMap(data); GdbServerProvider::toMap(data);
data.insert(executableFileKeyC, m_executableFile.toSettings());
data.insert(jlinkDeviceKeyC, m_jlinkDevice); data.insert(jlinkDeviceKeyC, m_jlinkDevice);
data.insert(jlinkHostInterfaceKeyC, m_jlinkHost); data.insert(jlinkHostInterfaceKeyC, m_jlinkHost);
data.insert(jlinkHostInterfaceIPAddressKeyC, m_jlinkHostAddr); data.insert(jlinkHostInterfaceIPAddressKeyC, m_jlinkHostAddr);
data.insert(jlinkTargetInterfaceKeyC, m_jlinkTargetIface); data.insert(jlinkTargetInterfaceKeyC, m_jlinkTargetIface);
data.insert(jlinkTargetInterfaceSpeedKeyC, m_jlinkTargetIfaceSpeed); data.insert(jlinkTargetInterfaceSpeedKeyC, m_jlinkTargetIfaceSpeed);
data.insert(additionalArgumentsKeyC, m_additionalArguments);
} }
void JLinkGdbServerProvider::fromMap(const Store &data) void JLinkGdbServerProvider::fromMap(const Store &data)
{ {
GdbServerProvider::fromMap(data); GdbServerProvider::fromMap(data);
m_executableFile = FilePath::fromSettings(data.value(executableFileKeyC));
m_jlinkDevice = data.value(jlinkDeviceKeyC).toString(); m_jlinkDevice = data.value(jlinkDeviceKeyC).toString();
m_additionalArguments = data.value(additionalArgumentsKeyC).toString();
m_jlinkHost = data.value(jlinkHostInterfaceKeyC).toString(); m_jlinkHost = data.value(jlinkHostInterfaceKeyC).toString();
m_jlinkHostAddr = data.value(jlinkHostInterfaceIPAddressKeyC).toString(); m_jlinkHostAddr = data.value(jlinkHostInterfaceIPAddressKeyC).toString();
m_jlinkTargetIface = data.value(jlinkTargetInterfaceKeyC).toString(); m_jlinkTargetIface = data.value(jlinkTargetInterfaceKeyC).toString();

View File

@@ -22,10 +22,8 @@ using namespace Utils;
namespace BareMetal::Internal { namespace BareMetal::Internal {
const char executableFileKeyC[] = "ExecutableFile";
const char rootScriptsDirKeyC[] = "RootScriptsDir"; const char rootScriptsDirKeyC[] = "RootScriptsDir";
const char configurationFileKeyC[] = "ConfigurationPath"; const char configurationFileKeyC[] = "ConfigurationPath";
const char additionalArgumentsKeyC[] = "AdditionalArguments";
// OpenOcdGdbServerProviderConfigWidget // OpenOcdGdbServerProviderConfigWidget
@@ -74,10 +72,8 @@ private:
static QString defaultInitCommands(); static QString defaultInitCommands();
static QString defaultResetCommands(); static QString defaultResetCommands();
Utils::FilePath m_executableFile = "openocd";
Utils::FilePath m_rootScriptsDir; Utils::FilePath m_rootScriptsDir;
Utils::FilePath m_configurationFile; Utils::FilePath m_configurationFile;
QString m_additionalArguments;
friend class OpenOcdGdbServerProviderConfigWidget; friend class OpenOcdGdbServerProviderConfigWidget;
friend class OpenOcdGdbServerProviderFactory; friend class OpenOcdGdbServerProviderFactory;
@@ -87,6 +83,7 @@ private:
OpenOcdGdbServerProvider::OpenOcdGdbServerProvider() OpenOcdGdbServerProvider::OpenOcdGdbServerProvider()
: GdbServerProvider(Constants::GDBSERVER_OPENOCD_PROVIDER_ID) : GdbServerProvider(Constants::GDBSERVER_OPENOCD_PROVIDER_ID)
{ {
m_executableFile = "openocd";
setInitCommands(defaultInitCommands()); setInitCommands(defaultInitCommands());
setResetCommands(defaultResetCommands()); setResetCommands(defaultResetCommands());
setChannel("localhost", 3333); setChannel("localhost", 3333);
@@ -183,19 +180,15 @@ bool OpenOcdGdbServerProvider::isValid() const
void OpenOcdGdbServerProvider::toMap(Store &data) const void OpenOcdGdbServerProvider::toMap(Store &data) const
{ {
GdbServerProvider::toMap(data); GdbServerProvider::toMap(data);
data.insert(executableFileKeyC, m_executableFile.toSettings());
data.insert(rootScriptsDirKeyC, m_rootScriptsDir.toSettings()); data.insert(rootScriptsDirKeyC, m_rootScriptsDir.toSettings());
data.insert(configurationFileKeyC, m_configurationFile.toSettings()); data.insert(configurationFileKeyC, m_configurationFile.toSettings());
data.insert(additionalArgumentsKeyC, m_additionalArguments);
} }
void OpenOcdGdbServerProvider::fromMap(const Store &data) void OpenOcdGdbServerProvider::fromMap(const Store &data)
{ {
GdbServerProvider::fromMap(data); GdbServerProvider::fromMap(data);
m_executableFile = FilePath::fromSettings(data.value(executableFileKeyC));
m_rootScriptsDir = FilePath::fromSettings(data.value(rootScriptsDirKeyC)); m_rootScriptsDir = FilePath::fromSettings(data.value(rootScriptsDirKeyC));
m_configurationFile = FilePath::fromSettings(data.value(configurationFileKeyC)); m_configurationFile = FilePath::fromSettings(data.value(configurationFileKeyC));
m_additionalArguments = data.value(additionalArgumentsKeyC).toString();
} }
bool OpenOcdGdbServerProvider::operator==(const IDebugServerProvider &other) const bool OpenOcdGdbServerProvider::operator==(const IDebugServerProvider &other) const