From owner-svn-src-all@FreeBSD.ORG Mon Feb 27 21:10:11 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 96A0F106564A; Mon, 27 Feb 2012 21:10:11 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 813948FC08; Mon, 27 Feb 2012 21:10:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1RLABqS037143; Mon, 27 Feb 2012 21:10:11 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1RLABjb037139; Mon, 27 Feb 2012 21:10:11 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201202272110.q1RLABjb037139@svn.freebsd.org> From: Konstantin Belousov Date: Mon, 27 Feb 2012 21:10:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232240 - in head/sys: kern sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Feb 2012 21:10:11 -0000 Author: kib Date: Mon Feb 27 21:10:10 2012 New Revision: 232240 URL: http://svn.freebsd.org/changeset/base/232240 Log: Currently, the debugger attached to the process executing vfork() does not get syscall exit notification until the child performed exec of exit. Swap the order of doing ptracestop() and waiting for P_PPWAIT clearing, by postponing the wait into syscallret after ptracestop() notification is done. Reported, tested and reviewed by: Dmitry Mikulin MFC after: 2 weeks Modified: head/sys/kern/kern_fork.c head/sys/kern/subr_syscall.c head/sys/sys/proc.h Modified: head/sys/kern/kern_fork.c ============================================================================== --- head/sys/kern/kern_fork.c Mon Feb 27 20:52:20 2012 (r232239) +++ head/sys/kern/kern_fork.c Mon Feb 27 21:10:10 2012 (r232240) @@ -708,6 +708,10 @@ do_fork(struct thread *td, int flags, st _PHOLD(p2); p2_held = 1; } + if (flags & RFPPWAIT) { + td->td_pflags |= TDP_RFPPWAIT; + td->td_rfppwait_p = p2; + } PROC_UNLOCK(p2); if ((flags & RFSTOPPED) == 0) { /* @@ -740,14 +744,6 @@ do_fork(struct thread *td, int flags, st cv_wait(&p2->p_dbgwait, &p2->p_mtx); if (p2_held) _PRELE(p2); - - /* - * Preserve synchronization semantics of vfork. If waiting for - * child to exec or exit, set P_PPWAIT on child, and sleep on our - * proc (in case of exit). - */ - while (p2->p_flag & P_PPWAIT) - cv_wait(&p2->p_pwait, &p2->p_mtx); PROC_UNLOCK(p2); } Modified: head/sys/kern/subr_syscall.c ============================================================================== --- head/sys/kern/subr_syscall.c Mon Feb 27 20:52:20 2012 (r232239) +++ head/sys/kern/subr_syscall.c Mon Feb 27 21:10:10 2012 (r232240) @@ -165,7 +165,7 @@ syscallenter(struct thread *td, struct s static inline void syscallret(struct thread *td, int error, struct syscall_args *sa __unused) { - struct proc *p; + struct proc *p, *p2; int traced; p = td->td_proc; @@ -223,4 +223,23 @@ syscallret(struct thread *td, int error, td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK); PROC_UNLOCK(p); } + + if (td->td_pflags & TDP_RFPPWAIT) { + /* + * Preserve synchronization semantics of vfork. If + * waiting for child to exec or exit, fork set + * P_PPWAIT on child, and there we sleep on our proc + * (in case of exit). + * + * Do it after the ptracestop() above is finished, to + * not block our debugger until child execs or exits + * to finish vfork wait. + */ + td->td_pflags &= ~TDP_RFPPWAIT; + p2 = td->td_rfppwait_p; + PROC_LOCK(p2); + while (p2->p_flag & P_PPWAIT) + cv_wait(&p2->p_pwait, &p2->p_mtx); + PROC_UNLOCK(p2); + } } Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Mon Feb 27 20:52:20 2012 (r232239) +++ head/sys/sys/proc.h Mon Feb 27 21:10:10 2012 (r232240) @@ -311,6 +311,7 @@ struct thread { struct vnet *td_vnet; /* (k) Effective vnet. */ const char *td_vnet_lpush; /* (k) Debugging vnet push / pop. */ struct trapframe *td_intr_frame;/* (k) Frame of the current irq */ + struct proc *td_rfppwait_p; /* (k) The vforked child */ }; struct mtx *thread_lock_block(struct thread *); @@ -415,6 +416,7 @@ do { \ #define TDP_CALLCHAIN 0x00400000 /* Capture thread's callchain */ #define TDP_IGNSUSP 0x00800000 /* Permission to ignore the MNTK_SUSPEND* */ #define TDP_AUDITREC 0x01000000 /* Audit record pending on thread */ +#define TDP_RFPPWAIT 0x02000000 /* Handle RFPPWAIT on syscall exit */ /* * Reasons that the current thread can not be run yet.