This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Fork event updates, part the sixth


And here's the interesting one.  I shoved most of follow_inferior_fork down
into hppah-nat; one common function (follow_inferior_reset_breakpoints)
stays in infrun but the rest of infrun is greatly simplified.  This will
lead to a little bit of code duplication on the GNU/Linux native
child_follow_fork, but the remote target follow_fork is much simplified by
not having to hack around detach_breakpoints().

The post_follow_vfork target method is removed and replaced with a
follow_fork method.  HP now holds vforks until all three of parent vfork,
child vfork, child exec have been seen - it's not robust in the face of
children which vfork and then _exit, but it wasn't to begin with.  This also
lets me move some more HP-specific comments and hacks out of infrun and back
into HP-specific code.  Yay!

I also re-enable foll-vfork.exp on HP/UX.  It works now.  There is a comment
about a kernel bug, but I'd prefer to turn the test on for now until we can
figure out where if anywhere the kernel bug actually surfaces; it doesn't on
any machines I have access to.

I haven't done it yet but next will probably be a cleanup patch.  After this
target_require_attach/target_require_detach can go away; they are now only
called from HP-specific code.  That's the last two target methods on my
immediate hit list.  So can a couple of macros that used to be checked in
infrun, to do strange things to the vforking parent/child as needed.  I'll
do that today if I get a chance.

This will also go in early next week barring feedback.  You may be
interested to know that the GNU/Linux support at this point is down to a
thousand line unified diff:
 25 files changed, 561 insertions(+), 63 deletions(-)
(396 of that is in one file, half the rest is in infrun and the other half
in lin-lwp.  Then a bunch of configuration changes to link in the new file.)
So after these patches and some cleanup go in I'll probably be ready to post
that.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-12-06  Daniel Jacobowitz  <drow@mvista.com>

	* config/pa/nm-hppah.h (CHILD_POST_FOLLOW_VFORK): Change to
	CHILD_FOLLOW_FORK.
	* hppah-nat.c (saved_vfork_pid): Add.
	(child_post_follow_vfork): Remove.
	(child_follow_fork): New function.A
	(child_wait): Call detach_breakpoints after receiving the child vfork.
	Call child_resume directly instead of going through resume ().
	Make sure we have the exec before reporting the vfork.
	* inferior.h (follow_inferior_reset_breakpoints): Add prototype.
	* infrun.c (follow_fork, follow_vfork, follow_inferior_fork): Remove.
	(follow_fork): New function.  Call target_follow_fork.
	(follow_inferior_reset_breakpoints): New function broken out from
	old follow_inferior_fork.
	(resume): Remove hack to follow exec after vfork.
	* inftarg.c (child_post_follow_vfork): Remove.
	(child_follow_fork): New function.
	(init_child_ops): Replace to_post_follow_vfork with to_follow_fork.
	* target.c (cleanup_target): Replace to_post_follow_vfork with
	to_follow_fork.
	(update_current_target): Likewise.
	(setup_target_debug): Likewise.
	(debug_to_post_follow_vfork): Remove.
	(debug_to_follow_fork): New function.
	* target.h (struct target_ops): Replace to_post_folow_vfork with
	to_follow_fork.
	(child_post_follow_vfork): Remove prototype.
	(child_follow_fork): Add prototype.
	(target_post_follow_vfork): Remove macro.
	(target_follow_fork): Add macro.

2002-12-06  Daniel Jacobowitz  <drow@mvista.com>

	* gdb.base/foll-vfork.exp: Re-enable test on HP/UX.

diff -urp gdb.work2/config/pa/nm-hppah.h gdb.work3/config/pa/nm-hppah.h
--- gdb.work2/config/pa/nm-hppah.h	2002-12-06 02:01:32.000000000 -0500
+++ gdb.work3/config/pa/nm-hppah.h	2002-12-06 01:06:10.000000000 -0500
@@ -65,7 +65,7 @@
 /* In hppah-nat.c: */
 #define FETCH_INFERIOR_REGISTERS
 #define CHILD_XFER_MEMORY
