Annotation of embedaddon/libiconv/srcm4/nocrash.m4, revision 1.1

1.1     ! misho       1: # nocrash.m4 serial 2
        !             2: dnl Copyright (C) 2005, 2009-2011 Free Software Foundation, Inc.
        !             3: dnl This file is free software; the Free Software Foundation
        !             4: dnl gives unlimited permission to copy and/or distribute it,
        !             5: dnl with or without modifications, as long as this notice is preserved.
        !             6: 
        !             7: dnl Based on libsigsegv, from Bruno Haible and Paolo Bonzini.
        !             8: 
        !             9: AC_PREREQ([2.13])
        !            10: 
        !            11: dnl Expands to some code for use in .c programs that will cause the configure
        !            12: dnl test to exit instead of crashing. This is useful to avoid triggering
        !            13: dnl action from a background debugger and to avoid core dumps.
        !            14: dnl Usage:   ...
        !            15: dnl          ]GL_NOCRASH[
        !            16: dnl          ...
        !            17: dnl          int main() { nocrash_init(); ... }
        !            18: AC_DEFUN([GL_NOCRASH],[[
        !            19: #include <stdlib.h>
        !            20: #if defined __MACH__ && defined __APPLE__
        !            21: /* Avoid a crash on MacOS X.  */
        !            22: #include <mach/mach.h>
        !            23: #include <mach/mach_error.h>
        !            24: #include <mach/thread_status.h>
        !            25: #include <mach/exception.h>
        !            26: #include <mach/task.h>
        !            27: #include <pthread.h>
        !            28: /* The exception port on which our thread listens.  */
        !            29: static mach_port_t our_exception_port;
        !            30: /* The main function of the thread listening for exceptions of type
        !            31:    EXC_BAD_ACCESS.  */
        !            32: static void *
        !            33: mach_exception_thread (void *arg)
        !            34: {
        !            35:   /* Buffer for a message to be received.  */
        !            36:   struct {
        !            37:     mach_msg_header_t head;
        !            38:     mach_msg_body_t msgh_body;
        !            39:     char data[1024];
        !            40:   } msg;
        !            41:   mach_msg_return_t retval;
        !            42:   /* Wait for a message on the exception port.  */
        !            43:   retval = mach_msg (&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof (msg),
        !            44:                      our_exception_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
        !            45:   if (retval != MACH_MSG_SUCCESS)
        !            46:     abort ();
        !            47:   exit (1);
        !            48: }
        !            49: static void
        !            50: nocrash_init (void)
        !            51: {
        !            52:   mach_port_t self = mach_task_self ();
        !            53:   /* Allocate a port on which the thread shall listen for exceptions.  */
        !            54:   if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port)
        !            55:       == KERN_SUCCESS) {
        !            56:     /* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html.  */
        !            57:     if (mach_port_insert_right (self, our_exception_port, our_exception_port,
        !            58:                                 MACH_MSG_TYPE_MAKE_SEND)
        !            59:         == KERN_SUCCESS) {
        !            60:       /* The exceptions we want to catch.  Only EXC_BAD_ACCESS is interesting
        !            61:          for us.  */
        !            62:       exception_mask_t mask = EXC_MASK_BAD_ACCESS;
        !            63:       /* Create the thread listening on the exception port.  */
        !            64:       pthread_attr_t attr;
        !            65:       pthread_t thread;
        !            66:       if (pthread_attr_init (&attr) == 0
        !            67:           && pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) == 0
        !            68:           && pthread_create (&thread, &attr, mach_exception_thread, NULL) == 0) {
        !            69:         pthread_attr_destroy (&attr);
        !            70:         /* Replace the exception port info for these exceptions with our own.
        !            71:            Note that we replace the exception port for the entire task, not only
        !            72:            for a particular thread.  This has the effect that when our exception
        !            73:            port gets the message, the thread specific exception port has already
        !            74:            been asked, and we don't need to bother about it.
        !            75:            See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html.  */
        !            76:         task_set_exception_ports (self, mask, our_exception_port,
        !            77:                                   EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
        !            78:       }
        !            79:     }
        !            80:   }
        !            81: }
        !            82: #else
        !            83: /* Avoid a crash on POSIX systems.  */
        !            84: #include <signal.h>
        !            85: /* A POSIX signal handler.  */
        !            86: static void
        !            87: exception_handler (int sig)
        !            88: {
        !            89:   exit (1);
        !            90: }
        !            91: static void
        !            92: nocrash_init (void)
        !            93: {
        !            94: #ifdef SIGSEGV
        !            95:   signal (SIGSEGV, exception_handler);
        !            96: #endif
        !            97: #ifdef SIGBUS
        !            98:   signal (SIGBUS, exception_handler);
        !            99: #endif
        !           100: }
        !           101: #endif
        !           102: ]])

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>