diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-01-18 08:23:10 -0500 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2017-01-18 08:23:10 -0500 |
commit | 1ec4b9f28bab4400c882a0f3e966eb12b73cee1a (patch) | |
tree | d5c4263ec5061e83bc72f5096247ec0ebec1b892 /gas | |
parent | 319b82e47dd12d6554e17a2ceedd3139b88ba55f (diff) | |
download | binutils-1ec4b9f28bab4400c882a0f3e966eb12b73cee1a.zip binutils-1ec4b9f28bab4400c882a0f3e966eb12b73cee1a.tar.gz binutils-1ec4b9f28bab4400c882a0f3e966eb12b73cee1a.tar.bz2 |
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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 15 | ||||
-rw-r--r-- | gas/as.c | 1 | ||||
-rw-r--r-- | gas/as.h | 5 | ||||
-rw-r--r-- | gas/config.in | 3 | ||||
-rwxr-xr-x | gas/configure | 11 | ||||
-rw-r--r-- | gas/configure.ac | 1 | ||||
-rw-r--r-- | 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. @@ -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 @@ -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. */ |