-#define CHILD_POST_FOLLOW_VFORK
+#define CHILD_FOLLOW_FORK
 
 /* While this is for use by threaded programs, it doesn't appear
  * to hurt non-threaded ones.  This is used in infrun.c: */
diff -urp gdb.work2/hppah-nat.c gdb.work3/hppah-nat.c
--- gdb.work2/hppah-nat.c	2002-12-06 17:11:28.000000000 -0500
+++ gdb.work3/hppah-nat.c	2002-12-06 14:14:49.000000000 -0500
@@ -385,6 +385,7 @@ child_xfer_memory (CORE_ADDR memaddr, ch
 }
 
 char *saved_child_execd_pathname = NULL;
+int saved_vfork_pid;
 enum {
   STATE_NONE,
   STATE_GOT_CHILD,
@@ -393,48 +394,121 @@ enum {
   STATE_FAKE_EXEC
 } saved_vfork_state = STATE_NONE;
 
-void
-child_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
-			 int followed_child)
+int
+child_follow_fork (int follow_child)
 {
-  /* Are we a debugger that followed the parent of a vfork?  If so,
-     then recall that the child's vfork event was delivered to us
-     first.  And, that the parent was suspended by the OS until the
-     child's exec or exit events were received.
-
-     Upon receiving that child vfork, then, we were forced to remove
-     all breakpoints in the child and continue it so that it could
-     reach the exec or exit point.
-
-     But also recall that the parent and child of a vfork share the
-     same address space.  Thus, removing bp's in the child also
-     removed them from the parent.
-
-     Now that the child has safely exec'd or exited, we must restore
-     the parent's breakpoints before we continue it.  Else, we may
-     cause it run past expected stopping points. */
-  if (followed_parent)
-    {
-      reattach_breakpoints (parent_pid);
-    }
-
-  /* If we followed the parent, don't try to follow the child's exec.  */
-  if (saved_vfork_state != STATE_GOT_PARENT && saved_vfork_state != STATE_FAKE_EXEC)
-    fprintf_unfiltered (gdb_stdout, "hppa: post follow vfork: confused state\n");
-
-  if (followed_parent || saved_vfork_state == STATE_GOT_PARENT)
-    saved_vfork_state = STATE_NONE;
-
-  /* Are we a debugger that followed the child of a vfork?  If so,
-     then recall that we don't actually acquire control of the child
-     until after it has exec'd or exited.  */
-  if (followed_child)
-    {
-      /* If the child has exited, then there's nothing for us to do.
-         In the case of an exec event, we'll let that be handled by
-         the normal mechanism that notices and handles exec events, in
-         resume(). */
+  ptid_t last_ptid;
+  struct target_waitstatus last_status;
+  int has_vforked;
+  int parent_pid, child_pid;
+
+  get_last_target_status (&last_ptid, &last_status);
+  has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
+  parent_pid = ptid_get_pid (last_ptid);
+  child_pid = last_status.value.related_pid;
+
+  /* At this point, if we are vforking, breakpoints were already
+     detached from the child in child_wait; and the child has already
+     called execve().  If we are forking, both the parent and child
+     have breakpoints inserted.  */
+
+  if (! follow_child)
+    {
+      if (! has_vforked)
+	{
+	  detach_breakpoints (child_pid);
+#ifdef SOLIB_REMOVE_INFERIOR_HOOK
+	  SOLIB_REMOVE_INFERIOR_HOOK (child_pid);
+#endif
+	}
+
+      /* Detach from the child. */
+      target_require_detach (child_pid, "", 1);
+
+      /* The parent and child of a vfork share the same address space.
+	 Also, on some targets the order in which vfork and exec events
+	 are received for parent in child requires some delicate handling
+	 of the events.
+
+	 For instance, on ptrace-based HPUX we receive the child's vfork
+	 event first, at which time the parent has been suspended by the
+	 OS and is essentially untouchable until the child's exit or second
+	 exec event arrives.  At that time, the parent's vfork event is
+	 delivered to us, and that's when we see and decide how to follow
+	 the vfork.  But to get to that point, we must continue the child
+	 until it execs or exits.  To do that smoothly, all breakpoints
+	 must be removed from the child, in case there are any set between
+	 the vfork() and exec() calls.  But removing them from the child
+	 also removes them from the parent, due to the shared-address-space
+	 nature of a vfork'd parent and child.  On HPUX, therefore, we must
+	 take care to restore the bp's to the parent before we continue it.
+	 Else, it's likely that we may not stop in the expected place.  (The
+	 worst scenario is when the user tries to step over a vfork() call;
+	 the step-resume bp must be restored for the step to properly stop
+	 in the parent after the call completes!)
+
+	 Sequence of events, as reported to gdb from HPUX:
+
+	 Parent        Child           Action for gdb to take
+	 -------------------------------------------------------
+	 1                VFORK               Continue child
+	 2                EXEC
+	 3                EXEC or EXIT
+	 4  VFORK
+
+	 Now that the child has safely exec'd or exited, we must restore
+	 the parent's breakpoints before we continue it.  Else, we may
+	 cause it run past expected stopping points.  */
+
+      if (has_vforked)
+	reattach_breakpoints (parent_pid);
+    }
+  else
+    {
+      char child_pid_spelling[40];
+
+      /* Needed to keep the breakpoint lists in sync.  */
+      if (! has_vforked)
+	detach_breakpoints (child_pid);
+
+      /* Before detaching from the parent, remove all breakpoints from it. */
+      remove_breakpoints ();
+
+      /* Also reset the solib inferior hook from the parent. */
+#ifdef SOLIB_REMOVE_INFERIOR_HOOK
+      SOLIB_REMOVE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+#endif
+
+      /* Detach from the parent. */
+      target_detach (NULL, 1);
+
+      /* Attach to the child. */
+      inferior_ptid = pid_to_ptid (child_pid);
+      sprintf (child_pid_spelling, "%d", child_pid);
+
+      target_require_attach (child_pid_spelling, 1);
+
+      /* If we vforked, then we've also execed by now.  The exec will be
+	 reported momentarily.  follow_exec () will handle breakpoints, so
+	 we don't have to..  */
+      if (!has_vforked)
+	follow_inferior_reset_breakpoints ();
+    }
+
+  if (has_vforked)
+    {
+      /* If we followed the parent, don't try to follow the child's exec.  */
+      if (saved_vfork_state != STATE_GOT_PARENT
+	  && saved_vfork_state != STATE_FAKE_EXEC)
+	fprintf_unfiltered (gdb_stdout,
+			    "hppa: post follow vfork: confused state\n");
+
+      if (! follow_child || saved_vfork_state == STATE_GOT_PARENT)
+	saved_vfork_state = STATE_NONE;
+      else
+	return 1;
     }
+  return 0;
 }
 
 /* Format a process id, given PID.  Be sure to terminate
@@ -592,15 +666,28 @@ child_wait (ptid_t ptid, struct target_w
 	  if (saved_vfork_state == STATE_GOT_CHILD)
 	    {
 	      child_post_startup_inferior (pid_to_ptid (pid));
-	      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
-	      return pid_to_ptid (pid);
+	      detach_breakpoints (pid);
+#ifdef SOLIB_REMOVE_INFERIOR_HOOK
+	      SOLIB_REMOVE_INFERIOR_HOOK (pid);
+#endif
+	      child_resume (pid_to_ptid (pid), 0, TARGET_SIGNAL_0);
+	      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+	      return pid_to_ptid (related_pid);
 	    }
-	  else
+	  else if (saved_vfork_state == STATE_FAKE_EXEC)
 	    {
 	      ourstatus->kind = TARGET_WAITKIND_VFORKED;
 	      ourstatus->value.related_pid = related_pid;
 	      return pid_to_ptid (pid);
 	    }
+	  else
+	    {
+	      /* We saw the parent's vfork, but we haven't seen the exec yet.
+		 Wait for it, for simplicity's sake.  It should be pending.  */
+	      saved_vfork_pid = related_pid;
+	      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+	      return pid_to_ptid (pid);
+	    }
 	}
 
       if (hpux_has_execd (pid, &execd_pathname))
