Also use mach exception handlers to trap SIGFPE

slava 2006-11-23 21:35:36 +00:00
parent 169b07e0b3
commit 29c3d757bd
2 changed files with 21 additions and 7 deletions

View File

@ -8,7 +8,6 @@
- graphical crossref tool - graphical crossref tool
- http://paste.lisp.org/display/30426 - http://paste.lisp.org/display/30426
- C+p: shows newlines as a box - C+p: shows newlines as a box
- use mach exception handling to trap div by zero on os x
- menu Command: quots look dumb - menu Command: quots look dumb
- top level window positioning on ms windows - top level window positioning on ms windows

View File

@ -1,6 +1,7 @@
/* Fault handler information. MacOSX version. /* Fault handler information. MacOSX version.
Copyright (C) 1993-1999, 2002-2003 Bruno Haible <clisp.org at bruno> Copyright (C) 1993-1999, 2002-2003 Bruno Haible <clisp.org at bruno>
Copyright (C) 2003 Paolo Bonzini <gnu.org at bonzini> Copyright (C) 2003 Paolo Bonzini <gnu.org at bonzini>
Various modifications to support Intel Macs by Slava Pestov
Used under BSD license with permission from Paolo Bonzini and Bruno Haible, Used under BSD license with permission from Paolo Bonzini and Bruno Haible,
2005-03-10 2005-03-10
@ -19,14 +20,20 @@ see http://www.caddr.com/macho/archives/sbcl-devel/2005-3/4764.html */
/* The exception port on which our thread listens. */ /* The exception port on which our thread listens. */
static mach_port_t our_exception_port; static mach_port_t our_exception_port;
/* A handler that is called in the faulting thread. */ /* Handlers that are called in the faulting thread. */
static void static void
terminating_handler (void *fault_addr) memory_protection_handler (void *fault_addr)
{ {
memory_protection_error((CELL)fault_addr,SIGSEGV); memory_protection_error((CELL)fault_addr,SIGSEGV);
abort (); abort ();
} }
static void
arithmetic_handler (void *ignore)
{
signal_error(SIGFPE);
abort ();
}
/* Handle an exception by invoking the user's fault handler and/or forwarding /* Handle an exception by invoking the user's fault handler and/or forwarding
the duty to the previously installed handlers. */ the duty to the previously installed handlers. */
@ -66,7 +73,16 @@ catch_exception_raise (mach_port_t exception_port,
sp = (unsigned long) (SIGSEGV_STACK_POINTER (thread_state)); sp = (unsigned long) (SIGSEGV_STACK_POINTER (thread_state));
SIGSEGV_PROGRAM_COUNTER (thread_state) = (unsigned long) terminating_handler; void *handler;
if(exception == EXC_BAD_ACCESS)
handler = memory_protection_handler;
else if(exception == EXC_ARITHMETIC)
handler = arithmetic_handler;
else
abort();
SIGSEGV_PROGRAM_COUNTER (thread_state) = (unsigned long) handler;
SIGSEGV_STACK_POINTER (thread_state) = fix_stack_ptr(sp); SIGSEGV_STACK_POINTER (thread_state) = fix_stack_ptr(sp);
pass_arg0(&thread_state,SIGSEGV_EXC_STATE_FAULT(exc_state)); pass_arg0(&thread_state,SIGSEGV_EXC_STATE_FAULT(exc_state));
@ -155,9 +171,8 @@ int mach_initialize ()
!= KERN_SUCCESS) != KERN_SUCCESS)
return -1; return -1;
/* The exceptions we want to catch. Only EXC_BAD_ACCESS is interesting /* The exceptions we want to catch. */
for us (see above in function catch_exception_raise). */ mask = EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC;
mask = EXC_MASK_BAD_ACCESS;
/* Create the thread listening on the exception port. */ /* Create the thread listening on the exception port. */
if (pthread_attr_init (&attr) != 0) if (pthread_attr_init (&attr) != 0)