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

View File

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

View File

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

View File

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

View File

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

View File

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