How to Programmatically Set Thread Name in Debugger Window(native) ?
Most of windows Debuggers supports thread names. This is really helpful to identify the purpose of threads especially when you’re having multiple threads in your application. In Visual Studio you can see the details of threads including it’s name in the “Threads” window. [updated types 9.15 AM 11-03-2008 IST]
There are no direction functions to set the thread names for a thread. But it’s possible to implement by exploiting exception handling mechanism of a debugger. The debugger will get the first chance to handle the exception when an application is being debugged. Using this concept we will be explicitly raising an exception with parameters which specifies the thread name and other information. The particular exception will be specially handled by debugger and thus it will update the name of corresponding thread.
When application running without debugger, raising exceptions lead to application crash. So we’ve to enclose the RaiseException code inside a try-except block.
Here’s the sample snippet. This has been specified in MSDN directly.
[sourcecode language='cpp']
#define MS_VC_EXCEPTION 0×406D1388
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0×1000.
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;
#pragma pack(pop)
void SetThreadName( DWORD dwThreadID, char* threadName)
{
THREADNAME_INFO info;
info.dwType = 0×1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
__try
{
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// printf(”Not under debugger. Swallowing exception”);
}
}
[/sourcecode]
The function can be used either by specifying the thread ID of the particular thread to be named or passing -1 as thread ID will set the name for the current thread which is calling the function. The demonstration of inside and external calling is demonstrated below. If same thread function is used to create multiple threads, then setting name from external thread or by getting current thread ID is better than passing -1 as thread ID.
[sourcecode language='cpp']
DWORD WINAPI Thread2(LPVOID)
{
// Setting for current thread
SetThreadName( -1, “DisplayThread” );
return 0;
}
DWORD WINAPI Thread1(LPVOID)
{
SetThreadName( -1, “Worker” );
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwID;
CreateThread( 0,0,Thread1, 0,0,&dwID);
// Setting using thread ID.
SetThreadName(dwID,”External1″);
CreateThread( 0,0,Thread2, 0,0,&dwID);
// Setting using thread ID.
SetThreadName(dwID,”External2″);
// Creating new thread using Thread2 function again
HANDLE h = CreateThread( 0,0,Thread2, 0,0,&dwID);
// Setting using thread ID.
SetThreadName(dwID,”External3″);
WaitForSingleObject( h, INFINITE );
return 0;
}
[/sourcecode]
MSDN has also specified how to set thread name in Managed code
