]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: clean up signal handling and add EXC_BAD_INSTRUCTION Mach exception handler for...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 22 Oct 2009 10:22:59 +0000 (05:22 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 22 Oct 2009 10:22:59 +0000 (05:22 -0500)
20 files changed:
vm/mach_signal.cpp
vm/os-freebsd-x86.32.hpp
vm/os-freebsd-x86.64.hpp
vm/os-genunix.hpp
vm/os-linux-arm.hpp
vm/os-linux-ppc.hpp
vm/os-linux-x86.32.hpp
vm/os-linux-x86.64.hpp
vm/os-macosx-ppc.hpp
vm/os-macosx-x86.32.hpp
vm/os-macosx-x86.64.hpp
vm/os-macosx.hpp
vm/os-netbsd-x86.32.hpp
vm/os-netbsd-x86.64.hpp
vm/os-openbsd-x86.32.hpp
vm/os-openbsd-x86.64.hpp
vm/os-solaris-x86.32.hpp
vm/os-solaris-x86.64.hpp
vm/os-unix.cpp
vm/vm.hpp

index 2d76b12c38701cd61f762498a8d237d4b317ec48..d05942ff7efe3c6cff315a9d888713639ed79110 100644 (file)
@@ -47,7 +47,7 @@ void factor_vm::call_fault_handler(
        else
                signal_callstack_top = NULL;
 
-       MACH_STACK_POINTER(thread_state) = fix_stack_pointer(MACH_STACK_POINTER(thread_state));
+       MACH_STACK_POINTER(thread_state) = align_stack_pointer(MACH_STACK_POINTER(thread_state));
 
        /* Now we point the program counter at the right handler function. */
        if(exception == EXC_BAD_ACCESS)
@@ -63,7 +63,13 @@ void factor_vm::call_fault_handler(
        }
        else
        {
-               signal_number = (exception == EXC_ARITHMETIC ? SIGFPE : SIGABRT);
+               switch(exception)
+               {
+               case EXC_ARITHMETIC: signal_number = SIGFPE; break;
+               case EXC_BAD_INSTRUCTION: signal_number = SIGILL; break;
+               default: signal_number = SIGABRT; break;
+               }
+
                MACH_PROGRAM_COUNTER(thread_state) = (cell)factor::misc_signal_handler_impl;
        }
 }
@@ -226,7 +232,7 @@ void mach_initialize ()
                fatal_error("mach_port_insert_right() failed",0);
 
        /* The exceptions we want to catch. */
-       mask = EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC;
+       mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC;
 
        /* Create the thread listening on the exception port.  */
        start_thread(mach_exception_thread,NULL);
index e682fec13c6268356e2bdd3c0456d749ef95e3e7..5ed5cf0e81668f80b1318b8d3b1fe8a3534986b4 100644 (file)
@@ -4,12 +4,6 @@
 namespace factor
 {
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-        ucontext_t *ucontext = (ucontext_t *)uap;
-        return (void *)ucontext->uc_mcontext.mc_esp;
-}
-
 inline static unsigned int uap_fpu_status(void *uap)
 {
         ucontext_t *ucontext = (ucontext_t *)uap;
@@ -43,6 +37,8 @@ inline static void uap_clear_fpu_status(void *uap)
         }
 }
 
-#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_eip)
+
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_esp)
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_eip)
 
 }
index 8f8d218a104b49db376d9d02ae6767da05102c53..02f7fb3ad2ae45b6361f329dec688f7f6d21f62f 100644 (file)
@@ -4,12 +4,6 @@
 namespace factor
 {
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-        ucontext_t *ucontext = (ucontext_t *)uap;
-        return (void *)ucontext->uc_mcontext.mc_rsp;
-}
-
 inline static unsigned int uap_fpu_status(void *uap)
 {
         ucontext_t *ucontext = (ucontext_t *)uap;
@@ -33,6 +27,8 @@ inline static void uap_clear_fpu_status(void *uap)
         }
 }
 
-#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)(ucontext))->uc_mcontext.mc_rip)
+
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_rsp)
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.mc_rip)
 
 }
index 1972a728e6a3ce7077abc6fad0c40c9aa585568b..626d399a275ceb75c7492d693c8e00b7ea881867 100644 (file)
@@ -10,4 +10,9 @@ void early_init();
 const char *vm_executable_path();
 const char *default_image_path();
 
+inline static cell align_stack_pointer(cell sp)
+{
+       return sp;
+}
+
 }
