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:
parent
fdb7df230d
commit
9e0f9ec7ae
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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*/
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user