From 141c4ff8f185dd2ee1a8ffbf4d26a21e16c852bd 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 | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 3f67486..084d5a9 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 MS_VC_EXCEPTION 0x406D1388 +#define MS_VC_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,49 @@ handle_exception (struct target_waitstatus *ourstatus) DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION"); ourstatus->value.sig = GDB_SIGNAL_ILL; break; + case MS_VC_EXCEPTION: + if (current_event.u.Exception.ExceptionRecord.NumberParameters >= 3 + && current_event.u.Exception.ExceptionRecord.ExceptionInformation[0] == 0x1000) + { + long named_thread_id; + ptid_t named_thread_ptid; + struct thread_info *named_thread; + CORE_ADDR thread_name_target; + char *thread_name; + int thread_name_len; + + DEBUG_EXCEPTION_SIMPLE (MS_VC_EXCEPTION_S); + + named_thread_id = (long) current_event.u.Exception.ExceptionRecord.ExceptionInformation[2]; + thread_name_target = 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; + thread_name_len = target_read_string (thread_name_target, &thread_name, 1025, 0); + if (thread_name_len > 0 && thread_name != NULL) + { + if (thread_name[thread_name_len - 1] != '\0') + thread_name[thread_name_len - 1] = '\0'; + if (thread_name[0] != '\0') + { + xfree (named_thread->name); + named_thread->name = thread_name; + } + else + { + xfree (thread_name); + } + } + ourstatus->value.sig = GDB_SIGNAL_TRAP; + result = 2; + break; + } + /* treat improperly formed exception as unknown, fallthrough */ default: /* Treat unhandled first chance exceptions specially. */ if (current_event.u.Exception.dwFirstChance) @@ -1153,7 +1200,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 +1557,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