From f89c8be852e256d38bee82179e82f1599241d801 Mon Sep 17 00:00:00 2001 From: Brendan Shanks Date: Thu, 24 Feb 2022 10:52:18 -0800 Subject: [PATCH] winedbg: Prefer thread name from GetThreadDescription() in 'info thread' listing. --- programs/winedbg/debugger.h | 1 + programs/winedbg/info.c | 50 ++++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 17bebf9e886..c3eac423a13 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -385,6 +385,7 @@ extern void info_win32_virtual(DWORD pid); extern void info_win32_segments(DWORD start, int length); extern void info_win32_exception(void); extern void info_wine_dbg_channel(BOOL add, const char* chnl, const char* name); +extern WCHAR* fetch_thread_description(DWORD tid); /* memory.c */ extern BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result); diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index af68ab799da..5d6b45d715f 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -595,6 +595,39 @@ static BOOL get_process_name(DWORD pid, PROCESSENTRY32W* entry) return ret; } +WCHAR* fetch_thread_description(DWORD tid) +{ + static HRESULT (WINAPI *my_GetThreadDescription)(HANDLE, PWSTR*) = NULL; + static BOOL resolved = FALSE; + HANDLE h; + WCHAR* desc = NULL; + + if (!resolved) + { + HMODULE kernelbase = GetModuleHandleA("kernelbase.dll"); + if (kernelbase) + my_GetThreadDescription = (void *)GetProcAddress(kernelbase, "GetThreadDescription"); + resolved = TRUE; + } + + if (!my_GetThreadDescription) + return NULL; + + h = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, tid); + if (!h) + return NULL; + + my_GetThreadDescription(h, &desc); + CloseHandle(h); + + if (desc && desc[0] == '\0') + { + LocalFree(desc); + return NULL; + } + return desc; +} + void info_win32_threads(void) { HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); @@ -605,6 +638,7 @@ void info_win32_threads(void) DWORD lastProcessId = 0; struct dbg_process* p = NULL; struct dbg_thread* t = NULL; + WCHAR *description; entry.dwSize = sizeof(entry); ok = Thread32First(snap, &entry); @@ -636,12 +670,20 @@ void info_win32_threads(void) entry.th32OwnerProcessID, p ? " (D)" : "", exename); lastProcessId = entry.th32OwnerProcessID; } - t = dbg_get_thread(p, entry.th32ThreadID); - dbg_printf("\t%08lx %4ld%s %s\n", + dbg_printf("\t%08lx %4ld%s ", entry.th32ThreadID, entry.tpBasePri, - (entry.th32ThreadID == dbg_curr_tid) ? " <==" : " ", - t ? t->name : ""); + (entry.th32ThreadID == dbg_curr_tid) ? " <==" : " "); + if ((description = fetch_thread_description(entry.th32ThreadID))) + { + dbg_printf("%ls\n", description); + LocalFree(description); + } + else + { + t = dbg_get_thread(p, entry.th32ThreadID); + dbg_printf("%s\n", t ? t->name : ""); + } } ok = Thread32Next(snap, &entry); }