Replaced static TargetController state object access with new GetState command

This corrects a bug where the DebugServer checks if the TargetController is in
service just before it's about to suspend. The DebugServer then attempts to start
a new debug session, only for the TargetController to go into a suspended state.
A fatal error occurs and a shutdown follows. This bug is only apparent when
the user stops and starts debug sessions very quickly, with releasePostDebugSession
set to true.
This commit is contained in:
Nav
2022-08-14 17:44:52 +01:00
parent 0665ef2927
commit c4bcf71424
7 changed files with 73 additions and 10 deletions

View File

@@ -7,6 +7,7 @@ namespace Bloom::TargetController::Commands
enum class CommandType: std::uint8_t
{
GENERIC,
GET_STATE,
GET_TARGET_DESCRIPTOR,
STOP_TARGET_EXECUTION,
RESUME_TARGET_EXECUTION,

View File

@@ -0,0 +1,29 @@
#pragma once
#include "Command.hpp"
#include "src/TargetController/Responses/State.hpp"
namespace Bloom::TargetController::Commands
{
class GetState: public Command
{
public:
using SuccessResponseType = Responses::State;
static constexpr CommandType type = CommandType::GET_STATE;
static inline const std::string name = "GetState";
[[nodiscard]] CommandType getType() const override {
return GetState::type;
}
[[nodiscard]] bool requiresActiveState() const override {
return false;
}
[[nodiscard]] bool requiresDebugMode() const override {
return false;
}
};
}

View File

@@ -8,6 +8,7 @@ namespace Bloom::TargetController::Responses
{
GENERIC,
ERROR,
STATE,
TARGET_DESCRIPTOR,
TARGET_REGISTERS_READ,
TARGET_MEMORY_READ,

View File

@@ -0,0 +1,24 @@
#pragma once
#include "Response.hpp"
#include "src/TargetController/TargetControllerState.hpp"
namespace Bloom::TargetController::Responses
{
class State: public Response
{
public:
static constexpr ResponseType type = ResponseType::STATE;
TargetControllerState state;
explicit State(TargetControllerState state)
: state(state)
{}
[[nodiscard]] ResponseType getType() const override {
return State::type;
}
};
}

View File

@@ -23,6 +23,7 @@ namespace Bloom::TargetController
using Commands::CommandIdType;
using Commands::Command;
using Commands::GetState;
using Commands::GetTargetDescriptor;
using Commands::GetTargetState;
using Commands::StopTargetExecution;
@@ -109,10 +110,6 @@ namespace Bloom::TargetController
this->shutdown();
}
TargetControllerState TargetControllerComponent::getState() {
return TargetControllerComponent::state;
}
void TargetControllerComponent::registerCommand(std::unique_ptr<Command> command) {
auto commandQueueLock = TargetControllerComponent::commandQueue.acquireLock();
TargetControllerComponent::commandQueue.getValue().push(std::move(command));
@@ -171,6 +168,9 @@ namespace Bloom::TargetController
TargetControllerComponent::checkUdevRules();
// Register command handlers
this->registerCommandHandler<GetState>(
std::bind(&TargetControllerComponent::handleGetState, this, std::placeholders::_1)
);
this->registerCommandHandler<GetTargetDescriptor>(
std::bind(&TargetControllerComponent::handleGetTargetDescriptor, this, std::placeholders::_1)
@@ -761,6 +761,10 @@ namespace Bloom::TargetController
}
}
std::unique_ptr<Responses::State> TargetControllerComponent::handleGetState(GetState& command) {
return std::make_unique<Responses::State>(this->state);
}
std::unique_ptr<Responses::TargetDescriptor> TargetControllerComponent::handleGetTargetDescriptor(
GetTargetDescriptor& command
) {

View File

@@ -20,6 +20,7 @@
// Commands
#include "Commands/Command.hpp"
#include "Commands/GetState.hpp"
#include "Commands/GetTargetDescriptor.hpp"
#include "Commands/GetTargetState.hpp"
#include "Commands/StopTargetExecution.hpp"
@@ -42,6 +43,7 @@
// Responses
#include "Responses/Response.hpp"
#include "Responses/State.hpp"
#include "Responses/TargetDescriptor.hpp"
#include "Responses/TargetState.hpp"
#include "Responses/TargetRegistersRead.hpp"
@@ -86,8 +88,6 @@ namespace Bloom::TargetController
*/
void run();
static TargetControllerState getState();
static void registerCommand(std::unique_ptr<Commands::Command> command);
static std::optional<std::unique_ptr<Responses::Response>> waitForResponse(
@@ -111,7 +111,7 @@ namespace Bloom::TargetController
* The TC starts off in a suspended state. TargetControllerComponent::resume() is invoked from the startup
* routine.
*/
static inline std::atomic<TargetControllerState> state = TargetControllerState::SUSPENDED;
TargetControllerState state = TargetControllerState::SUSPENDED;
ProjectConfig projectConfig;
EnvironmentConfig environmentConfig;
@@ -334,6 +334,7 @@ namespace Bloom::TargetController
void onDebugSessionFinishedEvent(const Events::DebugSessionFinished& event);
// Command handlers
std::unique_ptr<Responses::State> handleGetState(Commands::GetState& command);
std::unique_ptr<Responses::TargetDescriptor> handleGetTargetDescriptor(Commands::GetTargetDescriptor& command);
std::unique_ptr<Responses::TargetState> handleGetTargetState(Commands::GetTargetState& command);
std::unique_ptr<Responses::Response> handleStopTargetExecution(Commands::StopTargetExecution& command);

View File

@@ -1,8 +1,7 @@
#include "TargetControllerConsole.hpp"
#include "TargetControllerComponent.hpp"
// Commands
#include "Commands/GetState.hpp"
#include "Commands/GetTargetDescriptor.hpp"
#include "Commands/GetTargetState.hpp"
#include "Commands/StopTargetExecution.hpp"
@@ -25,6 +24,7 @@
namespace Bloom::TargetController
{
using Commands::GetState;
using Commands::GetTargetDescriptor;
using Commands::GetTargetState;
using Commands::StopTargetExecution;
@@ -62,7 +62,10 @@ namespace Bloom::TargetController
using Targets::TargetPinStateMappingType;
TargetControllerState TargetControllerConsole::getTargetControllerState() {
return TargetControllerComponent::getState();
return this->commandManager.sendCommandAndWaitForResponse(
std::make_unique<GetState>(),
this->defaultTimeout
)->state;
}
bool TargetControllerConsole::isTargetControllerInService() noexcept {