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
This commit is contained in:
Jon Turney 2016-07-28 00:40:23 +01:00
parent fdb7df230d
commit 9e0f9ec7ae
7 changed files with 38 additions and 1 deletions

View File

@ -213,6 +213,8 @@ cygthread::create ()
this, 0, &id); this, 0, &id);
if (!htobe) if (!htobe)
api_fatal ("CreateThread failed for %s - %p<%y>, %E", __name, h, id); 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); thread_printf ("created name '%s', thread %p, id %y", __name, h, id);
#ifdef DEBUGGING #ifdef DEBUGGING
terminated = false; terminated = false;

View File

@ -964,6 +964,7 @@ dll_crt0_1 (void *)
if (cp > __progname && ascii_strcasematch (cp, ".exe")) if (cp > __progname && ascii_strcasematch (cp, ".exe"))
*cp = '\0'; *cp = '\0';
} }
SetThreadName (GetCurrentThreadId (), program_invocation_short_name);
(void) xdr_set_vprintf (&cygxdr_vwarnx); (void) xdr_set_vprintf (&cygxdr_vwarnx);
cygwin_finished_initializing = true; cygwin_finished_initializing = true;

View File

@ -1288,7 +1288,7 @@ DWORD WINAPI
dumpstack_overflow_wrapper (PVOID arg) dumpstack_overflow_wrapper (PVOID arg)
{ {
cygwin_exception *exc = (cygwin_exception *) arg; cygwin_exception *exc = (cygwin_exception *) arg;
SetThreadName (GetCurrentThreadId (), "__dumpstack_overflow");
exc->dumpstack (); exc->dumpstack ();
return 0; return 0;
} }

View File

@ -1110,3 +1110,29 @@ wmemcpy: \n\
.seh_endproc \n\ .seh_endproc \n\
"); ");
#endif #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);
}

View File

@ -85,4 +85,6 @@ extern "C" HANDLE WINAPI CygwinCreateThread (LPTHREAD_START_ROUTINE thread_func,
DWORD creation_flags, DWORD creation_flags,
LPDWORD thread_id); LPDWORD thread_id);
void SetThreadName (DWORD dwThreadID, const char* threadName);
#endif /*_MISCFUNCS_H*/ #endif /*_MISCFUNCS_H*/

View File

@ -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 The OS allocates stacks bottom up, so chances are good that the new
stack will be located in the lower address area. */ stack will be located in the lower address area. */
HANDLE thr = CreateThread (NULL, 0, call_gaa, &param, 0, NULL); HANDLE thr = CreateThread (NULL, 0, call_gaa, &param, 0, NULL);
SetThreadName (GetThreadId (thr), "__call_gaa");
if (!thr) if (!thr)
{ {
debug_printf ("CreateThread: %E"); debug_printf ("CreateThread: %E");

View File

@ -1992,6 +1992,9 @@ pthread::thread_init_wrapper (void *arg)
_my_tls.sigmask = thread->parent_sigmask; _my_tls.sigmask = thread->parent_sigmask;
thread->set_tls_self_pointer (); thread->set_tls_self_pointer ();
// Give thread default name
SetThreadName (GetCurrentThreadId (), program_invocation_short_name);
thread->mutex.lock (); thread->mutex.lock ();
// if thread is detached force cleanup on exit // 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; oldname = thread->attr.name;
thread->attr.name = cp; thread->attr.name = cp;
SetThreadName (GetThreadId (thread->win32_obj_id), thread->attr.name);
if (oldname) if (oldname)
free (oldname); free (oldname);