index 70c3eb3ff633f4f09cf7528ed8f3990fbfb8007d..3af92fda998db88ddc41915f5bfbb7048f0a5f95 100644 (file)
@@ -5,15 +5,9 @@
 namespace factor
 {
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-       ucontext_t *ucontext = (ucontext_t *)uap;
-       return (void *)ucontext->uc_mcontext.arm_sp;
-}
-
-#define UAP_PROGRAM_COUNTER(ucontext) \
-       (((ucontext_t *)(ucontext))->uc_mcontext.arm_pc)
-
 void flush_icache(cell start, cell len);
 
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.arm_sp)
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.arm_pc)
+
 }
index 62671e5ded63802ef9e62f6531556bf95f85112a..51e017bdad70758ab87b179ca2724a085c13ce47 100644 (file)
@@ -4,14 +4,7 @@ namespace factor
 {
 
 #define FRAME_RETURN_ADDRESS(frame,vm) *((void **)(vm->frame_successor(frame) + 1) + 1)
-
-inline static void *ucontext_stack_pointer(void *uap)
-{
-        ucontext_t *ucontext = (ucontext_t *)uap;
-        return (void *)ucontext->uc_mcontext.uc_regs->gregs[PT_R1];
-}
-
-#define UAP_PROGRAM_COUNTER(ucontext) \
-       (((ucontext_t *)(ucontext))->uc_mcontext.uc_regs->gregs[PT_NIP])
+#define UAP_STACK_POINTER(ucontext) ((ucontext_t *)ucontext)->uc_mcontext.uc_regs->gregs[PT_R1]
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.uc_regs->gregs[PT_NIP])
 
 }
index bd2315ccef6394e55c592f379fea5c34b0bbff12..53a93d17de0f9745f5bd29d644f707c3e98dced3 100644 (file)
@@ -29,12 +29,6 @@ struct _fpstate {
 
 #define X86_FXSR_MAGIC          0x0000
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-       ucontext_t *ucontext = (ucontext_t *)uap;
-       return (void *)ucontext->uc_mcontext.gregs[7];
-}
-
 inline static unsigned int uap_fpu_status(void *uap)
 {
        ucontext_t *ucontext = (ucontext_t *)uap;
@@ -54,7 +48,8 @@ inline static void uap_clear_fpu_status(void *uap)
            fpregs->mxcsr &= 0xffffffc0;
 }
 
-#define UAP_PROGRAM_COUNTER(ucontext) \
-       (((ucontext_t *)(ucontext))->uc_mcontext.gregs[14])
+
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[7])
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[14])
 
 }
index 42adb3c6b8cffffac90a481b3bb4a9421714d858..14ba9fb00255485b994926d8ef4de64dc6aade25 100644 (file)
@@ -3,12 +3,6 @@
 namespace factor
 {
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-        ucontext_t *ucontext = (ucontext_t *)uap;
-        return (void *)ucontext->uc_mcontext.gregs[15];
-}
-
 inline static unsigned int uap_fpu_status(void *uap)
 {
         ucontext_t *ucontext = (ucontext_t *)uap;
@@ -23,7 +17,7 @@ inline static void uap_clear_fpu_status(void *uap)
         ucontext->uc_mcontext.fpregs->mxcsr &= 0xffffffc0;
 }
 
-#define UAP_PROGRAM_COUNTER(ucontext) \
-       (((ucontext_t *)(ucontext))->uc_mcontext.gregs[16])
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[15])
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[16])
 
 }
index 2bea926890f4b59ed73053052fdd9772af4b1e8c..70fa18142acd2e1dc7c08a86886453c0be33f8f0 100644 (file)
@@ -62,7 +62,7 @@ inline static unsigned int uap_fpu_status(void *uap)
        return mach_fpu_status(UAP_FS(uap));
 }
 
-inline static cell fix_stack_pointer(cell sp)
+inline static cell align_stack_pointer(cell sp)
 {
        return sp;
 }
index 89906cd9a4f6b765e8dfc9510a6334b219ea1d0a..4bdc68ff7214d3d9a2b8a7d5b15689bc8e77826f 100644 (file)
@@ -64,7 +64,7 @@ inline static unsigned int uap_fpu_status(void *uap)
        return mach_fpu_status(UAP_FS(uap));
 }
 
-inline static cell fix_stack_pointer(cell sp)
+inline static cell align_stack_pointer(cell sp)
 {
        return ((sp + 4) & ~15) - 4;
 }
index fd6db4d68cc02a093901c4aaf68650f415c8a001..b923674cd1da218a6afad5a070487a429ed36cc5 100644 (file)
@@ -62,7 +62,7 @@ inline static unsigned int uap_fpu_status(void *uap)
        return mach_fpu_status(UAP_FS(uap));
 }
 
-inline static cell fix_stack_pointer(cell sp)
+inline static cell align_stack_pointer(cell sp)
 {
        return ((sp + 8) & ~15) - 8;
 }
