Cygwin: Set threadnames with SetThreadDescription()

gdb master recently learnt how to use GetThreadDescription() [1], so set
threadnames using SetThreadDescription() [available since Windows 10
1607] as well.

This is superior to using a special exception to indicate the thread
name to the debugger, because the thread name isn't missed if you don't
have a debugger attached at the time it's set.

It's not clear what the encoding of a thread name string is, we assume
UTF8 for the moment.

For the moment, continue to use the old method as well, for the benefit
of older gdb versions etc.

[1] https://sourceware.org/pipermail/gdb-patches/2022-April/187833.html
This commit is contained in:
Jon Turney 2022-05-19 17:27:39 +01:00
parent f145174f80
commit d4689b99c6
No known key found for this signature in database
GPG Key ID: C7C86F0370285C81
2 changed files with 32 additions and 2 deletions

View File

@ -473,6 +473,7 @@ LoadDLLfuncEx (PrefetchVirtualMemory, 16, kernel32, 1)
LoadDLLfunc (QueryInterruptTime, 4, KernelBase) LoadDLLfunc (QueryInterruptTime, 4, KernelBase)
LoadDLLfunc (QueryInterruptTimePrecise, 4, KernelBase) LoadDLLfunc (QueryInterruptTimePrecise, 4, KernelBase)
LoadDLLfunc (QueryUnbiasedInterruptTimePrecise, 4, KernelBase) LoadDLLfunc (QueryUnbiasedInterruptTimePrecise, 4, KernelBase)
LoadDLLfuncEx (SetThreadDescription, 8, KernelBase, 1)
LoadDLLfunc (VirtualAlloc2, 28, KernelBase) LoadDLLfunc (VirtualAlloc2, 28, KernelBase)
LoadDLLfunc (NtMapViewOfSectionEx, 36, ntdll) LoadDLLfunc (NtMapViewOfSectionEx, 36, ntdll)

View File

@ -18,6 +18,9 @@ details. */
#include "tls_pbuf.h" #include "tls_pbuf.h"
#include "mmap_alloc.h" #include "mmap_alloc.h"
/* not yet prototyped in w32api */
extern "C" HRESULT WINAPI SetThreadDescription (HANDLE hThread, PCWSTR lpThreadDescription);
/* Get handle count of an object. */ /* Get handle count of an object. */
ULONG ULONG
get_obj_handle_count (HANDLE h) get_obj_handle_count (HANDLE h)
@ -916,8 +919,8 @@ wmempcpy: \n\
#define MS_VC_EXCEPTION 0x406D1388 #define MS_VC_EXCEPTION 0x406D1388
void static void
SetThreadName(DWORD dwThreadID, const char* threadName) SetThreadNameExc (DWORD dwThreadID, const char* threadName)
{ {
if (!IsDebuggerPresent ()) if (!IsDebuggerPresent ())
return; return;
@ -938,6 +941,32 @@ SetThreadName(DWORD dwThreadID, const char* threadName)
__endtry __endtry
} }
void
SetThreadName (DWORD dwThreadID, const char* threadName)
{
HANDLE hThread = OpenThread (THREAD_SET_LIMITED_INFORMATION, FALSE, dwThreadID);
if (hThread)
{
/* SetThreadDescription only exists in a wide-char version, so we must
convert threadname to wide-char. The encoding of threadName is
unclear, so use UTF8 until we know better. */
int bufsize = MultiByteToWideChar (CP_UTF8, 0, threadName, -1, NULL, 0);
WCHAR buf[bufsize];
bufsize = MultiByteToWideChar (CP_UTF8, 0, threadName, -1, buf, bufsize);
HRESULT hr = SetThreadDescription (hThread, buf);
if (hr != S_OK)
{
debug_printf ("SetThreadDescription() failed. %08x %08x\n",
GetLastError (), hr);
}
CloseHandle (hThread);
}
/* also use the older, exception-based method of setting threadname for the
benefit of things which don't known about GetThreadDescription. */
SetThreadNameExc (dwThreadID, threadName);
}
#define add_size(p,s) ((p) = ((__typeof__(p))((PBYTE)(p)+(s)))) #define add_size(p,s) ((p) = ((__typeof__(p))((PBYTE)(p)+(s))))
static WORD num_cpu_per_group = 0; static WORD num_cpu_per_group = 0;