gc: fix signal handlers for generational garbage collector
The boehm gc needs SIGSEGV or SIGBUS to track dirty pages (see GC_write_fault_handler). Thus these signals need to be unblocked at all times.
This commit is contained in:
parent
f7f0edebd6
commit
73af5cdcdd
3 changed files with 16 additions and 4 deletions
|
|
@ -592,14 +592,16 @@ mp_process_enable(cl_object process)
|
|||
pthread_attr_init(&pthreadattr);
|
||||
pthread_attr_setdetachstate(&pthreadattr, PTHREAD_CREATE_DETACHED);
|
||||
/*
|
||||
* We launch the thread with the signal mask specified in cl_core.
|
||||
* The reason is that we might need to block certain signals
|
||||
* to be processed by the signal handling thread in unixint.d
|
||||
* Block all asynchronous signals until the thread is completely
|
||||
* set up. The synchronous signals SIGSEGV and SIGBUS are needed
|
||||
* by the gc and thus can't be blocked.
|
||||
*/
|
||||
#ifdef HAVE_SIGPROCMASK
|
||||
{
|
||||
sigset_t new, previous;
|
||||
sigfillset(&new);
|
||||
sigdelset(&new, SIGSEGV);
|
||||
sigdelset(&new, SIGBUS);
|
||||
pthread_sigmask(SIG_BLOCK, &new, &previous);
|
||||
code = pthread_create(&process->process.thread, &pthreadattr,
|
||||
thread_entry_point, process);
|
||||
|
|
@ -764,6 +766,10 @@ mp_block_signals(void)
|
|||
cl_object previous = mp_get_sigmask();
|
||||
sigset_t all_signals;
|
||||
sigfillset(&all_signals);
|
||||
/* SIGSEGV or SIGBUS are needed by the gc in incremental mode and
|
||||
* can thus never be blocked */
|
||||
sigdelset(&all_signals, SIGSEGV);
|
||||
sigdelset(&all_signals, SIGBUS);
|
||||
if (pthread_sigmask(SIG_SETMASK, &all_signals, NULL))
|
||||
FElibc_error("MP:BLOCK-SIGNALS failed in a call to pthread_sigmask",0);
|
||||
@(return previous);
|
||||
|
|
|
|||
|
|
@ -580,7 +580,9 @@ asynchronous_signal_servicing_thread()
|
|||
const cl_env_ptr the_env = ecl_process_env();
|
||||
int interrupt_signal = -1;
|
||||
/*
|
||||
* We block all signals except the usual interrupt thread and GC signals.
|
||||
* We block all signals except the usual interrupt thread and
|
||||
* GC signals (including SIGSEGV and SIGSEGV which are needed
|
||||
* when the GC runs in incremental mode).
|
||||
*/
|
||||
{
|
||||
sigset_t handled_set;
|
||||
|
|
@ -591,6 +593,8 @@ asynchronous_signal_servicing_thread()
|
|||
sigdelset(&handled_set, interrupt_signal);
|
||||
sigdelset(&handled_set, GC_get_suspend_signal());
|
||||
sigdelset(&handled_set, GC_get_thr_restart_signal());
|
||||
sigdelset(&handled_set, SIGSEGV);
|
||||
sigdelset(&handled_set, SIGBUS);
|
||||
}
|
||||
pthread_sigmask(SIG_BLOCK, &handled_set, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
# define ECL_STACK_RESIZE_DISABLE_INTERRUPTS(the_env) \
|
||||
sigset_t __sigset_new, __sigset_previous; \
|
||||
sigfillset(&__sigset_new); \
|
||||
sigdelset(&__sigset_new, SIGSEGV); \
|
||||
sigdelset(&__sigset_new, SIGBUS); \
|
||||
pthread_sigmask(SIG_BLOCK, &__sigset_new, &__sigset_previous)
|
||||
# define ECL_STACK_RESIZE_ENABLE_INTERRUPTS(the_env) \
|
||||
pthread_sigmask(SIG_SETMASK, &__sigset_previous, NULL)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue