From 9e0f9ec7aedb59cacaf5831a27b925d791090113 Mon Sep 17 00:00:00 2001 From: Jon Turney Date: Thu, 28 Jul 2016 00:40:23 +0100 Subject: [PATCH] Send thread names to debugger GDB since commit 24cdb46e [1] can report and use these names. Add utility function SetThreadName(), which sends a thread name to the debugger. Use that: - to set the default thread name for main thread and newly created pthreads. - in pthread_setname_np() for user thread names. - for helper thread names in cygthread::create() - for helper threads which are created directly with CreateThread. Note that there can still be anonymous threads, created by system or injected DLLs. [1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=24cdb46e9f0a694b4fbc11085e094857f08c0419 --- winsup/cygwin/cygthread.cc | 2 ++ winsup/cygwin/dcrt0.cc | 1 + winsup/cygwin/exceptions.cc | 2 +- winsup/cygwin/miscfuncs.cc | 26 ++++++++++++++++++++++++++ winsup/cygwin/miscfuncs.h | 2 ++ winsup/cygwin/net.cc | 1 + winsup/cygwin/thread.cc | 5 +++++ 7 files changed, 38 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index b9d706bac..4404e4a19 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -213,6 +213,8 @@ cygthread::create () this, 0, &id); if (!htobe) api_fatal ("CreateThread failed for %s - %p<%y>, %E", __name, h, id); + else + SetThreadName (GetThreadId (htobe), __name); thread_printf ("created name '%s', thread %p, id %y", __name, h, id); #ifdef DEBUGGING terminated = false; diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 232841176..8ddee0ca7 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -964,6 +964,7 @@ dll_crt0_1 (void *) if (cp > __progname && ascii_strcasematch (cp, ".exe")) *cp = '\0'; } + SetThreadName (GetCurrentThreadId (), program_invocation_short_name); (void) xdr_set_vprintf (&cygxdr_vwarnx); cygwin_finished_initializing = true; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index d65f56e3f..0f5a890b6 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -1288,7 +1288,7 @@ DWORD WINAPI dumpstack_overflow_wrapper (PVOID arg) { cygwin_exception *exc = (cygwin_exception *) arg; - + SetThreadName (GetCurrentThreadId (), "__dumpstack_overflow"); exc->dumpstack (); return 0; } diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index d0e4bf719..5a63b267b 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -1110,3 +1110,29 @@ wmemcpy: \n\ .seh_endproc \n\ "); #endif + +/* Signal the thread name to any attached debugger + + (See "How to: Set a Thread Name in Native Code" + https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx) */ + +#define MS_VC_EXCEPTION 0x406D1388 + +void +SetThreadName(DWORD dwThreadID, const char* threadName) +{ + if (!IsDebuggerPresent ()) + return; + + ULONG_PTR info[] = + { + 0x1000, /* type, must be 0x1000 */ + (ULONG_PTR) threadName, /* pointer to threadname */ + dwThreadID, /* thread ID (+ flags on x86_64) */ +#ifdef __X86__ + 0, /* flags, must be zero */ +#endif + }; + + RaiseException (MS_VC_EXCEPTION, 0, sizeof (info)/sizeof (ULONG_PTR), (ULONG_PTR *) &info); +} diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h index a885dcf19..508729954 100644 --- a/winsup/cygwin/miscfuncs.h +++ b/winsup/cygwin/miscfuncs.h @@ -85,4 +85,6 @@ extern "C" HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func, DWORD creation_flags, LPDWORD thread_id); +void SetThreadName (DWORD dwThreadID, const char* threadName); + #endif /*_MISCFUNCS_H*/ diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 52b3d9874..e4805d3e1 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -1819,6 +1819,7 @@ get_adapters_addresses (PIP_ADAPTER_ADDRESSES *pa_ret, ULONG family) The OS allocates stacks bottom up, so chances are good that the new stack will be located in the lower address area. */ HANDLE thr = CreateThread (NULL, 0, call_gaa, ¶m, 0, NULL); + SetThreadName (GetThreadId (thr), "__call_gaa"); if (!thr) { debug_printf ("CreateThread: %E"); diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index e8622f9b9..7084657e0 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -1992,6 +1992,9 @@ pthread::thread_init_wrapper (void *arg) _my_tls.sigmask = thread->parent_sigmask; thread->set_tls_self_pointer (); + // Give thread default name + SetThreadName (GetCurrentThreadId (), program_invocation_short_name); + thread->mutex.lock (); // if thread is detached force cleanup on exit @@ -2631,6 +2634,8 @@ pthread_setname_np (pthread_t thread, const char *name) oldname = thread->attr.name; thread->attr.name = cp; + SetThreadName (GetThreadId (thread->win32_obj_id), thread->attr.name); + if (oldname) free (oldname); -- 2.43.5