Created new ServerInterface class and refactored the AVR GDB RSP debug server into an implementation of ServerInterface
This commit is contained in:
@@ -390,15 +390,9 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Application::startDebugServer() {
|
void Application::startDebugServer() {
|
||||||
auto supportedDebugServers = this->getSupportedDebugServers();
|
this->debugServer = std::make_unique<DebugServers::DebugServer>(
|
||||||
if (!supportedDebugServers.contains(this->debugServerConfig->name)) {
|
this->debugServerConfig.value()
|
||||||
throw Exceptions::InvalidConfig(
|
);
|
||||||
"DebugServer \"" + this->debugServerConfig->name + "\" not found."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->debugServer = supportedDebugServers.at(this->debugServerConfig->name)();
|
|
||||||
Logger::info("Selected DebugServer: " + this->debugServer->getName());
|
|
||||||
|
|
||||||
this->debugServerThread = std::thread(
|
this->debugServerThread = std::thread(
|
||||||
&DebugServers::DebugServer::run,
|
&DebugServers::DebugServer::run,
|
||||||
@@ -414,7 +408,6 @@ namespace Bloom
|
|||||||
|
|
||||||
void Application::stopDebugServer() {
|
void Application::stopDebugServer() {
|
||||||
if (this->debugServer == nullptr) {
|
if (this->debugServer == nullptr) {
|
||||||
// DebugServer hasn't been resolved yet.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "src/Helpers/Thread.hpp"
|
#include "src/Helpers/Thread.hpp"
|
||||||
|
|
||||||
#include "src/TargetController/TargetController.hpp"
|
#include "src/TargetController/TargetController.hpp"
|
||||||
#include "src/DebugServers/GdbRsp/AvrGdb/AvrGdbRsp.hpp"
|
#include "src/DebugServers/DebugServer.hpp"
|
||||||
#include "src/Insight/Insight.hpp"
|
#include "src/Insight/Insight.hpp"
|
||||||
#include "src/SignalHandler/SignalHandler.hpp"
|
#include "src/SignalHandler/SignalHandler.hpp"
|
||||||
|
|
||||||
@@ -37,29 +37,6 @@ namespace Bloom
|
|||||||
|
|
||||||
explicit Application() = default;
|
explicit Application() = default;
|
||||||
|
|
||||||
/**
|
|
||||||
* This mapping is used to map debug server names from project configuration files to polymorphic instances of
|
|
||||||
* the DebugServer class.
|
|
||||||
*
|
|
||||||
* See Application::startDebugServer() for more on this.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
auto getSupportedDebugServers() {
|
|
||||||
return std::map<std::string, std::function<std::unique_ptr<DebugServers::DebugServer>()>> {
|
|
||||||
{
|
|
||||||
"avr-gdb-rsp",
|
|
||||||
[this] () -> std::unique_ptr<DebugServers::DebugServer> {
|
|
||||||
return std::make_unique<DebugServers::Gdb::AvrGdb::AvrGdbRsp>(
|
|
||||||
this->projectConfig.value(),
|
|
||||||
this->environmentConfig.value(),
|
|
||||||
this->debugServerConfig.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main entry-point for the Bloom program.
|
* Main entry-point for the Bloom program.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
// Debug server implementations
|
||||||
|
#include "GdbRsp/AvrGdb/AvrGdbRsp.hpp"
|
||||||
|
|
||||||
#include "src/Exceptions/InvalidConfig.hpp"
|
#include "src/Exceptions/InvalidConfig.hpp"
|
||||||
#include "src/Logger/Logger.hpp"
|
#include "src/Logger/Logger.hpp"
|
||||||
|
|
||||||
@@ -9,6 +12,10 @@ namespace Bloom::DebugServers
|
|||||||
{
|
{
|
||||||
using namespace Bloom::Events;
|
using namespace Bloom::Events;
|
||||||
|
|
||||||
|
DebugServer::DebugServer(const DebugServerConfig& debugServerConfig)
|
||||||
|
: debugServerConfig(debugServerConfig)
|
||||||
|
{}
|
||||||
|
|
||||||
void DebugServer::run() {
|
void DebugServer::run() {
|
||||||
try {
|
try {
|
||||||
this->startup();
|
this->startup();
|
||||||
@@ -16,7 +23,7 @@ namespace Bloom::DebugServers
|
|||||||
Logger::info("DebugServer ready");
|
Logger::info("DebugServer ready");
|
||||||
|
|
||||||
while (this->getThreadState() == ThreadState::READY) {
|
while (this->getThreadState() == ThreadState::READY) {
|
||||||
this->serve();
|
this->server->run();
|
||||||
this->eventListener->dispatchCurrentEvents();
|
this->eventListener->dispatchCurrentEvents();
|
||||||
}
|
}
|
||||||
} catch (const std::exception& exception) {
|
} catch (const std::exception& exception) {
|
||||||
@@ -26,23 +33,42 @@ namespace Bloom::DebugServers
|
|||||||
this->shutdown();
|
this->shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::function<std::unique_ptr<ServerInterface>()>> DebugServer::getAvailableServersByName() {
|
||||||
|
return std::map<std::string, std::function<std::unique_ptr<ServerInterface>()>> {
|
||||||
|
{
|
||||||
|
"avr-gdb-rsp",
|
||||||
|
[this] () -> std::unique_ptr<ServerInterface> {
|
||||||
|
return std::make_unique<DebugServers::Gdb::AvrGdb::AvrGdbRsp>(
|
||||||
|
this->debugServerConfig,
|
||||||
|
*(this->eventListener.get())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
void DebugServer::startup() {
|
void DebugServer::startup() {
|
||||||
this->setName("DS");
|
this->setName("DS");
|
||||||
Logger::info("Starting DebugServer");
|
Logger::info("Starting DebugServer");
|
||||||
|
|
||||||
EventManager::registerListener(this->eventListener);
|
EventManager::registerListener(this->eventListener);
|
||||||
|
this->eventListener->setInterruptEventNotifier(&this->interruptEventNotifier);
|
||||||
this->interruptEventNotifier = std::make_shared<EventNotifier>();
|
|
||||||
this->eventListener->setInterruptEventNotifier(this->interruptEventNotifier);
|
|
||||||
|
|
||||||
// Register event handlers
|
// Register event handlers
|
||||||
this->eventListener->registerCallbackForEventType<Events::ShutdownDebugServer>(
|
this->eventListener->registerCallbackForEventType<Events::ShutdownDebugServer>(
|
||||||
std::bind(&DebugServer::onShutdownDebugServerEvent, this, std::placeholders::_1)
|
std::bind(&DebugServer::onShutdownDebugServerEvent, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
|
|
||||||
this->targetDescriptor = this->targetControllerConsole.getTargetDescriptor();
|
static const auto availableServersByName = this->getAvailableServersByName();
|
||||||
|
if (!availableServersByName.contains(this->debugServerConfig.name)) {
|
||||||
|
throw Exceptions::InvalidConfig(
|
||||||
|
"DebugServer \"" + this->debugServerConfig.name + "\" not found."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this->init();
|
this->server = availableServersByName.at(this->debugServerConfig.name)();
|
||||||
|
Logger::info("Selected DebugServer: " + this->server->getName());
|
||||||
|
|
||||||
|
this->server->init();
|
||||||
this->setThreadStateAndEmitEvent(ThreadState::READY);
|
this->setThreadStateAndEmitEvent(ThreadState::READY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +81,7 @@ namespace Bloom::DebugServers
|
|||||||
|
|
||||||
this->setThreadState(ThreadState::SHUTDOWN_INITIATED);
|
this->setThreadState(ThreadState::SHUTDOWN_INITIATED);
|
||||||
Logger::info("Shutting down DebugServer");
|
Logger::info("Shutting down DebugServer");
|
||||||
this->close();
|
this->server->close();
|
||||||
this->setThreadStateAndEmitEvent(ThreadState::STOPPED);
|
this->setThreadStateAndEmitEvent(ThreadState::STOPPED);
|
||||||
EventManager::deregisterListener(this->eventListener->getId());
|
EventManager::deregisterListener(this->eventListener->getId());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cstdint>
|
#include <memory>
|
||||||
|
|
||||||
#include "src/TargetController/TargetControllerConsole.hpp"
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
||||||
#include "src/EventManager/Events/Events.hpp"
|
#include "src/EventManager/Events/Events.hpp"
|
||||||
@@ -14,6 +15,8 @@
|
|||||||
#include "src/Targets/TargetRegister.hpp"
|
#include "src/Targets/TargetRegister.hpp"
|
||||||
#include "src/Targets/TargetBreakpoint.hpp"
|
#include "src/Targets/TargetBreakpoint.hpp"
|
||||||
|
|
||||||
|
#include "ServerInterface.hpp"
|
||||||
|
|
||||||
namespace Bloom::DebugServers
|
namespace Bloom::DebugServers
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -28,28 +31,16 @@ namespace Bloom::DebugServers
|
|||||||
class DebugServer: public Thread
|
class DebugServer: public Thread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DebugServer(
|
explicit DebugServer(const DebugServerConfig& debugServerConfig);
|
||||||
const ProjectConfig& projectConfig,
|
|
||||||
const EnvironmentConfig& environmentConfig,
|
|
||||||
const DebugServerConfig& debugServerConfig
|
|
||||||
)
|
|
||||||
: projectConfig(projectConfig)
|
|
||||||
, environmentConfig(environmentConfig)
|
|
||||||
, debugServerConfig(debugServerConfig)
|
|
||||||
{};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point for the DebugServer. This must called from a dedicated thread.
|
* Entry point for the DebugServer. This must called from a dedicated thread.
|
||||||
*/
|
*/
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
virtual std::string getName() const = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EventListenerPointer eventListener = std::make_shared<EventListener>("DebugServerEventListener");
|
EventListenerPointer eventListener = std::make_shared<EventListener>("DebugServerEventListener");
|
||||||
|
|
||||||
ProjectConfig projectConfig;
|
|
||||||
EnvironmentConfig environmentConfig;
|
|
||||||
DebugServerConfig debugServerConfig;
|
DebugServerConfig debugServerConfig;
|
||||||
|
|
||||||
TargetControllerConsole targetControllerConsole = TargetControllerConsole(*(this->eventListener));
|
TargetControllerConsole targetControllerConsole = TargetControllerConsole(*(this->eventListener));
|
||||||
@@ -57,26 +48,13 @@ namespace Bloom::DebugServers
|
|||||||
/**
|
/**
|
||||||
* Enables the interruption of any blocking file IO.
|
* Enables the interruption of any blocking file IO.
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<EventNotifier> interruptEventNotifier = nullptr;
|
EventNotifier interruptEventNotifier = EventNotifier();
|
||||||
|
|
||||||
Targets::TargetDescriptor targetDescriptor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called on startup of the DebugServer thread. Derived classes should implement any initialisation work here.
|
|
||||||
*/
|
|
||||||
virtual void init() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called repeatedly in an infinite loop when the DebugServer is running.
|
|
||||||
*/
|
|
||||||
virtual void serve() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called on shutdown of the debug server.
|
|
||||||
*/
|
|
||||||
virtual void close() = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<ServerInterface> server = nullptr;
|
||||||
|
|
||||||
|
std::map<std::string, std::function<std::unique_ptr<ServerInterface>()>> getAvailableServersByName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares the debug server thread and then calls init().
|
* Prepares the debug server thread and then calls init().
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,9 +7,18 @@ namespace Bloom::DebugServers::Gdb::AvrGdb
|
|||||||
using Bloom::Targets::TargetRegisterDescriptor;
|
using Bloom::Targets::TargetRegisterDescriptor;
|
||||||
using Bloom::Targets::TargetRegisterType;
|
using Bloom::Targets::TargetRegisterType;
|
||||||
|
|
||||||
|
AvrGdbRsp::AvrGdbRsp(
|
||||||
|
const DebugServerConfig& debugServerConfig,
|
||||||
|
EventListener& eventListener
|
||||||
|
)
|
||||||
|
: GdbRspDebugServer(debugServerConfig, eventListener)
|
||||||
|
{}
|
||||||
|
|
||||||
void AvrGdbRsp::init() {
|
void AvrGdbRsp::init() {
|
||||||
DebugServers::Gdb::GdbRspDebugServer::init();
|
DebugServers::Gdb::GdbRspDebugServer::init();
|
||||||
|
|
||||||
this->gdbTargetDescriptor = TargetDescriptor(this->targetDescriptor);
|
this->gdbTargetDescriptor = TargetDescriptor(
|
||||||
|
this->targetControllerConsole.getTargetDescriptor()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,11 +26,10 @@ namespace Bloom::DebugServers::Gdb::AvrGdb
|
|||||||
class AvrGdbRsp: public GdbRspDebugServer
|
class AvrGdbRsp: public GdbRspDebugServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit AvrGdbRsp(
|
AvrGdbRsp(
|
||||||
const ProjectConfig& projectConfig,
|
const DebugServerConfig& debugServerConfig,
|
||||||
const EnvironmentConfig& environmentConfig,
|
EventListener& eventListener
|
||||||
const DebugServerConfig& debugServerConfig
|
);
|
||||||
): GdbRspDebugServer(projectConfig, environmentConfig, debugServerConfig) {};
|
|
||||||
|
|
||||||
std::string getName() const override {
|
std::string getName() const override {
|
||||||
return "AVR GDB Remote Serial Protocol Debug Server";
|
return "AVR GDB Remote Serial Protocol Debug Server";
|
||||||
|
|||||||
@@ -9,26 +9,30 @@
|
|||||||
#include "Exceptions/ClientNotSupported.hpp"
|
#include "Exceptions/ClientNotSupported.hpp"
|
||||||
#include "Exceptions/ClientCommunicationError.hpp"
|
#include "Exceptions/ClientCommunicationError.hpp"
|
||||||
#include "Exceptions/DebugSessionAborted.hpp"
|
#include "Exceptions/DebugSessionAborted.hpp"
|
||||||
|
|
||||||
#include "src/Exceptions/Exception.hpp"
|
#include "src/Exceptions/Exception.hpp"
|
||||||
#include "src/Exceptions/InvalidConfig.hpp"
|
#include "src/Exceptions/InvalidConfig.hpp"
|
||||||
|
#include "src/Exceptions/DebugServerInterrupted.hpp"
|
||||||
|
|
||||||
|
#include "ResponsePackets/TargetStopped.hpp"
|
||||||
|
|
||||||
namespace Bloom::DebugServers::Gdb
|
namespace Bloom::DebugServers::Gdb
|
||||||
{
|
{
|
||||||
using namespace CommandPackets;
|
|
||||||
using namespace ResponsePackets;
|
|
||||||
using namespace Exceptions;
|
using namespace Exceptions;
|
||||||
using namespace Bloom::Events;
|
|
||||||
using namespace Bloom::Exceptions;
|
using namespace Bloom::Exceptions;
|
||||||
|
|
||||||
using Bloom::Targets::TargetRegister;
|
GdbRspDebugServer::GdbRspDebugServer(
|
||||||
using Bloom::Targets::TargetRegisterType;
|
const DebugServerConfig& debugServerConfig,
|
||||||
using Bloom::Targets::TargetRegisterDescriptor;
|
EventListener& eventListener
|
||||||
using Bloom::Targets::TargetRegisterDescriptors;
|
)
|
||||||
using Bloom::Targets::TargetBreakpoint;
|
: debugServerConfig(GdbDebugServerConfig(debugServerConfig))
|
||||||
|
, eventListener(eventListener)
|
||||||
|
, interruptEventNotifier(eventListener.getInterruptEventNotifier())
|
||||||
|
{
|
||||||
|
assert(this->interruptEventNotifier != nullptr && this->interruptEventNotifier->isInitialised());
|
||||||
|
}
|
||||||
|
|
||||||
void GdbRspDebugServer::init() {
|
void GdbRspDebugServer::init() {
|
||||||
this->debugServerConfig = GdbDebugServerConfig(DebugServer::debugServerConfig);
|
|
||||||
|
|
||||||
this->socketAddress.sin_family = AF_INET;
|
this->socketAddress.sin_family = AF_INET;
|
||||||
this->socketAddress.sin_port = htons(this->debugServerConfig->listeningPortNumber);
|
this->socketAddress.sin_port = htons(this->debugServerConfig->listeningPortNumber);
|
||||||
|
|
||||||
@@ -83,24 +87,22 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
throw Exception("Failed epoll_ctl server socket");
|
throw Exception("Failed epoll_ctl server socket");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->interruptEventNotifier != nullptr) {
|
const auto interruptFileDescriptor = this->interruptEventNotifier->getFileDescriptor();
|
||||||
auto interruptFileDescriptor = this->interruptEventNotifier->getFileDescriptor();
|
event.events = EPOLLIN;
|
||||||
event.events = EPOLLIN;
|
event.data.fd = interruptFileDescriptor;
|
||||||
event.data.fd = interruptFileDescriptor;
|
|
||||||
|
|
||||||
if (::epoll_ctl(this->eventFileDescriptor, EPOLL_CTL_ADD, interruptFileDescriptor, &event) != 0) {
|
if (::epoll_ctl(this->eventFileDescriptor, EPOLL_CTL_ADD, interruptFileDescriptor, &event) != 0) {
|
||||||
throw Exception("Failed epoll_ctl interrupt event fd");
|
throw Exception("Failed epoll_ctl interrupt event fd");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::info("GDB RSP address: " + this->debugServerConfig->listeningAddress);
|
Logger::info("GDB RSP address: " + this->debugServerConfig->listeningAddress);
|
||||||
Logger::info("GDB RSP port: " + std::to_string(this->debugServerConfig->listeningPortNumber));
|
Logger::info("GDB RSP port: " + std::to_string(this->debugServerConfig->listeningPortNumber));
|
||||||
|
|
||||||
this->eventListener->registerCallbackForEventType<Events::TargetControllerStateReported>(
|
this->eventListener.registerCallbackForEventType<Events::TargetControllerStateReported>(
|
||||||
std::bind(&GdbRspDebugServer::onTargetControllerStateReported, this, std::placeholders::_1)
|
std::bind(&GdbRspDebugServer::onTargetControllerStateReported, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
|
|
||||||
this->eventListener->registerCallbackForEventType<Events::TargetExecutionStopped>(
|
this->eventListener.registerCallbackForEventType<Events::TargetExecutionStopped>(
|
||||||
std::bind(&GdbRspDebugServer::onTargetExecutionStopped, this, std::placeholders::_1)
|
std::bind(&GdbRspDebugServer::onTargetExecutionStopped, this, std::placeholders::_1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -113,7 +115,7 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbRspDebugServer::serve() {
|
void GdbRspDebugServer::run() {
|
||||||
try {
|
try {
|
||||||
if (!this->activeDebugSession.has_value()) {
|
if (!this->activeDebugSession.has_value()) {
|
||||||
Logger::info("Waiting for GDB RSP connection");
|
Logger::info("Waiting for GDB RSP connection");
|
||||||
@@ -131,6 +133,7 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
this->activeDebugSession.emplace(
|
this->activeDebugSession.emplace(
|
||||||
DebugSession(connection.value(), this->getGdbTargetDescriptor())
|
DebugSession(connection.value(), this->getGdbTargetDescriptor())
|
||||||
);
|
);
|
||||||
|
|
||||||
EventManager::triggerEvent(std::make_shared<Events::DebugSessionStarted>());
|
EventManager::triggerEvent(std::make_shared<Events::DebugSessionStarted>());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -205,7 +208,7 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Connection(this->interruptEventNotifier);
|
return Connection(*(this->interruptEventNotifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -229,7 +232,9 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
|
|
||||||
void GdbRspDebugServer::onTargetExecutionStopped(const Events::TargetExecutionStopped&) {
|
void GdbRspDebugServer::onTargetExecutionStopped(const Events::TargetExecutionStopped&) {
|
||||||
if (this->activeDebugSession.has_value() && this->activeDebugSession->waitingForBreak) {
|
if (this->activeDebugSession.has_value() && this->activeDebugSession->waitingForBreak) {
|
||||||
this->activeDebugSession->connection.writePacket(TargetStopped(Signal::TRAP));
|
this->activeDebugSession->connection.writePacket(
|
||||||
|
ResponsePackets::TargetStopped(Signal::TRAP)
|
||||||
|
);
|
||||||
this->activeDebugSession->waitingForBreak = false;
|
this->activeDebugSession->waitingForBreak = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <cstdint>
|
#include <optional>
|
||||||
|
|
||||||
#include "src/DebugServers/DebugServer.hpp"
|
#include "src/DebugServers/ServerInterface.hpp"
|
||||||
|
|
||||||
#include "GdbDebugServerConfig.hpp"
|
#include "GdbDebugServerConfig.hpp"
|
||||||
|
#include "src/EventManager/EventListener.hpp"
|
||||||
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
||||||
|
|
||||||
#include "Connection.hpp"
|
#include "Connection.hpp"
|
||||||
#include "TargetDescriptor.hpp"
|
#include "TargetDescriptor.hpp"
|
||||||
@@ -18,15 +21,11 @@
|
|||||||
#include "Feature.hpp"
|
#include "Feature.hpp"
|
||||||
#include "CommandPackets/CommandPacketFactory.hpp"
|
#include "CommandPackets/CommandPacketFactory.hpp"
|
||||||
|
|
||||||
#include "src/Helpers/EventNotifier.hpp"
|
#include "src/EventManager/Events/TargetControllerStateReported.hpp"
|
||||||
|
#include "src/EventManager/Events/TargetExecutionStopped.hpp"
|
||||||
|
|
||||||
#include "src/Helpers/BiMap.hpp"
|
#include "src/Helpers/BiMap.hpp"
|
||||||
|
|
||||||
#include "src/Targets/TargetRegister.hpp"
|
|
||||||
|
|
||||||
// Response packets
|
|
||||||
#include "ResponsePackets/SupportedFeaturesResponse.hpp"
|
|
||||||
#include "ResponsePackets/TargetStopped.hpp"
|
|
||||||
|
|
||||||
namespace Bloom::DebugServers::Gdb
|
namespace Bloom::DebugServers::Gdb
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -40,22 +39,44 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
*
|
*
|
||||||
* @TODO: This could do with some cleaning.
|
* @TODO: This could do with some cleaning.
|
||||||
*/
|
*/
|
||||||
class GdbRspDebugServer: public DebugServer
|
class GdbRspDebugServer: public ServerInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit GdbRspDebugServer(
|
explicit GdbRspDebugServer(
|
||||||
const ProjectConfig& projectConfig,
|
const DebugServerConfig& debugServerConfig,
|
||||||
const EnvironmentConfig& environmentConfig,
|
EventListener& eventListener
|
||||||
const DebugServerConfig& debugServerConfig
|
);
|
||||||
): DebugServer(projectConfig, environmentConfig, debugServerConfig) {};
|
|
||||||
|
|
||||||
std::string getName() const override {
|
[[nodiscard]] std::string getName() const override {
|
||||||
return "GDB Remote Serial Protocol DebugServer";
|
return "GDB Remote Serial Protocol DebugServer";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the GDB server for listing on the selected address and port.
|
||||||
|
*/
|
||||||
|
void init() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminates any active debug session and closes the listening socket.
|
||||||
|
*/
|
||||||
|
void close() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits for a connection from a GDB client or services an active one.
|
||||||
|
*
|
||||||
|
* This function will return when any blocking operation is interrupted via this->interruptEventNotifier.
|
||||||
|
*/
|
||||||
|
void run() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::optional<GdbDebugServerConfig> debugServerConfig;
|
std::optional<GdbDebugServerConfig> debugServerConfig;
|
||||||
|
|
||||||
|
EventListener& eventListener;
|
||||||
|
|
||||||
|
EventNotifier* interruptEventNotifier = nullptr;
|
||||||
|
|
||||||
|
TargetControllerConsole targetControllerConsole = TargetControllerConsole(this->eventListener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listening socket address
|
* Listening socket address
|
||||||
*/
|
*/
|
||||||
@@ -84,21 +105,6 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
|
|
||||||
std::optional<DebugSession> activeDebugSession;
|
std::optional<DebugSession> activeDebugSession;
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepares the GDB server for listing on the selected address and port.
|
|
||||||
*/
|
|
||||||
void init() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes any client connection as well as the listening socket file descriptor.
|
|
||||||
*/
|
|
||||||
void close() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See DebugServer::serve()
|
|
||||||
*/
|
|
||||||
void serve() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for a GDB client to connect on the listening socket.
|
* Waits for a GDB client to connect on the listening socket.
|
||||||
*
|
*
|
||||||
@@ -110,7 +116,6 @@ namespace Bloom::DebugServers::Gdb
|
|||||||
|
|
||||||
virtual const TargetDescriptor& getGdbTargetDescriptor() = 0;
|
virtual const TargetDescriptor& getGdbTargetDescriptor() = 0;
|
||||||
|
|
||||||
|
|
||||||
void onTargetControllerStateReported(const Events::TargetControllerStateReported& event);
|
void onTargetControllerStateReported(const Events::TargetControllerStateReported& event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
35
src/DebugServers/ServerInterface.hpp
Normal file
35
src/DebugServers/ServerInterface.hpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Bloom::DebugServers
|
||||||
|
{
|
||||||
|
class ServerInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Should return the name of the server.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual std::string getName() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on startup of the DebugServerComponent. The server should implement any initialisation work here.
|
||||||
|
*/
|
||||||
|
virtual void init() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called repeatedly in an infinite loop when the DebugServerComponent is running. The server should serve
|
||||||
|
* from here.
|
||||||
|
*
|
||||||
|
* This function should return when any blocking operation is interrupted via an EventNotifier instance.
|
||||||
|
*/
|
||||||
|
virtual void run() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on shutdown of the DebugServerComponent.
|
||||||
|
*/
|
||||||
|
virtual void close() = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user