aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-01-18 08:23:10 -0500
committerNathan Sidwell <nathan@acm.org>2017-01-18 08:23:10 -0500
commit1ec4b9f28bab4400c882a0f3e966eb12b73cee1a (patch)
treed5c4263ec5061e83bc72f5096247ec0ebec1b892 /gas
parent319b82e47dd12d6554e17a2ceedd3139b88ba55f (diff)
downloadbinutils-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/ChangeLog15
-rw-r--r--gas/as.c1
-rw-r--r--gas/as.h5
-rw-r--r--gas/config.in3
-rwxr-xr-xgas/configure11
-rw-r--r--gas/configure.ac1
-rw-r--r--gas/messages.c76
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. */