@@ -608,27 +695,32 @@ child_wait (ptid_t ptid, struct target_w
 	  /* On HP-UX, events associated with a vforking inferior come in
 	     threes: a vfork event for the child (always first), followed
 	     a vfork event for the parent and an exec event for the child.
-	     The latter two can come in either order.
-
-	     If we get the parent vfork event first, life's good: We follow
-	     either the parent or child, and then the child's exec event is
-	     a "don't care".
-
-	     But if we get the child's exec event first, then we delay
-	     responding to it until we handle the parent's vfork.  Because,
-	     otherwise we can't satisfy a "catch vfork".  */
-	  if (saved_vfork_state == STATE_GOT_CHILD)
+	     The latter two can come in either order.  Make sure we get
+	     both.  */
+	  if (saved_vfork_state != STATE_NONE)
 	    {
-	      saved_child_execd_pathname = execd_pathname;
-	      saved_vfork_state = STATE_GOT_EXEC;
+	      if (saved_vfork_state == STATE_GOT_CHILD)
+		{
+		  saved_vfork_state = STATE_GOT_EXEC;
+		  /* On HP/UX with ptrace, the child must be resumed before
+		     the parent vfork event is delivered.  A single-step
+		     suffices.  */
+		  if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ())
+		    target_resume (pid_to_ptid (pid), 1, TARGET_SIGNAL_0);
+		  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+		}
+	      else if (saved_vfork_state == STATE_GOT_PARENT)
+		{
+		  saved_vfork_state = STATE_FAKE_EXEC;
+		  ourstatus->kind = TARGET_WAITKIND_VFORKED;
+		  ourstatus->value.related_pid = saved_vfork_pid;
+		}
+	      else
+		fprintf_unfiltered (gdb_stdout,
+				    "hppa: exec: unexpected state\n");
 
-	      /* On HP/UX with ptrace, the child must be resumed before
-		 the parent vfork event is delivered.  A single-step
-		 suffices.  */
-	      if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ())
-		target_resume (pid_to_ptid (pid), 1, TARGET_SIGNAL_0);
+	      saved_child_execd_pathname = execd_pathname;
 
