21

How do I set a name to a Win32 thread. I did'nt find any Win32 API to achieve the same. Basically I want to add the Thread Name in the Log file. Is TLS (Thread Local Storage) the only way to do it?

Canopus
  • 7,351
  • 11
  • 46
  • 57
  • 1
    The SetThreadDescription() API is, going forward, the API by which Microsoft will be supporting this. For more details, see this answer: http://stackoverflow.com/a/43787005/434413 – Chris Kline May 04 '17 at 15:25
  • Also see the discussion [here](https://randomascii.wordpress.com/2015/10/26/thread-naming-in-windows-time-for-something-better/). – Albert Aug 17 '18 at 07:24

10 Answers10

30

Does this help ? How to: Set a Thread Name in Native Code

In managed code, it is as easy as setting the Name property of the corresponding Thread object.

Gishu
  • 134,492
  • 47
  • 225
  • 308
  • 3
    I guess its only for the Visual Studio debugger to display the thread name. – Canopus May 25 '09 at 08:39
  • 2
    Other debuggers have followed suit and respond to the same signal – David Heffernan Feb 13 '11 at 21:46
  • 4
    As http://thetweaker.wordpress.com/2009/04/10/naming-threads/ notes, they all do so by storing the thread name in a debugger data structure. Ergo, without a debugger the name would not be stored, and would not be available for logging purposes. Nasty bug, too: when you try to debug it, it suddenly works again. – MSalters Jun 27 '11 at 13:29
23

http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.90).aspx

//
// Usage: SetThreadName (-1, "MainThread");
//
#include <windows.h>
const DWORD MS_VC_EXCEPTION=0x406D1388;

#pragma pack(push,8)
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;
#pragma pack(pop)

void SetThreadName( DWORD dwThreadID, char* threadName)
{
   THREADNAME_INFO info;
   info.dwType = 0x1000;
   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)
  {
  }
}
phyatt
  • 18,472
  • 5
  • 61
  • 80
fazhang
  • 485
  • 6
  • 13
  • 1
    This won't work, unless you run the code under a debugger. It certainly cannot be used to log a thread's name in a live system. – IInspectable Nov 06 '16 at 21:05
12

According to discussion with the Microsoft debugging team leads (see link below for details) the SetThreadDescription API is the API that will be used going forward by Microsoft to support thread naming officially in native code. By "officially" I mean an MS-supported API for naming threads, as opposed to the current exception-throwing hack that currently only works while a process is running in Visual Studio.

This API became available starting in Windows 10, version 1607.

Currently, however, there is very little tooling support, so the names you set won't be visible in the Visual Studio or WinDbg debuggers. As of April 2017, however, the Microsoft xperf/WPA tools do support it (threads named via this API will have their names show up properly in those tools).

If you would like to see this gain better support, such as in WinDbg, Visual Studio, and crash dump files, please vote for it using this link:

https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/17608120-properly-support-native-thread-naming-via-the-sett

Chris Kline
  • 2,249
  • 26
  • 32
  • Update: Windows Performance Analyzer and an upcoming build of WinDbg now support showing the thread names set via SetThreadDescriptionAPI. https://blogs.msdn.microsoft.com/windbg/2017/06/29/debugger-updates-in-the-16225-sdk-preview/ – Chris Kline Jun 30 '17 at 14:11
  • Update: Version starting with version 15.6, Visual Studio 2017 is now able to display thread names that are set via SetThreadDescription APIs in dump debugging. This feature requires dumps to be collected on Windows 10 Fall Creators Update or later builds. https://learn.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-v15.6#diagnostics4 – Chris Kline Sep 12 '18 at 13:32
  • Note: though the VS release notes state that SetThreadDescription() allows you to see thread names in dumps in Visual Studio 15.6+, I've confirmed in VS 15.9.2 that it also allows you to see thread names while debugging normally as well. I'm working with the documentation team to clarify this (https://github.com/MicrosoftDocs/visualstudio-docs/issues/2057) – Chris Kline Dec 19 '18 at 14:59
10

Win32 threads do not have names. There is a Microsoft convention whereby applications raise special SEH exceptions containing a thread name. These exceptions can be intercepted by debuggers and used to indicate the thread name. A couple of the answers cover that.

However, that is all handled by the debugger. Threads themselves are nameless objects. So, if you want to associate names with your threads, you'll have to develop your own mechanism. Whilst you could use thread local storage that will only allow you to obtain the name from code executing in that thread. So a global map between thread ID and the name would seem like the most natural and useful approach.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
3

You can use a thread-local storage object to store the name. For example,

__declspec( thread ) char threadName[32];

Then you can write and read this from a thread. This might be useful in a logger application, where you want to print out the name of the thread for every message. You probably want to write this variable as soon as the thread starts, and also throw the Microsoft exception (https://stackoverflow.com/a/10364541/364818) so that the debugger also knows the thread name.

Community
  • 1
  • 1
Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
3

If your application runs on Windows version 1607+, you can use SetThreadDescription()

Marcos Marin
  • 752
  • 1
  • 5
  • 17
0

Another way to do this is to store a pointer to the name in the ArbitraryUserPointer field of the TEB of the thread. This can be written to and read from at runtime.

There's a CodeProject article titled "Debugging With The Thread Information Block" that shows you how to do this.

Chris Kline
  • 2,249
  • 26
  • 32
0

Encountered an issue where using the Microsoft solution in Windows 10/11 would only set the first letter of the thread name, and no matter how hard I tried to fix it, either nothing worked at all or only the first letter of the string was set. The solution turned out to be this:

void SetThreadName(const std::wstring& threadName)
{
    SetThreadDescription(thread.m_hThread, threadName.c_str());
}
0

If you want to see the name of your thread in the debugger (windbg or visual studio): http://blogs.msdn.com/stevejs/archive/2005/12/19/505815.aspx

I'm not actually sure if there's a reverse method to get the thread name. But TLS sounds like the way to go.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • You got the wrong impression. The thread's name is **not** stored with the thread. It's stored in the debugger only, and consequently only exists, when a debugger is attached. Without a debugger, the exception simply runs into the following exception filter, that continues like nothing ever happened. The thread name is lost when the application isn't run under a debugger. – IInspectable Nov 06 '16 at 21:08
-2

You can always store this information for yourself in a suitable data structure. Use a hash or a map to map GetThreadId() to this name. Since GetThreadId() is always a unique identifier, this works just fine.

Cheers !

Of course, if he's creating many threads, that hashmap will slowly fill up and use more and more memory, so some cleanup procedure is probably a good thing as well.

You're absolutely right. When a thread dies, it's corresponding entry in the map should naturally be removed.

rtn
  • 127,556
  • 20
  • 111
  • 121
  • Of course, if he's creating many threads, that hashmap will slowly fill up and use more and more memory, so some cleanup procedure is probably a good thing as well. – Lasse V. Karlsen May 26 '09 at 21:27
  • 1
    downvoting because i too need an answer to this question, but i actually need to set a name to the thread for profiling reasons. Your answer doesn't answer the question asked :P – Alan Wolfe Jul 09 '15 at 23:31