summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-09-13 15:51:18 +0000
committerjhb <jhb@FreeBSD.org>2012-09-13 15:51:18 +0000
commit1e4174de1a4f6a3cd6d80a545ec7187ecc402d68 (patch)
tree0776d8701c7affd40cb32386af9dfa7fc3e33f2f /sys/kern/kern_sig.c
parenta312b7ef4e0305785acfab807d352fe859634f31 (diff)
downloadFreeBSD-src-1e4174de1a4f6a3cd6d80a545ec7187ecc402d68.zip
FreeBSD-src-1e4174de1a4f6a3cd6d80a545ec7187ecc402d68.tar.gz
Ignore stop and continue signals sent to an exiting process. Stop signals
set p_xstat to the signal that triggered the stop, but p_xstat is also used to hold the exit status of an exiting process. Without this change, a stop signal that arrived after a process was marked P_WEXIT but before it was marked a zombie would overwrite the exit status with the stop signal number. Reviewed by: kib MFC after: 1 week
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 4b43855..13848b6 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2134,6 +2134,8 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
* We try do the per-process part here.
*/
if (P_SHOULDSTOP(p)) {
+ KASSERT(!(p->p_flag & P_WEXIT),
+ ("signal to stopped but exiting process"));
if (sig == SIGKILL) {
/*
* If traced process is already stopped,
@@ -2248,7 +2250,7 @@ tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
MPASS(action == SIG_DFL);
if (prop & SA_STOP) {
- if (p->p_flag & P_PPWAIT)
+ if (p->p_flag & (P_PPWAIT|P_WEXIT))
goto out;
p->p_flag |= P_STOPPED_SIG;
p->p_xstat = sig;
@@ -2410,6 +2412,7 @@ ptracestop(struct thread *td, int sig)
struct proc *p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ KASSERT(!(p->p_flag & P_WEXIT), ("Stopping exiting process"));
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
&p->p_mtx.lock_object, "Stopping for traced signal");
@@ -2648,7 +2651,7 @@ issignal(struct thread *td, int stop_allowed)
* process group, ignore tty stop signals.
*/
if (prop & SA_STOP) {
- if (p->p_flag & P_TRACED ||
+ if (p->p_flag & (P_TRACED|P_WEXIT) ||
(p->p_pgrp->pg_jobc == 0 &&
prop & SA_TTYSTOP))
break; /* == ignore */
OpenPOWER on IntegriCloud