From b908e23481452834d238421cfa4dc3ec396ea62b Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 4 Nov 2007 19:52:07 +0100 Subject: [PATCH] New module 'nocrash'. --- ChangeLog | 6 ++++ m4/nocrash.m4 | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ modules/nocrash | 20 +++++++++++ 3 files changed, 128 insertions(+) create mode 100644 m4/nocrash.m4 create mode 100644 modules/nocrash diff --git a/ChangeLog b/ChangeLog index f6ca51a08..d9bebd263 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2007-11-04 Bruno Haible + * modules/nocrash: New file. + * m4/nocrash.m4: New file, taken from GNU clisp. Code taken from + GNU libsigsegv, with permission of GNU libsigsegv's copyright holders. + +2007-11-04 Bruno Haible + * tests/test-vasnprintf-posix.c (test_function): Add some tests of precision handling. * tests/test-vasprintf-posix.c (test_function): Likewise. diff --git a/m4/nocrash.m4 b/m4/nocrash.m4 new file mode 100644 index 000000000..1f92c26d9 --- /dev/null +++ b/m4/nocrash.m4 @@ -0,0 +1,102 @@ +# nocrash.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Based on libsigsegv, from Bruno Haible and Paolo Bonzini. + +AC_PREREQ(2.13) + +dnl Expands to some code for use in .c programs that will cause the configure +dnl test to exit instead of crashing. This is useful to avoid triggering +dnl action from a background debugger and to avoid core dumps. +dnl Usage: ... +dnl ]GL_NOCRASH[ +dnl ... +dnl int main() { nocrash_init(); ... } +AC_DEFUN([GL_NOCRASH],[[ +#include +#if defined __MACH__ && defined __APPLE__ +/* Avoid a crash on MacOS X. */ +#include +#include +#include +#include +#include +#include +/* The exception port on which our thread listens. */ +static mach_port_t our_exception_port; +/* The main function of the thread listening for exceptions of type + EXC_BAD_ACCESS. */ +static void * +mach_exception_thread (void *arg) +{ + /* Buffer for a message to be received. */ + struct { + mach_msg_header_t head; + mach_msg_body_t msgh_body; + char data[1024]; + } msg; + mach_msg_return_t retval; + /* Wait for a message on the exception port. */ + retval = mach_msg (&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof (msg), + our_exception_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if (retval != MACH_MSG_SUCCESS) + abort (); + exit (1); +} +static void +nocrash_init (void) +{ + mach_port_t self = mach_task_self (); + /* Allocate a port on which the thread shall listen for exceptions. */ + if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port) + == KERN_SUCCESS) { + /* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html. */ + if (mach_port_insert_right (self, our_exception_port, our_exception_port, + MACH_MSG_TYPE_MAKE_SEND) + == KERN_SUCCESS) { + /* The exceptions we want to catch. Only EXC_BAD_ACCESS is interesting + for us. */ + exception_mask_t mask = EXC_MASK_BAD_ACCESS; + /* Create the thread listening on the exception port. */ + pthread_attr_t attr; + pthread_t thread; + if (pthread_attr_init (&attr) == 0 + && pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) == 0 + && pthread_create (&thread, &attr, mach_exception_thread, NULL) == 0) { + pthread_attr_destroy (&attr); + /* Replace the exception port info for these exceptions with our own. + Note that we replace the exception port for the entire task, not only + for a particular thread. This has the effect that when our exception + port gets the message, the thread specific exception port has already + been asked, and we don't need to bother about it. + See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */ + task_set_exception_ports (self, mask, our_exception_port, + EXCEPTION_DEFAULT, MACHINE_THREAD_STATE); + } + } + } +} +#else +/* Avoid a crash on POSIX systems. */ +#include +/* A POSIX signal handler. */ +static void +exception_handler (int sig) +{ + exit (1); +} +static void +nocrash_init (void) +{ +#ifdef SIGSEGV + signal (SIGSEGV, exception_handler); +#endif +#ifdef SIGBUS + signal (SIGBUS, exception_handler); +#endif +} +#endif +]]) diff --git a/modules/nocrash b/modules/nocrash new file mode 100644 index 000000000..607c39402 --- /dev/null +++ b/modules/nocrash @@ -0,0 +1,20 @@ +Description: +Macro that avoids crashes in configure tests. + +Files: +m4/nocrash.m4 + +Depends-on: + +configure.ac: + +Makefile.am: + +Include: + +License: +unlimited + +Maintainer: +Bruno Haible, Paolo Bonzini + -- 2.11.0