Author: obrien
Date: Tue Jun 14 17:09:30 2011
New Revision: 223088
URL: http://svn.freebsd.org/changeset/base/223088

Log:
  We should not return ECHILD when debugging a child and the parent does a
  "wait4(-1, ..., WNOHANG, ...)".  Instead wait(2) should behave as if the
  child does not wish to report status at this time.
  
  Reviewed by:  jhb

Modified:
  head/sys/kern/kern_exit.c
  head/sys/kern/sys_process.c
  head/sys/sys/proc.h

Modified: head/sys/kern/kern_exit.c
==============================================================================
--- head/sys/kern/kern_exit.c   Tue Jun 14 16:50:29 2011        (r223087)
+++ head/sys/kern/kern_exit.c   Tue Jun 14 17:09:30 2011        (r223088)
@@ -701,8 +701,9 @@ proc_reap(struct thread *td, struct proc
         */
        if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) {
                PROC_LOCK(p);
-               p->p_oppid = 0;
                proc_reparent(p, t);
+               p->p_pptr->p_dbg_child--;
+               p->p_oppid = 0;
                PROC_UNLOCK(p);
                pksignal(t, SIGCHLD, p->p_ksi);
                wakeup(t);
@@ -794,7 +795,8 @@ kern_wait(struct thread *td, pid_t pid, 
                pid = -q->p_pgid;
                PROC_UNLOCK(q);
        }
-       if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
+       /* If we don't know the option, just return. */
+       if (options & ~(WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
                return (EINVAL);
 loop:
        if (q->p_flag & P_STATCHILD) {
@@ -873,7 +875,10 @@ loop:
        }
        if (nfound == 0) {
                sx_xunlock(&proctree_lock);
-               return (ECHILD);
+               if (td->td_proc->p_dbg_child)
+                       return (0);
+               else
+                       return (ECHILD);
        }
        if (options & WNOHANG) {
                sx_xunlock(&proctree_lock);

Modified: head/sys/kern/sys_process.c
==============================================================================
--- head/sys/kern/sys_process.c Tue Jun 14 16:50:29 2011        (r223087)
+++ head/sys/kern/sys_process.c Tue Jun 14 17:09:30 2011        (r223088)
@@ -831,8 +831,11 @@ kern_ptrace(struct thread *td, int req, 
                /* security check done above */
                p->p_flag |= P_TRACED;
                p->p_oppid = p->p_pptr->p_pid;
-               if (p->p_pptr != td->td_proc)
+               if (p->p_pptr != td->td_proc) {
+                       /* Remember that a child is being debugged(traced). */
+                       p->p_pptr->p_dbg_child++;
                        proc_reparent(p, td->td_proc);
+               }
                data = SIGSTOP;
                goto sendsig;   /* in PT_CONTINUE below */
 
@@ -919,11 +922,12 @@ kern_ptrace(struct thread *td, int req, 
                                        PROC_UNLOCK(pp);
                                PROC_LOCK(p);
                                proc_reparent(p, pp);
+                               p->p_pptr->p_dbg_child--;
                                if (pp == initproc)
                                        p->p_sigparent = SIGCHLD;
                        }
-                       p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK);
                        p->p_oppid = 0;
+                       p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK);
 
                        /* should we send SIGCHLD? */
                        /* childproc_continued(p); */

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h Tue Jun 14 16:50:29 2011        (r223087)
+++ head/sys/sys/proc.h Tue Jun 14 17:09:30 2011        (r223088)
@@ -503,6 +503,8 @@ struct proc {
 /* The following fields are all zeroed upon creation in fork. */
 #define        p_startzero     p_oppid
        pid_t           p_oppid;        /* (c + e) Save ppid in ptrace. XXX */
+       int             p_dbg_child;    /* (c + e) # of debugged children in
+                                                       ptrace. */
        struct vmspace  *p_vmspace;     /* (b) Address space. */
        u_int           p_swtick;       /* (c) Tick when swapped in or out. */
        struct itimerval p_realtimer;   /* (c) Alarm timer. */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to