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

1.1.1.2 ! misho       1: # nocrash.m4 serial 5
        !             2: dnl Copyright (C) 2005, 2009-2019 Free Software Foundation, Inc.
1.1       misho       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__
1.1.1.2 ! misho      21: /* Avoid a crash on Mac OS X.  */
1.1       misho      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: }
1.1.1.2 ! misho      82: #elif defined _WIN32 && ! defined __CYGWIN__
        !            83: /* Avoid a crash on native Windows.  */
        !            84: #define WIN32_LEAN_AND_MEAN
        !            85: #include <windows.h>
        !            86: #include <winerror.h>
        !            87: static LONG WINAPI
        !            88: exception_filter (EXCEPTION_POINTERS *ExceptionInfo)
        !            89: {
        !            90:   switch (ExceptionInfo->ExceptionRecord->ExceptionCode)
        !            91:     {
        !            92:     case EXCEPTION_ACCESS_VIOLATION:
        !            93:     case EXCEPTION_IN_PAGE_ERROR:
        !            94:     case EXCEPTION_STACK_OVERFLOW:
        !            95:     case EXCEPTION_GUARD_PAGE:
        !            96:     case EXCEPTION_PRIV_INSTRUCTION:
        !            97:     case EXCEPTION_ILLEGAL_INSTRUCTION:
        !            98:     case EXCEPTION_DATATYPE_MISALIGNMENT:
        !            99:     case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
        !           100:     case EXCEPTION_NONCONTINUABLE_EXCEPTION:
        !           101:       exit (1);
        !           102:     }
        !           103:   return EXCEPTION_CONTINUE_SEARCH;
        !           104: }
        !           105: static void
        !           106: nocrash_init (void)
        !           107: {
        !           108:   SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) exception_filter);
        !           109: }
1.1       misho     110: #else
                    111: /* Avoid a crash on POSIX systems.  */
                    112: #include <signal.h>
1.1.1.2 ! misho     113: #include <unistd.h>
1.1       misho     114: /* A POSIX signal handler.  */
                    115: static void
                    116: exception_handler (int sig)
                    117: {
1.1.1.2 ! misho     118:   _exit (1);
1.1       misho     119: }
                    120: static void
                    121: nocrash_init (void)
                    122: {
                    123: #ifdef SIGSEGV
                    124:   signal (SIGSEGV, exception_handler);
                    125: #endif
                    126: #ifdef SIGBUS
                    127:   signal (SIGBUS, exception_handler);
                    128: #endif
                    129: }
                    130: #endif
                    131: ]])

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