GC is not safe from a signal handler since the ds/rs registers might be invalid. So disable the GC in signal handlers
parent
12f61890ca
commit
5038554251
|
@ -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
|
||||
|
|
34
vm/os-unix.c
34
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;
|
||||
|
|
11
vm/run.c
11
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue