public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 3/3] Use a real vfork done event on FreeBSD when available.
  2016-07-18 14:58 [PATCH 0/3] Add "real" vfork done handling on FreeBSD John Baldwin
  2016-07-18 14:58 ` [PATCH 2/3] Enable ptrace events on new child processes John Baldwin
  2016-07-18 14:58 ` [PATCH 1/3] Consolidate code to enable optional FreeBSD native target event reporting John Baldwin
@ 2016-07-18 14:58 ` John Baldwin
  2016-07-19 18:44 ` [PATCH 0/3] Add "real" vfork done handling on FreeBSD Pedro Alves
  3 siblings, 0 replies; 5+ messages in thread
From: John Baldwin @ 2016-07-18 14:58 UTC (permalink / raw)
  To: gdb-patches

FreeBSD 12 recently added a new ptrace event to indicate when the vfork
parent resumes after the child process stops sharing the address space.
Use this event to report a proper TARGET_WAITKIND_VFORK_DONE rather than
faking a vfork done event after a delay.

gdb/ChangeLog:

	* 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.
---
 gdb/ChangeLog  | 18 ++++++++++++++++++
 gdb/fbsd-nat.c | 30 +++++++++++++++++++++++++++---
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 33cd6a7..f11871c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,23 @@
 2016-07-15  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-15  John Baldwin  <jhb@FreeBSD.org>
+
 	* fbsd-nat.c (fbsd_wait): Use "fbsd_enable_proc_events" on
 	new child processes.
 
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 5e4304e..ade62f1 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -435,6 +435,9 @@ fbsd_enable_proc_events (pid_t pid)
 	      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"));
@@ -598,6 +601,7 @@ fbsd_is_child_pending (pid_t pid)
   return null_ptid;
 }
 
+#ifndef PTRACE_VFORK
 static struct fbsd_fork_info *fbsd_pending_vfork_done;
 
 /* Record a pending vfork done event.  */
@@ -647,6 +651,7 @@ fbsd_next_vfork_done (void)
   return null_ptid;
 }
 #endif
+#endif
 
 static int
 resume_one_thread_cb (struct thread_info *tp, void *data)
@@ -686,7 +691,7 @@ static void
 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.  */
@@ -731,12 +736,14 @@ fbsd_wait (struct target_ops *ops,
 
   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)
 	{
@@ -812,12 +819,18 @@ fbsd_wait (struct target_ops *ops,
 #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);
@@ -839,11 +852,13 @@ fbsd_wait (struct target_ops *ops,
 	      /* 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;
@@ -857,6 +872,14 @@ fbsd_wait (struct target_ops *ops,
 	      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
@@ -918,7 +941,6 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child,
   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
@@ -927,7 +949,8 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child,
       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
@@ -953,6 +976,7 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child,
 	     wait.  */
 	  fbsd_add_vfork_done (inferior_ptid);
 	}
+#endif
     }
 
   return 0;
-- 
2.8.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 0/3] Add "real" vfork done handling on FreeBSD
@ 2016-07-18 14:58 John Baldwin
  2016-07-18 14:58 ` [PATCH 2/3] Enable ptrace events on new child processes John Baldwin
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: John Baldwin @ 2016-07-18 14:58 UTC (permalink / raw)
  To: gdb-patches

FreeBSD 12 recently gained a real vfork done event via ptrace(2).
This changes the FreeBSD native targets to use this when it exists
instead of faking a done event after a sleep.

John Baldwin (3):
  Consolidate code to enable optional FreeBSD native target event
    reporting.
  Enable ptrace events on new child processes.
  Use a real vfork done event on FreeBSD when available.

 gdb/ChangeLog  | 31 ++++++++++++++++++++
 gdb/fbsd-nat.c | 92 ++++++++++++++++++++++++++++++++++++----------------------
 2 files changed, 89 insertions(+), 34 deletions(-)

-- 
2.8.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/3] Enable ptrace events on new child processes.
  2016-07-18 14:58 [PATCH 0/3] Add "real" vfork done handling on FreeBSD John Baldwin
@ 2016-07-18 14:58 ` John Baldwin
  2016-07-18 14:58 ` [PATCH 1/3] Consolidate code to enable optional FreeBSD native target event reporting John Baldwin
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: John Baldwin @ 2016-07-18 14:58 UTC (permalink / raw)
  To: gdb-patches

New child processes on FreeBSD do not inherit optional ptrace events
such as fork and LWP events from the parent process.  Instead,
explicitly enable events on new children when reporting a fork
event.

gdb/ChangeLog:

	* fbsd-nat.c (fbsd_wait): Use "fbsd_enable_proc_events" on
	new child processes.
---
 gdb/ChangeLog  | 5 +++++
 gdb/fbsd-nat.c | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index dcedc14..33cd6a7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2016-07-15  John Baldwin  <jhb@FreeBSD.org>
 
+	* fbsd-nat.c (fbsd_wait): Use "fbsd_enable_proc_events" on
+	new child processes.
+
+2016-07-15  John Baldwin  <jhb@FreeBSD.org>
+
 	* fbsd-nat.c (fbsd_enable_lwp_events): Remove function.
 	(fbsd_enable_proc_events): New function.
 	(fbsd_enable_follow_fork): Remove function.
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 508ab19..5e4304e 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -836,6 +836,9 @@ fbsd_wait (struct target_ops *ops,
 		  child_ptid = ptid_build (child, pl.pl_lwpid, 0);
 		}
 
+	      /* Enable additional events on the child process.  */
+	      fbsd_enable_proc_events (ptid_get_pid (child_ptid));
+
 	      /* For vfork, the child process will have the P_PPWAIT
 		 flag set.  */
 	      fbsd_fetch_kinfo_proc (child, &kp);
-- 
2.8.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] Consolidate code to enable optional FreeBSD native target event reporting.
  2016-07-18 14:58 [PATCH 0/3] Add "real" vfork done handling on FreeBSD John Baldwin
  2016-07-18 14:58 ` [PATCH 2/3] Enable ptrace events on new child processes John Baldwin
@ 2016-07-18 14:58 ` John Baldwin
  2016-07-18 14:58 ` [PATCH 3/3] Use a real vfork done event on FreeBSD when available John Baldwin
  2016-07-19 18:44 ` [PATCH 0/3] Add "real" vfork done handling on FreeBSD Pedro Alves
  3 siblings, 0 replies; 5+ messages in thread
From: John Baldwin @ 2016-07-18 14:58 UTC (permalink / raw)
  To: gdb-patches

Add a new function to enable optional event reporting for FreeBSD native
targets.  Specifically, use this to enable fork and LWP events.
The bodies of fbsd_enable_follow_fork and fbsd_enable_lwp_events have been
subsumed into the new function.  In addition, use the PT_GET_EVENT_MASK
and PT_EVENT_SET_MASK requests added in FreeBSD 12 when present to enable
these events.

gdb/ChangeLog:

	* fbsd-nat.c (fbsd_enable_lwp_events): Remove function.
	(fbsd_enable_proc_events): New function.
	(fbsd_enable_follow_fork): Remove function.
	(fbsd_post_startup_inferior): Use "fbsd_enable_proc_events".
	(fbsd_post_attach): Likewise.
---
 gdb/ChangeLog  |  8 ++++++++
 gdb/fbsd-nat.c | 59 ++++++++++++++++++++++++++++------------------------------
 2 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6c187dc..dcedc14 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@
 2016-07-15  John Baldwin  <jhb@FreeBSD.org>
 
+	* fbsd-nat.c (fbsd_enable_lwp_events): Remove function.
+	(fbsd_enable_proc_events): New function.
+	(fbsd_enable_follow_fork): Remove function.
+	(fbsd_post_startup_inferior): Use "fbsd_enable_proc_events".
+	(fbsd_post_attach): Likewise.
+
+2016-07-15  John Baldwin  <jhb@FreeBSD.org>
+
 	* common/signals.c (gdb_signal_from_host): Handle SIGLIBRT.
 	(do_gdb_signal_to_host): Likewise.
 	* infrun.c (_initialize_infrun): Pass GDB_SIGNAL_LIBRT through to
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index fa9516e..508ab19 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -412,22 +412,43 @@ fbsd_thread_name (struct target_ops *self, struct thread_info *thr)
 }
 #endif
 
-#ifdef PT_LWP_EVENTS
-/* Enable LWP events for a specific process.
+/* Enable additional event reporting on new processes.
 
-   To catch LWP events, PT_LWP_EVENTS is set on every traced process.
+   To catch fork events, PTRACE_FORK is set on every traced process
+   to enable stops on returns from fork or vfork.  Note that both the
+   parent and child will always stop, even if system call stops are
+   not enabled.
+
+   To catch LWP events, PTRACE_EVENTS is set on every traced process.
    This enables stops on the birth for new LWPs (excluding the "main" LWP)
    and the death of LWPs (excluding the last LWP in a process).  Note
    that unlike fork events, the LWP that creates a new LWP does not
    report an event.  */
 
 static void
-fbsd_enable_lwp_events (pid_t pid)
+fbsd_enable_proc_events (pid_t pid)
 {
+#ifdef PT_GET_EVENT_MASK
+  int events;
+
+  if (ptrace (PT_GET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
+	      sizeof (events)) == -1)
+    perror_with_name (("ptrace"));
+  events |= PTRACE_FORK | PTRACE_LWP;
+  if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
+	      sizeof (events)) == -1)
+    perror_with_name (("ptrace"));
+#else
+#ifdef TDP_RFPPWAIT
+  if (ptrace (PT_FOLLOW_FORK, pid, (PTRACE_TYPE_ARG3)0, 1) == -1)
+    perror_with_name (("ptrace"));
+#endif
+#ifdef PT_LWP_EVENTS
   if (ptrace (PT_LWP_EVENTS, pid, (PTRACE_TYPE_ARG3)0, 1) == -1)
     perror_with_name (("ptrace"));
-}
 #endif
+#endif
+}
 
 /* Add threads for any new LWPs in a process.
 
@@ -957,20 +978,6 @@ fbsd_remove_vfork_catchpoint (struct target_ops *self, int pid)
 {
   return 0;
 }
-
-/* Enable fork tracing for a specific process.
-   
-   To catch fork events, PT_FOLLOW_FORK is set on every traced process
-   to enable stops on returns from fork or vfork.  Note that both the
-   parent and child will always stop, even if system call stops are
-   not enabled.  */
-
-static void
-fbsd_enable_follow_fork (pid_t pid)
-{
-  if (ptrace (PT_FOLLOW_FORK, pid, (PTRACE_TYPE_ARG3)0, 1) == -1)
-    perror_with_name (("ptrace"));
-}
 #endif
 
 /* Implement the "to_post_startup_inferior" target_ops method.  */
@@ -978,12 +985,7 @@ fbsd_enable_follow_fork (pid_t pid)
 static void
 fbsd_post_startup_inferior (struct target_ops *self, ptid_t pid)
 {
-#ifdef TDP_RFPPWAIT
-  fbsd_enable_follow_fork (ptid_get_pid (pid));
-#endif
-#ifdef PT_LWP_EVENTS
-  fbsd_enable_lwp_events (ptid_get_pid (pid));
-#endif
+  fbsd_enable_proc_events (ptid_get_pid (pid));
 }
 
 /* Implement the "to_post_attach" target_ops method.  */
@@ -991,12 +993,7 @@ fbsd_post_startup_inferior (struct target_ops *self, ptid_t pid)
 static void
 fbsd_post_attach (struct target_ops *self, int pid)
 {
-#ifdef TDP_RFPPWAIT
-  fbsd_enable_follow_fork (pid);
-#endif
-#ifdef PT_LWP_EVENTS
-  fbsd_enable_lwp_events (pid);
-#endif
+  fbsd_enable_proc_events (pid);
   fbsd_add_threads (pid);
 }
 
-- 
2.8.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] Add "real" vfork done handling on FreeBSD
  2016-07-18 14:58 [PATCH 0/3] Add "real" vfork done handling on FreeBSD John Baldwin
                   ` (2 preceding siblings ...)
  2016-07-18 14:58 ` [PATCH 3/3] Use a real vfork done event on FreeBSD when available John Baldwin
@ 2016-07-19 18:44 ` Pedro Alves
  3 siblings, 0 replies; 5+ messages in thread
From: Pedro Alves @ 2016-07-19 18:44 UTC (permalink / raw)
  To: John Baldwin, gdb-patches

On 07/18/2016 03:57 PM, John Baldwin wrote:
> FreeBSD 12 recently gained a real vfork done event via ptrace(2).
> This changes the FreeBSD native targets to use this when it exists
> instead of faking a done event after a sleep.

That was fast...

LGTM.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-07-19 18:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-18 14:58 [PATCH 0/3] Add "real" vfork done handling on FreeBSD John Baldwin
2016-07-18 14:58 ` [PATCH 2/3] Enable ptrace events on new child processes John Baldwin
2016-07-18 14:58 ` [PATCH 1/3] Consolidate code to enable optional FreeBSD native target event reporting John Baldwin
2016-07-18 14:58 ` [PATCH 3/3] Use a real vfork done event on FreeBSD when available John Baldwin
2016-07-19 18:44 ` [PATCH 0/3] Add "real" vfork done handling on FreeBSD Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).