-	      ourstatus->kind = TARGET_WAITKIND_IGNORE;
 	      return inferior_ptid;
 	    }
 	  
diff -urp gdb.work2/inferior.h gdb.work3/inferior.h
--- gdb.work2/inferior.h	2002-12-06 01:43:04.000000000 -0500
+++ gdb.work3/inferior.h	2002-12-06 01:19:41.000000000 -0500
@@ -301,6 +301,8 @@ extern int signal_pass_update (int, int)
 extern void get_last_target_status(ptid_t *ptid,
                                    struct target_waitstatus *status);
 
+extern void follow_inferior_reset_breakpoints (void);
+
 /* From infcmd.c */
 
 extern void tty_command (char *, int);
diff -urp gdb.work2/infrun.c gdb.work3/infrun.c
--- gdb.work2/infrun.c	2002-12-06 17:14:19.000000000 -0500
+++ gdb.work3/infrun.c	2002-12-06 12:36:41.000000000 -0500
@@ -66,12 +66,7 @@ static int restore_selected_frame (void 
 
 static void build_infrun (void);
 
-static void follow_inferior_fork (int parent_pid, int child_pid,
-				  int has_forked, int has_vforked);
-
-static void follow_fork (int parent_pid, int child_pid);
-
-static void follow_vfork (int parent_pid, int child_pid);
+static int follow_fork ();
 
 static void set_schedlock_func (char *args, int from_tty,
 				struct cmd_list_element *c);
@@ -384,15 +379,11 @@ static const char *follow_fork_mode_kind
 static const char *follow_fork_mode_string = follow_fork_mode_parent;
 
 
-static void
-follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
-		      int has_vforked)
+static int
+follow_fork ()
 {
-  int followed_parent = 0;
-  int followed_child = 0;
-
-  /* Which process did the user want us to follow? */
   const char *follow_mode = follow_fork_mode_string;
+  int follow_child = (follow_mode == follow_fork_mode_child);
 
   /* Or, did the user not know, and want us to ask? */
   if (follow_fork_mode_string == follow_fork_mode_ask)
@@ -402,138 +393,36 @@ follow_inferior_fork (int parent_pid, in
       /* follow_mode = follow_fork_mode_...; */
     }
 
-  /* If we're to be following the parent, then detach from child_pid.
-     We're already following the parent, so need do nothing explicit
-     for it. */
-  if (follow_mode == follow_fork_mode_parent)
-    {
-      followed_parent = 1;
-
-      /* We're already attached to the parent, by default. */
-
-      /* Before detaching from the child, remove all breakpoints from
-         it.  (This won't actually modify the breakpoint list, but will
-         physically remove the breakpoints from the child.) */
-      detach_breakpoints (child_pid);
-#ifdef SOLIB_REMOVE_INFERIOR_HOOK
-      SOLIB_REMOVE_INFERIOR_HOOK (child_pid);
-#endif
-
-      /* Detach from the child. */
-      dont_repeat ();
-
-      target_require_detach (child_pid, "", 1);
-    }
-
-  /* If we're to be following the child, then attach to it, detach
-     from inferior_ptid, and set inferior_ptid to child_pid. */
-  else if (follow_mode == follow_fork_mode_child)
-    {
-      char child_pid_spelling[100];	/* Arbitrary length. */
-
-      followed_child = 1;
-
-      /* Before detaching from the parent, detach all breakpoints from
-         the child.  Note that this only works if we're following vforks
-	 right away; if we've exec'd then the breakpoints are already detached
-	 and the shadow contents are out of date.  */
-      detach_breakpoints (child_pid);
-
-      /* Before detaching from the parent, remove all breakpoints from it. */
-      remove_breakpoints ();
-
-      /* Also reset the solib inferior hook from the parent. */
-#ifdef SOLIB_REMOVE_INFERIOR_HOOK
-      SOLIB_REMOVE_INFERIOR_HOOK (PIDGET (inferior_ptid));
-#endif
-
-      /* Detach from the parent. */
-      dont_repeat ();
-      target_detach (NULL, 1);
-
-      /* Attach to the child. */
-      inferior_ptid = pid_to_ptid (child_pid);
-      sprintf (child_pid_spelling, "%d", child_pid);
-      dont_repeat ();
-
-      target_require_attach (child_pid_spelling, 1);
-
-      /* Was there a step_resume breakpoint?  (There was if the user
-         did a "next" at the fork() call.)  If so, explicitly reset its
-         thread number.
-
-         step_resumes are a form of bp that are made to be per-thread.
-         Since we created the step_resume bp when the parent process
-         was being debugged, and now are switching to the child process,
-         from the breakpoint package's viewpoint, that's a switch of
-         "threads".  We must update the bp's notion of which thread
-         it is for, or it'll be ignored when it triggers... */
-      /* As above, if we're following vforks at exec time then resetting the
-	 step resume breakpoint is probably wrong.  */
-      if (step_resume_breakpoint)
-	breakpoint_re_set_thread (step_resume_breakpoint);
-
-      /* Reinsert all breakpoints in the child.  (The user may've set
-         breakpoints after catching the fork, in which case those
-         actually didn't get set in the child, but only in the parent.) */
-      breakpoint_re_set ();
-      insert_breakpoints ();
-    }
-
-  /* The parent and child of a vfork share the same address space.
-     Also, on some targets the order in which vfork and exec events
-     are received for parent in child requires some delicate handling
-     of the events.
-
-     For instance, on ptrace-based HPUX we receive the child's vfork
-     event first, at which time the parent has been suspended by the
-     OS and is essentially untouchable until the child's exit or second
-     exec event arrives.  At that time, the parent's vfork event is
-     delivered to us, and that's when we see and decide how to follow
-     the vfork.  But to get to that point, we must continue the child
-     until it execs or exits.  To do that smoothly, all breakpoints
-     must be removed from the child, in case there are any set between
-     the vfork() and exec() calls.  But removing them from the child
-     also removes them from the parent, due to the shared-address-space
-     nature of a vfork'd parent and child.  On HPUX, therefore, we must
-     take care to restore the bp's to the parent before we continue it.
-     Else, it's likely that we may not stop in the expected place.  (The
-     worst scenario is when the user tries to step over a vfork() call;
-     the step-resume bp must be restored for the step to properly stop
-     in the parent after the call completes!)
-
-     Sequence of events, as reported to gdb from HPUX:
-
-     Parent        Child           Action for gdb to take
-     -------------------------------------------------------
-     1                VFORK               Continue child
-     2                EXEC
-     3                EXEC or EXIT
-     4  VFORK */
-  if (has_vforked)
-    {
-      target_post_follow_vfork (parent_pid,
-				followed_parent, child_pid, followed_child);
-    }
-
   pending_follow.fork_event.saw_parent_fork = 0;
   pending_follow.fork_event.saw_child_fork = 0;
+
+  return target_follow_fork (follow_child);
 }
 
