[PATCH v2 5/6] winedbg: Prefer thread name from GetThreadDescription() in 'info thread' listing.

Brendan Shanks bshanks at codeweavers.com
Wed Mar 16 15:42:02 CDT 2022


Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
---

v2: Use runtime linking for GetThreadDescription() (it was added during
Windows 10).

 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 1b57ac0d2fe..30e4eec0ffc 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -388,6 +388,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 2b8e377e6f4..aae0c2f4a8a 100644
--- a/programs/winedbg/info.c
+++ b/programs/winedbg/info.c
@@ -581,6 +581,39 @@ static BOOL get_process_name(DWORD pid, PROCESSENTRY32* 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);
@@ -591,6 +624,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);
@@ -622,12 +656,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);
         }
-- 
2.34.1




More information about the wine-devel mailing list