Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Tom Tromey <tromey@adacore.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tromey@adacore.com>
Subject: [PATCH v3 21/29] Share handle_exception
Date: Fri, 13 Mar 2020 13:08:47 -0600	[thread overview]
Message-ID: <20200313190855.28662-22-tromey@adacore.com> (raw)
In-Reply-To: <20200313190855.28662-1-tromey@adacore.com>

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
2020-03-13  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.
	(STATUS_WX86_BREAKPOINT, STATUS_WX86_SINGLE_STEP): Move to
	nat/windows-nat.c.
	* 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)
	(STATUS_WX86_SINGLE_STEP, STATUS_WX86_BREAKPOINT): Move from
	windows-nat.c.

gdbserver/ChangeLog
2020-03-13  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.
---
 gdb/ChangeLog          |  17 ++++
 gdb/nat/windows-nat.c  | 175 +++++++++++++++++++++++++++++++++
 gdb/nat/windows-nat.h  |  20 ++++
 gdb/windows-nat.c      | 218 ++++++-----------------------------------
 gdbserver/ChangeLog    |   8 ++
 gdbserver/win32-low.cc | 132 ++++---------------------
 6 files changed, 266 insertions(+), 304 deletions(-)

diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 80a1583b884..6bbf41c7b13 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -18,6 +18,10 @@
 
 #include "gdbsupport/common-defs.h"
 #include "nat/windows-nat.h"
+#include "gdbsupport/common-debug.h"
+
+#define STATUS_WX86_BREAKPOINT 0x4000001F
+#define STATUS_WX86_SINGLE_STEP 0x4000001E
 
 namespace windows_nat
 {
@@ -137,4 +141,175 @@ get_image_name (HANDLE h, void *address, int unicode)
   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 = &current_event.u.Exception.ExceptionRecord;
+  DWORD code = rec->ExceptionCode;
+  handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
+
+  memcpy (&siginfo_er, rec, sizeof siginfo_er);
+
+  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:
+#ifdef __x86_64__
+      if (ignore_first_breakpoint)
+	{
+	  /* For WOW64 processes, there are always 2 breakpoint exceptions
+	     on startup, first a BREAKPOINT for the 64bit ntdll.dll,
+	     then a WX86_BREAKPOINT for the 32bit ntdll.dll.
+	     Here we only care about the WX86_BREAKPOINT's.  */
+	  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+	  ignore_first_breakpoint = false;
+	}
+#endif
+      /* FALLTHROUGH */
+    case STATUS_WX86_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:
+    case STATUS_WX86_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 2b2fd116269..a4e0b39fcab 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -143,6 +143,16 @@ extern void handle_load_dll ();
 
 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;
@@ -205,6 +215,16 @@ extern EXCEPTION_RECORD siginfo_er;
    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 3dc31ebd452..a9656a8c91b 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -72,9 +72,6 @@
 #include "gdbsupport/gdb_wait.h"
 #include "nat/windows-nat.h"
 
-#define STATUS_WX86_BREAKPOINT 0x4000001F
-#define STATUS_WX86_SINGLE_STEP 0x4000001E
-
 using namespace windows_nat;
 
 #define AdjustTokenPrivileges		dyn_AdjustTokenPrivileges
@@ -213,19 +210,6 @@ static int debug_registers_used;
 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
@@ -1203,189 +1187,45 @@ display_selectors (const char * args, int from_tty)
     }
 }
 
-#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 = &current_event.u.Exception.ExceptionRecord;
-  DWORD code = rec->ExceptionCode;
-  handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
-
-  memcpy (&siginfo_er, rec, sizeof siginfo_er);
-
-  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;
-
-	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:
-#ifdef __x86_64__
-      if (ignore_first_breakpoint)
-	{
-	  /* For WOW64 processes, there are always 2 breakpoint exceptions
-	     on startup, first a BREAKPOINT for the 64bit ntdll.dll,
-	     then a WX86_BREAKPOINT for the 32bit ntdll.dll.
-	     Here we only care about the WX86_BREAKPOINT's.  */
-	  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
-	  ignore_first_breakpoint = false;
-	}
-#endif
-      /* FALLTHROUGH */
-    case STATUS_WX86_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:
-    case STATUS_WX86_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)
-	{
-	  DWORD named_thread_id;
-	  windows_thread_info *named_thread;
-	  CORE_ADDR thread_name_target;
+      DWORD named_thread_id;
+      windows_thread_info *named_thread;
+      CORE_ADDR thread_name_target;
 
-	  DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
+      thread_name_target = rec->ExceptionInformation[1];
+      named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]);
 
-	  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;
 
-	  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)
+	{
+	  int thread_name_len;
+	  gdb::unique_xmalloc_ptr<char> thread_name;
 
-	  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
@@ -1876,7 +1716,7 @@ windows_nat_target::get_windows_debug_event (int pid,
 		     "EXCEPTION_DEBUG_EVENT"));
       if (saw_create != 1)
 	break;
-      switch (handle_exception (ourstatus))
+      switch (handle_exception (ourstatus, debug_exceptions))
 	{
 	case HANDLE_EXCEPTION_UNHANDLED:
 	default:
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 73d4a6a2d8a..7018083746b 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -1154,117 +1154,6 @@ windows_nat::handle_unload_dll ()
   unloaded_dll (NULL, load_addr);
 }
 
