summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_fork.c1
-rw-r--r--sys/kern/subr_syscall.c8
-rw-r--r--sys/kern/sys_process.c8
-rw-r--r--sys/sys/proc.h1
-rw-r--r--sys/sys/ptrace.h3
5 files changed, 19 insertions, 2 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index c7447fb..0f7dd2e 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -736,6 +736,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
if (fr->fr_flags & RFPPWAIT) {
td->td_pflags |= TDP_RFPPWAIT;
td->td_rfppwait_p = p2;
+ td->td_dbgflags |= TDB_VFORK;
}
PROC_UNLOCK(p2);
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index aad2a1e..3e2a3b3 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -242,5 +242,13 @@ again:
cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz);
}
PROC_UNLOCK(p2);
+
+ if (td->td_dbgflags & TDB_VFORK) {
+ PROC_LOCK(p);
+ if (p->p_ptevents & PTRACE_VFORK)
+ ptracestop(td, SIGTRAP);
+ td->td_dbgflags &= ~TDB_VFORK;
+ PROC_UNLOCK(p);
+ }
}
}
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 751db15..7d2fd72 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1000,7 +1000,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
}
tmp = *(int *)addr;
if ((tmp & ~(PTRACE_EXEC | PTRACE_SCE | PTRACE_SCX |
- PTRACE_FORK | PTRACE_LWP)) != 0) {
+ PTRACE_FORK | PTRACE_LWP | PTRACE_VFORK)) != 0) {
error = EINVAL;
break;
}
@@ -1321,7 +1321,11 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
if (td2->td_dbgflags & TDB_FORK) {
pl->pl_flags |= PL_FLAG_FORKED;
pl->pl_child_pid = td2->td_dbg_forked;
- }
+ if (td2->td_dbgflags & TDB_VFORK)
+ pl->pl_flags |= PL_FLAG_VFORKED;
+ } else if ((td2->td_dbgflags & (TDB_SCX | TDB_VFORK)) ==
+ TDB_VFORK)
+ pl->pl_flags |= PL_FLAG_VFORK_DONE;
if (td2->td_dbgflags & TDB_CHILD)
pl->pl_flags |= PL_FLAG_CHILD;
if (td2->td_dbgflags & TDB_BORN)
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index e25a64b..6ab638b 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -422,6 +422,7 @@ do { \
#define TDB_CHILD 0x00000100 /* New child indicator for ptrace() */
#define TDB_BORN 0x00000200 /* New LWP indicator for ptrace() */
#define TDB_EXIT 0x00000400 /* Exiting LWP indicator for ptrace() */
+#define TDB_VFORK 0x00000800 /* vfork indicator for ptrace() */
#define TDB_FSTP 0x00001000 /* The thread is PT_ATTACH leader */
/*
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
index 0cf25e8..e2045c8 100644
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -89,6 +89,7 @@
#define PTRACE_SYSCALL (PTRACE_SCE | PTRACE_SCX)
#define PTRACE_FORK 0x0008
#define PTRACE_LWP 0x0010
+#define PTRACE_VFORK 0x0020
#define PTRACE_DEFAULT (PTRACE_EXEC)
@@ -124,6 +125,8 @@ struct ptrace_lwpinfo {
#define PL_FLAG_CHILD 0x80 /* I am from child */
#define PL_FLAG_BORN 0x100 /* new LWP */
#define PL_FLAG_EXITED 0x200 /* exiting LWP */
+#define PL_FLAG_VFORKED 0x400 /* new child via vfork */
+#define PL_FLAG_VFORK_DONE 0x800 /* vfork parent has resumed */
sigset_t pl_sigmask; /* LWP signal mask */
sigset_t pl_siglist; /* LWP pending signal */
struct __siginfo pl_siginfo; /* siginfo for signal */
OpenPOWER on IntegriCloud