diff options
author | Jon Turney <jon.turney@dronecode.org.uk> | 2016-07-28 00:40:23 +0100 |
---|---|---|
committer | Jon Turney <jon.turney@dronecode.org.uk> | 2016-08-23 15:07:42 +0100 |
commit | 9e0f9ec7aedb59cacaf5831a27b925d791090113 (patch) | |
tree | 2c0578bb4a92c36a8f06e95ca5e7dfd373abd792 | |
parent | fdb7df230ded019be0472565d79de14fe677dea7 (diff) | |
download | newlib-9e0f9ec7aedb59cacaf5831a27b925d791090113.zip newlib-9e0f9ec7aedb59cacaf5831a27b925d791090113.tar.gz newlib-9e0f9ec7aedb59cacaf5831a27b925d791090113.tar.bz2 |
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
-rw-r--r-- | winsup/cygwin/cygthread.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/miscfuncs.cc | 26 | ||||
-rw-r--r-- | winsup/cygwin/miscfuncs.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/net.cc | 1 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 5 |
7 files changed, 38 insertions, 1 deletions
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index b9d706b..4404e4a 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 2328411..8ddee0c 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 d65f56e..0f5a890 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 d0e4bf7..5a63b26 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 a885dcf..5087299 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 52b3d98..e4805d3 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 e8622f9..7084657 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); |