From owner-svn-src-stable-9@freebsd.org Wed Sep 9 23:41:25 2015 Return-Path: Delivered-To: svn-src-stable-9@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C006DA00855; Wed, 9 Sep 2015 23:41:25 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A103117E9; Wed, 9 Sep 2015 23:41:25 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t89NfPe1061681; Wed, 9 Sep 2015 23:41:25 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t89NfOvm061678; Wed, 9 Sep 2015 23:41:24 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201509092341.t89NfOvm061678@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Wed, 9 Sep 2015 23:41:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r287605 - in stable/9/sys: fs/procfs kern X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Sep 2015 23:41:26 -0000 Author: jhb Date: Wed Sep 9 23:41:24 2015 New Revision: 287605 URL: https://svnweb.freebsd.org/changeset/base/287605 Log: MFC 283281,283282,283562,286158: Various fixes to orphan handling which also fix issues with following forks. Unlike the changes in HEAD, this merge does not include the changes to the ATF ptrace test since ATF is not present in 9. 283281: Always set p_oppid when attaching to an existing process via procfs tracing. This matches the behavior of ptrace(PT_ATTACH). Also, the procfs detach request assumes p_oppid is always set. 283282: Only reparent a traced process to its old parent if the tracing process is not the old parent. Otherwise, proc_reap() will leave the zombie in place resulting in the process' status being returned twice to its parent. 283562: Do not allow a process to reap an orphan (a child currently being traced by another process such as a debugger). The parent process does need to check for matching orphan pids to avoid returning ECHILD if an orphan has exited, but it should not return the exited status for the child until after the debugger has detached from the orphan process either explicitly or implicitly via wait(). 286158: Clear P_TRACED before reparenting a detached process back to its original parent. Otherwise the debugee will be set as an orphan of the debugger. Modified: stable/9/sys/fs/procfs/procfs_ctl.c stable/9/sys/kern/kern_exit.c stable/9/sys/kern/sys_process.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/fs/ (props changed) Modified: stable/9/sys/fs/procfs/procfs_ctl.c ============================================================================== --- stable/9/sys/fs/procfs/procfs_ctl.c Wed Sep 9 23:39:30 2015 (r287604) +++ stable/9/sys/fs/procfs/procfs_ctl.c Wed Sep 9 23:41:24 2015 (r287605) @@ -143,8 +143,8 @@ procfs_control(struct thread *td, struct p->p_flag |= P_TRACED; faultin(p); p->p_xstat = 0; /* XXX ? */ + p->p_oppid = p->p_pptr->p_pid; if (p->p_pptr != td->td_proc) { - p->p_oppid = p->p_pptr->p_pid; proc_reparent(p, td->td_proc); } kern_psignal(p, SIGSTOP); Modified: stable/9/sys/kern/kern_exit.c ============================================================================== --- stable/9/sys/kern/kern_exit.c Wed Sep 9 23:39:30 2015 (r287604) +++ stable/9/sys/kern/kern_exit.c Wed Sep 9 23:41:24 2015 (r287605) @@ -825,13 +825,13 @@ proc_reap(struct thread *td, struct proc PROC_LOCK(q); sigqueue_take(p->p_ksi); PROC_UNLOCK(q); - PROC_UNLOCK(p); /* * If we got the child via a ptrace 'attach', we need to give it back * to the old parent. */ - if (p->p_oppid != 0) { + if (p->p_oppid != 0 && p->p_oppid != p->p_pptr->p_pid) { + PROC_UNLOCK(p); t = proc_realparent(p); PROC_LOCK(t); PROC_LOCK(p); @@ -848,6 +848,8 @@ proc_reap(struct thread *td, struct proc sx_xunlock(&proctree_lock); return; } + p->p_oppid = 0; + PROC_UNLOCK(p); /* * Remove other references to this process to ensure we have an @@ -926,7 +928,8 @@ proc_reap(struct thread *td, struct proc static int proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id, - int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo) + int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo, + int check_only) { struct proc *q; struct rusage *rup; @@ -1065,7 +1068,7 @@ proc_to_reap(struct thread *td, struct p calccru(p, &rup->ru_utime, &rup->ru_stime); } - if (p->p_state == PRS_ZOMBIE) { + if (p->p_state == PRS_ZOMBIE && !check_only) { proc_reap(td, p, status, options); return (-1); } @@ -1159,7 +1162,7 @@ loop: sx_xlock(&proctree_lock); LIST_FOREACH(p, &q->p_children, p_sibling) { ret = proc_to_reap(td, p, idtype, id, status, options, - wrusage, siginfo); + wrusage, siginfo, 0); if (ret == 0) continue; else if (ret == 1) @@ -1261,15 +1264,17 @@ loop: * for. By maintaining a list of orphans we allow the parent * to successfully wait until the child becomes a zombie. */ - LIST_FOREACH(p, &q->p_orphans, p_orphan) { - ret = proc_to_reap(td, p, idtype, id, status, options, - wrusage, siginfo); - if (ret == 0) - continue; - else if (ret == 1) - nfound++; - else - return (0); + if (nfound == 0) { + LIST_FOREACH(p, &q->p_orphans, p_orphan) { + ret = proc_to_reap(td, p, idtype, id, NULL, options, + NULL, NULL, 1); + if (ret != 0) { + KASSERT(ret != -1, ("reaped an orphan (pid %d)", + (int)td->td_retval[0])); + nfound++; + break; + } + } } if (nfound == 0) { sx_xunlock(&proctree_lock); Modified: stable/9/sys/kern/sys_process.c ============================================================================== --- stable/9/sys/kern/sys_process.c Wed Sep 9 23:39:30 2015 (r287604) +++ stable/9/sys/kern/sys_process.c Wed Sep 9 23:41:24 2015 (r287605) @@ -949,7 +949,15 @@ kern_ptrace(struct thread *td, int req, } break; case PT_DETACH: - /* reset process parent */ + /* + * Reset the process parent. + * + * NB: This clears P_TRACED before reparenting + * a detached process back to its original + * parent. Otherwise the debugee will be set + * as an orphan of the debugger. + */ + p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK); if (p->p_oppid != p->p_pptr->p_pid) { PROC_LOCK(p->p_pptr); sigqueue_take(p->p_ksi); @@ -965,7 +973,6 @@ kern_ptrace(struct thread *td, int req, } else CTR1(KTR_PTRACE, "PT_DETACH: pid %d", p->p_pid); p->p_oppid = 0; - p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK); /* should we send SIGCHLD? */ /* childproc_continued(p); */