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
|
79562815144503850065234921197651376510595262628033069372760833939060637564931
|
||||||
bignum-mod
|
bignum-mod
|
||||||
] unit-test
|
] 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);
|
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);
|
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)
|
static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -174,18 +179,25 @@ static void sigaction_safe(int signum, const struct sigaction *act, struct sigac
|
||||||
|
|
||||||
void unix_init_signals(void)
|
void unix_init_signals(void)
|
||||||
{
|
{
|
||||||
struct sigaction custom_sigaction;
|
struct sigaction memory_sigaction;
|
||||||
|
struct sigaction misc_sigaction;
|
||||||
struct sigaction ign_sigaction;
|
struct sigaction ign_sigaction;
|
||||||
|
|
||||||
sigemptyset(&custom_sigaction.sa_mask);
|
sigemptyset(&memory_sigaction.sa_mask);
|
||||||
custom_sigaction.sa_sigaction = signal_handler;
|
memory_sigaction.sa_sigaction = memory_signal_handler;
|
||||||
custom_sigaction.sa_flags = SA_SIGINFO;
|
memory_sigaction.sa_flags = SA_SIGINFO;
|
||||||
sigaction_safe(SIGABRT,&custom_sigaction,NULL);
|
|
||||||
sigaction_safe(SIGFPE,&custom_sigaction,NULL);
|
sigaction_safe(SIGBUS,&memory_sigaction,NULL);
|
||||||
sigaction_safe(SIGBUS,&custom_sigaction,NULL);
|
sigaction_safe(SIGSEGV,&memory_sigaction,NULL);
|
||||||
sigaction_safe(SIGQUIT,&custom_sigaction,NULL);
|
|
||||||
sigaction_safe(SIGSEGV,&custom_sigaction,NULL);
|
sigemptyset(&misc_sigaction.sa_mask);
|
||||||
sigaction_safe(SIGILL,&custom_sigaction,NULL);
|
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);
|
sigemptyset(&ign_sigaction.sa_mask);
|
||||||
ign_sigaction.sa_handler = SIG_IGN;
|
ign_sigaction.sa_handler = SIG_IGN;
|
||||||
|
|
9
vm/run.c
9
vm/run.c
|
@ -42,6 +42,7 @@ void handle_error(void)
|
||||||
{
|
{
|
||||||
if(throwing)
|
if(throwing)
|
||||||
{
|
{
|
||||||
|
gc_off = false;
|
||||||
extra_roots = stack_chain->extra_roots;
|
extra_roots = stack_chain->extra_roots;
|
||||||
|
|
||||||
if(thrown_keep_stacks)
|
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)
|
void memory_protection_error(CELL addr, int signal)
|
||||||
{
|
{
|
||||||
/* this is here to catch GC bugs; see the comment in push_callframe()
|
gc_off = true;
|
||||||
above */
|
|
||||||
garbage_collection(NURSERY,false);
|
|
||||||
|
|
||||||
if(in_page(addr, ds_bot, 0, -1))
|
if(in_page(addr, ds_bot, 0, -1))
|
||||||
general_error(ERROR_DS_UNDERFLOW,F,F,false);
|
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);
|
general_error(ERROR_CS_OVERFLOW,F,F,false);
|
||||||
else if(in_page(addr, nursery.limit, 0, 0))
|
else if(in_page(addr, nursery.limit, 0, 0))
|
||||||
critical_error("Out of memory in allot",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)
|
void signal_error(int signal)
|
||||||
{
|
{
|
||||||
|
gc_off = true;
|
||||||
general_error(ERROR_SIGNAL,tag_fixnum(signal),F,false);
|
general_error(ERROR_SIGNAL,tag_fixnum(signal),F,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue