GC is not safe from a signal handler since the ds/rs registers might be invalid. So disable the GC in signal handlers

darcs
slava 2006-11-22 06:24:55 +00:00
parent 12f61890ca
commit 5038554251
3 changed files with 32 additions and 17 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);
}