[PATCH 2/2] Send thread names to debugger

Corinna Vinschen corinna-cygwin@cygwin.com
Thu Jul 28 19:35:00 GMT 2016


On Jul 28 12:43, Jon Turney wrote:
> GDB with the patch from [1] can report and use these names.

This is still WIP, right?

> Add utility function SetThreadName(), which sends a thread name to the
> debugger.
> 
> Wire this up to set the default thread name for main thread and newly
> created pthreads.
> 
> Wire this up in pthread_setname_np() for user thread names.
> 
> Wire this up in cygthread::create() for helper thread names.  Also wire it
> up for helper threads which are created directly with CreateThread.
> 
> TODO: Make SetThreadName() available to libgmon.a so the profiling thread
> created by that can be named as well.
> 
> Note that there can still be anonymous threads, created by the kernel or
> injected DLLs.
> 
> [1] https://sourceware.org/ml/gdb-patches/2016-07/msg00307.html
> 
> Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
> ---
>  winsup/cygwin/cygthread.cc  |  2 ++
>  winsup/cygwin/dcrt0.cc      |  1 +
>  winsup/cygwin/exceptions.cc |  2 +-
>  winsup/cygwin/miscfuncs.cc  | 28 ++++++++++++++++++++++++++++
>  winsup/cygwin/miscfuncs.h   |  2 ++
>  winsup/cygwin/net.cc        |  2 ++
>  winsup/cygwin/profil.c      |  2 ++
>  winsup/cygwin/thread.cc     |  5 +++++
>  8 files changed, 43 insertions(+), 1 deletion(-)
> 
> diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
> index b9d706b..2f7f2a1 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);
                    ^^^         ^^^
                   space?      space?

Just wondering: Wouldn't it make sense to rename the internal threads
so they either always start with "cyg_" or with double underscore or
something like that to mark them as internal?  E.g.

  new cygthread (wait_sig, cygself, "cyg_wait_sig");

>        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..de581c1 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);
                 ^^^                ^^^
                space?             space?

>  
>    (void) xdr_set_vprintf (&cygxdr_vwarnx);
>    cygwin_finished_initializing = true;
> diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
> index d65f56e..1d028a7 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");
                 ^^^                ^^^
                space?             space?

>    exc->dumpstack ();
>    return 0;
>  }
> diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc
> index d0e4bf7..353633b 100644
> --- a/winsup/cygwin/miscfuncs.cc
> +++ b/winsup/cygwin/miscfuncs.cc
> @@ -1110,3 +1110,31 @@ 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)
> +//

/* */, please

> +
> +#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 */
                  ^^^
                 space?

> +      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);
                                              ^^^          ^^^
                                             space?       space?

> +}
> diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h
> index a885dcf..5390dd1 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);
                    ^^^
                   space?

> +
>  #endif /*_MISCFUNCS_H*/
> diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
> index 52b3d98..94ae604 100644
> --- a/winsup/cygwin/net.cc
> +++ b/winsup/cygwin/net.cc
> @@ -1776,6 +1776,8 @@ call_gaa (LPVOID param)
>    gaa_wa *p = (gaa_wa *) param;
>    PIP_ADAPTER_ADDRESSES pa0 = NULL;
>  
> +  SetThreadName(GetCurrentThreadId(), "call_gaa");
                 ^^^                ^^^
                space?             space?



> +
>    if (!p->pa_ret)
>      return GetAdaptersAddresses (p->family, GAA_FLAG_INCLUDE_PREFIX
>  					    | GAA_FLAG_INCLUDE_ALL_INTERFACES,
> diff --git a/winsup/cygwin/profil.c b/winsup/cygwin/profil.c
> index be59b49..4b2e873 100644
> --- a/winsup/cygwin/profil.c
> +++ b/winsup/cygwin/profil.c
> @@ -91,6 +91,8 @@ static void CALLBACK
>  profthr_func (LPVOID arg)
>  {
>    struct profinfo *p = (struct profinfo *) arg;
> +  // XXX: can't use SetThreadName() here as it's part of the cygwin DLL
> +  // SetThreadName(GetCurrentThreadId(), "prof");
                    ^^^                ^^^
                   space?             space?

Since it's such a short function, why not just add a copy to profile.c
or just perform the RaiseException directly?

>  
>    for (;;)
>      {
> diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
> index e41e0c1..7f60db7 100644
> --- a/winsup/cygwin/thread.cc
> +++ b/winsup/cygwin/thread.cc
> @@ -1985,6 +1985,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);
                 ^^^                ^^^
                space?             space?

> +
>    thread->mutex.lock ();
>  
>    // if thread is detached force cleanup on exit
> @@ -2622,6 +2625,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);
                 ^^^                ^^^
                space?             space?

> +
>    if (oldname)
>      free(oldname);
          ^^^
         space?


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20160728/a6078dee/attachment.sig>


More information about the Cygwin-patches mailing list