Re: [PATCH v3 21/29] Share handle_exception

Tom Tromey
2020-04-15T19:13:17Z

>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

Simon> It helps, but there's still:

Simon> CXX nat/windows-nat.o
Simon> /home/smarchi/src/binutils-gdb/gdbserver/../gdb/nat/windows-nat.c: In function ‘windows_nat::handle_exception_result windows_nat::handle_exception(target_waitstatus*, bool)’:
Simon> /home/smarchi/src/binutils-gdb/gdbserver/../gdb/nat/windows-nat.c:214:10: error: ‘find_pc_partial_function’ was not declared in this scope
Simon> 214 | || (find_pc_partial_function (addr, &fn, NULL, NULL)
Simon> | ^~~~~~~~~~~~~~~~~~~~~~~~

Yeah, I realized this quite a while after sending it.

Simon> If we look at gdbserver's version of the function before this change, it didn't have that part,
Simon> so perhaps it should be factored out into a callback, which will reside in gdb/windows-nat.c.

Yep, please try this.

Tom

commit 3cb8f05b1e897a617e499edc54c9fc5cf456634c
Author: Tom Tromey <tromey@adacore.com>
Date: Wed Apr 15 13:11:23 2020 -0600

Fix Cygwin gdb build

Simon pointed out that the windows-nat sharing series broke the Cygwin
build. This patch fixes the problem, by moving the Cygwin-specific
code to a new handler function. This approach is taken because this
code calls find_pc_partial_function, which isn't available in
gdbserver.

gdb/ChangeLog
2020-04-15 Tom Tromey <tromey@adacore.com>

* windows-nat.c (windows_nat::handle_access_violation): New
function.
* nat/windows-nat.h (handle_access_violation): Declare.
* nat/windows-nat.c (handle_exception): Move Cygwin code to
windows-nat.c. Call handle_access_violation.

gdbserver/ChangeLog
2020-04-15 Tom Tromey <tromey@adacore.com>

* win32-low.cc (windows_nat::handle_access_violation): New
function.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b0a535a624f..f6a15d1482c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2020-04-15 Tom Tromey <tromey@adacore.com>
+
+ * windows-nat.c (windows_nat::handle_access_violation): New
+ function.
+ * nat/windows-nat.h (handle_access_violation): Declare.
+ * nat/windows-nat.c (handle_exception): Move Cygwin code to
+ windows-nat.c. Call handle_access_violation.
+
2020-04-15 Tom Tromey <tromey@adacore.com>

* windows-nat.c (DEBUG_EXEC, DEBUG_EVENTS, DEBUG_MEM)
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index cd7c1d177c6..8c2092a51d7 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -184,26 +184,8 @@ handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
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
+ if (handle_access_violation (rec))
+ return HANDLE_EXCEPTION_UNHANDLED;
break;
case STATUS_STACK_OVERFLOW:
DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index aea1519672d..8d0fa9bd216 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -157,6 +157,13 @@ extern void handle_unload_dll ();

extern bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);

+/* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding
+ application a chance to change it to be considered "unhandled".
+ This function must be supplied by the embedding application. If it
+ returns true, then the exception is "unhandled". */
+
+extern bool handle_access_violation (const EXCEPTION_RECORD *rec);
+

/* Currently executing process */
extern HANDLE current_process_handle;
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index e82e58ec1f2..b857f82eb89 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1230,6 +1230,31 @@ windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
return false;
}

+/* See nat/windows-nat.h. */
+
+bool
+windows_nat::handle_access_violation (const EXCEPTION_RECORD *rec)
+{
+#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 true;
+#endif
+ return false;
+}
+
/* Resume thread specified by ID, or all artificially suspended
threads, if we are continuing execution. KILLED non-zero means we
have killed the inferior, so we should ignore weird errors due to
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog
index 2b381455ed7..d22b6b2daef 100644
--- a/gdbserver/ChangeLog
+++ b/gdbserver/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-15 Tom Tromey <tromey@adacore.com>
+
+ * win32-low.cc (windows_nat::handle_access_violation): New
+ function.
+
2020-04-13 Tom Tromey <tom@tromey.com>

* server.h (gdb_fildes_t): Remove typedef.
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index e1226b4b0db..41348dd77d4 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -1198,6 +1198,14 @@ windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
return false;
}

+/* See nat/windows-nat.h. */
+
+bool
+windows_nat::handle_access_violation (const EXCEPTION_RECORD *rec)
+{
+ return false;
+}
+
/* A helper function that will, if needed, set
'stopped_at_software_breakpoint' on the thread and adjust the
PC. */