Index: kern/kern_sig.c =================================================================== --- kern/kern_sig.c (revision 274791) +++ kern/kern_sig.c (working copy) @@ -1882,7 +1882,34 @@ } } + /* + * Adjusts thread's signal mask and process signal handler + * according to the signal action flags. + * + * Must be called after mach-specific routine sv_sendsig(), + * because we may manipulate ps_siginfo and other fields, + * but sv_sendsig() expects to work with original settings. + */ +static inline void +sendsig_adjust(int sig, struct thread *td, struct sigacts *ps) +{ + sigset_t mask; + + PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); + mtx_assert(&ps->mtx, MA_OWNED); + + mask = ps->ps_catchmask[_SIG_IDX(sig)]; + if (!SIGISMEMBER(ps->ps_signodefer, sig)) + SIGADDSET(mask, sig); + kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, + SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED); + if (SIGISMEMBER(ps->ps_sigreset, sig)) + sigdflt(ps, sig); +} + + +/* * Send a signal caused by a trap to the current thread. If it will be * caught immediately, deliver it with correct code. Otherwise, post it * normally. @@ -1891,7 +1918,6 @@ trapsignal(struct thread *td, ksiginfo_t *ksi) { struct sigacts *ps; - sigset_t mask; struct proc *p; int sig; int code; @@ -1906,21 +1932,15 @@ mtx_lock(&ps->ps_mtx); if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) && !SIGISMEMBER(td->td_sigmask, sig)) { - td->td_ru.ru_nsignals++; #ifdef KTRACE if (KTRPOINT(curthread, KTR_PSIG)) ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)], &td->td_sigmask, code); #endif + td->td_ru.ru_nsignals++; (*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)], ksi, &td->td_sigmask); - mask = ps->ps_catchmask[_SIG_IDX(sig)]; - if (!SIGISMEMBER(ps->ps_signodefer, sig)) - SIGADDSET(mask, sig); - kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, - SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED); - if (SIGISMEMBER(ps->ps_sigreset, sig)) - sigdflt(ps, sig); + sendsig_adjust(sig, td, ps); mtx_unlock(&ps->ps_mtx); } else { /* @@ -2802,7 +2822,7 @@ struct sigacts *ps; sig_t action; ksiginfo_t ksi; - sigset_t returnmask, mask; + sigset_t returnmask; KASSERT(sig != 0, ("postsig")); @@ -2857,20 +2877,13 @@ } else returnmask = td->td_sigmask; - mask = ps->ps_catchmask[_SIG_IDX(sig)]; - if (!SIGISMEMBER(ps->ps_signodefer, sig)) - SIGADDSET(mask, sig); - kern_sigprocmask(td, SIG_BLOCK, &mask, NULL, - SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED); - - if (SIGISMEMBER(ps->ps_sigreset, sig)) - sigdflt(ps, sig); - td->td_ru.ru_nsignals++; if (p->p_sig == sig) { p->p_code = 0; p->p_sig = 0; } + td->td_ru.ru_nsignals++; (*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask); + sendsig_adjust(sig, td, ps); } return (1); }