2017-01-12 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.
@@ -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);
@@ -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
@@ -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
@@ -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
@@ -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. */