Mask signals during background thread creation.

This prevents signals from being inadvertently delivered to background
threads.
This commit is contained in:
Jason Evans 2017-06-19 20:35:33 -07:00 committed by Qi Wang
parent d35c037e03
commit 37f3fa0941
2 changed files with 36 additions and 3 deletions

View File

@ -22,6 +22,7 @@
# include <sys/uio.h> # include <sys/uio.h>
# endif # endif
# include <pthread.h> # include <pthread.h>
# include <signal.h>
# ifdef JEMALLOC_OS_UNFAIR_LOCK # ifdef JEMALLOC_OS_UNFAIR_LOCK
# include <os/lock.h> # include <os/lock.h>
# endif # endif

View File

@ -347,6 +347,38 @@ background_threads_disable_single(tsd_t *tsd, background_thread_info_t *info) {
static void *background_thread_entry(void *ind_arg); static void *background_thread_entry(void *ind_arg);
static int
background_thread_create_signals_masked(pthread_t *thread,
const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) {
/*
* Mask signals during thread creation so that the thread inherits
* an empty signal set.
*/
sigset_t set;
sigemptyset(&set);
sigset_t oldset;
int mask_err = pthread_sigmask(SIG_SETMASK, &set, &oldset);
if (mask_err != 0) {
return mask_err;
}
int create_err = pthread_create_wrapper(thread, attr, start_routine,
arg);
/*
* Restore the signal mask. Failure to restore the signal mask here
* changes program behavior.
*/
int restore_err = pthread_sigmask(SIG_SETMASK, &oldset, NULL);
if (restore_err != 0) {
malloc_printf("<jemalloc>: background thread creation "
"failed (%d), and signal mask restoration failed "
"(%d)\n", create_err, restore_err);
if (opt_abort) {
abort();
}
}
return create_err;
}
static void static void
check_background_thread_creation(tsd_t *tsd, unsigned *n_created, check_background_thread_creation(tsd_t *tsd, unsigned *n_created,
bool *created_threads) { bool *created_threads) {
@ -377,8 +409,8 @@ label_restart:
malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock); malloc_mutex_unlock(tsd_tsdn(tsd), &background_thread_lock);
pre_reentrancy(tsd); pre_reentrancy(tsd);
int err = pthread_create_wrapper(&info->thread, NULL, int err = background_thread_create_signals_masked(&info->thread,
background_thread_entry, (void *)(uintptr_t)i); NULL, background_thread_entry, (void *)(uintptr_t)i);
post_reentrancy(tsd); post_reentrancy(tsd);
if (err == 0) { if (err == 0) {
@ -528,7 +560,7 @@ background_thread_create(tsd_t *tsd, unsigned arena_ind) {
* To avoid complications (besides reentrancy), create internal * To avoid complications (besides reentrancy), create internal
* background threads with the underlying pthread_create. * background threads with the underlying pthread_create.
*/ */
int err = pthread_create_wrapper(&info->thread, NULL, int err = background_thread_create_signals_masked(&info->thread, NULL,
background_thread_entry, (void *)thread_ind); background_thread_entry, (void *)thread_ind);
post_reentrancy(tsd); post_reentrancy(tsd);