index cdc0ff7b426bbb89a6075ba7ac18211baccf8aa7..0d230f48e3651c0568e6f7935ebc80596def9521 100644 (file)
@@ -11,12 +11,8 @@ void early_init();
 const char *vm_executable_path();
 const char *default_image_path();
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-       ucontext_t *ucontext = (ucontext_t *)uap;
-       return ucontext->uc_stack.ss_sp;
-}
-
 void c_to_factor_toplevel(cell quot);
 
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_stack.ss_sp)
+
 }
index f2f47ecf6ccd14160b060eb705a3588226111401..21b3557239fa61c00587a579a8d4c52a35d6a2b2 100644 (file)
@@ -3,9 +3,9 @@
 namespace factor
 {
 
-#define ucontext_stack_pointer(uap) ((void *)_UC_MACHINE_SP((ucontext_t *)uap))
-
 static inline unsigned int uap_fpu_status(void *uap) { return 0; }
-static inline void uap_clear_fpu_status(void *uap) {  }
+static inline void uap_clear_fpu_status(void *uap) {}
+
+#define UAP_STACK_POINTER(ucontext) (_UC_MACHINE_SP((ucontext_t *)ucontext))
 
 }
index a9d52a6c2bfb071689cd42d18f8d2a7a4a2645a1..3e9499899304cdb69211f39e433e41126f14449f 100644 (file)
@@ -3,10 +3,9 @@
 namespace factor
 {
 
-#define ucontext_stack_pointer(uap) \
-       ((void *)(((ucontext_t *)(uap))->uc_mcontext.__gregs[_REG_URSP]))
-
 static inline unsigned int uap_fpu_status(void *uap) { return 0; }
-static inline void uap_clear_fpu_status(void *uap) {  }
+static inline void uap_clear_fpu_status(void *uap) {}
+
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.__gregs[_REG_URSP])
 
 }
index 0abd01921904d8bee7d0b333c0d98222995810d2..34a641c2358c44a79fa6d23554f49eeccad47452 100644 (file)
@@ -3,16 +3,10 @@
 namespace factor
 {
 
-inline static void *openbsd_stack_pointer(void *uap)
-{
-       struct sigcontext *sc = (struct sigcontext*) uap;
-       return (void *)sc->sc_esp;
-}
-
-#define ucontext_stack_pointer openbsd_stack_pointer
-#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_eip)
-
 static inline unsigned int uap_fpu_status(void *uap) { return 0; }
-static inline void uap_clear_fpu_status(void *uap) {  }
+static inline void uap_clear_fpu_status(void *uap) {}
+
+#define UAP_STACK_POINTER(ucontext) (((struct sigcontext *)ucontext)->sc_esp)
+#define UAP_PROGRAM_COUNTER(ucontext) (((struct sigcontext *)ucontext)->sc_eip)
 
 }
index 9dce48ee910cd13ff07dd4cce4c92b8f7ec03914..032e77b154a9c31e0954358b305dd3f473996766 100644 (file)
@@ -3,16 +3,10 @@
 namespace factor
 {
 
-inline static void *openbsd_stack_pointer(void *uap)
-{
-       struct sigcontext *sc = (struct sigcontext*) uap;
-       return (void *)sc->sc_rsp;
-}
-
-#define ucontext_stack_pointer openbsd_stack_pointer
-#define UAP_PROGRAM_COUNTER(uap) (((struct sigcontext*)(uap))->sc_rip)
-
 static inline unsigned int uap_fpu_status(void *uap) { return 0; }
-static inline void uap_clear_fpu_status(void *uap) {  }
+static inline void uap_clear_fpu_status(void *uap) {}
+
+#define UAP_STACK_POINTER(ucontext) (((struct sigcontext *)ucontext)->sc_rsp)
+#define UAP_PROGRAM_COUNTER(ucontext) (((struct sigcontext *)ucontext)->sc_rip)
 
 }
index b89b8d541b6c5b3cfde87bc32fb4ac0f4c5fd3f4..2ec8bc138f38bf224274d24917de54d607b982ae 100644 (file)
@@ -3,13 +3,7 @@
 namespace factor
 {
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-        ucontext_t *ucontext = (ucontext_t *)uap;
-        return (void *)ucontext->uc_mcontext.gregs[ESP];
-}
-
-#define UAP_PROGRAM_COUNTER(ucontext) \
-       (((ucontext_t *)(ucontext))->uc_mcontext.gregs[EIP])
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[ESP])
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[EIP])
 
 }
