2021-10-02 17:39:27 +01:00
|
|
|
#include "GdbRspDebugServer.hpp"
|
|
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
#include <sys/socket.h>
|
2022-04-05 22:37:00 +01:00
|
|
|
#include <unistd.h>
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-08-13 03:06:30 +01:00
|
|
|
#include "src/EventManager/EventManager.hpp"
|
2021-10-06 21:12:31 +01:00
|
|
|
#include "src/Logger/Logger.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
|
|
|
|
|
#include "Exceptions/ClientDisconnected.hpp"
|
|
|
|
|
#include "Exceptions/ClientNotSupported.hpp"
|
|
|
|
|
#include "Exceptions/ClientCommunicationError.hpp"
|
2022-11-17 00:13:12 +00:00
|
|
|
#include "Exceptions/DebugSessionInitialisationFailure.hpp"
|
2022-11-18 20:26:20 +00:00
|
|
|
#include "Exceptions/DebugServerInterrupted.hpp"
|
2022-03-27 18:32:13 +01:00
|
|
|
|
2021-04-04 21:04:12 +01:00
|
|
|
#include "src/Exceptions/Exception.hpp"
|
|
|
|
|
#include "src/Exceptions/InvalidConfig.hpp"
|
2022-03-27 18:32:13 +01:00
|
|
|
|
2022-03-27 19:43:20 +01:00
|
|
|
// Command packets
|
|
|
|
|
#include "CommandPackets/CommandPacket.hpp"
|
|
|
|
|
#include "CommandPackets/SupportedFeaturesQuery.hpp"
|
|
|
|
|
#include "CommandPackets/InterruptExecution.hpp"
|
|
|
|
|
#include "CommandPackets/ContinueExecution.hpp"
|
|
|
|
|
#include "CommandPackets/StepExecution.hpp"
|
|
|
|
|
#include "CommandPackets/SetBreakpoint.hpp"
|
|
|
|
|
#include "CommandPackets/RemoveBreakpoint.hpp"
|
2022-04-08 22:18:52 +01:00
|
|
|
#include "CommandPackets/Monitor.hpp"
|
2022-04-08 22:23:30 +01:00
|
|
|
#include "CommandPackets/ResetTarget.hpp"
|
2022-05-05 20:14:59 +01:00
|
|
|
#include "CommandPackets/HelpMonitorInfo.hpp"
|
2022-05-05 20:13:30 +01:00
|
|
|
#include "CommandPackets/BloomVersion.hpp"
|
2022-05-05 20:14:23 +01:00
|
|
|
#include "CommandPackets/BloomVersionMachine.hpp"
|
2022-09-15 00:33:01 +01:00
|
|
|
#include "CommandPackets/Detach.hpp"
|
2024-08-26 12:38:31 +01:00
|
|
|
#include "CommandPackets/ReadRegistersMonitor.hpp"
|
2022-03-27 19:43:20 +01:00
|
|
|
|
2023-05-24 23:15:47 +01:00
|
|
|
#ifndef EXCLUDE_INSIGHT
|
|
|
|
|
#include "CommandPackets/ActivateInsight.hpp"
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-03-27 19:43:20 +01:00
|
|
|
// Response packets
|
2022-03-27 18:32:13 +01:00
|
|
|
#include "ResponsePackets/TargetStopped.hpp"
|
2022-12-26 21:35:24 +00:00
|
|
|
|
|
|
|
|
#include "src/Services/ProcessService.hpp"
|
2023-09-10 22:27:10 +01:00
|
|
|
#include "src/Services/StringService.hpp"
|
2021-04-04 21:04:12 +01:00
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
namespace DebugServer::Gdb
|
2022-02-05 15:32:08 +00:00
|
|
|
{
|
|
|
|
|
using namespace Exceptions;
|
2023-08-13 15:47:51 +01:00
|
|
|
using namespace ::Exceptions;
|
2022-02-05 15:32:08 +00:00
|
|
|
|
2022-03-27 19:43:20 +01:00
|
|
|
using CommandPackets::CommandPacket;
|
|
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
GdbRspDebugServer::GdbRspDebugServer(
|
|
|
|
|
const DebugServerConfig& debugServerConfig,
|
2024-07-23 21:14:22 +01:00
|
|
|
const Targets::TargetDescriptor& targetDescriptor,
|
2022-04-15 22:05:50 +01:00
|
|
|
EventListener& eventListener,
|
|
|
|
|
EventFdNotifier& eventNotifier
|
2022-03-27 18:32:13 +01:00
|
|
|
)
|
|
|
|
|
: debugServerConfig(GdbDebugServerConfig(debugServerConfig))
|
2024-07-23 21:14:22 +01:00
|
|
|
, targetDescriptor(targetDescriptor)
|
2022-03-27 18:32:13 +01:00
|
|
|
, eventListener(eventListener)
|
2022-04-15 22:05:50 +01:00
|
|
|
, interruptEventNotifier(eventNotifier)
|
|
|
|
|
{}
|
2022-02-05 15:32:08 +00:00
|
|
|
|
|
|
|
|
void GdbRspDebugServer::init() {
|
|
|
|
|
this->socketAddress.sin_family = AF_INET;
|
2022-04-05 18:49:54 +01:00
|
|
|
this->socketAddress.sin_port = htons(this->debugServerConfig.listeningPortNumber);
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (
|
|
|
|
|
::inet_pton(
|
2022-03-19 15:16:59 +00:00
|
|
|
AF_INET,
|
2022-04-05 18:49:54 +01:00
|
|
|
this->debugServerConfig.listeningAddress.c_str(),
|
2022-03-19 15:16:59 +00:00
|
|
|
&(this->socketAddress.sin_addr)
|
|
|
|
|
) == 0
|
|
|
|
|
) {
|
2022-02-05 15:32:08 +00:00
|
|
|
// Invalid IP address
|
2024-07-23 21:14:22 +01:00
|
|
|
throw InvalidConfig{
|
|
|
|
|
"Invalid IP address provided in config file: (\"" + this->debugServerConfig.listeningAddress + "\")"
|
|
|
|
|
};
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
auto socketFileDescriptor = int{0};
|
2022-02-05 15:32:08 +00:00
|
|
|
if ((socketFileDescriptor = ::socket(AF_INET, SOCK_STREAM, 0)) == 0) {
|
2024-07-23 21:14:22 +01:00
|
|
|
throw Exception{"Failed to create socket file descriptor."};
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto enableReuseAddressSocketOption = int{1};
|
|
|
|
|
if (
|
|
|
|
|
::setsockopt(
|
2022-02-05 15:32:08 +00:00
|
|
|
socketFileDescriptor,
|
|
|
|
|
SOL_SOCKET,
|
|
|
|
|
SO_REUSEADDR,
|
2022-04-05 18:49:54 +01:00
|
|
|
&(enableReuseAddressSocketOption),
|
|
|
|
|
sizeof(enableReuseAddressSocketOption)
|
2022-02-05 15:32:08 +00:00
|
|
|
) < 0
|
|
|
|
|
) {
|
|
|
|
|
Logger::error("Failed to set socket SO_REUSEADDR option.");
|
|
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (
|
|
|
|
|
::bind(
|
2022-02-05 15:32:08 +00:00
|
|
|
socketFileDescriptor,
|
|
|
|
|
reinterpret_cast<const sockaddr*>(&(this->socketAddress)),
|
|
|
|
|
sizeof(this->socketAddress)
|
|
|
|
|
) < 0
|
|
|
|
|
) {
|
2024-07-23 21:14:22 +01:00
|
|
|
throw Exception{
|
|
|
|
|
"Failed to bind address. The selected port number ("
|
|
|
|
|
+ std::to_string(this->debugServerConfig.listeningPortNumber) + ") may be in use."
|
|
|
|
|
};
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-02-05 15:32:08 +00:00
|
|
|
this->serverSocketFileDescriptor = socketFileDescriptor;
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-03-28 01:04:14 +01:00
|
|
|
this->epollInstance.addEntry(
|
2022-04-05 18:49:54 +01:00
|
|
|
this->serverSocketFileDescriptor.value(),
|
2022-09-26 21:21:57 +01:00
|
|
|
static_cast<std::uint16_t>(::EPOLL_EVENTS::EPOLLIN)
|
2022-03-28 01:04:14 +01:00
|
|
|
);
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-03-28 01:04:14 +01:00
|
|
|
this->epollInstance.addEntry(
|
2022-04-15 22:05:50 +01:00
|
|
|
this->interruptEventNotifier.getFileDescriptor(),
|
2022-09-26 21:21:57 +01:00
|
|
|
static_cast<std::uint16_t>(::EPOLL_EVENTS::EPOLLIN)
|
2022-03-28 01:04:14 +01:00
|
|
|
);
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-04-05 18:49:54 +01:00
|
|
|
Logger::info("GDB RSP address: " + this->debugServerConfig.listeningAddress);
|
|
|
|
|
Logger::info("GDB RSP port: " + std::to_string(this->debugServerConfig.listeningPortNumber));
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
this->eventListener.registerCallbackForEventType<Events::TargetStateChanged>(
|
|
|
|
|
std::bind(&GdbRspDebugServer::onTargetStateChanged, this, std::placeholders::_1)
|
2023-05-07 19:44:19 +01:00
|
|
|
);
|
|
|
|
|
|
2022-12-26 21:35:24 +00:00
|
|
|
if (Services::ProcessService::isManagedByClion()) {
|
2022-09-15 00:33:01 +01:00
|
|
|
Logger::warning(
|
|
|
|
|
"Bloom's process is being managed by CLion - Bloom will automatically shutdown upon detaching from GDB."
|
|
|
|
|
);
|
|
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
}
|
|
|
|
|
|
2022-02-05 15:32:08 +00:00
|
|
|
void GdbRspDebugServer::close() {
|
2023-09-10 22:27:10 +01:00
|
|
|
this->endDebugSession();
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-04-05 18:49:54 +01:00
|
|
|
if (this->serverSocketFileDescriptor.has_value()) {
|
|
|
|
|
::close(this->serverSocketFileDescriptor.value());
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-03-27 18:32:13 +01:00
|
|
|
void GdbRspDebugServer::run() {
|
2022-02-05 15:32:08 +00:00
|
|
|
try {
|
2023-09-10 22:27:10 +01:00
|
|
|
if (this->getActiveDebugSession() == nullptr) {
|
2022-02-05 15:32:08 +00:00
|
|
|
Logger::info("Waiting for GDB RSP connection");
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-03-24 19:17:41 +00:00
|
|
|
auto connection = this->waitForConnection();
|
2022-11-18 20:26:20 +00:00
|
|
|
Logger::info("Accepted GDP RSP connection from " + connection.getIpAddress());
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2023-09-10 22:27:10 +01:00
|
|
|
this->startDebugSession(std::move(connection));
|
2022-03-27 18:32:13 +01:00
|
|
|
|
2022-12-26 21:27:19 +00:00
|
|
|
this->targetControllerService.stopTargetExecution();
|
|
|
|
|
this->targetControllerService.resetTarget();
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-12-10 19:23:06 +00:00
|
|
|
const auto commandPacket = this->waitForCommandPacket();
|
2022-11-18 20:26:20 +00:00
|
|
|
if (commandPacket) {
|
2024-07-23 21:14:22 +01:00
|
|
|
commandPacket->handle(
|
|
|
|
|
*(this->getActiveDebugSession()),
|
|
|
|
|
this->getGdbTargetDescriptor(),
|
|
|
|
|
this->targetDescriptor,
|
|
|
|
|
this->targetControllerService
|
|
|
|
|
);
|
2022-03-27 19:43:20 +01:00
|
|
|
}
|
|
|
|
|
|
2022-02-05 15:32:08 +00:00
|
|
|
} catch (const ClientDisconnected&) {
|
|
|
|
|
Logger::info("GDB RSP client disconnected");
|
2023-09-10 22:27:10 +01:00
|
|
|
this->endDebugSession();
|
2022-02-05 15:32:08 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
} catch (const ClientCommunicationError& exception) {
|
|
|
|
|
Logger::error(
|
|
|
|
|
"GDB RSP client communication error - " + exception.getMessage() + " - closing connection"
|
|
|
|
|
);
|
2023-09-10 22:27:10 +01:00
|
|
|
this->endDebugSession();
|
2022-02-05 15:32:08 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
} catch (const ClientNotSupported& exception) {
|
|
|
|
|
Logger::error("Invalid GDB RSP client - " + exception.getMessage() + " - closing connection");
|
2023-09-10 22:27:10 +01:00
|
|
|
this->endDebugSession();
|
2022-02-05 15:32:08 +00:00
|
|
|
return;
|
|
|
|
|
|
2022-11-17 00:13:12 +00:00
|
|
|
} catch (const DebugSessionInitialisationFailure& exception) {
|
|
|
|
|
Logger::warning("GDB debug session initialisation failure - " + exception.getMessage());
|
2023-09-10 22:27:10 +01:00
|
|
|
this->endDebugSession();
|
2022-02-05 15:32:08 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
} catch (const DebugServerInterrupted&) {
|
2022-11-18 20:26:20 +00:00
|
|
|
// Server was interrupted by an event
|
2022-02-05 15:32:08 +00:00
|
|
|
Logger::debug("GDB RSP interrupted");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-11-18 20:26:20 +00:00
|
|
|
Connection GdbRspDebugServer::waitForConnection() {
|
2022-04-05 18:49:54 +01:00
|
|
|
if (::listen(this->serverSocketFileDescriptor.value(), 3) != 0) {
|
2024-07-23 21:14:22 +01:00
|
|
|
throw Exception{"Failed to listen on server socket"};
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
|
2022-03-28 01:04:14 +01:00
|
|
|
const auto eventFileDescriptor = this->epollInstance.waitForEvent();
|
|
|
|
|
if (
|
|
|
|
|
!eventFileDescriptor.has_value()
|
2024-07-23 21:14:22 +01:00
|
|
|
|| *eventFileDescriptor == this->interruptEventNotifier.getFileDescriptor()
|
2022-03-28 01:04:14 +01:00
|
|
|
) {
|
2022-04-15 22:05:50 +01:00
|
|
|
this->interruptEventNotifier.clear();
|
2024-07-23 21:14:22 +01:00
|
|
|
throw DebugServerInterrupted{};
|
2022-03-24 19:17:41 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
return {this->serverSocketFileDescriptor.value(), this->interruptEventNotifier};
|
2022-03-24 19:17:41 +00:00
|
|
|
}
|
|
|
|
|
|
2022-03-27 19:43:20 +01:00
|
|
|
std::unique_ptr<CommandPacket> GdbRspDebugServer::waitForCommandPacket() {
|
2023-09-10 22:27:10 +01:00
|
|
|
auto* debugSession = this->getActiveDebugSession();
|
|
|
|
|
const auto rawPackets = debugSession->connection.readRawPackets();
|
2024-07-23 21:14:22 +01:00
|
|
|
assert(!rawPackets.empty());
|
2022-03-27 19:43:20 +01:00
|
|
|
|
2022-11-18 20:26:20 +00:00
|
|
|
if (rawPackets.size() > 1) {
|
2023-05-07 19:44:19 +01:00
|
|
|
const auto& firstRawPacket = rawPackets.front();
|
|
|
|
|
|
|
|
|
|
if (firstRawPacket.size() == 5 && firstRawPacket[1] == 0x03) {
|
|
|
|
|
// Interrupt packet that came in too quickly before another packet
|
2023-09-10 22:27:10 +01:00
|
|
|
debugSession->pendingInterrupt = true;
|
2023-05-07 19:44:19 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
} else {
|
|
|
|
|
Logger::warning("Multiple packets received from GDB - only the most recent will be processed");
|
|
|
|
|
}
|
2022-03-27 19:43:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this->resolveCommandPacket(rawPackets.back());
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-01 21:01:37 +01:00
|
|
|
std::unique_ptr<CommandPacket> GdbRspDebugServer::resolveCommandPacket(const RawPacket& rawPacket) {
|
2024-07-23 21:14:22 +01:00
|
|
|
if (rawPacket.size() < 2) {
|
|
|
|
|
throw Exception{"Invalid raw packet - no data"};
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-27 19:43:20 +01:00
|
|
|
if (rawPacket.size() == 5 && rawPacket[1] == 0x03) {
|
2022-04-16 21:23:03 +01:00
|
|
|
// Interrupt request
|
2022-03-27 19:43:20 +01:00
|
|
|
return std::make_unique<CommandPackets::InterruptExecution>(rawPacket);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (rawPacket[1] == 'c') {
|
|
|
|
|
return std::make_unique<CommandPackets::ContinueExecution>(rawPacket);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rawPacket[1] == 's') {
|
|
|
|
|
return std::make_unique<CommandPackets::StepExecution>(rawPacket);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rawPacket[1] == 'Z') {
|
|
|
|
|
return std::make_unique<CommandPackets::SetBreakpoint>(rawPacket);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rawPacket[1] == 'z') {
|
|
|
|
|
return std::make_unique<CommandPackets::RemoveBreakpoint>(rawPacket);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-15 00:33:01 +01:00
|
|
|
if (rawPacket[1] == 'D') {
|
|
|
|
|
return std::make_unique<CommandPackets::Detach>(rawPacket);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto rawPacketString = std::string{rawPacket.begin() + 1, rawPacket.end()};
|
2022-03-27 19:43:20 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
/*
|
|
|
|
|
* First byte of the raw packet will be 0x24 ('$'), so std::string::find() should return 1, not 0, when
|
|
|
|
|
* looking for a command identifier string.
|
|
|
|
|
*/
|
|
|
|
|
if (rawPacketString.find("qSupported") == 0) {
|
|
|
|
|
return std::make_unique<CommandPackets::SupportedFeaturesQuery>(rawPacket);
|
|
|
|
|
}
|
2022-03-27 19:43:20 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (rawPacketString.find("qRcmd") == 0) {
|
|
|
|
|
// This is a monitor packet
|
|
|
|
|
auto monitorCommand = std::make_unique<CommandPackets::Monitor>(rawPacket);
|
2022-03-27 19:43:20 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (monitorCommand->command == "help") {
|
|
|
|
|
return std::make_unique<CommandPackets::HelpMonitorInfo>(std::move(*(monitorCommand.release())));
|
2022-03-27 19:43:20 +01:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (monitorCommand->command == "version") {
|
|
|
|
|
return std::make_unique<CommandPackets::BloomVersion>(std::move(*(monitorCommand.release())));
|
2022-03-27 19:43:20 +01:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (monitorCommand->command == "version machine") {
|
|
|
|
|
return std::make_unique<CommandPackets::BloomVersionMachine>(std::move(*(monitorCommand.release())));
|
2022-03-27 19:43:20 +01:00
|
|
|
}
|
2022-04-08 22:18:52 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (monitorCommand->command == "reset") {
|
|
|
|
|
return std::make_unique<CommandPackets::ResetTarget>(std::move(*(monitorCommand.release())));
|
|
|
|
|
}
|
2022-05-06 19:31:33 +01:00
|
|
|
|
2024-08-26 12:38:31 +01:00
|
|
|
if (monitorCommand->command.find("rr") == 0) {
|
|
|
|
|
return std::make_unique<CommandPackets::ReadRegistersMonitor>(std::move(*(monitorCommand.release())));
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-24 23:15:47 +01:00
|
|
|
#ifndef EXCLUDE_INSIGHT
|
2024-07-23 21:14:22 +01:00
|
|
|
if (monitorCommand->command.find("insight") == 0) {
|
|
|
|
|
return std::make_unique<CommandPackets::ActivateInsight>(std::move(*(monitorCommand.release())));
|
2022-04-08 22:18:52 +01:00
|
|
|
}
|
2024-07-23 21:14:22 +01:00
|
|
|
#endif
|
|
|
|
|
return monitorCommand;
|
2022-03-27 19:43:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return std::make_unique<CommandPacket>(rawPacket);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
void GdbRspDebugServer::onTargetStateChanged(const Events::TargetStateChanged& event) {
|
|
|
|
|
using Targets::TargetExecutionState;
|
2023-09-10 22:27:10 +01:00
|
|
|
|
|
|
|
|
auto* debugSession = this->getActiveDebugSession();
|
2024-07-23 21:14:22 +01:00
|
|
|
if (debugSession == nullptr) {
|
2022-04-16 21:21:29 +01:00
|
|
|
return;
|
2024-07-23 21:14:22 +01:00
|
|
|
}
|
2022-04-16 21:21:29 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
if (event.newState.executionState == event.previousState.executionState) {
|
|
|
|
|
// Execution state hasn't changed. Probably just a mode change. Ignore...
|
2022-04-16 21:21:29 +01:00
|
|
|
return;
|
2022-02-05 15:32:08 +00:00
|
|
|
}
|
2023-05-07 19:44:19 +01:00
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
const auto executionState = event.newState.executionState.load();
|
2023-05-07 19:44:19 +01:00
|
|
|
|
2023-09-10 22:27:10 +01:00
|
|
|
try {
|
2024-07-23 21:14:22 +01:00
|
|
|
if (executionState == TargetExecutionState::STOPPED && debugSession->waitingForBreak) {
|
|
|
|
|
this->handleTargetStoppedGdbResponse(event.newState.programCounter.load().value());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (executionState == TargetExecutionState::RUNNING || executionState == TargetExecutionState::STEPPING) {
|
2023-09-10 22:27:10 +01:00
|
|
|
this->handleTargetResumedGdbResponse();
|
2024-07-23 21:14:22 +01:00
|
|
|
return;
|
2023-05-07 19:44:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (const ClientDisconnected&) {
|
|
|
|
|
Logger::info("GDB RSP client disconnected");
|
2023-09-10 22:27:10 +01:00
|
|
|
this->endDebugSession();
|
2023-05-07 19:44:19 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
} catch (const ClientCommunicationError& exception) {
|
|
|
|
|
Logger::error(
|
|
|
|
|
"GDB RSP client communication error - " + exception.getMessage() + " - closing connection"
|
|
|
|
|
);
|
2023-09-10 22:27:10 +01:00
|
|
|
this->endDebugSession();
|
2023-05-07 19:44:19 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
} catch (const DebugServerInterrupted&) {
|
|
|
|
|
// Server was interrupted
|
|
|
|
|
Logger::debug("GDB RSP interrupted");
|
|
|
|
|
return;
|
2023-08-30 20:47:11 +01:00
|
|
|
|
|
|
|
|
} catch (const Exception& exception) {
|
2024-07-23 21:14:22 +01:00
|
|
|
Logger::error("Failed to handle target execution stopped event - " + exception.getMessage());
|
2023-09-10 22:27:10 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 00:40:30 +01:00
|
|
|
void GdbRspDebugServer::handleTargetStoppedGdbResponse(Targets::TargetMemoryAddress programAddress) {
|
2023-09-10 22:27:10 +01:00
|
|
|
auto* debugSession = this->getActiveDebugSession();
|
|
|
|
|
|
|
|
|
|
if (debugSession->activeRangeSteppingSession.has_value()) {
|
|
|
|
|
debugSession->terminateRangeSteppingSession(this->targetControllerService);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
debugSession->connection.writePacket(ResponsePackets::TargetStopped{Signal::TRAP});
|
2023-09-10 22:27:10 +01:00
|
|
|
debugSession->waitingForBreak = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GdbRspDebugServer::handleTargetResumedGdbResponse() {
|
|
|
|
|
auto* debugSession = this->getActiveDebugSession();
|
|
|
|
|
|
|
|
|
|
if (debugSession->waitingForBreak && debugSession->pendingInterrupt) {
|
|
|
|
|
Logger::info("Servicing pending interrupt");
|
|
|
|
|
this->targetControllerService.stopTargetExecution();
|
|
|
|
|
|
|
|
|
|
if (debugSession->activeRangeSteppingSession.has_value()) {
|
|
|
|
|
debugSession->terminateRangeSteppingSession(this->targetControllerService);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 21:14:22 +01:00
|
|
|
debugSession->connection.writePacket(ResponsePackets::TargetStopped{Signal::INTERRUPTED});
|
2023-09-10 22:27:10 +01:00
|
|
|
debugSession->pendingInterrupt = false;
|
|
|
|
|
debugSession->waitingForBreak = false;
|
2023-05-07 19:44:19 +01:00
|
|
|
}
|
|
|
|
|
}
|
2021-10-06 21:12:31 +01:00
|
|
|
}
|