From 86c5d2ae2a1b43d493d5ebcb0bcee8c5baab80da Mon Sep 17 00:00:00 2001 From: Ziemas Date: Thu, 23 Apr 2026 03:04:11 +0200 Subject: [PATCH] DebugInterface: Allow stack tracing any IOP thread --- pcsx2/DebugTools/BiosDebugData.cpp | 7 ++++--- pcsx2/DebugTools/BiosDebugData.h | 9 +++++---- pcsx2/DebugTools/DebugInterface.cpp | 7 ++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pcsx2/DebugTools/BiosDebugData.cpp b/pcsx2/DebugTools/BiosDebugData.cpp index a825f54d7c..048a16bd03 100644 --- a/pcsx2/DebugTools/BiosDebugData.cpp +++ b/pcsx2/DebugTools/BiosDebugData.cpp @@ -49,7 +49,8 @@ std::vector> getIOPThreads() return {}; } - data.stackTop = iopMemRead32(item + 0x3c); + data.stackBottom = iopMemRead32(item + 0x3c); + data.stackSize = iopMemRead32(item + 0x40); data.status = iopMemRead8(item + 0xc); data.tid = iopMemRead16(item + 0xa); data.entrypoint = iopMemRead32(item + 0x38); @@ -57,9 +58,9 @@ std::vector> getIOPThreads() data.waitId = iopMemRead32(item + 0x20); data.initPriority = iopMemRead16(item + 0xe); - data.SavedSP = iopMemRead32(item + 0x10); + data.regCtx = iopMemRead32(item + 0x10); - data.PC = iopMemRead32(data.SavedSP + 0x8c); + data.PC = iopMemRead32(data.regCtx + 0x8c); threads.emplace_back(std::make_unique(data)); diff --git a/pcsx2/DebugTools/BiosDebugData.h b/pcsx2/DebugTools/BiosDebugData.h index de2b0ff432..2c3baa81db 100644 --- a/pcsx2/DebugTools/BiosDebugData.h +++ b/pcsx2/DebugTools/BiosDebugData.h @@ -59,8 +59,9 @@ struct IOPInternalThread { u32 tid; u32 PC; - u32 stackTop; - u32 SavedSP; + u32 stackBottom; + u32 stackSize; + u32 regCtx; u32 status; u32 entrypoint; u32 waitstate; @@ -189,9 +190,9 @@ public: }; [[nodiscard]] u32 WaitId() const override { return data.waitId; }; [[nodiscard]] u32 EntryPoint() const override { return data.entrypoint; }; - [[nodiscard]] u32 StackTop() const override { return data.stackTop; }; + [[nodiscard]] u32 StackTop() const override { return data.stackBottom + data.stackSize; }; [[nodiscard]] u32 Priority() const override { return data.initPriority; }; - [[nodiscard]] u32 RegCtx() const override { return 0; }; + [[nodiscard]] u32 RegCtx() const override { return data.regCtx; }; private: IOPInternalThread data; diff --git a/pcsx2/DebugTools/DebugInterface.cpp b/pcsx2/DebugTools/DebugInterface.cpp index 584286b7f1..bc3e348987 100644 --- a/pcsx2/DebugTools/DebugInterface.cpp +++ b/pcsx2/DebugTools/DebugInterface.cpp @@ -1074,7 +1074,12 @@ std::vector R3000DebugInterface::StackTrace(const Bio thread.EntryPoint(), thread.StackTop()); } - return {}; + u32 p = thread.RegCtx(); + u32 pc = Read32(p + 0x8c); + u32 ra = Read32(p + 0x7c); + u32 sp = Read32(p + 0x74); + + return MipsStackWalk::Walk(this, pc, ra, sp, thread.EntryPoint(), thread.StackTop()); } std::vector R3000DebugInterface::GetModuleList() const