This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2] 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 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, &param, 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 fac801b..1205ce3 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
@@ -2630,6 +2633,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.8.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]