mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-13 07:14:49 +00:00
debugger: Fix single stepping (#9793)
This commit is contained in:
parent
e76d8eb046
commit
20eb4352fb
@ -667,6 +667,26 @@ bool cpu_thread::check_state() noexcept
|
||||
store = true;
|
||||
}
|
||||
|
||||
// Can't process dbg_step if we only paused temporarily
|
||||
if (cpu_can_stop && flags & cpu_flag::dbg_step)
|
||||
{
|
||||
if (u32 pc = get_pc(), *pc2 = get_pc2(); pc != umax && pc2)
|
||||
{
|
||||
if (pc != *pc2)
|
||||
{
|
||||
flags -= cpu_flag::dbg_step;
|
||||
flags += cpu_flag::dbg_pause;
|
||||
store = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't test, ignore flag
|
||||
flags -= cpu_flag::dbg_step;
|
||||
store = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Atomically clean wait flag and escape
|
||||
if (!(flags & (cpu_flag::exit + cpu_flag::ret + cpu_flag::stop)))
|
||||
{
|
||||
@ -703,14 +723,6 @@ bool cpu_thread::check_state() noexcept
|
||||
retval = cpu_can_stop;
|
||||
}
|
||||
|
||||
if (cpu_can_stop && flags & cpu_flag::dbg_step)
|
||||
{
|
||||
// Can't process dbg_step if we only paused temporarily
|
||||
flags += cpu_flag::dbg_pause;
|
||||
flags -= cpu_flag::dbg_step;
|
||||
store = true;
|
||||
}
|
||||
|
||||
escape = true;
|
||||
state1 = flags;
|
||||
return store;
|
||||
@ -876,6 +888,29 @@ u32 cpu_thread::get_pc() const
|
||||
return pc ? atomic_storage<u32>::load(*pc) : UINT32_MAX;
|
||||
}
|
||||
|
||||
u32* cpu_thread::get_pc2()
|
||||
{
|
||||
switch (id_type())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return &static_cast<ppu_thread*>(this)->dbg_step_pc;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return &static_cast<spu_thread*>(this)->dbg_step_pc;
|
||||
}
|
||||
case 0x55:
|
||||
{
|
||||
const auto ctrl = static_cast<rsx::thread*>(this)->ctrl;
|
||||
return ctrl ? &static_cast<rsx::thread*>(this)->dbg_step_pc : nullptr;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string cpu_thread::dump_all() const
|
||||
{
|
||||
std::string ret = cpu_thread::dump_misc();
|
||||
|
@ -105,6 +105,7 @@ public:
|
||||
}
|
||||
|
||||
u32 get_pc() const;
|
||||
u32* get_pc2(); // Last PC before stepping for the debugger (may be null)
|
||||
|
||||
void notify();
|
||||
|
||||
|
@ -455,7 +455,7 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_function_t ptr)
|
||||
static bool ppu_break(ppu_thread& ppu, ppu_opcode_t op)
|
||||
{
|
||||
// Pause
|
||||
ppu.state += cpu_flag::dbg_pause;
|
||||
ppu.state.atomic_op([](bs_t<cpu_flag>& state) { if (!(state & cpu_flag::dbg_step)) state += cpu_flag::dbg_pause; });
|
||||
|
||||
if (ppu.check_state())
|
||||
{
|
||||
|
@ -277,6 +277,8 @@ public:
|
||||
u64 last_fail = 0;
|
||||
u64 last_succ = 0;
|
||||
|
||||
u32 dbg_step_pc = 0;
|
||||
|
||||
be_t<u64>* get_stack_arg(s32 i, u64 align = alignof(u64));
|
||||
void exec_task();
|
||||
void fast_call(u32 addr, u32 rtoc);
|
||||
|
@ -643,6 +643,7 @@ public:
|
||||
spu_thread(lv2_spu_group* group, u32 index, std::string_view name, u32 lv2_id, bool is_isolated = false, u32 option = 0);
|
||||
|
||||
u32 pc = 0;
|
||||
u32 dbg_step_pc = 0;
|
||||
|
||||
// May be used internally by recompilers.
|
||||
u32 base_pc = 0;
|
||||
|
@ -648,6 +648,7 @@ namespace rsx
|
||||
u32 dma_address{0};
|
||||
rsx_iomap_table iomap_table;
|
||||
u32 restore_point = 0;
|
||||
u32 dbg_step_pc = 0;
|
||||
atomic_t<u32> external_interrupt_lock{ 0 };
|
||||
atomic_t<bool> external_interrupt_ack{ false };
|
||||
bool is_fifo_idle() const;
|
||||
|
@ -825,7 +825,7 @@ void debugger_frame::DoStep(bool stepOver)
|
||||
{
|
||||
bool should_step_over = stepOver && cpu->id_type() == 1;
|
||||
|
||||
if (cpu->state & s_pause_flags)
|
||||
if (auto _state = +cpu->state; _state & s_pause_flags && _state & cpu_flag::wait && !(_state & cpu_flag::dbg_step))
|
||||
{
|
||||
if (should_step_over)
|
||||
{
|
||||
@ -849,7 +849,14 @@ void debugger_frame::DoStep(bool stepOver)
|
||||
{
|
||||
state -= s_pause_flags;
|
||||
|
||||
if (!should_step_over) state += cpu_flag::dbg_step;
|
||||
if (!should_step_over)
|
||||
{
|
||||
if (u32* ptr = cpu->get_pc2())
|
||||
{
|
||||
state += cpu_flag::dbg_step;
|
||||
*ptr = cpu->get_pc();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cpu->state.notify_one(s_pause_flags);
|
||||
|
Loading…
x
Reference in New Issue
Block a user