diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 23d89577f5..7600b316aa 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -892,6 +892,8 @@ u32* cpu_thread::get_pc2() return nullptr; } +std::shared_ptr make_disasm(const cpu_thread* cpu); + std::string cpu_thread::dump_all() const { std::string ret = cpu_thread::dump_misc(); @@ -901,6 +903,24 @@ std::string cpu_thread::dump_all() const ret += dump_regs(); ret += '\n'; ret += dump_callstack(); + ret += '\n'; + + if (u32 cur_pc = get_pc(); cur_pc != umax) + { + // Dump a snippet of currently executed code (may be unreliable with non-static-interpreter decoders) + auto disasm = make_disasm(this); + + const auto rsx = try_get(); + + for (u32 i = (rsx ? rsx->try_get_pc_of_x_cmds_backwards(20, cur_pc).second : cur_pc - 4 * 20), count = 0; count < 30; count++) + { + u32 advance = disasm->disasm(i); + ret += disasm->last_opcode; + i += std::max(advance, 4u); + disasm->dump_pc = i; + ret += '\n'; + } + } return ret; } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 6f6af30131..5fc182dc71 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2674,13 +2674,13 @@ namespace rsx } else { - return {0, umax}; + return {0, get}; } } if (pcs_of_valid_cmds.size() == 1u || pcs_of_valid_cmds.back() != get) { - return {0, umax}; + return {0, get}; } u32 found_cmds_count = std::min(count, ::size32(pcs_of_valid_cmds) - 1); diff --git a/rpcs3/rpcs3qt/debugger_frame.cpp b/rpcs3/rpcs3qt/debugger_frame.cpp index 1528f30aa1..f7d2f4124e 100644 --- a/rpcs3/rpcs3qt/debugger_frame.cpp +++ b/rpcs3/rpcs3qt/debugger_frame.cpp @@ -50,6 +50,17 @@ extern bool is_using_interpreter(u32 id_type) } } +extern std::shared_ptr make_disasm(const cpu_thread* cpu) +{ + switch (cpu->id_type()) + { + case 1: return std::make_shared(cpu_disasm_mode::interpreter, vm::g_sudo_addr); + case 2: return std::make_shared(cpu_disasm_mode::interpreter, static_cast(cpu)->ls); + case 0x55: return std::make_shared(cpu_disasm_mode::interpreter, vm::g_sudo_addr, 0, cpu); + default: return nullptr; + } +} + debugger_frame::debugger_frame(std::shared_ptr gui_settings, QWidget *parent) : custom_dock_widget(tr("Debugger"), parent) , m_gui_settings(std::move(gui_settings)) @@ -895,7 +906,7 @@ void debugger_frame::OnSelectUnit() if (selected == m_cpu.get()) { - m_disasm = std::make_shared(cpu_disasm_mode::interpreter, vm::g_sudo_addr); + m_disasm = make_disasm(selected); } else { @@ -911,7 +922,7 @@ void debugger_frame::OnSelectUnit() if (selected == m_cpu.get()) { - m_disasm = std::make_shared(cpu_disasm_mode::interpreter, static_cast(m_cpu.get())->ls); + m_disasm = make_disasm(selected); } else { @@ -927,7 +938,7 @@ void debugger_frame::OnSelectUnit() if (get_cpu()) { - m_disasm = std::make_shared(cpu_disasm_mode::interpreter, vm::g_sudo_addr, 0, m_rsx); + m_disasm = make_disasm(m_rsx); } break;