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);