From 2767fb1f9e73b8ef2d7412eb8c756e872e6c2e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 7 Nov 2024 12:55:53 +0100 Subject: [PATCH 1/2] Actually fix the black background in the win32 debugger --- Windows/Debugger/CtrlDisAsmView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 501cc51cbb21..202feaf8c168 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -527,10 +527,10 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) addressPositions[address] = rowY1; // draw background - COLORREF backgroundColor = whiteBackground ? 0xFFFFFF : debugger->getColor(address, false); + COLORREF backgroundColor = whiteBackground ? 0xFFFFFF : (debugger->getColor(address, false) & 0xFFFFFF); COLORREF textColor = 0x000000; - if (isInInterval(address,line.totalSize,debugger->getPC())) + if (isInInterval(address, line.totalSize, debugger->getPC())) { backgroundColor = scaleColor(backgroundColor,1.05f); } From 88a2994a4d5d9d53dc5b5e3677feced35b478f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 7 Nov 2024 13:29:27 +0100 Subject: [PATCH 2/2] Make some more ImGui debugger windows (modules, threads, callstack) Funcionality is a bit limited though (no context menus yet) --- UI/ImDebugger/ImDebugger.cpp | 165 ++++++++++++++++++++++++++++ UI/ImDebugger/ImDebugger.h | 3 + Windows/Debugger/Debugger_Lists.cpp | 3 +- 3 files changed, 169 insertions(+), 2 deletions(-) diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 1bbda2493575..9adde3ad2ee1 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -12,6 +12,12 @@ #include "Core/MemMap.h" #include "Common/System/Request.h" +// Threads window +#include "Core/HLE/sceKernelThread.h" + +// Callstack window +#include "Core/MIPS/MIPSStackWalk.h" + #include "UI/ImDebugger/ImDebugger.h" void DrawRegisterView(MIPSDebugInterface *mipsDebug, bool *open) { @@ -82,6 +88,150 @@ void DrawRegisterView(MIPSDebugInterface *mipsDebug, bool *open) { ImGui::End(); } +static const char *ThreadStatusToString(u32 status) { + switch (status) { + case THREADSTATUS_RUNNING: return "Running"; + case THREADSTATUS_READY: return "Ready"; + case THREADSTATUS_WAIT: return "Wait"; + case THREADSTATUS_SUSPEND: return "Suspend"; + case THREADSTATUS_DORMANT: return "Dormant"; + case THREADSTATUS_DEAD: return "Dead"; + case THREADSTATUS_WAITSUSPEND: return "WaitSuspend"; + default: + break; + } + return "(unk)"; +} + +void DrawThreadView(bool *open) { + if (!ImGui::Begin("Threads", open)) { + ImGui::End(); + return; + } + + std::vector info = GetThreadsInfo(); + if (ImGui::BeginTable("threads", 5, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("PC", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Entry", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Priority", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("State", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + + // TODO: Add context menu + for (auto &thread : info) { + ImGui::TableSetColumnIndex(0); + ImGui::Text("%s", thread.name); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%08x", thread.curPC); + ImGui::TableSetColumnIndex(2); + ImGui::Text("%08x", thread.entrypoint); + ImGui::TableSetColumnIndex(3); + ImGui::Text("%d", thread.priority); + ImGui::TableSetColumnIndex(4); + ImGui::Text("%s", ThreadStatusToString(thread.status)); + ImGui::TableNextRow(); + // TODO: More fields? + } + + ImGui::EndTable(); + } + ImGui::End(); +} + +void DrawCallStacks(MIPSDebugInterface *debug, bool *open) { + if (!ImGui::Begin("Callstacks", open)) { + ImGui::End(); + return; + } + + std::vector info = GetThreadsInfo(); + // TODO: Add dropdown for thread choice. + u32 entry = 0; + u32 stackTop = 0; + for (auto &thread : info) { + if (thread.isCurrent) { + entry = thread.entrypoint; + stackTop = thread.initialStack; + break; + } + } + + if (entry != 0 && ImGui::BeginTable("frames", 6, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("Entry", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("EntryAddr", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CurPC", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CurOpCode", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CurSP", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + + std::vector frames = MIPSStackWalk::Walk(debug->GetPC(), debug->GetRegValue(0, 31), debug->GetRegValue(0, 29), entry, stackTop); + + // TODO: Add context menu and clickability + for (auto &frame : frames) { + const std::string entrySym = g_symbolMap->GetLabelString(frame.entry); + + ImGui::TableSetColumnIndex(0); + ImGui::Text("%s", entrySym.c_str()); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%08x", frame.entry); + ImGui::TableSetColumnIndex(2); + ImGui::Text("%08x", frame.pc); + ImGui::TableSetColumnIndex(3); + ImGui::Text("%s", "N/A"); // opcode, see the old debugger + ImGui::TableSetColumnIndex(4); + ImGui::Text("%08x", frame.sp); + ImGui::TableSetColumnIndex(5); + ImGui::Text("%d", frame.stackSize); + ImGui::TableNextRow(); + // TODO: More fields? + } + + ImGui::EndTable(); + } + ImGui::End(); +} + +void DrawModules(MIPSDebugInterface *debug, bool *open) { + if (!ImGui::Begin("Modules", open)) { + ImGui::End(); + return; + } + + std::vector modules = g_symbolMap->getAllModules(); + + if (ImGui::BeginTable("modules", 4, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Address", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("Active", ImGuiTableColumnFlags_WidthFixed); + + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + + // TODO: Add context menu and clickability + for (auto &module : modules) { + ImGui::TableSetColumnIndex(0); + ImGui::Text("%s", module.name.c_str()); + ImGui::TableSetColumnIndex(1); + ImGui::Text("%08x", module.address); + ImGui::TableSetColumnIndex(2); + ImGui::Text("%08x", module.size); + ImGui::TableSetColumnIndex(3); + ImGui::Text("%s", module.active ? "yes" : "no"); + ImGui::TableNextRow(); + } + + ImGui::EndTable(); + } + ImGui::End(); +} + void ImDebugger::Frame(MIPSDebugInterface *mipsDebug) { // Snapshot the coreState to avoid inconsistency. const CoreState coreState = ::coreState; @@ -116,6 +266,9 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug) { ImGui::Checkbox("Dear ImGUI Demo", &demoOpen_); ImGui::Checkbox("CPU debugger", &disasmOpen_); ImGui::Checkbox("Registers", ®sOpen_); + ImGui::Checkbox("Callstacks", &callstackOpen_); + ImGui::Checkbox("HLE Modules", &modulesOpen_); + ImGui::Checkbox("HLE Threads", &threadsOpen_); ImGui::EndMenu(); } ImGui::EndMainMenuBar(); @@ -132,6 +285,18 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug) { if (regsOpen_) { DrawRegisterView(mipsDebug, ®sOpen_); } + + if (threadsOpen_) { + DrawThreadView(&threadsOpen_); + } + + if (callstackOpen_) { + DrawCallStacks(mipsDebug, &callstackOpen_); + } + + if (modulesOpen_) { + DrawModules(mipsDebug, &modulesOpen_); + } } void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState coreState) { diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 574aad01aece..1eba71030cd4 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -58,4 +58,7 @@ struct ImDebugger { bool disasmOpen_ = true; bool demoOpen_ = false; bool regsOpen_ = true; + bool threadsOpen_ = true; + bool callstackOpen_ = true; + bool modulesOpen_ = true; }; diff --git a/Windows/Debugger/Debugger_Lists.cpp b/Windows/Debugger/Debugger_Lists.cpp index c5f2a67b51b1..f960eedad52a 100644 --- a/Windows/Debugger/Debugger_Lists.cpp +++ b/Windows/Debugger/Debugger_Lists.cpp @@ -404,8 +404,7 @@ void CtrlBreakpointList::removeBreakpoint(int itemIndex) int index = getBreakpointIndex(itemIndex,isMemory); if (index == -1) return; - if (isMemory) - { + if (isMemory) { auto mc = displayedMemChecks_[index]; CBreakPoints::RemoveMemCheck(mc.start, mc.end); } else {