There is a nice feature that is all but undocumented, and has next to no web presence too: you can give your threads meaningful names.
While this is trivial in managed code, it is hardly obvious for native. The TIB (the internal thread administration data table) does not include a name slot, so there’s not much use looking for some SetThreadName(…) API in win32.
Anyway, the MS debuggers (both Visual Studio and the WinDbg family) have a secret trap door just for that: the exception 0x406D1388. When raised, the debugger (obviously) gets a first-chance of handling it. This exception can carry thread-naming info, in an undocumented THREADNAME_INFO type, and the debuggers can interpret this info and internally attach that name to that thread ID. A quick rehash of the MSDN code:
// // Usage: SetThreadName ("CurrentThread"); // SetThreadName ("OtherThread", 4567); // typedef struct tagTHREADNAME_INFO { DWORD dwType; // must be 0x1000 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; void SetThreadName( LPCSTR szThreadName, CONST DWORD dwThreadID = -1) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = szThreadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; __try { RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); } __except(EXCEPTION_CONTINUE_EXECUTION) {} }
This can be a valuable debugging aid in multi-threaded apps – which today amounts to practically all of them.
Thanks, it’s very useful.
If you can figure out how to make it work under WinCE6 and VS2005, please post an update!