-static void
-handle_exception (struct target_waitstatus *ourstatus)
-{
-  DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
-
-  memcpy (&siginfo_er, &current_event.u.Exception.ExceptionRecord,
-	  sizeof siginfo_er);
-
-  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)
 {
@@ -1297,15 +1186,25 @@ auto_delete_breakpoint (CORE_ADDR stop_pc)
 }
 #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 ();
@@ -1488,7 +1387,9 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
 		"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:
@@ -1536,7 +1437,8 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
 
   while (1)
     {
-      if (!get_child_debug_event (ourstatus))
+      DWORD continue_status;
+      if (!get_child_debug_event (&continue_status, ourstatus))
 	continue;
 
       switch (ourstatus->kind)
@@ -1560,7 +1462,7 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
 	  /* fall-through */
 	case TARGET_WAITKIND_SPURIOUS:
 	  /* do nothing, just continue */
-	  child_continue (DBG_CONTINUE, -1);
+	  child_continue (continue_status, -1);
 	  break;
 	}
     }
-- 
2.21.1



  parent reply	other threads:[~2020-03-13 19:09 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-13 19:08 [PATCH v3 00/29] Windows code sharing + bug fix Tom Tromey
2020-03-13 19:08 ` [PATCH v3 01/29] Remove the "next" field from windows_thread_info Tom Tromey
2020-03-13 19:08 ` [PATCH v3 02/29] Rename win32_thread_info to windows_thread_info Tom Tromey
2020-03-13 19:08 ` [PATCH v3 03/29] Rename windows_thread_info::id to "tid" Tom Tromey
2020-03-13 19:08 ` [PATCH v3 04/29] Share windows_thread_info between gdb and gdbserver Tom Tromey
2020-03-13 19:08 ` [PATCH v3 05/29] Use new and delete for windows_thread_info Tom Tromey
2020-03-13 19:08 ` [PATCH v3 06/29] Change two windows_thread_info members to "bool" Tom Tromey
2020-03-13 19:08 ` [PATCH v3 07/29] Make windows_thread_info::name a unique_xmalloc_ptr Tom Tromey
2020-03-13 19:08 ` [PATCH v3 08/29] Use lwp, not tid, for Windows thread id Tom Tromey
2020-03-13 19:08 ` [PATCH v3 09/29] Share Windows thread-suspend and -resume code Tom Tromey
2020-03-13 19:08 ` [PATCH v3 10/29] Change type of argument to windows-nat.c:thread_rec Tom Tromey
2020-03-13 19:08 ` [PATCH v3 11/29] Handle pending stops from the Windows kernel Tom Tromey
2020-03-13 19:08 ` [PATCH v3 12/29] Call CloseHandle from ~windows_thread_info Tom Tromey
2020-03-13 19:08 ` [PATCH v3 13/29] Wrap shared windows-nat code in windows_nat namespace Tom Tromey
2020-03-13 19:08 ` [PATCH v3 14/29] Share thread_rec between gdb and gdbserver Tom Tromey
2020-03-13 19:08 ` [PATCH v3 15/29] Share get_image_name " Tom Tromey
2020-03-13 19:08 ` [PATCH v3 16/29] Share some Windows-related globals Tom Tromey
2020-03-13 19:08 ` [PATCH v3 17/29] Normalize handle_output_debug_string API Tom Tromey
2020-03-13 19:08 ` [PATCH v3 18/29] Fix up complaints.h for namespace use Tom Tromey
2020-03-13 19:08 ` [PATCH v3 19/29] Share handle_load_dll and handle_unload_dll declarations Tom Tromey
2020-03-13 19:08 ` [PATCH v3 20/29] Remove some globals from windows-nat.c Tom Tromey
2020-03-13 19:08 ` Tom Tromey [this message]
2020-04-15 15:27   ` [PATCH v3 21/29] Share handle_exception Simon Marchi
2020-04-15 16:54     ` Tom Tromey
2020-04-15 17:54       ` Simon Marchi
2020-04-15 19:13         ` Tom Tromey
2020-04-16  0:52           ` Simon Marchi
2020-03-13 19:08 ` [PATCH v3 22/29] Share some inferior-related Windows code Tom Tromey
2020-03-13 19:08 ` [PATCH v3 23/29] Introduce fetch_pending_stop Tom Tromey
2020-03-13 19:08 ` [PATCH v3 24/29] Move wait_for_debug_event to nat/windows-nat.c Tom Tromey
2020-03-13 19:08 ` [PATCH v3 25/29] Make last_wait_event static Tom Tromey
2020-03-13 19:08 ` [PATCH v3 26/29] Add read_pc / write_pc support to win32-low Tom Tromey
2020-03-13 19:08 ` [PATCH v3 27/29] Introduce win32_target_ops::decr_pc_after_break Tom Tromey
2020-03-13 19:08 ` [PATCH v3 28/29] Implement stopped_by_sw_breakpoint for Windows gdbserver Tom Tromey
2020-03-13 19:08 ` [PATCH v3 29/29] Add pending stop support to gdbserver's Windows port Tom Tromey
2020-04-16  1:11   ` [pushed] gdbserver: fix format string warning in win32-low.cc (was: Re: [PATCH v3 29/29] Add pending stop support to gdbserver's Windows port) Simon Marchi
2020-04-08 20:33 ` [PATCH v3 00/29] Windows code sharing + bug fix Tom Tromey
2020-04-08 22:17   ` Hannes Domani
2020-04-09  2:49     ` Tom Tromey
2020-04-09 14:57       ` Jon Turney
2020-04-09 15:08         ` Hannes Domani
2020-04-09 17:54         ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200313190855.28662-22-tromey@adacore.com \
    --to=tromey@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox