From bacfa9be19ef27183aa8b4f8df918e0a3a500591 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sun, 8 Nov 2020 15:42:20 +0200 Subject: [PATCH] Debugger fixups (#9226) Fix logic error in callstacks handling code, always set first to false after first iteration. Add explicit check for zero return addresses. Current code validity checks may not check for it properly when it sits on interrupt handler entry point (which may contain valid code). Do not allow 0x3FFF0 to be a back chain address because it needs space for LR save area, only 0x3FFE0 and below satisfy this criteria. --- rpcs3/Emu/Cell/PPUThread.cpp | 4 ++-- rpcs3/Emu/Cell/SPUThread.cpp | 6 +++--- rpcs3/rpcs3qt/kernel_explorer.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 1ba1f0d673..9e1ab60f86 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -584,7 +584,7 @@ std::vector> ppu_thread::dump_callstack_list() const for ( u64 sp = r1; sp % 0x10 == 0u && sp >= stack_min && sp <= stack_max - ppu_stack_start_offset; - sp = *vm::get_super_ptr(static_cast(sp)) + sp = *vm::get_super_ptr(static_cast(sp)), first = false ) { u64 addr = *vm::get_super_ptr(static_cast(sp + 16)); @@ -602,7 +602,7 @@ std::vector> ppu_thread::dump_callstack_list() const if (is_invalid(addr)) { - if (std::exchange(first, false)) + if (first) { // Function hasn't saved LR, could be because it's a leaf function // Use LR directly instead diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index fb344d1399..67fe63d850 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1265,7 +1265,7 @@ std::vector> spu_thread::dump_callstack_list() const bool first = true; // Declare first 128-bytes as invalid for stack (common values such as 0 do not make sense here) - for (u32 sp = gpr[1]._u32[3]; (sp & ~0x3FFF0) == 0u && sp >= 0x80u; sp = _ref(sp)) + for (u32 sp = gpr[1]._u32[3]; (sp & 0xF) == 0u && sp >= 0x80u && sp <= 0x3FFE0u; sp = _ref(sp), first = false) { v128 lr = _ref(sp + 16); @@ -1281,12 +1281,12 @@ std::vector> spu_thread::dump_callstack_list() const } const u32 op = _ref(addr); - return s_spu_itype.decode(op) == spu_itype::UNK || !op; + return s_spu_itype.decode(op) == spu_itype::UNK || !op || !addr; }; if (is_invalid(lr)) { - if (std::exchange(first, false)) + if (first) { // Function hasn't saved LR, could be because it's a leaf function // Use LR directly instead diff --git a/rpcs3/rpcs3qt/kernel_explorer.cpp b/rpcs3/rpcs3qt/kernel_explorer.cpp index 28dd02b946..60cd5a21e8 100644 --- a/rpcs3/rpcs3qt/kernel_explorer.cpp +++ b/rpcs3/rpcs3qt/kernel_explorer.cpp @@ -289,7 +289,7 @@ void kernel_explorer::Update() root->setText(0, qstr(fmt::format("Process 0x%08x: Total Memory Usage: 0x%x/0x%x (%0.2f/%0.2f MB)", process_getpid(), total_memory_usage, dct->size, 1. * total_memory_usage / (1024 * 1024) , 1. * dct->size / (1024 * 1024)))); - add_solid_node(m_tree, find_node(m_tree, additional_nodes::process_info), qstr(fmt::format("Process Info, Sdk Version 0x%08x: PPC SEG: %#x, SFO Categeory: %s", g_ps3_process_info.sdk_ver, g_ps3_process_info.ppc_seg, Emu.GetCat()))); + add_solid_node(m_tree, find_node(m_tree, additional_nodes::process_info), qstr(fmt::format("Process Info, Sdk Version: 0x%08x, PPC SEG: %#x, SFO Category: %s", g_ps3_process_info.sdk_ver, g_ps3_process_info.ppc_seg, Emu.GetCat()))); idm::select([&](u32 id, lv2_obj& obj) {