Author: jhb
Date: Tue Feb 26 21:05:06 2013
New Revision: 247350
URL: http://svnweb.freebsd.org/changeset/base/247350

Log:
  MFC 240467:
  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.

Modified:
  stable/8/sys/kern/kern_exit.c
  stable/8/sys/kern/kern_sig.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/kern/   (props changed)

Modified: stable/8/sys/kern/kern_exit.c
==============================================================================
--- stable/8/sys/kern/kern_exit.c       Tue Feb 26 21:04:58 2013        
(r247349)
+++ stable/8/sys/kern/kern_exit.c       Tue Feb 26 21:05:06 2013        
(r247350)
@@ -183,6 +183,14 @@ exit1(struct thread *td, int rv)
        _STOPEVENT(p, S_EXIT, rv);
 
        /*
+        * Ignore any pending request to stop due to a stop signal.
+        * Once P_WEXIT is set, future requests will be ignored as
+        * well.
+        */
+       p->p_flag &= ~P_STOPPED_SIG;
+       KASSERT(!P_SHOULDSTOP(p), ("exiting process is stopped"));
+
+       /*
         * Note that we are exiting and do another wakeup of anyone in
         * PIOCWAIT in case they aren't listening for S_EXIT stops or
         * decided to wait again after we told them we are exiting.

Modified: stable/8/sys/kern/kern_sig.c
==============================================================================
--- stable/8/sys/kern/kern_sig.c        Tue Feb 26 21:04:58 2013        
(r247349)
+++ stable/8/sys/kern/kern_sig.c        Tue Feb 26 21:05:06 2013        
(r247350)
@@ -2142,6 +2142,8 @@ tdsignal(struct proc *p, struct thread *
         * 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,
@@ -2256,7 +2258,7 @@ tdsignal(struct proc *p, struct thread *
                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;
@@ -2418,6 +2420,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");
 
@@ -2658,7 +2661,7 @@ issignal(struct thread *td, int stop_all
                         * 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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to