From b939b87f06b03653eaea8738752cce1155e908f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?= =?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Sun, 26 Jun 2016 11:14:49 +0000 Subject: [PATCH 1/3] Support settings thread name (MS-Windows) This is done by catching an exception number 0x406D1388 (it has no documented name), which is thrown by the program. The exception record contains an ID of a thread and a name to give it. This requires rolling back some changes in handle_exception(), which now again returns more than two distinct values. The code 2 means that gdb should just continue, without returning thread ID up the stack (which will result in further handling of the exception, which is not what we want). --- gdb/windows-nat.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 3f67486..01e7954 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -174,6 +174,9 @@ static int debug_registers_used; static int windows_initialization_done; #define DR6_CLEAR_VALUE 0xffff0ff0 +#define WINDOWS_THREADNAME_EXCEPTION 0x406D1388 +#define WINDOWS_THREADNAME_EXCEPTION_S "0x406D1388" + /* The string sent by cygwin when it processes a signal. FIXME: This should be in a cygwin include file. */ #ifndef _CYGWIN_SIGNAL_STRING @@ -1035,6 +1038,7 @@ static int handle_exception (struct target_waitstatus *ourstatus) { DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; + int result = 1; ourstatus->kind = TARGET_WAITKIND_STOPPED; @@ -1140,6 +1144,38 @@ handle_exception (struct target_waitstatus *ourstatus) DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION"); ourstatus->value.sig = GDB_SIGNAL_ILL; break; + case WINDOWS_THREADNAME_EXCEPTION: + DEBUG_EXCEPTION_SIMPLE (WINDOWS_THREADNAME_EXCEPTION_S); + ourstatus->value.sig = GDB_SIGNAL_TRAP; + if (current_event.u.Exception.ExceptionRecord.NumberParameters == 4) + { + DWORD named_thread_id; + ptid_t named_thread_ptid; + struct thread_info *named_thread; + uintptr_t thread_name_target; + char *thread_name; + + named_thread_id = (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionInformation[2]; + thread_name_target = (uintptr_t) current_event.u.Exception.ExceptionRecord.ExceptionInformation[1]; + + if (named_thread_id == (DWORD) -1) + named_thread_id = current_event.dwThreadId; + + named_thread_ptid = ptid_build (current_event.dwProcessId, 0, named_thread_id), + named_thread = find_thread_ptid (named_thread_ptid); + + thread_name = NULL; + if (!target_read_string ((CORE_ADDR) thread_name_target, &thread_name, 1024, 0) + || !thread_name || !*thread_name) + /* nothing to do */; + else + { + xfree (named_thread->name); + named_thread->name = thread_name; + } + result = 2; + } + break; default: /* Treat unhandled first chance exceptions specially. */ if (current_event.u.Exception.dwFirstChance) @@ -1153,7 +1189,7 @@ handle_exception (struct target_waitstatus *ourstatus) } exception_count++; last_sig = ourstatus->value.sig; - return 1; + return result; } /* Resume thread specified by ID, or all artificially suspended @@ -1510,10 +1546,19 @@ get_windows_debug_event (struct target_ops *ops, "EXCEPTION_DEBUG_EVENT")); if (saw_create != 1) break; - if (handle_exception (ourstatus)) - thread_id = current_event.dwThreadId; - else - continue_status = DBG_EXCEPTION_NOT_HANDLED; + switch (handle_exception (ourstatus)) + { + case 0: + default: + continue_status = DBG_EXCEPTION_NOT_HANDLED; + break; + case 1: + thread_id = current_event.dwThreadId; + break; + case 2: + continue_status = DBG_CONTINUE; + break; + } break; case OUTPUT_DEBUG_STRING_EVENT: /* Message from the kernel. */ -- 2.4.0