Index: sys/kern/kern_fork.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_fork.c,v retrieving revision 1.198 diff -u -r1.198 kern_fork.c --- sys/kern/kern_fork.c 10 Jan 2017 00:48:37 -0000 1.198 +++ sys/kern/kern_fork.c 13 Jan 2017 02:45:23 -0000 @@ -219,7 +219,7 @@ int count; vaddr_t uaddr; int tnprocs; - int tracefork; + int tracefork, tracevforkdone; int error = 0; p1 = l1->l_proc; @@ -471,11 +471,12 @@ p2->p_exitsig = exitsig; /* signal for parent on exit */ /* - * We don't want to tracefork vfork()ed processes because they - * will not receive the SIGTRAP until it is too late. + * Trace fork(2) and vfork(2)-like events on demand in a debugger. */ tracefork = (p1->p_slflag & (PSL_TRACEFORK|PSL_TRACED)) == (PSL_TRACEFORK|PSL_TRACED) && (flags && FORK_PPWAIT) == 0; + tracevforkdone = (p1->p_slflag & (PSL_TRACEVFORK_DONE|PSL_TRACED)) == + (PSL_TRACEVFORK_DONE|PSL_TRACED) && (flags && FORK_PPWAIT); if (tracefork) { proc_changeparent(p2, p1->p_pptr); /* @@ -484,6 +485,12 @@ p1->p_fpid = p2->p_pid; p2->p_fpid = p1->p_pid; } + if (tracevforkdone) { + /* + * Set ptrace status. + */ + p1->p_vfpid_done = p2->p_pid; + } LIST_INSERT_AFTER(p1, p2, p_pglist); LIST_INSERT_HEAD(&allproc, p2, p_list); @@ -576,7 +583,7 @@ /* * Let the parent know that we are tracing its child. */ - if (tracefork) { + if (tracefork || tracevforkdone) { ksiginfo_t ksi; KSI_INIT_EMPTY(&ksi); Index: sys/kern/sys_ptrace_common.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_ptrace_common.c,v retrieving revision 1.8 diff -u -r1.8 sys_ptrace_common.c --- sys/kern/sys_ptrace_common.c 6 Jan 2017 22:53:17 -0000 1.8 +++ sys/kern/sys_ptrace_common.c 13 Jan 2017 02:45:23 -0000 @@ -790,6 +790,8 @@ } sendsig: t->p_fpid = 0; + t->p_vfpid = 0; + t->p_vfpid_done = 0; /* Finally, deliver the requested signal (or none). */ if (t->p_stat == SSTOP) { /* @@ -855,6 +857,10 @@ memset(&pe, 0, sizeof(pe)); pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? PTRACE_FORK : 0; + pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ? + PTRACE_VFORK : 0; + pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ? + PTRACE_VFORK_DONE : 0; error = copyout(&pe, addr, sizeof(pe)); break; @@ -871,6 +877,14 @@ SET(t->p_slflag, PSL_TRACEFORK); else CLR(t->p_slflag, PSL_TRACEFORK); + if (pe.pe_set_event & PTRACE_VFORK) + SET(t->p_slflag, PSL_TRACEVFORK); + else + CLR(t->p_slflag, PSL_TRACEVFORK); + if (pe.pe_set_event & PTRACE_VFORK_DONE) + SET(t->p_slflag, PSL_TRACEVFORK_DONE); + else + CLR(t->p_slflag, PSL_TRACEVFORK_DONE); break; case PT_GET_PROCESS_STATE: @@ -884,6 +898,12 @@ if (t->p_fpid) { ps.pe_report_event = PTRACE_FORK; ps.pe_other_pid = t->p_fpid; + } else if (t->p_vfpid) { + ps.pe_report_event = PTRACE_VFORK; + ps.pe_other_pid = t->p_vfpid; + } else if (t->p_vfpid_done) { + ps.pe_report_event = PTRACE_VFORK_DONE; + ps.pe_other_pid = t->p_vfpid_done; } error = copyout(&ps, addr, sizeof(ps)); break; Index: sys/sys/proc.h =================================================================== RCS file: /cvsroot/src/sys/sys/proc.h,v retrieving revision 1.335 diff -u -r1.335 proc.h --- sys/sys/proc.h 19 Oct 2016 09:44:01 -0000 1.335 +++ sys/sys/proc.h 13 Jan 2017 02:45:23 -0000 @@ -310,6 +310,8 @@ struct lcproc *p_lwpctl; /* p, a: _lwp_ctl() information */ pid_t p_ppid; /* :: cached parent pid */ pid_t p_fpid; /* :: forked pid */ + pid_t p_vfpid; /* :: vforked pid */ + pid_t p_vfpid_done; /* :: vforked done pid */ u_int p_nsems; /* Count of semaphores */ /* @@ -398,6 +400,9 @@ * and p_lock. Access from process context only. */ #define PSL_TRACEFORK 0x00000001 /* traced process wants fork events */ +#define PSL_TRACEVFORK 0x00000002 /* traced process wants vfork events */ +#define PSL_TRACEVFORK_DONE \ + 0x00000004 /* traced process wants vfork done events */ #define PSL_TRACED 0x00000800 /* Debugged process being traced */ #define PSL_FSTRACE 0x00010000 /* Debugger process being traced by procfs */ #define PSL_CHTRACED 0x00400000 /* Child has been traced & reparented */ Index: sys/sys/ptrace.h =================================================================== RCS file: /cvsroot/src/sys/sys/ptrace.h,v retrieving revision 1.52 diff -u -r1.52 ptrace.h --- sys/sys/ptrace.h 6 Jan 2017 22:53:17 -0000 1.52 +++ sys/sys/ptrace.h 13 Jan 2017 02:45:23 -0000 @@ -93,7 +93,9 @@ pid_t pe_other_pid; } ptrace_state_t; -#define PTRACE_FORK 0x0001 /* Report forks */ +#define PTRACE_FORK 0x0001 /* Report forks */ +#define PTRACE_VFORK 0x0002 /* Report vforks */ +#define PTRACE_VFORK_DONE 0x0004 /* Report parent resumed from vforks */ /* * Argument structure for PT_IO.