void EstablishDylanExceptionHandlers(void) { if (exception_port == MACH_PORT_NULL) { // Need a port we can receive exceptions on kern_return_t rc = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &exception_port); if (rc != KERN_SUCCESS) { mach_error("mach_port_allocate send", rc); abort(); } // Need to be able to send on it too rc = mach_port_insert_right(mach_task_self(), exception_port, exception_port, MACH_MSG_TYPE_MAKE_SEND); if (rc != KERN_SUCCESS) { mach_error("mach_port_insert_right", rc); abort(); } // Spawn a thread to serve exception requests pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t thread; int prc = pthread_create(&thread, &attr, catcher, NULL); pthread_attr_destroy(&attr); if (prc != 0) { fprintf(stderr, "%s: pthread_create returned %d\n", __func__, prc); abort(); } } // Set this thread's exception port kern_return_t rc = thread_set_exception_ports(mach_thread_self(), EXC_MASK_ARITHMETIC|EXC_MASK_BREAKPOINT, exception_port, EXCEPTION_STATE_IDENTITY|MACH_EXCEPTION_CODES, THREAD_STATE_FLAVOR); if (rc != KERN_SUCCESS) { mach_error("thread_set_exception_ports", rc); abort(); } primitive_reset_float_environment(); }
void EstablishDylanExceptionHandlers(void) { struct sigaction fpehandler; sigemptyset(&fpehandler.sa_mask); fpehandler.sa_sigaction = DylanFPEHandler; fpehandler.sa_flags = SA_SIGINFO; sigaction(SIGFPE, &fpehandler, &oldfpehandler); #if defined OPEN_DYLAN_PLATFORM_LINUX struct sigaction segvhandler; sigemptyset(&segvhandler.sa_mask); segvhandler.sa_sigaction = DylanSEGVHandler; segvhandler.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &segvhandler, &oldsegvhandler); #endif primitive_reset_float_environment(); }