diff --git a/library/test/math/integer.factor b/library/test/math/integer.factor index 9860763f4c..d36e3acc4d 100644 --- a/library/test/math/integer.factor +++ b/library/test/math/integer.factor @@ -112,3 +112,7 @@ unit-test 79562815144503850065234921197651376510595262628033069372760833939060637564931 bignum-mod ] unit-test + +! We don't care if this fails or returns 0 (its CPU-specific) +! as long as it doesn't crash +[ ] [ [ 0 0 /i ] catch drop ] unit-test diff --git a/vm/os-unix.c b/vm/os-unix.c index def72f3c16..eda13839a2 100644 --- a/vm/os-unix.c +++ b/vm/os-unix.c @@ -158,11 +158,16 @@ void dealloc_segment(F_SEGMENT *block) free(block); } -void signal_handler(int signal, siginfo_t* siginfo, void* uap) +void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) { memory_protection_error((CELL)siginfo->si_addr, signal); } +void misc_signal_handler(int signal, siginfo_t* siginfo, void* uap) +{ + signal_error(signal); +} + static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact) { int ret; @@ -174,18 +179,25 @@ static void sigaction_safe(int signum, const struct sigaction *act, struct sigac void unix_init_signals(void) { - struct sigaction custom_sigaction; + struct sigaction memory_sigaction; + struct sigaction misc_sigaction; struct sigaction ign_sigaction; - sigemptyset(&custom_sigaction.sa_mask); - custom_sigaction.sa_sigaction = signal_handler; - custom_sigaction.sa_flags = SA_SIGINFO; - sigaction_safe(SIGABRT,&custom_sigaction,NULL); - sigaction_safe(SIGFPE,&custom_sigaction,NULL); - sigaction_safe(SIGBUS,&custom_sigaction,NULL); - sigaction_safe(SIGQUIT,&custom_sigaction,NULL); - sigaction_safe(SIGSEGV,&custom_sigaction,NULL); - sigaction_safe(SIGILL,&custom_sigaction,NULL); + sigemptyset(&memory_sigaction.sa_mask); + memory_sigaction.sa_sigaction = memory_signal_handler; + memory_sigaction.sa_flags = SA_SIGINFO; + + sigaction_safe(SIGBUS,&memory_sigaction,NULL); + sigaction_safe(SIGSEGV,&memory_sigaction,NULL); + + sigemptyset(&misc_sigaction.sa_mask); + misc_sigaction.sa_sigaction = misc_signal_handler; + misc_sigaction.sa_flags = SA_SIGINFO; + + sigaction_safe(SIGABRT,&misc_sigaction,NULL); + sigaction_safe(SIGFPE,&misc_sigaction,NULL); + sigaction_safe(SIGQUIT,&misc_sigaction,NULL); + sigaction_safe(SIGILL,&misc_sigaction,NULL); sigemptyset(&ign_sigaction.sa_mask); ign_sigaction.sa_handler = SIG_IGN; diff --git a/vm/run.c b/vm/run.c index de2f29e62e..45eef646cc 100644 --- a/vm/run.c +++ b/vm/run.c @@ -42,6 +42,7 @@ void handle_error(void) { if(throwing) { + gc_off = false; extra_roots = stack_chain->extra_roots; if(thrown_keep_stacks) @@ -318,9 +319,7 @@ void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2, bool keep_stacks) void memory_protection_error(CELL addr, int signal) { - /* this is here to catch GC bugs; see the comment in push_callframe() - above */ - garbage_collection(NURSERY,false); + gc_off = true; if(in_page(addr, ds_bot, 0, -1)) general_error(ERROR_DS_UNDERFLOW,F,F,false); @@ -336,13 +335,13 @@ void memory_protection_error(CELL addr, int signal) general_error(ERROR_CS_OVERFLOW,F,F,false); else if(in_page(addr, nursery.limit, 0, 0)) critical_error("Out of memory in allot",0); - signal_error(signal); + + signal_error(signal); } -/* It is not safe to access 'ds' from a signal handler, so we just not -touch it */ void signal_error(int signal) { + gc_off = true; general_error(ERROR_SIGNAL,tag_fixnum(signal),F,false); }