adjust the change of rev. 1.190 so that trap signals not matching

the reset condition are processed properly; this fixes PR#26687 by
Jan Schaumann

many thanks to Mark Davies, who tracked the offending change down
and helped test patches

while here, g/c unused sigtrapmask and rearrange some code to pre-r1.190 form
for better readability
This commit is contained in:
jdolecek 2004-09-28 08:59:20 +00:00
parent 94244ec3de
commit 3254cd78d8
1 changed files with 43 additions and 53 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sig.c,v 1.197 2004/06/08 19:35:30 he Exp $ */ /* $NetBSD: kern_sig.c,v 1.198 2004/09/28 08:59:20 jdolecek Exp $ */
/* /*
* Copyright (c) 1982, 1986, 1989, 1991, 1993 * Copyright (c) 1982, 1986, 1989, 1991, 1993
@ -37,7 +37,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.197 2004/06/08 19:35:30 he Exp $"); __KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.198 2004/09/28 08:59:20 jdolecek Exp $");
#include "opt_ktrace.h" #include "opt_ktrace.h"
#include "opt_compat_sunos.h" #include "opt_compat_sunos.h"
@ -88,7 +88,7 @@ static void ksiginfo_put(struct proc *, const ksiginfo_t *);
static ksiginfo_t *ksiginfo_get(struct proc *, int); static ksiginfo_t *ksiginfo_get(struct proc *, int);
static void kpsignal2(struct proc *, const ksiginfo_t *, int); static void kpsignal2(struct proc *, const ksiginfo_t *, int);
sigset_t contsigmask, stopsigmask, sigcantmask, sigtrapmask; sigset_t contsigmask, stopsigmask, sigcantmask;
struct pool sigacts_pool; /* memory pool for sigacts structures */ struct pool sigacts_pool; /* memory pool for sigacts structures */
@ -238,12 +238,6 @@ signal_init(void)
exithook_establish(ksiginfo_exithook, NULL); exithook_establish(ksiginfo_exithook, NULL);
exechook_establish(ksiginfo_exithook, NULL); exechook_establish(ksiginfo_exithook, NULL);
sigaddset(&sigtrapmask, SIGSEGV);
sigaddset(&sigtrapmask, SIGBUS);
sigaddset(&sigtrapmask, SIGILL);
sigaddset(&sigtrapmask, SIGFPE);
sigaddset(&sigtrapmask, SIGTRAP);
} }
/* /*
@ -1035,44 +1029,47 @@ kpsignal2(struct proc *p, const ksiginfo_t *ksi, int dolock)
/* /*
* If proc is traced, always give parent a chance. * If proc is traced, always give parent a chance.
*/ */
action = SIG_DFL; if (p->p_flag & P_TRACED) {
if ((p->p_flag & P_TRACED) == 0) { action = SIG_DFL;
if (KSI_TRAP_P(ksi)) {
/* /*
* If the signal was the result of a trap, only catch * If the process is being traced and the signal is being
* the signal if it isn't masked and there is a * caught, make sure to save any ksiginfo.
* non-default non-ignore handler installed for it. */
* Otherwise take the default action. if (sigismember(&p->p_sigctx.ps_sigcatch, signum))
*/ ksiginfo_put(p, ksi);
if (!sigismember(&p->p_sigctx.ps_sigmask, signum) && } else {
sigismember(&p->p_sigctx.ps_sigcatch, signum)) /*
action = SIG_CATCH; * If the signal was the result of a trap, reset it
/* * to default action if it's currently masked, so that it would
* If we are to take the default action, reset the * coredump immediatelly instead of spinning repeatedly
* signal back to its defaults. * taking the signal.
*/ */
if (action == SIG_DFL) { if (KSI_TRAP_P(ksi)
sigdelset(&p->p_sigctx.ps_sigignore, signum); && sigismember(&p->p_sigctx.ps_sigmask, signum)
sigdelset(&p->p_sigctx.ps_sigcatch, signum); && !sigismember(&p->p_sigctx.ps_sigcatch, signum)) {
sigdelset(&p->p_sigctx.ps_sigmask, signum); sigdelset(&p->p_sigctx.ps_sigignore, signum);
SIGACTION(p, signum).sa_handler = SIG_DFL; sigdelset(&p->p_sigctx.ps_sigcatch, signum);
} sigdelset(&p->p_sigctx.ps_sigmask, signum);
} else { SIGACTION(p, signum).sa_handler = SIG_DFL;
/*
* If the signal is being ignored,
* then we forget about it immediately.
* (Note: we don't set SIGCONT in p_sigctx.ps_sigignore,
* and if it is set to SIG_IGN,
* action will be SIG_DFL here.)
*/
if (sigismember(&p->p_sigctx.ps_sigignore, signum))
return;
if (sigismember(&p->p_sigctx.ps_sigmask, signum))
action = SIG_HOLD;
else if (sigismember(&p->p_sigctx.ps_sigcatch, signum))
action = SIG_CATCH;
} }
if (action == SIG_DFL) {
/*
* If the signal is being ignored,
* then we forget about it immediately.
* (Note: we don't set SIGCONT in p_sigctx.ps_sigignore,
* and if it is set to SIG_IGN,
* action will be SIG_DFL here.)
*/
if (sigismember(&p->p_sigctx.ps_sigignore, signum))
return;
if (sigismember(&p->p_sigctx.ps_sigmask, signum))
action = SIG_HOLD;
else if (sigismember(&p->p_sigctx.ps_sigcatch, signum))
action = SIG_CATCH;
else {
action = SIG_DFL;
if (prop & SA_KILL && p->p_nice > NZERO) if (prop & SA_KILL && p->p_nice > NZERO)
p->p_nice = NZERO; p->p_nice = NZERO;
@ -1085,13 +1082,6 @@ kpsignal2(struct proc *p, const ksiginfo_t *ksi, int dolock)
if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0) if (prop & SA_TTYSTOP && p->p_pgrp->pg_jobc == 0)
return; return;
} }
} else {
/*
* If the process is being traced and the signal is being
* caught, make sure to save any ksiginfo.
*/
if (sigismember(&p->p_sigctx.ps_sigcatch, signum))
ksiginfo_put(p, ksi);
} }
if (prop & SA_CONT) if (prop & SA_CONT)