-static void
-follow_fork (int parent_pid, int child_pid)
+void
+follow_inferior_reset_breakpoints (void)
 {
-  follow_inferior_fork (parent_pid, child_pid, 1, 0);
-}
+  /* Was there a step_resume breakpoint?  (There was if the user
+     did a "next" at the fork() call.)  If so, explicitly reset its
+     thread number.
+
+     step_resumes are a form of bp that are made to be per-thread.
+     Since we created the step_resume bp when the parent process
+     was being debugged, and now are switching to the child process,
+     from the breakpoint package's viewpoint, that's a switch of
+     "threads".  We must update the bp's notion of which thread
+     it is for, or it'll be ignored when it triggers.  */
 
+  if (step_resume_breakpoint)
+    breakpoint_re_set_thread (step_resume_breakpoint);
 
-/* Forward declaration. */
-static void follow_exec (int, char *);
+  /* Reinsert all breakpoints in the child.  The user may have set
+     breakpoints after catching the fork, in which case those
+     were never set in the child, but only in the parent.  This makes
+     sure the inserted breakpoints match the breakpoint list.  */
 
-static void
-follow_vfork (int parent_pid, int child_pid)
-{
-  follow_inferior_fork (parent_pid, child_pid, 0, 1);
+  breakpoint_re_set ();
+  insert_breakpoints ();
 }
 
 /* EXECD_PATHNAME is assumed to be non-NULL. */
