From 99bb393f1d107cf2c4016c486f85625d362027a7 Mon Sep 17 00:00:00 2001 From: Hannes Domani Date: Wed, 23 Sep 2020 18:16:24 +0200 Subject: [PATCH] Handle 64bit breakpoints of WOW64 processes as SIGINT When a WOW64 process triggers a breakpoint exception in 64bit code (which happens when a 64bit gdb calls DebugBreakProcess for a 32bit target), gdb ignores the breakpoint (because Wow64GetThreadContext can only report the pc of 32bit code, and there is not int3 at this location). But if these 64bit breakpoint exceptions are handled as SIGINT, gdb doesn't check for int3, and always stops the target. gdb/ChangeLog: 2020-09-23 Hannes Domani * nat/windows-nat.c (handle_exception): Handle 64bit breakpoints in WOW64 processes as SIGINT. * nat/windows-nat.h: Make wow64_process a shared variable. * windows-nat.c: Remove static wow64_process variable. gdbserver/ChangeLog: 2020-09-23 Hannes Domani * win32-low.cc: Remove local wow64_process variable. * win32-low.h: Remove local wow64_process variable. --- gdb/ChangeLog | 7 +++++++ gdb/nat/windows-nat.c | 15 +++++++++++++++ gdb/nat/windows-nat.h | 2 ++ gdb/windows-nat.c | 1 - gdbserver/ChangeLog | 5 +++++ gdbserver/win32-low.cc | 4 ---- gdbserver/win32-low.h | 2 -- 7 files changed, 29 insertions(+), 7 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 241f3e70271..3b851dba41e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2020-09-23 Hannes Domani + + * nat/windows-nat.c (handle_exception): Handle 64bit breakpoints + in WOW64 processes as SIGINT. + * nat/windows-nat.h: Make wow64_process a shared variable. + * windows-nat.c: Remove static wow64_process variable. + 2020-09-23 Tom Tromey PR symtab/25470: diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c index be6db9719a0..2cbbc0f2ccb 100644 --- a/gdb/nat/windows-nat.c +++ b/gdb/nat/windows-nat.c @@ -41,6 +41,7 @@ std::vector pending_stops; EXCEPTION_RECORD siginfo_er; #ifdef __x86_64__ +bool wow64_process = false; bool ignore_first_breakpoint = false; #endif @@ -240,6 +241,20 @@ handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions) ourstatus->kind = TARGET_WAITKIND_SPURIOUS; ignore_first_breakpoint = false; } + else if (wow64_process) + { + /* This breakpoint exception is triggered for WOW64 processes when + reaching an int3 instruction in 64bit code. + gdb checks for int3 in case of SIGTRAP, this fails because + Wow64GetThreadContext can only report the pc of 32bit code, and + gdb lets the target process continue. + So handle it as SIGINT instead, then the target is stopped + unconditionally. */ + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT"); + rec->ExceptionCode = DBG_CONTROL_C; + ourstatus->value.sig = GDB_SIGNAL_INT; + break; + } #endif /* FALLTHROUGH */ case STATUS_WX86_BREAKPOINT: diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h index f742db2acc8..9bfcb16865c 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -215,6 +215,8 @@ extern std::vector pending_stops; extern EXCEPTION_RECORD siginfo_er; #ifdef __x86_64__ +/* The target is a WOW64 process */ +extern bool wow64_process; /* Ignore first breakpoint exception of WOW64 process */ extern bool ignore_first_breakpoint; #endif diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index ba88c33cac3..7fff41de760 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -235,7 +235,6 @@ static std::vector thread_list; static int saw_create; static int open_process_used = 0; #ifdef __x86_64__ -static bool wow64_process = false; static void *wow64_dbgbreak; #endif diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index d47fcfd300a..c97d4b1d284 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,8 @@ +2020-09-23 Hannes Domani + + * win32-low.cc: Remove local wow64_process variable. + * win32-low.h: Remove local wow64_process variable. + 2020-09-18 Tom Tromey * netbsd-low.h (class netbsd_process_target) : Update. diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 9980986c739..e5f85a1a22f 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -91,10 +91,6 @@ static int faked_breakpoint = 0; /* True if current_process_handle needs to be closed. */ static bool open_process_used = false; -#ifdef __x86_64__ -bool wow64_process = false; -#endif - const struct target_desc *win32_tdesc; #ifdef __x86_64__ const struct target_desc *wow64_win32_tdesc; diff --git a/gdbserver/win32-low.h b/gdbserver/win32-low.h index d4ad5d83d29..8c113f86c77 100644 --- a/gdbserver/win32-low.h +++ b/gdbserver/win32-low.h @@ -30,8 +30,6 @@ extern const struct target_desc *win32_tdesc; #ifdef __x86_64__ extern const struct target_desc *wow64_win32_tdesc; -extern bool wow64_process; - typedef BOOL (WINAPI *winapi_Wow64GetThreadContext) (HANDLE, PWOW64_CONTEXT); extern winapi_Wow64GetThreadContext win32_Wow64GetThreadContext; #endif -- 2.30.2