Index: sys/kern/kern_exec.c =================================================================== --- sys/kern/kern_exec.c (revision 230617) +++ sys/kern/kern_exec.c (working copy) @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -888,16 +889,22 @@ free(imgp->freepath, M_TEMP); if (error == 0) { + if ((p->p_flag & (P_TRACED | P_FOLLOWEXEC)) == + (P_TRACED | P_FOLLOWEXEC)) { + PROC_LOCK(p); + td->td_dbgflags |= TDB_EXEC; + PROC_UNLOCK(p); + } + /* + * Stop the process here if its stop event mask has + * the S_EXEC bit set. + */ + STOPEVENT(p, S_EXEC, 0); + PTRACESTOP_SC(p, td, S_PT_EXEC); PROC_LOCK(p); - td->td_dbgflags |= TDB_EXEC; + td->td_dbgflags &= ~TDB_EXEC; PROC_UNLOCK(p); - - /* - * Stop the process here if its stop event mask has - * the S_EXEC bit set. - */ - STOPEVENT(p, S_EXEC, 0); - goto done2; + goto done2; } exec_fail: Index: sys/kern/sys_process.c =================================================================== --- sys/kern/sys_process.c (revision 230617) +++ sys/kern/sys_process.c (working copy) @@ -660,6 +660,7 @@ case PT_TO_SCX: case PT_SYSCALL: case PT_FOLLOW_FORK: + case PT_FOLLOW_EXEC: case PT_DETACH: sx_xlock(&proctree_lock); proctree_locked = 1; @@ -874,6 +875,17 @@ p->p_flag &= ~P_FOLLOWFORK; break; + case PT_FOLLOW_EXEC: + if (data) { + p->p_flag |= P_FOLLOWEXEC; + p->p_stops |= S_PT_EXEC; + } + else { + p->p_flag &= ~P_FOLLOWEXEC; + p->p_stops &= ~S_PT_EXEC; + } + break; + case PT_STEP: case PT_CONTINUE: case PT_TO_SCE: @@ -936,7 +948,8 @@ p->p_sigparent = SIGCHLD; } p->p_oppid = 0; - p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK); + p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK | + P_FOLLOWEXEC); /* should we send SIGCHLD? */ /* childproc_continued(p); */ Index: sys/sys/proc.h =================================================================== --- sys/sys/proc.h (revision 230617) +++ sys/sys/proc.h (working copy) @@ -617,6 +617,7 @@ #define P_INMEM 0x10000000 /* Loaded into memory. */ #define P_SWAPPINGOUT 0x20000000 /* Process is being swapped out. */ #define P_SWAPPINGIN 0x40000000 /* Process is being swapped in. */ +#define P_FOLLOWEXEC 0x80000000 /* Notify debugger of exec events. */ #define P_STOPPED (P_STOPPED_SIG|P_STOPPED_SINGLE|P_STOPPED_TRACE) #define P_SHOULDSTOP(p) ((p)->p_flag & P_STOPPED) Index: sys/sys/ptrace.h =================================================================== --- sys/sys/ptrace.h (revision 230617) +++ sys/sys/ptrace.h (working copy) @@ -64,6 +64,7 @@ #define PT_SYSCALL 22 #define PT_FOLLOW_FORK 23 +#define PT_FOLLOW_EXEC 24 #define PT_GETREGS 33 /* get general-purpose registers */ #define PT_SETREGS 34 /* set general-purpose registers */ @@ -142,6 +143,7 @@ */ #define S_PT_SCE 0x000010000 #define S_PT_SCX 0x000020000 +#define S_PT_EXEC 0x000080000 int ptrace_set_pc(struct thread *_td, unsigned long _addr); int ptrace_single_step(struct thread *_td);