Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- programs/winedbg/debugger.h | 6 ++++-- programs/winedbg/memory.c | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 0cc2f8b7a6c..d275182c4f9 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -402,8 +402,10 @@ extern void memory_examine(const struct dbg_lvalue *lvalue, int coun extern void* memory_to_linear_addr(const ADDRESS64* address); extern BOOL memory_get_current_pc(ADDRESS64* address); extern BOOL memory_get_current_stack(ADDRESS64* address); -extern BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size); -extern BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, WCHAR* buffer, int size); +extern BOOL memory_get_string(struct dbg_process* pcs, const void* addr, BOOL in_debuggee, BOOL unicode, + char* buffer, int size); +extern BOOL memory_get_string_indirect(struct dbg_process* pcs, const void* addr, BOOL unicode, + WCHAR* buffer, int size); extern BOOL memory_get_register(DWORD regno, DWORD_PTR** value, char* buffer, int len); extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count); extern BOOL memory_disasm_one_insn(ADDRESS64* addr); diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c index faa5ac9ddcb..7fe3d342b33 100644 --- a/programs/winedbg/memory.c +++ b/programs/winedbg/memory.c @@ -371,7 +371,7 @@ BOOL memory_store_float(const struct dbg_lvalue* lvalue, double *ret) return memory_write_value(lvalue, size, ret); }
-BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, +BOOL memory_get_string(struct dbg_process* pcs, const void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size) { SIZE_T sz; @@ -402,7 +402,7 @@ BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, return TRUE; }
-BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, WCHAR* buffer, int size) +BOOL memory_get_string_indirect(struct dbg_process* pcs, const void* addr, BOOL unicode, WCHAR* buffer, int size) { void* ad = 0; SIZE_T sz;
Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- programs/winedbg/tgt_active.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 2caa62206d6..628627fabc5 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -257,12 +257,9 @@ static DWORD dbg_handle_exception(const EXCEPTION_RECORD* rec, BOOL first_chance dbg_printf("Thread ID=%04lx not in our list of threads -> can't rename\n", pThreadName->dwThreadID); return DBG_CONTINUE; } - if (dbg_read_memory(pThreadName->szName, pThread->name, sizeof(pThread->name))) - { - pThread->name[sizeof(pThread->name) - 1] = '\0'; + if (memory_get_string(dbg_curr_process, pThreadName->szName, TRUE, FALSE, pThread->name, sizeof(pThread->name))) dbg_printf("Thread ID=%04lx renamed using MSVC extension (name=="%s")\n", pThread->tid, pThread->name); - } return DBG_CONTINUE; case EXCEPTION_INVALID_HANDLE: return DBG_CONTINUE;
Signed-off-by: Brendan Shanks bshanks@codeweavers.com ---
v2: Use memory_get_string().
programs/winedbg/gdbproxy.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 0268a288481..e9f3875db2d 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -482,8 +482,6 @@ static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* e { const THREADNAME_INFO *threadname = (const THREADNAME_INFO *)rec->ExceptionInformation; struct dbg_thread *thread; - char name[9]; - SIZE_T read;
if (threadname->dwType != 0x1000) return FALSE; @@ -493,12 +491,10 @@ static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* e thread = dbg_get_thread(gdbctx->process, threadname->dwThreadID); if (thread) { - if (gdbctx->process->process_io->read( gdbctx->process->handle, - threadname->szName, name, sizeof(name), &read) && read == sizeof(name)) - { - fprintf(stderr, "Thread ID=%04lx renamed to "%.9s"\n", - threadname->dwThreadID, name); - } + if (memory_get_string(gdbctx->process, threadname->szName, TRUE, FALSE, + thread->name, sizeof(thread->name))) + fprintf(stderr, "Thread ID=%04lx renamed to "%s"\n", + threadname->dwThreadID, thread->name); } else ERR("Cannot set name of thread %04lx\n", threadname->dwThreadID);
Signed-off-by: Brendan Shanks bshanks@codeweavers.com ---
I don't believe the 9 character limit has been relevant since MSVC 6.
Current applications often use longer thread names ('ThreadPoolSingleThreadCOMSTASharedForegroundBlocking1' in Chromium being an extreme example).
If memory usage is a concern, thread->name could be dynamically allocated instead.
programs/winedbg/debugger.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index d275182c4f9..1b57ac0d2fe 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -182,7 +182,7 @@ struct dbg_breakpoint typedef struct tagTHREADNAME_INFO { DWORD dwType; /* Must be 0x1000 */ - LPCSTR szName; /* Pointer to name - limited to 9 bytes (8 characters + terminator) */ + LPCSTR szName; /* Pointer to name (in user addr space). */ DWORD dwThreadID; /* Thread ID (-1 = caller thread) */ DWORD dwFlags; /* Reserved for future use. Must be zero. */ } THREADNAME_INFO; @@ -205,7 +205,7 @@ struct dbg_thread ADDRESS_MODE addr_mode; /* mode */ int stopped_xpoint; /* xpoint on which the thread has stopped (-1 if none) */ struct dbg_breakpoint step_over_bp; - char name[9]; + char name[64]; BOOL in_exception; /* TRUE if thread stopped with an exception */ BOOL first_chance; /* TRUE if thread stopped with a first chance exception * - only valid when in_exception is TRUE
Signed-off-by: Brendan Shanks bshanks@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); }
Signed-off-by: Brendan Shanks bshanks@codeweavers.com ---
v2: Use the fetch_thread_description() previously added to info.c.
programs/winedbg/gdbproxy.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index e9f3875db2d..eb1246c5912 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -1773,6 +1773,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;
@@ -1786,7 +1787,19 @@ 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))) + { + char* name; + int len; + + len = WideCharToMultiByte(CP_ACP, 0, description, -1, NULL, 0, NULL, NULL); + name = HeapAlloc(GetProcessHeap(), 0, len); + if (WideCharToMultiByte(CP_ACP, 0, description, -1, name, len, NULL, NULL)) + reply_buffer_append_str(reply, name); + HeapFree(GetProcessHeap(), 0, name); + LocalFree(description); + } + else if (strlen(thread->name)) { reply_buffer_append_str(reply, thread->name); }