Changelog from David Pelton's original patch:
While using lttng-ust with an application that was calling fork()
with pending signals, I found that all signals were getting unmasked
shortly before the underlying call to fork(). After some
investigation, I found that the rcu_bp_before_fork() function was
unmasking all signals. Based on the comments for this function, it
should be masking all signals. Inspection of the rest of the code
in urcu-bp.c revealed the same pattern in two other functions.
This patch changes the code to use a filled signal mask to disable
all signals. The change to rcu_bp_before_fork() addressed the
problem I was seeing while using lttng-ust. The changes to the
other two functions appear to fix other instances of the same
problem.
Updates by Mathieu Desnoyers:
- Use SIG_BLOCK instead of SIG_SETMASK when setting a filled mask. This
has the same behavior in this case (since we're blocking all signals),
but is semantically neater: if we ever some signals from that mask,
we'd like to to a union with the signal mask already blocked by the
application.
- Also fix incorrect signal masking in compat_arch_x86.c.
Reported-by: David Pelton <dpelton@ciena.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
int ret;
/* Disable signals */
int ret;
/* Disable signals */
- ret = sigemptyset(&newmask);
+ ret = sigfillset(&newmask);
- ret = pthread_sigmask(SIG_SETMASK, &newmask, oldmask);
+ ret = pthread_sigmask(SIG_BLOCK, &newmask, oldmask);
assert(!ret);
ret = pthread_mutex_lock(&compat_mutex);
assert(!ret);
assert(!ret);
ret = pthread_mutex_lock(&compat_mutex);
assert(!ret);
sigset_t newmask, oldmask;
int ret;
sigset_t newmask, oldmask;
int ret;
- ret = sigemptyset(&newmask);
+ ret = sigfillset(&newmask);
- ret = pthread_sigmask(SIG_SETMASK, &newmask, &oldmask);
+ ret = pthread_sigmask(SIG_BLOCK, &newmask, &oldmask);
assert(!ret);
mutex_lock(&rcu_gp_lock);
assert(!ret);
mutex_lock(&rcu_gp_lock);
sigset_t newmask, oldmask;
int ret;
sigset_t newmask, oldmask;
int ret;
- ret = sigemptyset(&newmask);
+ ret = sigfillset(&newmask);
- ret = pthread_sigmask(SIG_SETMASK, &newmask, &oldmask);
+ ret = pthread_sigmask(SIG_BLOCK, &newmask, &oldmask);
sigset_t newmask, oldmask;
int ret;
sigset_t newmask, oldmask;
int ret;
- ret = sigemptyset(&newmask);
+ ret = sigfillset(&newmask);
- ret = pthread_sigmask(SIG_SETMASK, &newmask, &oldmask);
+ ret = pthread_sigmask(SIG_BLOCK, &newmask, &oldmask);
assert(!ret);
mutex_lock(&rcu_gp_lock);
saved_fork_signal_mask = oldmask;
assert(!ret);
mutex_lock(&rcu_gp_lock);
saved_fork_signal_mask = oldmask;