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>