From e0a1d658ea86dae1456e99c96ad34ba5068174fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 8 Dec 2024 15:41:13 +0100 Subject: [PATCH] ImDebugger thread window: Visualize the wait ID when possible --- UI/ImDebugger/ImDebugger.cpp | 71 +++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 343aaa5b6554..f8fd6b443c97 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -160,6 +160,50 @@ static const char *ThreadStatusToString(u32 status) { return "(unk)"; } +void WaitIDToString(WaitType waitType, SceUID waitID, char *buffer, size_t bufSize) { + switch (waitType) { + case WAITTYPE_AUDIOCHANNEL: + snprintf(buffer, bufSize, "chan %d", (int)waitID); + return; + case WAITTYPE_IO: + // TODO: More detail + snprintf(buffer, bufSize, "fd: %d", (int)waitID); + return; + case WAITTYPE_ASYNCIO: + snprintf(buffer, bufSize, "id: %d", (int)waitID); + return; + case WAITTYPE_THREADEND: + case WAITTYPE_MUTEX: + case WAITTYPE_LWMUTEX: + case WAITTYPE_MODULE: + case WAITTYPE_MSGPIPE: + case WAITTYPE_FPL: + case WAITTYPE_VPL: + case WAITTYPE_MBX: + case WAITTYPE_EVENTFLAG: + case WAITTYPE_SEMA: + // Get the name of the thread + if (kernelObjects.IsValid(waitID)) { + auto obj = kernelObjects.GetFast(waitID); + if (obj && obj->GetName()) { + truncate_cpy(buffer, bufSize, obj->GetName()); + return; + } + } + break; + case WAITTYPE_DELAY: + case WAITTYPE_SLEEP: + case WAITTYPE_HLEDELAY: + case WAITTYPE_UMD: + truncate_cpy(buffer, bufSize, "-"); + return; + default: + truncate_cpy(buffer, bufSize, "(unimpl)"); + return; + } + +} + void DrawThreadView(ImConfig &cfg) { ImGui::SetNextWindowSize(ImVec2(420, 300), ImGuiCond_FirstUseEver); if (!ImGui::Begin("Threads", &cfg.threadsOpen)) { @@ -168,7 +212,8 @@ void DrawThreadView(ImConfig &cfg) { } std::vector info = GetThreadsInfo(); - if (ImGui::BeginTable("threads", 7, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + if (ImGui::BeginTable("threads", 8, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) { + ImGui::TableSetupColumn("Id", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("PC", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("Entry", ImGuiTableColumnFlags_WidthFixed); @@ -183,6 +228,8 @@ void DrawThreadView(ImConfig &cfg) { const DebugThreadInfo &thread = info[i]; ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("%d", thread.id); + ImGui::TableNextColumn(); ImGui::PushID(i); if (ImGui::Selectable(thread.name, cfg.selectedThread == i, ImGuiSelectableFlags_AllowDoubleClick | ImGuiSelectableFlags_SpanAllColumns)) { cfg.selectedThread = i; @@ -200,16 +247,11 @@ void DrawThreadView(ImConfig &cfg) { ImGui::TableNextColumn(); ImGui::TextUnformatted(ThreadStatusToString(thread.status)); ImGui::TableNextColumn(); - if (thread.waitType != WAITTYPE_NONE) { - ImGui::TextUnformatted(getWaitTypeName(thread.waitType)); - } else { - ImGui::TextUnformatted("N/A"); - } + ImGui::TextUnformatted(getWaitTypeName(thread.waitType)); ImGui::TableNextColumn(); - switch (thread.waitType) { - default: - ImGui::TextUnformatted("N/A"); - } + char temp[64]; + WaitIDToString(thread.waitType, thread.waitID, temp, sizeof(temp)); + ImGui::TextUnformatted(temp); if (ImGui::BeginPopup("threadPopup")) { DebugThreadInfo &thread = info[i]; ImGui::Text("Thread: %s", thread.name); @@ -218,16 +260,19 @@ void DrawThreadView(ImConfig &cfg) { snprintf(temp, sizeof(temp), "%08x", thread.entrypoint); System_CopyStringToClipboard(temp); } - if (ImGui::MenuItem("Copy PC to clipboard")) { + if (ImGui::MenuItem("Copy thread PC to clipboard")) { char temp[64]; snprintf(temp, sizeof(temp), "%08x", thread.curPC); System_CopyStringToClipboard(temp); } if (ImGui::MenuItem("Kill thread")) { + // Dangerous! sceKernelTerminateThread(thread.id); } - if (ImGui::MenuItem("Force run")) { - __KernelResumeThreadFromWait(thread.id, 0); + if (thread.status == THREADSTATUS_WAIT) { + if (ImGui::MenuItem("Force run now")) { + __KernelResumeThreadFromWait(thread.id, 0); + } } ImGui::EndPopup(); }