From f552359c31ba4b5495b5d5fcbe636c62933d9b69 Mon Sep 17 00:00:00 2001 From: James Hatheway Date: Mon, 9 Apr 2001 18:31:47 +0000 Subject: [PATCH] Modify debugger to understand special undocumented "Name Thread" exception from MS VC6. --- debugger/debugger.h | 18 ++++++++++++++++++ debugger/winedbg.c | 20 ++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/debugger/debugger.h b/debugger/debugger.h index 7bda3c5ccad..9516d201b9a 100644 --- a/debugger/debugger.h +++ b/debugger/debugger.h @@ -150,6 +150,23 @@ enum dbg_mode MODE_INVALID, MODE_16, MODE_32, MODE_VM86 }; + + +/* Wine extension; Windows doesn't have a name for this code. This is an + undocumented exception understood by MS VC debugger, allowing the program + to name a particular thread. Search google.com or deja.com for "0x406d1388" + for more info. */ +#define EXCEPTION_NAME_THREAD 0x406D1388 + +/* Helper structure */ +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; /* Must be 0x1000 */ + LPCTSTR szName; /* Pointer to name - limited to 9 bytes (8 characters + terminator) */ + DWORD dwThreadID; /* Thread ID (-1 = caller thread) */ + DWORD dwFlags; /* Reserved for future use. Must be zero. */ +} THREADNAME_INFO; + typedef struct tagDBG_THREAD { struct tagDBG_PROCESS* process; HANDLE handle; @@ -161,6 +178,7 @@ typedef struct tagDBG_THREAD { enum exec_mode dbg_exec_mode; int dbg_exec_count; DBG_BREAKPOINT stepOverBP; + char name[9]; struct tagDBG_THREAD* next; struct tagDBG_THREAD* prev; } DBG_THREAD; diff --git a/debugger/winedbg.c b/debugger/winedbg.c index d4e05b31ddb..7488a83b49c 100644 --- a/debugger/winedbg.c +++ b/debugger/winedbg.c @@ -377,8 +377,11 @@ static DWORD DEBUG_ExceptionEpilog(void) static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL force, LPDWORD cont) { - BOOL is_debug = FALSE; - BOOL ret = TRUE; + BOOL is_debug = FALSE; + BOOL ret = TRUE; + THREADNAME_INFO *pThreadName; + DBG_THREAD *pThread; + *cont = DBG_CONTINUE; @@ -388,6 +391,19 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL case EXCEPTION_SINGLE_STEP: is_debug = TRUE; break; + case EXCEPTION_NAME_THREAD: + pThreadName = (THREADNAME_INFO*)(rec->ExceptionInformation); + if (pThreadName->dwThreadID == -1) + pThread = DEBUG_CurrThread; + else + pThread = DEBUG_GetThread(DEBUG_CurrProcess, pThreadName->dwThreadID); + + if (ReadProcessMemory(DEBUG_CurrThread->process->handle, pThreadName->szName, + pThread->name, 9, NULL)) + DEBUG_Printf (DBG_CHN_MESG, + "Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n", + pThread->tid, pThread->name); + return TRUE; } if (first_chance && !force && !DBG_IVAR(BreakOnFirstChance))