views:

426

answers:

3

I have a server application that uses "a lot" of threads. Without wanting to get into an argument about how many threads it really should be using, it would be nice to be able to see some descriptive text in the debugger "threads" window describing what each one is, without having to click through to it and determine from the context what it is.

They all have the same start address so generally the threads window says something like "thread_base::start" or something similar. I'd like to know if there is an API call or something that allows me to customise that text.

+5  A: 

Use SetThreadName

David Norman
Probably worth noting that it works by sending a special exception to the debugger; if a debugger isn't attached to the process at the time you call SetThreadName, the thread won't have a name. And there's no "GetThreadName" to complement. If a thread should know its own name, it needs to store it.
Rob Kennedy
+5  A: 

Here is the code I use.

This goes in a header file.

#pragma once

#define MS_VC_EXCEPTION 0x406d1388
#pragma warning(disable: 6312)
#pragma warning(disable: 6322)

typedef struct tagTHREADNAME_INFO
{
    DWORD dwType;        // must be 0x1000
    LPCSTR szName;       // pointer to name (in same addr space)
    DWORD dwThreadID;    // thread ID (-1 caller thread)
    DWORD dwFlags;       // reserved for future use, most be zero
} THREADNAME_INFO;

inline
void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
{
#ifdef _DEBUG
    THREADNAME_INFO info;
    info.dwType = 0x1000;
    info.szName = szThreadName;
    info.dwThreadID = dwThreadID;
    info.dwFlags = 0;

    __try
    {
        RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info);
    }
    __except (EXCEPTION_CONTINUE_EXECUTION)
    {
    }
#else
    dwThreadID;
    szThreadName;
#endif
}

Then I call it like this inside the threads proc.

SetThreadName(GetCurrentThreadId(), "VideoSource Thread");

It is worth noting that this is the exact code that David posted a link to (Thanks! I had forgotten where I got it). I didn't delete this post because I'd like the code to still be available if MSDN decides to reorganize its links (again).

Jere.Jones
out of curiosity, why did you make it a DEBUG only thingie?
Serge - appTranslator
Well, it's not the *exact* version. The MSDN version doesn't vary by _DEBUG. With this code, if you run the release version under a debugger, the threads won't have names.
Rob Kennedy
I use the names to identify the threads in the debugger. If I'm not debugging, I d0n't want the overhead or possible attach vector.
Jere.Jones
You can still attach a debugger to a release build, and it is there that you will need all the help you can get
1800 INFORMATION
A: 

I have this working for Win32 desktop apps with VS2005, but the same code doesn't work for WinCE6. VS2005 must be getting the thread name somehow because it is displayed in the debugger. If the same mechanism is used, maybe just the exception id is different under WinCE6? Has anyone got this working under WinCE6?

MersennePrime
I should add that the exception is getting through to the debugger, as I can get it to break upon receiving exception 0x406d1388. It just doesn't convey the exception information to the display of thread names in the debugger.
MersennePrime