This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Catch gas exit-via-signal


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1ec4b9f28bab4400c882a0f3e966eb12b73cee1a

commit 1ec4b9f28bab4400c882a0f3e966eb12b73cee1a
Author: Nathan Sidwell <nathan@acm.org>
Date:   Wed Jan 18 08:23:10 2017 -0500

    Catch gas exit-via-signal
    
    	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.

Diff:
---
 gas/ChangeLog    | 15 +++++++++++
 gas/as.c         |  1 +
 gas/as.h         |  5 ++--
 gas/config.in    |  3 +++
 gas/configure    | 11 ++++++++
 gas/configure.ac |  1 +
 gas/messages.c   | 76 ++++++++++++++++++++++++++++++++++++++++----------------
 7 files changed, 88 insertions(+), 24 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 93d76f9..b189e36 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/as.c b/gas/as.c
index 6c55e76..83a572b 100644
--- 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
diff --git a/gas/as.h b/gas/as.h
index 76aa9ac..fee7c75 100644
--- 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);
diff --git a/gas/config.in b/gas/config.in
index 5129c28..0855179 100644
--- a/gas/config.in
+++ b/gas/config.in
@@ -144,6 +144,9 @@
 /* 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
 
diff --git a/gas/configure b/gas/configure
index 2b54054..d3ae96e 100755
--- a/gas/configure
+++ b/gas/configure
@@ -13899,6 +13899,17 @@ _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
+
 
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5
diff --git a/gas/configure.ac b/gas/configure.ac
index c4c3036..cc70aa7 100644
--- a/gas/configure.ac
+++ b/gas/configure.ac
@@ -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
 
diff --git a/gas/messages.c b/gas/messages.c
index f452f22..57d4ed7 100644
--- a/gas/messages.c
+++ b/gas/messages.c
@@ -18,11 +18,19 @@
    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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]