@@ -722,38 +611,19 @@ resume (int step, enum target_signal sig
 #endif
 
   /* If there were any forks/vforks/execs that were caught and are
-     now to be followed, then do so. */
+     now to be followed, then do so.  */
   switch (pending_follow.kind)
     {
-    case (TARGET_WAITKIND_FORKED):
+    case TARGET_WAITKIND_FORKED:
+    case TARGET_WAITKIND_VFORKED:
       pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-      follow_fork (PIDGET (inferior_ptid),
-		   pending_follow.fork_event.child_pid);
-      break;
-
-    case (TARGET_WAITKIND_VFORKED):
-      {
-	int saw_child_exec = pending_follow.fork_event.saw_child_exec;
-
-	pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-	follow_vfork (PIDGET (inferior_ptid),
-		      pending_follow.fork_event.child_pid);
-
-	/* Did we follow the child, but not yet see the child's exec event?
-	   If so, then it actually ought to be waiting for us; we respond to
-	   parent vfork events.  We don't actually want to resume the child
-	   in this situation; we want to just get its exec event. */
-	if (!saw_child_exec &&
-	    (PIDGET (inferior_ptid) == pending_follow.fork_event.child_pid))
-	  should_resume = 0;
-      }
+      if (follow_fork ())
+	should_resume = 0;
       break;
 
-    case (TARGET_WAITKIND_EXECD):
-      /* If we saw a vfork event but couldn't follow it until we saw
-         an exec, then now might be the time! */
-      pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+    case TARGET_WAITKIND_EXECD:
       /* follow_exec is called as soon as the exec event is seen. */
+      pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
       break;
 
     default:
diff -urp gdb.work2/inftarg.c gdb.work3/inftarg.c
--- gdb.work2/inftarg.c	2002-11-16 14:24:41.000000000 -0500
+++ gdb.work3/inftarg.c	2002-12-06 12:32:24.000000000 -0500
@@ -469,14 +469,12 @@ child_remove_vfork_catchpoint (int pid)
 }
 #endif
 
-#if !defined(CHILD_POST_FOLLOW_VFORK)
-void
-child_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
-			 int followed_child)
+#if !defined(CHILD_FOLLOW_FORK)
+int
+child_follow_fork (int follow_child)
 {
-  /* This version of Unix doesn't require a meaningful "post follow vfork"
-     operation by a clone debugger.
-   */
+  /* This version of Unix doesn't support following fork or vfork events.  */
+  return 0;
 }
 #endif
 
