2021-04-04 21:04:12 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
|
2021-04-24 20:23:17 +01:00
|
|
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
#include "src/EventManager/Events/Events.hpp"
|
|
|
|
|
#include "src/EventManager/EventManager.hpp"
|
|
|
|
|
#include "src/Exceptions/DebugServerInterrupted.hpp"
|
|
|
|
|
#include "src/ApplicationConfig.hpp"
|
|
|
|
|
#include "src/Helpers/Thread.hpp"
|
2021-08-07 17:22:59 +01:00
|
|
|
#include "src/Targets/TargetDescriptor.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
#include "src/Targets/TargetRegister.hpp"
|
|
|
|
|
#include "src/Targets/TargetBreakpoint.hpp"
|
|
|
|
|
|
|
|
|
|
namespace Bloom::DebugServers
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* The DebugServer exposes the connected target to third-party debugging software such as IDEs.
|
|
|
|
|
* The DebugServer runs on a dedicated thread which is kicked off shortly after the TargetController has been
|
|
|
|
|
* started.
|
|
|
|
|
*
|
|
|
|
|
* All supported DebugServers should be derived from this class.
|
|
|
|
|
*
|
|
|
|
|
* Bloom currently only supports one DebugServer - the GdbRspDebugServer.
|
|
|
|
|
*/
|
|
|
|
|
class DebugServer: public Thread
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
/**
|
|
|
|
|
* Prepares the debug server thread and then calls init().
|
|
|
|
|
*
|
|
|
|
|
* Derived classes should not override this method - they should instead use init().
|
|
|
|
|
*/
|
|
|
|
|
void startup();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calls close() and updates the thread state.
|
|
|
|
|
*
|
|
|
|
|
* As with startup(), derived classes should not override this method. They should use close() instead.
|
|
|
|
|
*/
|
|
|
|
|
void shutdown();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Updates the state of the DebugServer and emits a state changed event.
|
|
|
|
|
*
|
|
|
|
|
* @param state
|
|
|
|
|
* @param emitEvent
|
|
|
|
|
*/
|
2021-05-29 21:39:00 +01:00
|
|
|
void setThreadStateAndEmitEvent(ThreadState state) {
|
|
|
|
|
Thread::setThreadState(state);
|
2021-04-04 21:04:12 +01:00
|
|
|
this->eventManager.triggerEvent(
|
2021-05-24 21:09:50 +01:00
|
|
|
std::make_shared<Events::DebugServerThreadStateChanged>(state)
|
2021-04-04 21:04:12 +01:00
|
|
|
);
|
2021-05-29 21:39:00 +01:00
|
|
|
}
|
2021-04-04 21:04:12 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles a shutdown request.
|
|
|
|
|
*
|
|
|
|
|
* @param event
|
|
|
|
|
*/
|
2021-06-22 14:44:00 +01:00
|
|
|
void onShutdownDebugServerEvent(const Events::ShutdownDebugServer& event);
|
2021-04-04 21:04:12 +01:00
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
/**
|
|
|
|
|
* Application-wide instance to EventManager
|
|
|
|
|
*/
|
|
|
|
|
EventManager& eventManager;
|
|
|
|
|
EventListenerPointer eventListener = std::make_shared<EventListener>("DebugServerEventListener");
|
|
|
|
|
|
2021-04-24 20:23:17 +01:00
|
|
|
TargetControllerConsole targetControllerConsole = TargetControllerConsole(
|
|
|
|
|
this->eventManager,
|
|
|
|
|
*(this->eventListener)
|
|
|
|
|
);
|
|
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
/**
|
|
|
|
|
* Enables the interruption of any blocking file IO.
|
|
|
|
|
*/
|
|
|
|
|
std::shared_ptr<EventNotifier> interruptEventNotifier = nullptr;
|
|
|
|
|
|
|
|
|
|
ApplicationConfig applicationConfig;
|
|
|
|
|
EnvironmentConfig environmentConfig;
|
|
|
|
|
DebugServerConfig debugServerConfig;
|
|
|
|
|
|
2021-08-07 17:22:59 +01:00
|
|
|
Targets::TargetDescriptor targetDescriptor;
|
|
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
|
|
|
|
|
public:
|
2021-06-22 23:52:31 +01:00
|
|
|
explicit DebugServer(EventManager& eventManager): eventManager(eventManager) {};
|
2021-04-04 21:04:12 +01:00
|
|
|
|
|
|
|
|
void setApplicationConfig(const ApplicationConfig& applicationConfig) {
|
|
|
|
|
this->applicationConfig = applicationConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setEnvironmentConfig(const EnvironmentConfig& environmentConfig) {
|
|
|
|
|
this->environmentConfig = environmentConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setDebugServerConfig(const DebugServerConfig& debugServerConfig) {
|
|
|
|
|
this->debugServerConfig = debugServerConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Entry point for the DebugServer. This must called from a dedicated thread.
|
|
|
|
|
*/
|
|
|
|
|
void run();
|
|
|
|
|
|
|
|
|
|
virtual std::string getName() const = 0;
|
|
|
|
|
|
|
|
|
|
virtual ~DebugServer() = default;
|
|
|
|
|
};
|
|
|
|
|
}
|