* [review] Share handle_exception
@ 2019-11-26 17:21 Tom Tromey (Code Review)
2019-11-29 20:03 ` Pedro Alves (Code Review)
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Tom Tromey (Code Review) @ 2019-11-26 17:21 UTC (permalink / raw)
To: gdb-patches
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/716
......................................................................
Share handle_exception
Both gdb and gdbserver have a "handle_exception" function, the bulk of
which is shared between the two implementations. This patch arranges
for the entire thing to be moved into nat/windows-nat.c, with the
differences handled by callbacks. This patch introduces one more
callback to make this possible.
gdb/ChangeLog
2019-11-26 Tom Tromey <tromey@adacore.com>
* windows-nat.c (MS_VC_EXCEPTION): Move to nat/windows-nat.c.
(handle_exception_result): Move to nat/windows-nat.h.
(DEBUG_EXCEPTION_SIMPLE): Remove.
(windows_nat::handle_ms_vc_exception): New function.
(handle_exception): Move to nat/windows-nat.c.
(get_windows_debug_event): Update.
* nat/windows-nat.h (handle_ms_vc_exception): Declare.
(handle_exception_result): Move from windows-nat.c.
(handle_exception): Declare.
* nat/windows-nat.c (MS_VC_EXCEPTION, handle_exception): Move from
windows-nat.c.
gdb/gdbserver/ChangeLog
2019-11-26 Tom Tromey <tromey@adacore.com>
* win32-low.c (handle_exception): Remove.
(windows_nat::handle_ms_vc_exception): New function.
(get_child_debug_event): Add "continue_status" parameter.
Update.
(win32_wait): Update.
Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
---
M gdb/ChangeLog
M gdb/gdbserver/ChangeLog
M gdb/gdbserver/win32-low.c
M gdb/nat/windows-nat.c
M gdb/nat/windows-nat.h
M gdb/windows-nat.c
6 files changed, 245 insertions(+), 283 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 221a6e7..d2caa25 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@
2019-11-26 Tom Tromey <tromey@adacore.com>
+ * windows-nat.c (MS_VC_EXCEPTION): Move to nat/windows-nat.c.
+ (handle_exception_result): Move to nat/windows-nat.h.
+ (DEBUG_EXCEPTION_SIMPLE): Remove.
+ (windows_nat::handle_ms_vc_exception): New function.
+ (handle_exception): Move to nat/windows-nat.c.
+ (get_windows_debug_event): Update.
+ * nat/windows-nat.h (handle_ms_vc_exception): Declare.
+ (handle_exception_result): Move from windows-nat.c.
+ (handle_exception): Declare.
+ * nat/windows-nat.c (MS_VC_EXCEPTION, handle_exception): Move from
+ windows-nat.c.
+
+2019-11-26 Tom Tromey <tromey@adacore.com>
+
* windows-nat.c (exception_count, event_count): Remove.
(handle_exception, get_windows_debug_event)
(do_initial_windows_stuff): Update.
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 5c4c580..8ca754b 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,13 @@
2019-11-26 Tom Tromey <tromey@adacore.com>
+ * win32-low.c (handle_exception): Remove.
+ (windows_nat::handle_ms_vc_exception): New function.
+ (get_child_debug_event): Add "continue_status" parameter.
+ Update.
+ (win32_wait): Update.
+
+2019-11-26 Tom Tromey <tromey@adacore.com>
+
* win32-low.c (windows_nat::handle_load_dll): Rename from
handle_load_dll. No longer static.
(windows_nat::handle_unload_dll): Rename from handle_unload_dll.
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index 3fcd2a6..ba49dd9 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -1143,114 +1143,6 @@
}
static void
-handle_exception (struct target_waitstatus *ourstatus)
-{
- DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
-
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
- switch (code)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_STACK_OVERFLOW:
- OUTMSG2 (("STATUS_STACK_OVERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_FLOAT_DENORMAL_OPERAND:
- OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INEXACT_RESULT:
- OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INVALID_OPERATION:
- OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_OVERFLOW:
- OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_STACK_CHECK:
- OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_UNDERFLOW:
- OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_OVERFLOW:
- OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_BREAKPOINT:
- OUTMSG2 (("EXCEPTION_BREAKPOINT"));
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
-#ifdef _WIN32_WCE
- /* Remove the initial breakpoint. */
- check_breakpoints ((CORE_ADDR) (long) current_event
- .u.Exception.ExceptionRecord.ExceptionAddress);
-#endif
- break;
- case DBG_CONTROL_C:
- OUTMSG2 (("DBG_CONTROL_C"));
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case DBG_CONTROL_BREAK:
- OUTMSG2 (("DBG_CONTROL_BREAK"));
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case EXCEPTION_SINGLE_STEP:
- OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_PRIV_INSTRUCTION:
- OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- default:
- if (current_event.u.Exception.dwFirstChance)
- {
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- return;
- }
- OUTMSG2 (("gdbserver: unknown target exception 0x%08x at 0x%s",
- (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
- phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord.
- ExceptionAddress, sizeof (uintptr_t))));
- ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
- break;
- }
- OUTMSG2 (("\n"));
- last_sig = ourstatus->value.sig;
-}
-
-
-static void
suspend_one_thread (thread_info *thread)
{
windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
@@ -1282,15 +1174,25 @@
}
#endif
+/* See nat/windows-nat.h. */
+
+bool
+windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
+{
+ return false;
+}
+
/* Get the next event from the child. */
static int
-get_child_debug_event (struct target_waitstatus *ourstatus)
+get_child_debug_event (DWORD *continue_status,
+ struct target_waitstatus *ourstatus)
{
ptid_t ptid;
last_sig = GDB_SIGNAL_0;
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ *continue_status = DBG_CONTINUE;
/* Check if GDB sent us an interrupt request. */
check_remote_input_interrupt_request ();
@@ -1457,7 +1359,9 @@
"for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
- handle_exception (ourstatus);
+ if (handle_exception (ourstatus, debug_threads)
+ == HANDLE_EXCEPTION_UNHANDLED)
+ *continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
case OUTPUT_DEBUG_STRING_EVENT:
@@ -1504,7 +1408,8 @@
while (1)
{
- if (!get_child_debug_event (ourstatus))
+ DWORD continue_status;
+ if (!get_child_debug_event (&continue_status, ourstatus))
continue;
switch (ourstatus->kind)
@@ -1527,7 +1432,7 @@
/* fall-through */
case TARGET_WAITKIND_SPURIOUS:
/* do nothing, just continue */
- child_continue (DBG_CONTINUE, -1);
+ child_continue (continue_status, -1);
break;
}
}
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 57bbae1..1d76f37 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -18,6 +18,7 @@
#include "gdbsupport/common-defs.h"
#include "nat/windows-nat.h"
+#include "gdbsupport/common-debug.h"
namespace windows_nat
{
@@ -137,4 +138,159 @@
return buf;
}
+/* The exception thrown by a program to tell the debugger the name of
+ a thread. The exception record contains an ID of a thread and a
+ name to give it. This exception has no documented name, but MSDN
+ dubs it "MS_VC_EXCEPTION" in one code example. */
+#define MS_VC_EXCEPTION 0x406d1388
+
+handle_exception_result
+handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
+{
+#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
+ debug_printf ("gdb: Target exception %s at %s\n", x, \
+ host_address_to_string (\
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress))
+
+ EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord;
+ DWORD code = rec->ExceptionCode;
+ handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
+
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+
+ /* Record the context of the current thread. */
+ thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
+ DONT_SUSPEND);
+
+ switch (code)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
+ ourstatus->value.sig = GDB_SIGNAL_SEGV;
+#ifdef __CYGWIN__
+ {
+ /* See if the access violation happened within the cygwin DLL
+ itself. Cygwin uses a kind of exception handling to deal
+ with passed-in invalid addresses. gdb should not treat
+ these as real SEGVs since they will be silently handled by
+ cygwin. A real SEGV will (theoretically) be caught by
+ cygwin later in the process and will be sent as a
+ cygwin-specific-signal. So, ignore SEGVs if they show up
+ within the text segment of the DLL itself. */
+ const char *fn;
+ CORE_ADDR addr = (CORE_ADDR) (uintptr_t) rec->ExceptionAddress;
+
+ if ((!cygwin_exceptions && (addr >= cygwin_load_start
+ && addr < cygwin_load_end))
+ || (find_pc_partial_function (addr, &fn, NULL, NULL)
+ && startswith (fn, "KERNEL32!IsBad")))
+ return HANDLE_EXCEPTION_UNHANDLED;
+ }
+#endif
+ break;
+ case STATUS_STACK_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_SEGV;
+ break;
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_INEXACT_RESULT:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_INVALID_OPERATION:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_STACK_CHECK:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_UNDERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_INTEGER_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case EXCEPTION_BREAKPOINT:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
+#ifdef _WIN32_WCE
+ /* Remove the initial breakpoint. */
+ check_breakpoints ((CORE_ADDR) (long) current_event
+ .u.Exception.ExceptionRecord.ExceptionAddress);
+#endif
+ break;
+ case DBG_CONTROL_C:
+ DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
+ ourstatus->value.sig = GDB_SIGNAL_INT;
+ break;
+ case DBG_CONTROL_BREAK:
+ DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
+ ourstatus->value.sig = GDB_SIGNAL_INT;
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
+ break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
+ break;
+ case EXCEPTION_PRIV_INSTRUCTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
+ break;
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
+ break;
+ case MS_VC_EXCEPTION:
+ DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
+ if (handle_ms_vc_exception (rec))
+ {
+ 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 HANDLE_EXCEPTION_UNHANDLED;
+ debug_printf ("gdb: unknown target exception 0x%08x at %s\n",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
+ host_address_to_string (
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
+ break;
+ }
+
+ last_sig = ourstatus->value.sig;
+ return result;
+
+#undef DEBUG_EXCEPTION_SIMPLE
+}
+
}
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 78d0421..5fd6174 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -133,6 +133,16 @@
extern void handle_unload_dll ();
+/* Handle MS_VC_EXCEPTION when processing a stop. MS_VC_EXCEPTION is
+ somewhat undocumented but is used to tell the debugger the name of
+ a thread.
+
+ Return true if the exception was handled; return false otherwise.
+
+ This function must be supplied by the embedding application. */
+
+extern bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
+
/* Currently executing process */
extern HANDLE current_process_handle;
@@ -193,6 +203,16 @@
get_image_name. */
extern const char *get_image_name (HANDLE h, void *address, int unicode);
+typedef enum
+{
+ HANDLE_EXCEPTION_UNHANDLED = 0,
+ HANDLE_EXCEPTION_HANDLED,
+ HANDLE_EXCEPTION_IGNORED
+} handle_exception_result;
+
+extern handle_exception_result handle_exception
+ (struct target_waitstatus *ourstatus, bool debug_exceptions);
+
}
#endif
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index c046f91..8c690b6 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -182,19 +182,6 @@
static int windows_initialization_done;
#define DR6_CLEAR_VALUE 0xffff0ff0
-/* The exception thrown by a program to tell the debugger the name of
- a thread. The exception record contains an ID of a thread and a
- name to give it. This exception has no documented name, but MSDN
- dubs it "MS_VC_EXCEPTION" in one code example. */
-#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
@@ -1067,173 +1054,45 @@
}
}
-#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
- printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
- host_address_to_string (\
- current_event.u.Exception.ExceptionRecord.ExceptionAddress))
+/* See nat/windows-nat.h. */
-static handle_exception_result
-handle_exception (struct target_waitstatus *ourstatus)
+bool
+windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
{
- EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord;
- DWORD code = rec->ExceptionCode;
- handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
-
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
- /* Record the context of the current thread. */
- thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
- DONT_SUSPEND);
-
- switch (code)
+ if (rec->NumberParameters >= 3
+ && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
{
- case EXCEPTION_ACCESS_VIOLATION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
-#ifdef __CYGWIN__
- {
- /* See if the access violation happened within the cygwin DLL
- itself. Cygwin uses a kind of exception handling to deal
- with passed-in invalid addresses. gdb should not treat
- these as real SEGVs since they will be silently handled by
- cygwin. A real SEGV will (theoretically) be caught by
- cygwin later in the process and will be sent as a
- cygwin-specific-signal. So, ignore SEGVs if they show up
- within the text segment of the DLL itself. */
- const char *fn;
- CORE_ADDR addr = (CORE_ADDR) (uintptr_t) rec->ExceptionAddress;
+ DWORD named_thread_id;
+ windows_thread_info *named_thread;
+ CORE_ADDR thread_name_target;
- if ((!cygwin_exceptions && (addr >= cygwin_load_start
- && addr < cygwin_load_end))
- || (find_pc_partial_function (addr, &fn, NULL, NULL)
- && startswith (fn, "KERNEL32!IsBad")))
- return HANDLE_EXCEPTION_UNHANDLED;
- }
-#endif
- break;
- case STATUS_STACK_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_FLOAT_DENORMAL_OPERAND:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INEXACT_RESULT:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INVALID_OPERATION:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_STACK_CHECK:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_UNDERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_BREAKPOINT:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case DBG_CONTROL_C:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case DBG_CONTROL_BREAK:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case EXCEPTION_SINGLE_STEP:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_PRIV_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case MS_VC_EXCEPTION:
- if (rec->NumberParameters >= 3
- && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
+ thread_name_target = rec->ExceptionInformation[1];
+ named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]);
+
+ if (named_thread_id == (DWORD) -1)
+ named_thread_id = current_event.dwThreadId;
+
+ named_thread = thread_rec (ptid_t (current_event.dwProcessId,
+ named_thread_id, 0),
+ DONT_INVALIDATE_CONTEXT);
+ if (named_thread != NULL)
{
- DWORD named_thread_id;
- windows_thread_info *named_thread;
- CORE_ADDR thread_name_target;
+ int thread_name_len;
+ gdb::unique_xmalloc_ptr<char> thread_name;
- DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
-
- thread_name_target = rec->ExceptionInformation[1];
- named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]);
-
- if (named_thread_id == (DWORD) -1)
- named_thread_id = current_event.dwThreadId;
-
- named_thread = thread_rec (ptid_t (current_event.dwProcessId,
- named_thread_id, 0),
- DONT_INVALIDATE_CONTEXT);
- if (named_thread != NULL)
+ thread_name_len = target_read_string (thread_name_target,
+ &thread_name, 1025, NULL);
+ if (thread_name_len > 0)
{
- int thread_name_len;
- gdb::unique_xmalloc_ptr<char> thread_name;
-
- thread_name_len = target_read_string (thread_name_target,
- &thread_name, 1025, NULL);
- if (thread_name_len > 0)
- {
- thread_name.get ()[thread_name_len - 1] = '\0';
- named_thread->name = std::move (thread_name);
- }
+ thread_name.get ()[thread_name_len - 1] = '\0';
+ named_thread->name = std::move (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 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 (
- current_event.u.Exception.ExceptionRecord.ExceptionAddress));
- ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
- break;
+
+ return true;
}
- last_sig = ourstatus->value.sig;
- return result;
+
+ return false;
}
/* Resume thread specified by ID, or all artificially suspended
@@ -1644,7 +1503,7 @@
"EXCEPTION_DEBUG_EVENT"));
if (saw_create != 1)
break;
- switch (handle_exception (ourstatus))
+ switch (handle_exception (ourstatus, debug_exceptions))
{
case HANDLE_EXCEPTION_UNHANDLED:
default:
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
Gerrit-Change-Number: 716
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: newchange
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
2019-11-26 17:21 [review] Share handle_exception Tom Tromey (Code Review)
@ 2019-11-29 20:03 ` Pedro Alves (Code Review)
2019-11-29 20:05 ` Simon Marchi (Code Review)
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves (Code Review) @ 2019-11-29 20:03 UTC (permalink / raw)
To: Tom Tromey, gdb-patches
Pedro Alves has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/716
......................................................................
Patch Set 1:
I'm confused since gerrit thinks this is a new patch instead of a revision of:
https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/425
Did you consider not having the new callbacks and instead install target_ops::thread_name on gdbserver too?
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
Gerrit-Change-Number: 716
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-CC: Pedro Alves <palves@redhat.com>
Gerrit-Comment-Date: Fri, 29 Nov 2019 20:03:45 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
2019-11-26 17:21 [review] Share handle_exception Tom Tromey (Code Review)
2019-11-29 20:03 ` Pedro Alves (Code Review)
@ 2019-11-29 20:05 ` Simon Marchi (Code Review)
2019-11-29 20:51 ` Pedro Alves (Code Review)
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Simon Marchi (Code Review) @ 2019-11-29 20:05 UTC (permalink / raw)
To: Tom Tromey, gdb-patches; +Cc: Pedro Alves
Simon Marchi has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/716
......................................................................
Patch Set 1:
> Patch Set 1:
>
> I'm confused since gerrit thinks this is a new patch instead of a revision of:
It seems like the Change-Id has been changed between the two revisions.
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
Gerrit-Change-Number: 716
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-CC: Pedro Alves <palves@redhat.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Fri, 29 Nov 2019 20:05:43 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
2019-11-26 17:21 [review] Share handle_exception Tom Tromey (Code Review)
2019-11-29 20:03 ` Pedro Alves (Code Review)
2019-11-29 20:05 ` Simon Marchi (Code Review)
@ 2019-11-29 20:51 ` Pedro Alves (Code Review)
2019-11-29 20:57 ` Simon Marchi (Code Review)
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves (Code Review) @ 2019-11-29 20:51 UTC (permalink / raw)
To: Tom Tromey, gdb-patches; +Cc: Simon Marchi
Pedro Alves has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/716
......................................................................
Patch Set 1:
> Patch Set 1:
> > Patch Set 1:
> > I'm confused since gerrit thinks this is a new patch instead of a revision of:
> It seems like the Change-Id has been changed between the two revisions.
AFAICS, it's "I4e6e0d17b868cd51964c273fb28ec066fea6b767" for both.
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
Gerrit-Change-Number: 716
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-CC: Pedro Alves <palves@redhat.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Fri, 29 Nov 2019 20:51:38 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
2019-11-26 17:21 [review] Share handle_exception Tom Tromey (Code Review)
` (2 preceding siblings ...)
2019-11-29 20:51 ` Pedro Alves (Code Review)
@ 2019-11-29 20:57 ` Simon Marchi (Code Review)
2019-12-04 16:20 ` Tom Tromey (Code Review)
2019-12-04 16:32 ` Pedro Alves (Code Review)
5 siblings, 0 replies; 9+ messages in thread
From: Simon Marchi (Code Review) @ 2019-11-29 20:57 UTC (permalink / raw)
To: Tom Tromey, gdb-patches; +Cc: Pedro Alves
Simon Marchi has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/716
......................................................................
Patch Set 1:
> Patch Set 1:
>
> > Patch Set 1:
> > > Patch Set 1:
> > > I'm confused since gerrit thinks this is a new patch instead of a revision of:
> > It seems like the Change-Id has been changed between the two revisions.
>
> AFAICS, it's "I4e6e0d17b868cd51964c273fb28ec066fea6b767" for both.
Ah, there are two in change 425, I4e6e0d17b868cd51964c273fb28ec066fea6b767 is above the ChangeLog entries and I2efe53c78f5a8e28381e539505f1b703967933c4 is below. I guess I2efe53c78f5a8e28381e539505f1b703967933c4 was the "real" one but Tom kept I4e6e0d17b868cd51964c273fb28ec066fea6b767.
In the old Gerrit interface you could see what the Change-Id as parsed by Gerrit was, but I don't see a similar field here.
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
Gerrit-Change-Number: 716
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-CC: Pedro Alves <palves@redhat.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Fri, 29 Nov 2019 20:57:40 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
2019-11-26 17:21 [review] Share handle_exception Tom Tromey (Code Review)
` (3 preceding siblings ...)
2019-11-29 20:57 ` Simon Marchi (Code Review)
@ 2019-12-04 16:20 ` Tom Tromey (Code Review)
2019-12-04 16:32 ` Pedro Alves (Code Review)
5 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey (Code Review) @ 2019-12-04 16:20 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi, Pedro Alves
Tom Tromey has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/716
......................................................................
Patch Set 1:
> Patch Set 1:
>
> I'm confused since gerrit thinks this is a new patch instead of a revision of:
>
> https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/425
>
> Did you consider not having the new callbacks and instead install target_ops::thread_name on gdbserver too?
I tried today. There's no shared target_read_string API, and I don't want
to add any more things to this series than are strictly required -- it's already
too long.
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
Gerrit-Change-Number: 716
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-Reviewer: Tom Tromey <tromey@sourceware.org>
Gerrit-CC: Pedro Alves <palves@redhat.com>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Wed, 04 Dec 2019 16:19:58 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
2019-11-26 17:21 [review] Share handle_exception Tom Tromey (Code Review)
` (4 preceding siblings ...)
2019-12-04 16:20 ` Tom Tromey (Code Review)
@ 2019-12-04 16:32 ` Pedro Alves (Code Review)
5 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves (Code Review) @ 2019-12-04 16:32 UTC (permalink / raw)
To: Tom Tromey, gdb-patches; +Cc: Simon Marchi
Pedro Alves has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/716
......................................................................
Patch Set 1: Code-Review+2
> Patch Set 1:
> > Patch Set 1:
> > Did you consider not having the new callbacks and instead install target_ops::thread_name on gdbserver too?
>
> I tried today. There's no shared target_read_string API, and I don't want
> to add any more things to this series than are strictly required -- it's already
> too long.
Fair enough.
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
Gerrit-Change-Number: 716
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-Reviewer: Pedro Alves <palves@redhat.com>
Gerrit-Reviewer: Tom Tromey <tromey@sourceware.org>
Gerrit-CC: Simon Marchi <simon.marchi@polymtl.ca>
Gerrit-Comment-Date: Wed, 04 Dec 2019 16:32:02 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
@ 2019-10-29 18:05 Tom Tromey (Code Review)
2019-11-19 19:55 ` Pedro Alves (Code Review)
0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey (Code Review) @ 2019-10-29 18:05 UTC (permalink / raw)
To: gdb-patches
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/425
......................................................................
Share handle_exception
Both gdb and gdbserver have a "handle_exception" function, the bulk of
which is shared between the two implementations. This patch arranges
for the entire thing to be moved into nat/windows-nat.c, with the
differences handled by callbacks. This patch introduces one more
callback to make this possible.
Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
gdb/ChangeLog
2019-10-29 Tom Tromey <tromey@adacore.com>
* windows-nat.c (MS_VC_EXCEPTION): Move to nat/windows-nat.c.
(handle_exception_result): Move to nat/windows-nat.h.
(DEBUG_EXCEPTION_SIMPLE): Remove.
(windows_nat::handle_ms_vc_exception): New function.
(handle_exception): Move to nat/windows-nat.c.
(get_windows_debug_event): Update.
* nat/windows-nat.h (handle_ms_vc_exception): Declare.
(handle_exception_result): Move from windows-nat.c.
(handle_exception): Declare.
* nat/windows-nat.c (MS_VC_EXCEPTION, handle_exception): Move from
windows-nat.c.
gdb/gdbserver/ChangeLog
2019-10-29 Tom Tromey <tromey@adacore.com>
* win32-low.c (handle_exception): Remove.
(windows_nat::handle_ms_vc_exception): New function.
(get_child_debug_event): Add "continue_status" parameter.
Update.
(win32_wait): Update.
Change-Id: I2efe53c78f5a8e28381e539505f1b703967933c4
---
M gdb/ChangeLog
M gdb/gdbserver/ChangeLog
M gdb/gdbserver/win32-low.c
M gdb/nat/windows-nat.c
M gdb/nat/windows-nat.h
M gdb/windows-nat.c
6 files changed, 243 insertions(+), 283 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bf55033..acc6961 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@
2019-10-29 Tom Tromey <tromey@adacore.com>
+ * windows-nat.c (MS_VC_EXCEPTION): Move to nat/windows-nat.c.
+ (handle_exception_result): Move to nat/windows-nat.h.
+ (DEBUG_EXCEPTION_SIMPLE): Remove.
+ (windows_nat::handle_ms_vc_exception): New function.
+ (handle_exception): Move to nat/windows-nat.c.
+ (get_windows_debug_event): Update.
+ * nat/windows-nat.h (handle_ms_vc_exception): Declare.
+ (handle_exception_result): Move from windows-nat.c.
+ (handle_exception): Declare.
+ * nat/windows-nat.c (MS_VC_EXCEPTION, handle_exception): Move from
+ windows-nat.c.
+
+2019-10-29 Tom Tromey <tromey@adacore.com>
+
* windows-nat.c (exception_count, event_count): Remove.
(handle_exception, get_windows_debug_event)
(do_initial_windows_stuff): Update.
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index d3ce252..050202b 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,13 @@
2019-10-29 Tom Tromey <tromey@adacore.com>
+ * win32-low.c (handle_exception): Remove.
+ (windows_nat::handle_ms_vc_exception): New function.
+ (get_child_debug_event): Add "continue_status" parameter.
+ Update.
+ (win32_wait): Update.
+
+2019-10-29 Tom Tromey <tromey@adacore.com>
+
* win32-low.c (windows_nat::handle_load_dll): Rename from
handle_load_dll. No longer static.
(windows_nat::handle_unload_dll): Rename from handle_unload_dll.
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index 3fcd2a6..1340e85 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -1143,114 +1143,6 @@
}
static void
-handle_exception (struct target_waitstatus *ourstatus)
-{
- DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
-
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
- switch (code)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION"));
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_STACK_OVERFLOW:
- OUTMSG2 (("STATUS_STACK_OVERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_FLOAT_DENORMAL_OPERAND:
- OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INEXACT_RESULT:
- OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INVALID_OPERATION:
- OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_OVERFLOW:
- OUTMSG2 (("STATUS_FLOAT_OVERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_STACK_CHECK:
- OUTMSG2 (("STATUS_FLOAT_STACK_CHECK"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_UNDERFLOW:
- OUTMSG2 (("STATUS_FLOAT_UNDERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_OVERFLOW:
- OUTMSG2 (("STATUS_INTEGER_OVERFLOW"));
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_BREAKPOINT:
- OUTMSG2 (("EXCEPTION_BREAKPOINT"));
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
-#ifdef _WIN32_WCE
- /* Remove the initial breakpoint. */
- check_breakpoints ((CORE_ADDR) (long) current_event
- .u.Exception.ExceptionRecord.ExceptionAddress);
-#endif
- break;
- case DBG_CONTROL_C:
- OUTMSG2 (("DBG_CONTROL_C"));
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case DBG_CONTROL_BREAK:
- OUTMSG2 (("DBG_CONTROL_BREAK"));
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case EXCEPTION_SINGLE_STEP:
- OUTMSG2 (("EXCEPTION_SINGLE_STEP"));
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION"));
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_PRIV_INSTRUCTION:
- OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION"));
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION"));
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- default:
- if (current_event.u.Exception.dwFirstChance)
- {
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- return;
- }
- OUTMSG2 (("gdbserver: unknown target exception 0x%08x at 0x%s",
- (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
- phex_nz ((uintptr_t) current_event.u.Exception.ExceptionRecord.
- ExceptionAddress, sizeof (uintptr_t))));
- ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
- break;
- }
- OUTMSG2 (("\n"));
- last_sig = ourstatus->value.sig;
-}
-
-
-static void
suspend_one_thread (thread_info *thread)
{
windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
@@ -1282,15 +1174,25 @@
}
#endif
+/* See nat/windows-nat.h. */
+
+bool
+windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
+{
+ return false;
+}
+
/* Get the next event from the child. */
static int
-get_child_debug_event (struct target_waitstatus *ourstatus)
+get_child_debug_event (DWORD *continue_status,
+ struct target_waitstatus *ourstatus)
{
ptid_t ptid;
last_sig = GDB_SIGNAL_0;
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+ *continue_status = DBG_CONTINUE;
/* Check if GDB sent us an interrupt request. */
check_remote_input_interrupt_request ();
@@ -1457,7 +1359,9 @@
"for pid=%u tid=%x\n",
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId));
- handle_exception (ourstatus);
+ if (handle_exception (ourstatus, debug_threads)
+ == HANDLE_EXCEPTION_UNHANDLED)
+ *continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
case OUTPUT_DEBUG_STRING_EVENT:
@@ -1504,7 +1408,8 @@
while (1)
{
- if (!get_child_debug_event (ourstatus))
+ DWORD continue_status = DBG_CONTINUE;
+ if (!get_child_debug_event (&continue_status, ourstatus))
continue;
switch (ourstatus->kind)
@@ -1527,7 +1432,7 @@
/* fall-through */
case TARGET_WAITKIND_SPURIOUS:
/* do nothing, just continue */
- child_continue (DBG_CONTINUE, -1);
+ child_continue (continue_status, -1);
break;
}
}
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 70ce6fd..3647014 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -18,6 +18,7 @@
#include "gdbsupport/common-defs.h"
#include "nat/windows-nat.h"
+#include "gdbsupport/common-debug.h"
namespace windows_nat
{
@@ -136,4 +137,159 @@
return buf;
}
+/* The exception thrown by a program to tell the debugger the name of
+ a thread. The exception record contains an ID of a thread and a
+ name to give it. This exception has no documented name, but MSDN
+ dubs it "MS_VC_EXCEPTION" in one code example. */
+#define MS_VC_EXCEPTION 0x406d1388
+
+handle_exception_result
+handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
+{
+#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
+ debug_printf ("gdb: Target exception %s at %s\n", x, \
+ host_address_to_string (\
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress))
+
+ EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord;
+ DWORD code = rec->ExceptionCode;
+ handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
+
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+
+ /* Record the context of the current thread. */
+ thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
+ DONT_SUSPEND);
+
+ switch (code)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
+ ourstatus->value.sig = GDB_SIGNAL_SEGV;
+#ifdef __CYGWIN__
+ {
+ /* See if the access violation happened within the cygwin DLL
+ itself. Cygwin uses a kind of exception handling to deal
+ with passed-in invalid addresses. gdb should not treat
+ these as real SEGVs since they will be silently handled by
+ cygwin. A real SEGV will (theoretically) be caught by
+ cygwin later in the process and will be sent as a
+ cygwin-specific-signal. So, ignore SEGVs if they show up
+ within the text segment of the DLL itself. */
+ const char *fn;
+ CORE_ADDR addr = (CORE_ADDR) (uintptr_t) rec->ExceptionAddress;
+
+ if ((!cygwin_exceptions && (addr >= cygwin_load_start
+ && addr < cygwin_load_end))
+ || (find_pc_partial_function (addr, &fn, NULL, NULL)
+ && startswith (fn, "KERNEL32!IsBad")))
+ return HANDLE_EXCEPTION_UNHANDLED;
+ }
+#endif
+ break;
+ case STATUS_STACK_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_SEGV;
+ break;
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_INEXACT_RESULT:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_INVALID_OPERATION:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_STACK_CHECK:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_UNDERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case STATUS_INTEGER_OVERFLOW:
+ DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
+ ourstatus->value.sig = GDB_SIGNAL_FPE;
+ break;
+ case EXCEPTION_BREAKPOINT:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
+#ifdef _WIN32_WCE
+ /* Remove the initial breakpoint. */
+ check_breakpoints ((CORE_ADDR) (long) current_event
+ .u.Exception.ExceptionRecord.ExceptionAddress);
+#endif
+ break;
+ case DBG_CONTROL_C:
+ DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
+ ourstatus->value.sig = GDB_SIGNAL_INT;
+ break;
+ case DBG_CONTROL_BREAK:
+ DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
+ ourstatus->value.sig = GDB_SIGNAL_INT;
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
+ ourstatus->value.sig = GDB_SIGNAL_TRAP;
+ break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
+ break;
+ case EXCEPTION_PRIV_INSTRUCTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
+ break;
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
+ ourstatus->value.sig = GDB_SIGNAL_ILL;
+ break;
+ case MS_VC_EXCEPTION:
+ DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
+ if (handle_ms_vc_exception (rec))
+ {
+ 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 HANDLE_EXCEPTION_UNHANDLED;
+ debug_printf ("gdb: unknown target exception 0x%08x at %s\n",
+ (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
+ host_address_to_string (
+ current_event.u.Exception.ExceptionRecord.ExceptionAddress));
+ ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
+ break;
+ }
+
+ last_sig = ourstatus->value.sig;
+ return result;
+
+#undef DEBUG_EXCEPTION_SIMPLE
+}
+
}
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 695170e..a089602 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -129,6 +129,14 @@
extern void handle_unload_dll ();
+/* Handle MS_VC_EXCEPTION when processing a FIXME.
+
+ Return true if the exception was handled; return false otherwise.
+
+ This function must be supplied by the embedding application. */
+
+extern bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
+
/* Currently executing process */
extern HANDLE current_process_handle;
@@ -193,6 +201,16 @@
get_image_name. */
extern const char *get_image_name (HANDLE h, void *address, int unicode);
+typedef enum
+{
+ HANDLE_EXCEPTION_UNHANDLED = 0,
+ HANDLE_EXCEPTION_HANDLED,
+ HANDLE_EXCEPTION_IGNORED
+} handle_exception_result;
+
+extern handle_exception_result handle_exception
+ (struct target_waitstatus *ourstatus, bool debug_exceptions);
+
}
#endif
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 159b093..0136b50 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -182,19 +182,6 @@
static int windows_initialization_done;
#define DR6_CLEAR_VALUE 0xffff0ff0
-/* The exception thrown by a program to tell the debugger the name of
- a thread. The exception record contains an ID of a thread and a
- name to give it. This exception has no documented name, but MSDN
- dubs it "MS_VC_EXCEPTION" in one code example. */
-#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
@@ -1042,173 +1029,45 @@
}
}
-#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
- printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
- host_address_to_string (\
- current_event.u.Exception.ExceptionRecord.ExceptionAddress))
+/* See nat/windows-nat.h. */
-static handle_exception_result
-handle_exception (struct target_waitstatus *ourstatus)
+bool
+windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
{
- EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord;
- DWORD code = rec->ExceptionCode;
- handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
-
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
- /* Record the context of the current thread. */
- thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
- DONT_SUSPEND);
-
- switch (code)
+ if (rec->NumberParameters >= 3
+ && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
{
- case EXCEPTION_ACCESS_VIOLATION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
-#ifdef __CYGWIN__
- {
- /* See if the access violation happened within the cygwin DLL
- itself. Cygwin uses a kind of exception handling to deal
- with passed-in invalid addresses. gdb should not treat
- these as real SEGVs since they will be silently handled by
- cygwin. A real SEGV will (theoretically) be caught by
- cygwin later in the process and will be sent as a
- cygwin-specific-signal. So, ignore SEGVs if they show up
- within the text segment of the DLL itself. */
- const char *fn;
- CORE_ADDR addr = (CORE_ADDR) (uintptr_t) rec->ExceptionAddress;
+ DWORD named_thread_id;
+ windows_thread_info *named_thread;
+ CORE_ADDR thread_name_target;
- if ((!cygwin_exceptions && (addr >= cygwin_load_start
- && addr < cygwin_load_end))
- || (find_pc_partial_function (addr, &fn, NULL, NULL)
- && startswith (fn, "KERNEL32!IsBad")))
- return HANDLE_EXCEPTION_UNHANDLED;
- }
-#endif
- break;
- case STATUS_STACK_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_FLOAT_DENORMAL_OPERAND:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INEXACT_RESULT:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INVALID_OPERATION:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_STACK_CHECK:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_UNDERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_BREAKPOINT:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case DBG_CONTROL_C:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case DBG_CONTROL_BREAK:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case EXCEPTION_SINGLE_STEP:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_PRIV_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case MS_VC_EXCEPTION:
- if (rec->NumberParameters >= 3
- && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
+ thread_name_target = rec->ExceptionInformation[1];
+ named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]);
+
+ if (named_thread_id == (DWORD) -1)
+ named_thread_id = current_event.dwThreadId;
+
+ named_thread = thread_rec (ptid_t (current_event.dwProcessId,
+ named_thread_id, 0),
+ DONT_INVALIDATE_CONTEXT);
+ if (named_thread != NULL)
{
- DWORD named_thread_id;
- windows_thread_info *named_thread;
- CORE_ADDR thread_name_target;
+ int thread_name_len;
+ gdb::unique_xmalloc_ptr<char> thread_name;
- DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
-
- thread_name_target = rec->ExceptionInformation[1];
- named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]);
-
- if (named_thread_id == (DWORD) -1)
- named_thread_id = current_event.dwThreadId;
-
- named_thread = thread_rec (ptid_t (current_event.dwProcessId,
- named_thread_id, 0),
- DONT_INVALIDATE_CONTEXT);
- if (named_thread != NULL)
+ thread_name_len = target_read_string (thread_name_target,
+ &thread_name, 1025, NULL);
+ if (thread_name_len > 0)
{
- int thread_name_len;
- gdb::unique_xmalloc_ptr<char> thread_name;
-
- thread_name_len = target_read_string (thread_name_target,
- &thread_name, 1025, NULL);
- if (thread_name_len > 0)
- {
- thread_name.get ()[thread_name_len - 1] = '\0';
- named_thread->name = std::move (thread_name);
- }
+ thread_name.get ()[thread_name_len - 1] = '\0';
+ named_thread->name = std::move (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 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 (
- current_event.u.Exception.ExceptionRecord.ExceptionAddress));
- ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
- break;
+
+ return true;
}
- last_sig = ourstatus->value.sig;
- return result;
+
+ return false;
}
/* Resume thread specified by ID, or all artificially suspended
@@ -1620,7 +1479,7 @@
"EXCEPTION_DEBUG_EVENT"));
if (saw_create != 1)
break;
- switch (handle_exception (ourstatus))
+ switch (handle_exception (ourstatus, debug_exceptions))
{
case HANDLE_EXCEPTION_UNHANDLED:
default:
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I2efe53c78f5a8e28381e539505f1b703967933c4
Gerrit-Change-Number: 425
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: newchange
^ permalink raw reply [flat|nested] 9+ messages in thread
* [review] Share handle_exception
2019-10-29 18:05 Tom Tromey (Code Review)
@ 2019-11-19 19:55 ` Pedro Alves (Code Review)
0 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves (Code Review) @ 2019-11-19 19:55 UTC (permalink / raw)
To: Tom Tromey, gdb-patches
Pedro Alves has posted comments on this change.
Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/425
......................................................................
Patch Set 1:
(5 comments)
| --- /dev/null
| +++ /COMMIT_MSG
| @@ -1,0 +3,20 @@ Author: Tom Tromey <tromey@adacore.com>
| +AuthorDate: 2019-10-18 13:26:45 -0600
| +Commit: Tom Tromey <tromey@adacore.com>
| +CommitDate: 2019-10-29 10:08:40 -0600
| +
| +Share handle_exception
| +
| +Both gdb and gdbserver have a "handle_exception" function, the bulk of
| +which is shared between the two implementations. This patch arranges
| +for the entire thing to be moved into nat/windows-nat.c, with the
| +differences handled by callbacks. This patch introduces one more
| +callback to make this possible.
PS1, Line 13:
That's:
> (windows_nat::handle_ms_vc_exception): New function.
There's no reason we couldn't just support thread names in gdbserver
as well. It just wasn't done when the original support was added,
left forever stuck as a TODO item. You'd just have to install a
target_ops::thread_name implementation on win32-low.c as well.
| +
| +Change-Id: I4e6e0d17b868cd51964c273fb28ec066fea6b767
| +
| +gdb/ChangeLog
| +2019-10-29 Tom Tromey <tromey@adacore.com>
| +
| + * windows-nat.c (MS_VC_EXCEPTION): Move to nat/windows-nat.c.
| + (handle_exception_result): Move to nat/windows-nat.h.
| + (DEBUG_EXCEPTION_SIMPLE): Remove.
| --- gdb/gdbserver/win32-low.c
| +++ gdb/gdbserver/win32-low.c
| @@ -1287,16 +1187,18 @@ /* Get the next event from the child. */
| static int
| -get_child_debug_event (struct target_waitstatus *ourstatus)
| +get_child_debug_event (DWORD *continue_status,
| + struct target_waitstatus *ourstatus)
| {
| ptid_t ptid;
|
| last_sig = GDB_SIGNAL_0;
| ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
| + *continue_status = DBG_CONTINUE;
PS1, Line 1195:
Given this...
|
| /* Check if GDB sent us an interrupt request. */
| check_remote_input_interrupt_request ();
|
| if (soft_interrupt_requested)
| {
| soft_interrupt_requested = 0;
| fake_breakpoint_event ();
| goto gotevent;
...
| @@ -1499,17 +1403,18 @@ win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
| fails). Report it now. */
| *ourstatus = cached_status;
| cached_status.kind = TARGET_WAITKIND_IGNORE;
| return debug_event_ptid (¤t_event);
| }
|
| while (1)
| {
| - if (!get_child_debug_event (ourstatus))
| + DWORD continue_status = DBG_CONTINUE;
PS1, Line 1411:
... this here doesn't appear necessary.
| + if (!get_child_debug_event (&continue_status, ourstatus))
| continue;
|
| switch (ourstatus->kind)
| {
| case TARGET_WAITKIND_EXITED:
| OUTMSG2 (("Child exited with retcode = %x\n",
| ourstatus->value.integer));
| win32_clear_inferiors ();
| --- gdb/nat/windows-nat.h
| +++ gdb/nat/windows-nat.h
| @@ -123,11 +123,19 @@ extern void handle_load_dll ();
| /* Handle a DLL unload event.
|
| This function assumes that this event did not occur during inferior
| initialization.
|
| This function must be supplied by the embedding application. */
|
| extern void handle_unload_dll ();
|
| +/* Handle MS_VC_EXCEPTION when processing a FIXME.
PS1, Line 132:
FIXME?
| +
| + Return true if the exception was handled; return false otherwise.
| +
| + This function must be supplied by the embedding application. */
| +
| +extern bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
| +
|
| /* Currently executing process */
...
| @@ -195,4 +203,14 @@ extern const char *get_image_name (HANDLE h, void *address, int unicode);
|
| +typedef enum
| +{
| + HANDLE_EXCEPTION_UNHANDLED = 0,
| + HANDLE_EXCEPTION_HANDLED,
| + HANDLE_EXCEPTION_IGNORED
| +} handle_exception_result;
| +
| +extern handle_exception_result handle_exception
| + (struct target_waitstatus *ourstatus, bool debug_exceptions);
PS1, Line 212:
Two leading spaces:
extern handle_exception_result handle_exception
(struct target_waitstatus *ourstatus, bool debug_exceptions);
See e.g. extension-priv.h.
| +
| }
|
| #endif
--
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I2efe53c78f5a8e28381e539505f1b703967933c4
Gerrit-Change-Number: 425
Gerrit-PatchSet: 1
Gerrit-Owner: Tom Tromey <tromey@sourceware.org>
Gerrit-CC: Pedro Alves <palves@redhat.com>
Gerrit-Comment-Date: Tue, 19 Nov 2019 19:55:20 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2019-12-04 16:32 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-26 17:21 [review] Share handle_exception Tom Tromey (Code Review)
2019-11-29 20:03 ` Pedro Alves (Code Review)
2019-11-29 20:05 ` Simon Marchi (Code Review)
2019-11-29 20:51 ` Pedro Alves (Code Review)
2019-11-29 20:57 ` Simon Marchi (Code Review)
2019-12-04 16:20 ` Tom Tromey (Code Review)
2019-12-04 16:32 ` Pedro Alves (Code Review)
-- strict thread matches above, loose matches on Subject: below --
2019-10-29 18:05 Tom Tromey (Code Review)
2019-11-19 19:55 ` Pedro Alves (Code Review)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).