GDBStub: Refactor the whole code

This commit is contained in:
aldelaro5
2021-10-21 08:26:50 -04:00
parent 94a0f416eb
commit 1b92f81379
8 changed files with 279 additions and 333 deletions
+5 -4
View File
@@ -318,7 +318,8 @@ static void CPUSetInitialExecutionState(bool force_paused = false)
// The CPU starts in stepping state, and will wait until a new state is set before executing.
// SetState must be called on the host thread, so we defer it for later.
QueueHostJob([force_paused]() {
SetState(SConfig::GetInstance().bBootToPause || force_paused ? State::Paused : State::Running);
bool paused = SConfig::GetInstance().bBootToPause || force_paused;
SetState(paused ? State::Paused : State::Running);
Host_UpdateDisasmDialog();
Host_UpdateMainFrame();
Host_Message(HostMessageID::WMUserCreate);
@@ -390,9 +391,9 @@ static void CpuThread(const std::optional<std::string>& savestate_path, bool del
if (_CoreParameter.bFastmem)
EMM::UninstallExceptionHandler();
if (gdb_active())
if (GDBStub::IsActive())
{
gdb_deinit();
GDBStub::Deinit();
INFO_LOG_FMT(GDB_STUB, "Killed by CPU shutdown");
return;
}
@@ -657,7 +658,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
}
INFO_LOG_FMT(CONSOLE, "{}", StopMessage(true, "Stopping GDB ..."));
gdb_deinit();
GDBStub::Deinit();
INFO_LOG_FMT(CONSOLE, "{}", StopMessage(true, "GDB stopped."));
}
+20 -5
View File
@@ -97,6 +97,7 @@ void Run()
s_state_cpu_cvar.wait(state_lock, [] { return !s_state_paused_and_locked; });
ExecutePendingJobs(state_lock);
Common::Event gdb_step_sync_event;
switch (s_state)
{
case State::Running:
@@ -130,16 +131,24 @@ void Run()
case State::Stepping:
// Wait for step command.
s_state_cpu_cvar.wait(state_lock, [&state_lock] {
s_state_cpu_cvar.wait(state_lock, [&state_lock, &gdb_step_sync_event] {
ExecutePendingJobs(state_lock);
state_lock.unlock();
if (gdb_active() && gdb_hasControl())
if (GDBStub::IsActive() && GDBStub::HasControl())
{
gdb_signal(GDB_SIGTRAP);
gdb_handle_exception(true);
GDBStub::SendSignal(GDBStub::Signal::Sigtrap);
GDBStub::ProcessCommands(true);
// If we are still going to step, emulate the fact we just sent a step command
if (gdb_hasControl())
if (GDBStub::HasControl())
{
// Make sure the previous step by gdb was serviced
if (s_state_cpu_step_instruction_sync &&
s_state_cpu_step_instruction_sync != &gdb_step_sync_event)
s_state_cpu_step_instruction_sync->Set();
s_state_cpu_step_instruction = true;
s_state_cpu_step_instruction_sync = &gdb_step_sync_event;
}
}
state_lock.lock();
return s_state_cpu_step_instruction || !IsStepping();
@@ -293,6 +302,12 @@ void Break()
RunAdjacentSystems(false);
}
void Continue()
{
CPU::EnableStepping(false);
Core::CallOnStateChangedCallbacks(Core::State::Running);
}
bool PauseAndLock(bool do_lock, bool unpause_on_unlock, bool control_adjacent)
{
// NOTE: This is protected by s_stepping_lock.
+3
View File
@@ -53,6 +53,9 @@ void EnableStepping(bool stepping);
// should not be used by the Host.
void Break();
// This should only be called from the CPU thread
void Continue();
// Shorthand for GetState() == State::Stepping.
// WARNING: State::PowerDown will return false, not just State::Running.
bool IsStepping();
File diff suppressed because it is too large Load Diff
+13 -34
View File
@@ -8,42 +8,21 @@
#include "Common/CommonTypes.h"
#include "Core/CoreTiming.h"
typedef enum
namespace GDBStub
{
GDB_SIGTRAP = 5,
GDB_SIGTERM = 15,
} gdb_signals;
typedef enum
enum class Signal
{
GDB_BP_TYPE_NONE = 0,
GDB_BP_TYPE_X,
GDB_BP_TYPE_R,
GDB_BP_TYPE_W,
GDB_BP_TYPE_A
} gdb_bp_type;
Sigtrap = 5,
Sigterm = 15,
};
const s64 GDB_UPDATE_CYCLES = 100000;
void Init(u32 port);
void InitLocal(const char* socket);
void Deinit();
bool IsActive();
bool HasControl();
void TakeControl();
void GDBStubUpdateCallback(u64 userdata, s64 cycles_late);
void gdb_init(u32 port);
void gdb_init_local(const char* socket);
void gdb_deinit();
bool gdb_active();
bool gdb_hasControl();
void gdb_takeControl();
void gdb_break();
void gdb_handle_exception(bool loopUntilContinue);
int gdb_signal(u32 signal);
int gdb_bp_x(u32 addr);
int gdb_bp_r(u32 addr);
int gdb_bp_w(u32 addr);
int gdb_bp_a(u32 addr);
bool gdb_add_bp(u32 type, u32 addr, u32 len);
void gdb_handle_exception(bool loop_until_continue);
void SendSignal(u32 signal);
void ProcessCommands(bool loop_until_continue);
void SendSignal(Signal signal);
} // namespace GDBStub
@@ -293,8 +293,8 @@ void Interpreter::Run()
#endif
INFO_LOG_FMT(POWERPC, "Hit Breakpoint - {:08x}", PC);
CPU::Break();
if (gdb_active())
gdb_takeControl();
if (GDBStub::IsActive())
GDBStub::TakeControl();
if (PowerPC::breakpoints.IsTempBreakPoint(PC))
PowerPC::breakpoints.Remove(PC);
+2 -2
View File
@@ -519,8 +519,8 @@ static void Memcheck(u32 address, u64 var, bool write, size_t size)
CPU::Break();
if (gdb_active())
gdb_takeControl();
if (GDBStub::IsActive())
GDBStub::TakeControl();
// Fake a DSI so that all the code that tests for it in order to skip
// the rest of the instruction will apply. (This means that
+2 -2
View File
@@ -614,8 +614,8 @@ void CheckBreakPoints()
if (PowerPC::breakpoints.IsBreakPointBreakOnHit(PC))
{
CPU::Break();
if (gdb_active())
gdb_takeControl();
if (GDBStub::IsActive())
GDBStub::TakeControl();
}
if (PowerPC::breakpoints.IsBreakPointLogOnHit(PC))
{