From: Brendan Shanks bshanks@codeweavers.com
--- 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); }
From: Brendan Shanks bshanks@codeweavers.com
--- programs/winedbg/gdbproxy.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 643860d55ee..3dfff4543a2 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -269,6 +269,18 @@ static inline void reply_buffer_append_str(struct reply_buffer* reply, const cha reply_buffer_append(reply, str, strlen(str)); }
+static inline void reply_buffer_append_wstr(struct reply_buffer* reply, const WCHAR* wstr) +{ + char* str; + int len; + + len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); + str = malloc(len); + if (WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL)) + reply_buffer_append_str(reply, str); + free(str); +} + static inline void reply_buffer_append_hex(struct reply_buffer* reply, const void* src, size_t len) { reply_buffer_grow(reply, len * 2); @@ -1777,6 +1789,7 @@ static enum packet_return packet_query_threads(struct gdb_context* gdbctx) struct reply_buffer* reply = &gdbctx->qxfer_buffer; struct dbg_process* process = gdbctx->process; struct dbg_thread* thread; + WCHAR* description;
if (!process) return packet_error;
@@ -1790,7 +1803,12 @@ static enum packet_return packet_query_threads(struct gdb_context* gdbctx) reply_buffer_append_str(reply, "id=""); reply_buffer_append_uinthex(reply, thread->tid, 4); reply_buffer_append_str(reply, "" name=""); - if (strlen(thread->name)) + if ((description = fetch_thread_description(thread->tid))) + { + reply_buffer_append_wstr(reply, description); + LocalFree(description); + } + else if (strlen(thread->name)) { reply_buffer_append_str(reply, thread->name); }
R��mi Bernon (@rbernon) commented about programs/winedbg/gdbproxy.c:
reply_buffer_append(reply, str, strlen(str));
}
+static inline void reply_buffer_append_wstr(struct reply_buffer* reply, const WCHAR* wstr) +{
- char* str;
- int len;
- len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
- str = malloc(len);
- if (WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL))
reply_buffer_append_str(reply, str);
This could maybe handle allocation failure more gracefully, skipping the append?