Catch gas exit-via-signal
authorNathan Sidwell <nathan@acm.org>
Wed, 18 Jan 2017 13:23:10 +0000 (08:23 -0500)
committerNathan Sidwell <nathan@acm.org>
Wed, 18 Jan 2017 13:23:10 +0000 (08:23 -0500)
gas/
* as.h (gas_assert): Use abort.
(as_assert): Remove.
(signal_init): Declare.
* as.c (main): Call signal_init.
* messages.c: #include <signal.h>
(as_assert): Delete.
(as_abort): Allow NULL FILE.
(signal_crash): New.
(signal_init): Register fatal signal handlers.
* configure.ac: Check for strsignal.
* config.in: Rebuilt.
* configure: Rebuilt.

gas/ChangeLog
gas/as.c
gas/as.h
gas/config.in
gas/configure
gas/configure.ac
gas/messages.c

index 93d76f9131219caea86b9e2bdca29c28170fcb48..b189e36e59c27ebe7aeb65f8a146e04d8c884ae9 100644 (file)
@@ -1,3 +1,18 @@
+2017-01-18  Nathan Sidwell  <nathan@acm.org>
+
+       * as.h (gas_assert): Use abort.
+       (as_assert): Remove.
+       (signal_init): Declare.
+       * as.c (main): Call signal_init.
+       * messages.c: #include <signal.h>
+       (as_assert): Delete.
+       (as_abort): Allow NULL FILE.
+       (signal_crash): New.
+       (signal_init): Register fatal signal handlers.
+       * configure.ac: Check for strsignal.
+       * config.in: Rebuilt.
+       * configure: Rebuilt.
+
 2017-01-17  Nick Clifton  <nickc@redhat.com>
 
        * po/sv.po: Updated Swedish translation.
index 6c55e76b487f49965197b319874b3ba43163f621..83a572b25096053a07c833953f0f0029048b9025 100644 (file)
--- a/gas/as.c
+++ b/gas/as.c
@@ -1186,6 +1186,7 @@ main (int argc, char ** argv)
   int macro_strip_at;
 
   start_time = get_run_time ();
+  signal_init ();
 #ifdef HAVE_SBRK
   start_sbrk = (char *) sbrk (0);
 #endif
index 76aa9ac182ba39364c0cbb53cc3788d73b7585bc..fee7c7524a44cbe0174bbece41326d30f9287e63 100644 (file)
--- a/gas/as.h
+++ b/gas/as.h
@@ -85,8 +85,7 @@
 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
 #define __PRETTY_FUNCTION__  ((char *) NULL)
 #endif
-#define gas_assert(P) \
-  ((void) ((P) ? 0 : (as_assert (__FILE__, __LINE__, __PRETTY_FUNCTION__), 0)))
+#define gas_assert(P)  ((void) ((P) ? 0 : (abort (), 0)))
 #undef abort
 #define abort()                as_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__)
 
@@ -459,8 +458,8 @@ PRINTF_LIKE (as_warn);
 PRINTF_WHERE_LIKE (as_bad_where);
 PRINTF_WHERE_LIKE (as_warn_where);
 
-void   as_assert (const char *, int, const char *) ATTRIBUTE_NORETURN;
 void   as_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
+void   signal_init (void);
 void   sprint_value (char *, addressT);
 int    had_errors (void);
 int    had_warnings (void);
index 5129c28b2070ced49f42851b07789e1fb8d7aeaa..08551796966f78b65bebbc2c78c364e18f583ea1 100644 (file)
 /* Define to 1 if you have the <string.h> header file. */
 #undef HAVE_STRING_H
 
+/* Define to 1 if you have the `strsignal' function. */
+#undef HAVE_STRSIGNAL
+
 /* Define if <sys/stat.h> has struct stat.st_mtim.tv_nsec */
 #undef HAVE_ST_MTIM_TV_NSEC
 
index 2b54054d66ec5417f2dfe5e8013b70e14fa2504f..d3ae96e76cbed2582e1604945bf277ee01ae335d 100755 (executable)
@@ -13896,6 +13896,17 @@ eval as_val=\$$as_ac_var
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
+fi
+done
+
+for ac_func in strsignal
+do :
+  ac_fn_c_check_func "$LINENO" "strsignal" "ac_cv_func_strsignal"
+if test "x$ac_cv_func_strsignal" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STRSIGNAL 1
+_ACEOF
+
 fi
 done
 