index 0d3a74e11d00f485465ebcb165fa432dc5095dc5..72a7b5c2fd2ff8063e0b2e4a58a9e41cb9200903 100644 (file)
@@ -3,13 +3,7 @@
 namespace factor
 {
 
-inline static void *ucontext_stack_pointer(void *uap)
-{
-        ucontext_t *ucontext = (ucontext_t *)uap;
-        return (void *)ucontext->uc_mcontext.gregs[RSP];
-}
-
-#define UAP_PROGRAM_COUNTER(ucontext) \
-       (((ucontext_t *)(ucontext))->uc_mcontext.gregs[RIP])
+#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[RSP])
+#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[RIP])
 
 }
index 2f9d5a3c89ff70d15fab31d29e1755f4fa983c4d..0f2570b1836ea21b60d51a3ce5f39cff07fc4db7 100644 (file)
@@ -115,63 +115,47 @@ segment::~segment()
        if(retval)
                fatal_error("Segment deallocation failed",0);
 }
-  
-stack_frame *factor_vm::uap_stack_pointer(void *uap)
+
+void factor_vm::dispatch_signal(void *uap, void (handler)())
 {
-       /* There is a race condition here, but in practice a signal
-       delivered during stack frame setup/teardown or while transitioning
-       from Factor to C is a sign of things seriously gone wrong, not just
-       a divide by zero or stack underflow in the listener */
        if(in_code_heap_p(UAP_PROGRAM_COUNTER(uap)))
        {
-               stack_frame *ptr = (stack_frame *)ucontext_stack_pointer(uap);
-               if(!ptr)
-                       critical_error("Invalid uap",(cell)uap);
-               return ptr;
+               stack_frame *ptr = (stack_frame *)UAP_STACK_POINTER(uap);
+               assert(ptr);
+               signal_callstack_top = ptr;
        }
        else
-               return NULL;
-}
+               signal_callstack_top = NULL;
 
-void factor_vm::memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
-{
-       signal_fault_addr = (cell)siginfo->si_addr;
-       signal_callstack_top = uap_stack_pointer(uap);
-       UAP_PROGRAM_COUNTER(uap) = (cell)factor::memory_signal_handler_impl;
+       UAP_STACK_POINTER(uap) = (void *)align_stack_pointer((cell)UAP_STACK_POINTER(uap));
+       UAP_PROGRAM_COUNTER(uap) = (cell)handler;
 }
 
 void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
 {
-       tls_vm()->memory_signal_handler(signal,siginfo,uap);
-}
-
-void factor_vm::misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
-{
-       signal_number = signal;
-       signal_callstack_top = uap_stack_pointer(uap);
-       UAP_PROGRAM_COUNTER(uap) = (cell)factor::misc_signal_handler_impl;
+       factor_vm *vm = tls_vm();
+       vm->signal_fault_addr = (cell)siginfo->si_addr;
+       vm->dispatch_signal(uap,factor::memory_signal_handler_impl);
 }
 
 void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
 {
-       tls_vm()->misc_signal_handler(signal,siginfo,uap);
+       factor_vm *vm = tls_vm();
+       vm->signal_number = signal;
+       vm->dispatch_signal(uap,factor::misc_signal_handler_impl);
 }
 
-void factor_vm::fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
+void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
 {
-       signal_number = signal;
-       signal_callstack_top = uap_stack_pointer(uap);
-       signal_fpu_status = fpu_status(uap_fpu_status(uap));
+       factor_vm *vm = tls_vm();
+       vm->signal_number = signal;
+       vm->signal_fpu_status = fpu_status(uap_fpu_status(uap));
        uap_clear_fpu_status(uap);
-       UAP_PROGRAM_COUNTER(uap) =
-               (siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF)
-               ? (cell)factor::misc_signal_handler_impl
-               : (cell)factor::fp_signal_handler_impl;
-}
 
-void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
-{
-       tls_vm()->fpe_signal_handler(signal, siginfo, uap);
+       vm->dispatch_signal(uap,
+               (siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF)
+               ? factor::misc_signal_handler_impl
+               : factor::fp_signal_handler_impl);
 }
 
 static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
index 202996ce2624a1dad3c6b80773e0e2da6390d7b5..4b115ecd3f6749beeb70ae94f8ef6d50937ab1ee 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -689,17 +689,12 @@ struct factor_vm
        void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length);
        bool windows_stat(vm_char *path);
 
-   #if defined(WINNT)
+  #if defined(WINNT)
        void open_console();
        LONG exception_handler(PEXCEPTION_POINTERS pe);
-       // next method here:
-   #endif
+  #endif
   #else  // UNIX
-       void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap);
-       void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap);
-       void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap);
-       stack_frame *uap_stack_pointer(void *uap);
-
+       void factor_vm::dispatch_signal(void *uap, void (handler)());
   #endif
 
   #ifdef __APPLE__