From 1ec4b9f28bab4400c882a0f3e966eb12b73cee1a Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 18 Jan 2017 08:23:10 -0500 Subject: [PATCH] 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 (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 | 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 93d76f91312..b189e36e59c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,18 @@ +2017-01-18 Nathan Sidwell + + * as.h (gas_assert): Use abort. + (as_assert): Remove. + (signal_init): Declare. + * as.c (main): Call signal_init. + * messages.c: #include + (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 * po/sv.po: Updated Swedish translation. diff --git a/gas/as.c b/gas/as.c index 6c55e76b487..83a572b2509 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 76aa9ac182b..fee7c7524a4 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 5129c28b207..08551796966 100644 --- a/gas/config.in +++ b/gas/config.in @@ -144,6 +144,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have the `strsignal' function. */ +#undef HAVE_STRSIGNAL + /* Define if has struct stat.st_mtim.tv_nsec */ #undef HAVE_ST_MTIM_TV_NSEC diff --git a/gas/configure b/gas/configure index 2b54054d66e..d3ae96e76cb 100755 --- a/gas/configure +++ b/gas/configure @@ -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 diff --git a/gas/configure.ac b/gas/configure.ac index c4c3036b0d7..cc70aa733ef 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 f452f227efb..57d4ed7c5e8 100644 --- a/gas/messages.c +++ b/gas/messages.c @@ -18,11 +18,19 @@ 02110-1301, USA. */ #include "as.h" +#include + +/* 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. */ -- 2.30.2