diff options
author | Eric Blake <ebb9@byu.net> | 2008-06-18 11:38:30 -0600 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2008-06-18 11:38:30 -0600 |
commit | e0408e69edb2e966f9a4c879124e14ec4fcacf00 (patch) | |
tree | bc8cd35f63d1f3bed95c03e5412f2efab9cfc5db | |
parent | 0b2dea68c4f3e2f6cca84291536b80b3c4eac058 (diff) | |
download | m4-e0408e69edb2e966f9a4c879124e14ec4fcacf00.tar.gz |
Also trap SIGILL, SIGFPE, SIGBUS.
* m4/gnulib-cache.m4: Import strsignal module.
* src/m4.c (main): Register more handlers, and prefer sigaction
when available.
(SIGBUS, NSIG): Provide fallback when lacking.
(signal_message): New variable, to keep async-safety.
(fault_handler): Display faulting signal description.
* configure.ac (gl_DISABLE_THREADS): Request gnulib modules to
optimize for single-threaded operation.
Signed-off-by: Eric Blake <ebb9@byu.net>
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | m4/gnulib-cache.m4 | 4 | ||||
-rw-r--r-- | src/m4.c | 58 |
4 files changed, 71 insertions, 6 deletions
@@ -1,3 +1,15 @@ +2008-06-18 Eric Blake <ebb9@byu.net> + + Also trap SIGILL, SIGFPE, SIGBUS. + * m4/gnulib-cache.m4: Import strsignal module. + * src/m4.c (main): Register more handlers, and prefer sigaction + when available. + (SIGBUS, NSIG): Provide fallback when lacking. + (signal_message): New variable, to keep async-safety. + (fault_handler): Display faulting signal description. + * configure.ac (gl_DISABLE_THREADS): Request gnulib modules to + optimize for single-threaded operation. + 2008-06-06 Eric Blake <ebb9@byu.net> Inform users what to do in case of programmer error. diff --git a/configure.ac b/configure.ac index 3456d8fe..f23cc422 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +32,9 @@ AC_CONFIG_HEADERS([lib/config.h:lib/config.hin]) AC_PROG_CC M4_EARLY +# M4 is single-threaded; so we can optimize gnulib code by using this: +gl_DISABLE_THREADS + # Tandem/NSK is broken - it has 'long long int' but not # 'unsigned long long int', which confuses assumptions made by gnulib. # Simply pretend that neither type exists if both do not work. diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index 7c1fb0d6..7f8d10be 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -15,11 +15,11 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --local-dir=local --lib=libm4 --source-base=lib --m4-base=m4 --doc-base=doc --aux-dir=build-aux --with-tests --no-libtool --macro-prefix=M4 announce-gen assert autobuild avltree-oset binary-io c-stack clean-temp cloexec close-stream closein config-h error fdl fflush flexmember fopen-safer fseeko gendocs getopt git-version-gen gnumakefile gnupload gpl-3.0 intprops memchr2 memmem mkstemp obstack progname quote regex stdbool stdint stdlib-safer strtod strtol unlocked-io vasnprintf-posix verror version-etc version-etc-fsf xalloc xmemdup0 xprintf xvasprintf-posix +# gnulib-tool --import --dir=. --local-dir=local --lib=libm4 --source-base=lib --m4-base=m4 --doc-base=doc --aux-dir=build-aux --with-tests --no-libtool --macro-prefix=M4 announce-gen assert autobuild avltree-oset binary-io c-stack clean-temp cloexec close-stream closein config-h error fdl fflush flexmember fopen-safer fseeko gendocs getopt git-version-gen gnumakefile gnupload gpl-3.0 intprops memchr2 memmem mkstemp obstack progname quote regex stdbool stdint stdlib-safer strsignal strtod strtol unlocked-io vasnprintf-posix verror version-etc version-etc-fsf xalloc xmemdup0 xprintf xvasprintf-posix # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([local]) -gl_MODULES([announce-gen assert autobuild avltree-oset binary-io c-stack clean-temp cloexec close-stream closein config-h error fdl fflush flexmember fopen-safer fseeko gendocs getopt git-version-gen gnumakefile gnupload gpl-3.0 intprops memchr2 memmem mkstemp obstack progname quote regex stdbool stdint stdlib-safer strtod strtol unlocked-io vasnprintf-posix verror version-etc version-etc-fsf xalloc xmemdup0 xprintf xvasprintf-posix]) +gl_MODULES([announce-gen assert autobuild avltree-oset binary-io c-stack clean-temp cloexec close-stream closein config-h error fdl fflush flexmember fopen-safer fseeko gendocs getopt git-version-gen gnumakefile gnupload gpl-3.0 intprops memchr2 memmem mkstemp obstack progname quote regex stdbool stdint stdlib-safer strsignal strtod strtol unlocked-io vasnprintf-posix verror version-etc version-etc-fsf xalloc xmemdup0 xprintf xvasprintf-posix]) gl_AVOID([]) gl_SOURCE_BASE([lib]) gl_M4_BASE([m4]) @@ -178,9 +178,23 @@ m4_warn (int errnum, const call_info *caller, const char *format, ...) } } -/* Translated message for program errors. Do not translate it in the - signal handler, since gettext is not async-signal-safe. */ +#ifndef SIGBUS +# define SIGBUS SIGILL +#endif + +#ifndef NSIG +# ifndef MAX +# define MAX(a,b) ((a) < (b) ? (b) : (a)) +# endif +# define NSIG (MAX (SIGABRT, MAX (SIGILL, MAX (SIGFPE, \ + MAX (SIGSEGV, SIGBUS)))) + 1) +#endif + +/* Pre-translated messages for program errors. Do not translate in + the signal handler, since gettext and strsignal are not + async-signal-safe. */ static const char * volatile program_error_message; +static const char * volatile signal_message[NSIG]; /* Print a nicer message about any programmer errors, then exit. This must be aysnc-signal safe, since it is executed as a signal @@ -191,10 +205,21 @@ fault_handler (int signo) { if (signo) { + /* POSIX states that reading static memory is, in general, not + async-safe. However, the static variables that we read are + never modified once this handler is installed, so this + particular usage is safe. And it seems an oversight that + POSIX claims strlen is not async-safe. */ write (STDERR_FILENO, program_name, strlen (program_name)); write (STDERR_FILENO, ": ", 2); write (STDERR_FILENO, program_error_message, strlen (program_error_message)); + if (signal_message[signo]) + { + write (STDERR_FILENO, ": ", 2); + write (STDERR_FILENO, signal_message[signo], + strlen (signal_message[signo])); + } write (STDERR_FILENO, "\n", 1); _exit (EXIT_INTERNAL_ERROR); } @@ -438,14 +463,39 @@ main (int argc, char *const *argv, char *const *envp) set_quoting_style (NULL, escape_quoting_style); set_char_quoting (NULL, ':', 1); - /* Stack overflow and program error handling. */ + /* Stack overflow and program error handling. Ignore failure to + install a handler, since this is merely for improved output on + crash, and we should never crash ;). */ if (c_stack_action (fault_handler) == 0) nesting_limit = 0; program_error_message = xasprintf (_("internal error detected; please report this bug to <%s>"), PACKAGE_BUGREPORT); - /* FIXME - use sigaction. */ + signal_message[SIGSEGV] = xstrdup (strsignal (SIGSEGV)); + signal_message[SIGABRT] = xstrdup (strsignal (SIGABRT)); + signal_message[SIGILL] = xstrdup (strsignal (SIGILL)); + signal_message[SIGFPE] = xstrdup (strsignal (SIGFPE)); + if (SIGBUS != SIGILL) + signal_message[SIGBUS] = xstrdup (strsignal (SIGBUS)); +#ifdef HAVE_SIGACTION + { + struct sigaction act; + sigemptyset (&act.sa_mask); + /* One-shot - if we fault while handling a fault, we want to + revert to default signal behavior. */ + act.sa_flags = SA_NODEFER | SA_RESETHAND; + act.sa_handler = fault_handler; + sigaction (SIGABRT, &act, NULL); + sigaction (SIGILL, &act, NULL); + sigaction (SIGFPE, &act, NULL); + sigaction (SIGBUS, &act, NULL); + } +#else /* !HAVE_SIGACTION */ signal (SIGABRT, fault_handler); + signal (SIGILL, fault_handler); + signal (SIGFPE, fault_handler); + signal (SIGBUS, fault_handler); +#endif /* !HAVE_SIGACTION */ /* First, we decode the arguments, to size up tables and stuff. */ |