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>