From 7a4fac770864393b1610b6bccc2e190620e4543e 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, though MSDN dubs it "MS_VC_EXCEPTION" in one code example), 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 value HANDLE_EXCEPTION_IGNORED 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 | 77 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 3f67486..8917997 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -174,6 +174,15 @@ static int debug_registers_used; static int windows_initialization_done; #define DR6_CLEAR_VALUE 0xffff0ff0 +#define MS_VC_EXCEPTION 0x406D1388 + +typedef enum +{ + HANDLE_EXCEPTION_UNHANDLED = 0, + HANDLE_EXCEPTION_HANDLED, + HANDLE_EXCEPTION_IGNORED +} handle_exception_result; + /* The string sent by cygwin when it processes a signal. FIXME: This should be in a cygwin include file. */ #ifndef _CYGWIN_SIGNAL_STRING @@ -1031,10 +1040,11 @@ display_selectors (char * args, int from_tty) host_address_to_string (\ current_event.u.Exception.ExceptionRecord.ExceptionAddress)) -static int +static handle_exception_result handle_exception (struct target_waitstatus *ourstatus) { DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; + handle_exception_result result = HANDLE_EXCEPTION_HANDLED; ourstatus->kind = TARGET_WAITKIND_STOPPED; @@ -1064,7 +1074,7 @@ handle_exception (struct target_waitstatus *ourstatus) && addr < cygwin_load_end)) || (find_pc_partial_function (addr, &fn, NULL, NULL) && startswith (fn, "KERNEL32!IsBad"))) - return 0; + return HANDLE_EXCEPTION_UNHANDLED; } #endif break; @@ -1140,10 +1150,52 @@ 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] & 0xFFFFFFFF) == 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"); + + named_thread_id = (long) (0xFFFFFFFF & 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) + { + thread_name[thread_name_len - 1] = '\0'; + if (thread_name[0] != '\0' && named_thread != NULL) + { + xfree (named_thread->name); + named_thread->name = thread_name; + } + else + { + xfree (thread_name); + } + } + ourstatus->value.sig = GDB_SIGNAL_TRAP; + result = HANDLE_EXCEPTION_IGNORED; + break; + } + /* treat improperly formed exception as unknown, fallthrough */ default: /* Treat unhandled first chance exceptions specially. */ if (current_event.u.Exception.dwFirstChance) - return 0; + return HANDLE_EXCEPTION_UNHANDLED; printf_unfiltered ("gdb: unknown target exception 0x%08x at %s\n", (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode, host_address_to_string ( @@ -1153,7 +1205,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 +1562,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 HANDLE_EXCEPTION_UNHANDLED: + default: + continue_status = DBG_EXCEPTION_NOT_HANDLED; + break; + case HANDLE_EXCEPTION_HANDLED: + thread_id = current_event.dwThreadId; + break; + case HANDLE_EXCEPTION_IGNORED: + continue_status = DBG_CONTINUE; + break; + } break; case OUTPUT_DEBUG_STRING_EVENT: /* Message from the kernel. */ -- 2.4.0