Patchwork [RFAv3,2/6] Improve process exit status macros on MinGW

login
register
mail settings
Submitter Philippe Waroquiers
Date May 4, 2019, 4:17 p.m.
Message ID <20190504161753.15530-3-philippe.waroquiers@skynet.be>
Download mbox | patch
Permalink /patch/32544/
State New
Headers show

Comments

Philippe Waroquiers - May 4, 2019, 4:17 p.m.
gdb/ChangeLog
2019-05-04  Eli Zaretskii  <eliz@gnu.org>
	    Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* common/gdb_wait.h (WIFEXITED, WIFSIGNALED, WEXITSTATUS,
	WTERMSIG): Define better versions for MinGW.
	* windows-nat.c (xlate): Uncomment the definition.
	(windows_status_to_termsig): New function.
---
 gdb/common/gdb_wait.h | 27 +++++++++++++++++++++++++++
 gdb/windows-nat.c     | 18 ++++++++++++++----
 2 files changed, 41 insertions(+), 4 deletions(-)

Patch

diff --git a/gdb/common/gdb_wait.h b/gdb/common/gdb_wait.h
index b3b752cf3a..ca95240009 100644
--- a/gdb/common/gdb_wait.h
+++ b/gdb/common/gdb_wait.h
@@ -40,13 +40,31 @@ 
    NOTE exception for GNU/Linux below).  We also fail to declare
    wait() and waitpid().  */
 
+/* For MINGW, the underlying idea is that when a Windows program is terminated
+   by a fatal exception, its exit code is the value of that exception, as
+   defined by the various STATUS_* symbols in the Windows API headers.
+
+   The below is not perfect, because a program could legitimately exit normally
+   with a status whose value happens to have the high bits set, but that's
+   extremely rare, to say the least, and it is deemed such a negligibly small
+   probability of false positives is justified by the utility of reporting the
+   terminating signal in the "normal" cases.  */
+
 #ifndef	WIFEXITED
+#if defined (__MINGW32__)
+#define WIFEXITED(stat_val)   (((stat_val) & 0xC0000000) == 0)
+#else
 #define WIFEXITED(w)	(((w)&0377) == 0)
 #endif
+#endif
 
 #ifndef	WIFSIGNALED
+#if defined (__MINGW32__)
+#define WIFSIGNALED(stat_val) (((stat_val) & 0xC0000000) == 0xC0000000)
+#else
 #define WIFSIGNALED(w)	(((w)&0377) != 0177 && ((w)&~0377) == 0)
 #endif
+#endif
 
 #ifndef	WIFSTOPPED
 #ifdef IBM6000
@@ -64,12 +82,21 @@ 
 #endif
 
 #ifndef	WEXITSTATUS
+#if defined (__MINGW32__)
+#define WEXITSTATUS(stat_val) ((stat_val) & 255)
+#else
 #define WEXITSTATUS(w)	(((w) >> 8) & 0377) /* same as WRETCODE */
 #endif
+#endif
 
 #ifndef	WTERMSIG
+#if defined (__MINGW32__)
+extern enum gdb_signal windows_status_to_termsig (int stat_val);
+#define WTERMSIG(stat_val)    windows_status_to_termsig (stat_val)
+#else
 #define WTERMSIG(w)	((w) & 0177)
 #endif
+#endif
 
 #ifndef	WSTOPSIG
 #define WSTOPSIG	WEXITSTATUS
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index ae4e3d55b3..c90caeda6a 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -280,9 +280,9 @@  static const int *mappings;
    a segment register or not.  */
 static segment_register_p_ftype *segment_register_p;
 
-/* See windows_nat_target::resume to understand why this is commented
-   out.  */
-#if 0
+/* See windows_nat_target::resume to understand why xlate is not used
+   to translate a signal into an exception.  */
+
 /* This vector maps the target's idea of an exception (extracted
    from the DEBUG_EVENT structure) to GDB's idea.  */
 
@@ -302,7 +302,17 @@  static const struct xlate_exception xlate[] =
   {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE}
 };
 
-#endif /* 0 */
+/* Translate a windows exception inside STAT_VAL into a gdb_signal.
+   This should only be called if WIFSIGNALED (stat_val).  */
+
+enum gdb_signal
+windows_status_to_termsig (int stat_val)
+{
+  for (const xlate_exception &x : xlate)
+    if (x.them == (stat_val & ~0xC0000000))
+      return x.us;
+  return GDB_SIGNAL_UNKNOWN;
+}
 
 struct windows_nat_target final : public x86_nat_target<inf_child_target>
 {