index c4c3036b0d71850049a690d956641ca1fa8b2288..cc70aa733efdb4496b9e2582c01addb2df08709c 100644 (file)
@@ -826,6 +826,7 @@ AC_C_INLINE
 # VMS doesn't have unlink.
 AC_CHECK_FUNCS(unlink remove, break)
 AC_CHECK_FUNCS(sbrk setlocale)
+AC_CHECK_FUNCS(strsignal)
 
 AM_LC_MESSAGES
 
index f452f227efb0ba8e1594a7318395cdb8b4dcdded..57d4ed7c5e863c614b0e936fb963083945155afe 100644 (file)
    02110-1301, USA.  */
 
 #include "as.h"
+#include <signal.h>
+
+/* If the system doesn't provide strsignal, we get it defined in
+   libiberty but no declaration is supplied.  Because, reasons. */
+#if !defined (HAVE_STRSIGNAL) && !defined (strsignal)
+extern const char *strsignal (int);
+#endif
 
 static void identify (const char *);
 static void as_show_where (void);
 static void as_warn_internal (const char *, unsigned int, char *);
 static void as_bad_internal (const char *, unsigned int, char *);
+static void signal_crash (int) ATTRIBUTE_NORETURN;
 
 /* Despite the rest of the comments in this file, (FIXME-SOON),
    here is the current scheme for error messages etc:
@@ -58,7 +66,10 @@ static void as_bad_internal (const char *, unsigned int, char *);
    as_tsktsk() is used when we see a minor error for which
    our error recovery action is almost certainly correct.
    In this case, we print a message and then assembly
-   continues as though no error occurred.  */
+   continues as though no error occurred.
+
+   as_abort () is used for logic failure (assert or abort, signal).
+*/
 
 static void
 identify (const char *file)
@@ -286,38 +297,61 @@ as_fatal (const char *format, ...)
   xexit (EXIT_FAILURE);
 }
 
-/* Indicate assertion failure.
-   Arguments: Filename, line number, optional function name.  */
+/* Indicate internal constency error.
+   Arguments: Filename, line number, optional function name.
+   FILENAME may be NULL, which we use for crash-via-signal.  */
 
 void
-as_assert (const char *file, int line, const char *fn)
+as_abort (const char *file, int line, const char *fn)
 {
   as_show_where ();
-  fprintf (stderr, _("Internal error!\n"));
-  if (fn)
-    fprintf (stderr, _("Assertion failure in %s at %s:%d.\n"),
-            fn, file, line);
+
+  if (!file)
+    fprintf (stderr, _("Internal error (%s).\n"), fn ? fn : "unknown");
+  else if (fn)
+    fprintf (stderr, _("Internal error in %s at %s:%d.\n"), fn, file, line);
   else
-    fprintf (stderr, _("Assertion failure at %s:%d.\n"), file, line);
+    fprintf (stderr, _("Internal error at %s:%d.\n"), file, line);
+
   fprintf (stderr, _("Please report this bug.\n"));
+
   xexit (EXIT_FAILURE);
 }
 
-/* as_abort: Print a friendly message saying how totally hosed we are,
-   and exit without producing a core file.  */
+/* Handler for fatal signals, such as SIGSEGV. */
+
+static void
+signal_crash (int signo)
+{
+  /* Reset, to prevent unbounded recursion.  */
+  signal (signo, SIG_DFL);
+
+  as_abort (NULL, 0, strsignal (signo));
+}
+
+/* Register signal handlers, for less abrubt crashes.  */
 
 void
-as_abort (const char *file, int line, const char *fn)
+signal_init (void)
 {
-  as_show_where ();
-  if (fn)
-    fprintf (stderr, _("Internal error, aborting at %s:%d in %s\n"),
-            file, line, fn);
-  else
-    fprintf (stderr, _("Internal error, aborting at %s:%d\n"),
-            file, line);
-  fprintf (stderr, _("Please report this bug.\n"));
-  xexit (EXIT_FAILURE);
+#ifdef SIGSEGV
+  signal (SIGSEGV, signal_crash);
+#endif
+#ifdef SIGILL
+  signal (SIGILL, signal_crash);
+#endif
+#ifdef SIGBUS
+  signal (SIGBUS, signal_crash);
+#endif
+#ifdef SIGABRT
+  signal (SIGABRT, signal_crash);
+#endif
+#if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT)
+  signal (SIGIOT, signal_crash);
+#endif
+#ifdef SIGFPE
+  signal (SIGFPE, signal_crash);
+#endif
 }
 
 /* Support routines.  */