2016-07-20 John Baldwin <jhb@FreeBSD.org>
+ * fbsd-nat.c (fbsd_enable_proc_events): Enable "PTRACE_VFORK"
+ events.
+ (fbsd_pending_vfork_done): Only define if "PTRACE_VFORK" is not
+ defined.
+ (fbsd_add_vfork_done): Likewise.
+ (fbsd_is_vfork_done_pending): Likewise.
+ (fbsd_next_vfork_done): Likewise.
+ (fbsd_resume): Only ignore pending vfork done events if
+ "PTRACE_VFORK" is not defined.
+ (fbsd_wait): Only look for pending vfork done events if
+ "PTRACE_VFORK" is not defined.
+ [PTRACE_VFORK]: Handle "PL_FLAG_VFORKED" and "PL_FLAG_VFORK_DONE"
+ events.
+ (fbsd_follow_fork): Only fake a vfork done event if "PTRACE_VFORK"
+ is not defined.
+
+2016-07-20 John Baldwin <jhb@FreeBSD.org>
+
* fbsd-nat.c (fbsd_wait): Use "fbsd_enable_proc_events" on
new child processes.
sizeof (events)) == -1)
perror_with_name (("ptrace"));
events |= PTRACE_FORK | PTRACE_LWP;
+#ifdef PTRACE_VFORK
+ events |= PTRACE_VFORK;
+#endif
if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
sizeof (events)) == -1)
perror_with_name (("ptrace"));
return null_ptid;
}
+#ifndef PTRACE_VFORK
static struct fbsd_fork_info *fbsd_pending_vfork_done;
/* Record a pending vfork done event. */
return null_ptid;
}
#endif
+#endif
static int
resume_one_thread_cb (struct thread_info *tp, void *data)
fbsd_resume (struct target_ops *ops,
ptid_t ptid, int step, enum gdb_signal signo)
{
-#ifdef TDP_RFPPWAIT
+#if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK)
pid_t pid;
/* Don't PT_CONTINUE a process which has a pending vfork done event. */
while (1)
{
+#ifndef PTRACE_VFORK
wptid = fbsd_next_vfork_done ();
if (!ptid_equal (wptid, null_ptid))
{
ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
return wptid;
}
+#endif
wptid = super_wait (ops, ptid, ourstatus, target_options);
if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
{
#ifdef TDP_RFPPWAIT
if (pl.pl_flags & PL_FLAG_FORKED)
{
+#ifndef PTRACE_VFORK
struct kinfo_proc kp;
+#endif
ptid_t child_ptid;
pid_t child;
child = pl.pl_child_pid;
ourstatus->kind = TARGET_WAITKIND_FORKED;
+#ifdef PTRACE_VFORK
+ if (pl.pl_flags & PL_FLAG_VFORKED)
+ ourstatus->kind = TARGET_WAITKIND_VFORKED;
+#endif
/* Make sure the other end of the fork is stopped too. */
child_ptid = fbsd_is_child_pending (child);
/* Enable additional events on the child process. */
fbsd_enable_proc_events (ptid_get_pid (child_ptid));
+#ifndef PTRACE_VFORK
/* For vfork, the child process will have the P_PPWAIT
flag set. */
fbsd_fetch_kinfo_proc (child, &kp);
if (kp.ki_flag & P_PPWAIT)
ourstatus->kind = TARGET_WAITKIND_VFORKED;
+#endif
ourstatus->value.related_pid = child_ptid;
return wptid;
fbsd_remember_child (wptid);
continue;
}
+
+#ifdef PTRACE_VFORK
+ if (pl.pl_flags & PL_FLAG_VFORK_DONE)
+ {
+ ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
+ return wptid;
+ }
+#endif
#endif
#ifdef PL_FLAG_EXEC
if (!follow_child && detach_fork)
{
struct thread_info *tp = inferior_thread ();
- int has_vforked = tp->pending_follow.kind == TARGET_WAITKIND_VFORKED;
pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid);
/* Breakpoints have already been detached from the child by
if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
perror_with_name (("ptrace"));
- if (has_vforked)
+#ifndef PTRACE_VFORK
+ if (tp->pending_follow.kind == TARGET_WAITKIND_VFORKED)
{
/* We can't insert breakpoints until the child process has
finished with the shared memory region. The parent
wait. */
fbsd_add_vfork_done (inferior_ptid);
}
+#endif
}
return 0;