@@ -645,7 +643,7 @@ init_child_ops (void)
   child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint;
   child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
   child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint;
-  child_ops.to_post_follow_vfork = child_post_follow_vfork;
+  child_ops.to_follow_fork = child_follow_fork;
   child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
   child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint;
   child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call;
diff -urp gdb.work2/target.c gdb.work3/target.c
--- gdb.work2/target.c	2002-11-16 14:24:41.000000000 -0500
+++ gdb.work3/target.c	2002-12-06 12:31:58.000000000 -0500
@@ -473,8 +473,8 @@ cleanup_target (struct target_ops *t)
   de_fault (to_remove_vfork_catchpoint, 
 	    (int (*) (int)) 
 	    tcomplain);
-  de_fault (to_post_follow_vfork, 
-	    (void (*) (int, int, int, int)) 
+  de_fault (to_follow_fork, 
+	    (int (*) (int)) 
 	    target_ignore);
   de_fault (to_insert_exec_catchpoint, 
 	    (int (*) (int)) 
@@ -597,7 +597,7 @@ update_current_target (void)
       INHERIT (to_remove_fork_catchpoint, t);
       INHERIT (to_insert_vfork_catchpoint, t);
       INHERIT (to_remove_vfork_catchpoint, t);
-      INHERIT (to_post_follow_vfork, t);
+      INHERIT (to_follow_fork, t);
       INHERIT (to_insert_exec_catchpoint, t);
       INHERIT (to_remove_exec_catchpoint, t);
       INHERIT (to_reported_exec_events_per_exec_call, t);
@@ -2064,15 +2064,15 @@ debug_to_remove_vfork_catchpoint (int pi
   return retval;
 }
 
-static void
-debug_to_post_follow_vfork (int parent_pid, int followed_parent, int child_pid,
-			    int followed_child)
+static int
+debug_to_follow_fork (int follow_child)
 {
-  debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child);
+  int retval =  debug_target.to_follow_fork (follow_child);
 
-  fprintf_unfiltered (gdb_stdlog,
-		      "target_post_follow_vfork (%d, %d, %d, %d)\n",
-		    parent_pid, followed_parent, child_pid, followed_child);
+  fprintf_unfiltered (gdb_stdlog, "target_follow_fork (%d) = %d\n",
+		      follow_child, retval);
+
+  return retval;
 }
 
 static int
@@ -2285,7 +2285,7 @@ setup_target_debug (void)
   current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint;
   current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint;
   current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint;
-  current_target.to_post_follow_vfork = debug_to_post_follow_vfork;
+  current_target.to_follow_fork = debug_to_follow_fork;
   current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint;
   current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint;
   current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call;
diff -urp gdb.work2/target.h gdb.work3/target.h
--- gdb.work2/target.h	2002-12-06 17:00:18.000000000 -0500
+++ gdb.work3/target.h	2002-12-06 17:00:35.000000000 -0500
@@ -276,7 +276,7 @@ struct target_ops
     int (*to_remove_fork_catchpoint) (int);
     int (*to_insert_vfork_catchpoint) (int);
     int (*to_remove_vfork_catchpoint) (int);
-    void (*to_post_follow_vfork) (int, int, int, int);
+    int (*to_follow_fork) (int);
     int (*to_insert_exec_catchpoint) (int);
     int (*to_remove_exec_catchpoint) (int);
     int (*to_reported_exec_events_per_exec_call) (void);
@@ -548,7 +548,7 @@ extern int child_remove_vfork_catchpoint
 
 extern void child_acknowledge_created_inferior (int);
 
-extern void child_post_follow_vfork (int, int, int, int);
+extern int child_follow_fork (int);
 
 extern int child_insert_exec_catchpoint (int);
 
@@ -705,16 +705,16 @@ extern void target_load (char *arg, int 
 #define target_remove_vfork_catchpoint(pid) \
      (*current_target.to_remove_vfork_catchpoint) (pid)
 
-/* An inferior process has been created via a vfork() system call.
-   The debugger has followed the parent, the child, or both.  The
-   process of setting up for that follow may have required some
-   target-specific trickery to track the sequence of reported events.
-   If so, this function should be defined by those targets that
-   require the debugger to perform cleanup or initialization after
-   the vfork follow.  */
+/* If the inferior forks or vforks, this function will be called at
+   the next resume in order to perform any bookkeeping and fiddling
+   necessary to continue debugging either the parent or child, as
+   requested, and releasing the other.  Information about the fork
+   or vfork event is available via get_last_target_status ().
+   This function returns 1 if the inferior should not be resumed
+   (i.e. there is another event pending).  */
 
-#define target_post_follow_vfork(parent_pid,followed_parent,child_pid,followed_child) \
-     (*current_target.to_post_follow_vfork) (parent_pid,followed_parent,child_pid,followed_child)
+#define target_follow_fork(follow_child) \
+     (*current_target.to_follow_fork) (follow_child)
 
 /* On some targets, we can catch an inferior exec event when it
    occurs.  These functions insert/remove an already-created
diff -urp gdb.work2/testsuite/gdb.base/foll-vfork.exp gdb.work3/testsuite/gdb.base/foll-vfork.exp
--- gdb.work2/testsuite/gdb.base/foll-vfork.exp	2002-12-06 12:49:10.000000000 -0500
+++ gdb.work3/testsuite/gdb.base/foll-vfork.exp	2002-12-06 12:48:42.000000000 -0500
@@ -28,10 +28,13 @@ if { ![isnative] } then {
 set prms_id 0
 set bug_id 0
 
-if [istarget "hppa2.0w-hp-hpux*"] {
-  warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem is fixed."
-  return 0
-}
+# NOTE drow/2002-12-06: I don't know what the referenced kernel problem
+# is, but it appears to be fixed in recent HP/UX versions.
+
+##if [istarget "hppa2.0w-hp-hpux*"] {
+##  warning "Don't run gdb.base/foll-vfork.exp until JAGaa43495 kernel problem is fixed."
+##  return 0
+##}
 
 set testfile "foll-vfork"
 set testfile2 "vforked-prog"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]