* run.c (usage): Fix typos.
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 76770cc5c100871ace1441f717151e39173087a2..aa404cfcd1446d7843f72a799f63ae12de872e89 100644 (file)
@@ -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);
@@ -360,10 +355,7 @@ static struct
   struct
   {
     int parent_pid;
-    int saw_parent_fork;
     int child_pid;
-    int saw_child_fork;
-    int saw_child_exec;
   }
   fork_event;
   char *execd_pathname;
@@ -384,15 +376,11 @@ static const char *follow_fork_mode_kind_names[] = {
 static const char *follow_fork_mode_string = follow_fork_mode_parent;
 \f
 
-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,148 +390,33 @@ follow_inferior_fork (int parent_pid, int child_pid, int has_forked,
       /* 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.  */
 
-/* Forward declaration. */
-static void follow_exec (int, char *);
+  if (step_resume_breakpoint)
+    breakpoint_re_set_thread (step_resume_breakpoint);
 
-static void
-follow_vfork (int parent_pid, int child_pid)
-{
-  follow_inferior_fork (parent_pid, child_pid, 0, 1);
+  /* 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.  */
 
-  /* Did we follow the child?  Had it exec'd before we saw the parent vfork? */
-  if (pending_follow.fork_event.saw_child_exec
-      && (PIDGET (inferior_ptid) == child_pid))
-    {
-      pending_follow.fork_event.saw_child_exec = 0;
-      pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-      follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
-      xfree (pending_follow.execd_pathname);
-    }
+  breakpoint_re_set ();
+  insert_breakpoints ();
 }
 
 /* EXECD_PATHNAME is assumed to be non-NULL. */
@@ -732,38 +605,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:
@@ -1010,9 +864,6 @@ init_wait_for_inferior (void)
 
   /* The first resume is not following a fork/vfork/exec. */
   pending_follow.kind = TARGET_WAITKIND_SPURIOUS;      /* I.e., none. */
-  pending_follow.fork_event.saw_parent_fork = 0;
-  pending_follow.fork_event.saw_child_fork = 0;
-  pending_follow.fork_event.saw_child_exec = 0;
 
   /* See wait_for_inferior's handling of SYSCALL_ENTRY/RETURN events. */
   number_of_threads_in_syscalls = 0;
@@ -1475,101 +1326,40 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* The following are the only cases in which we keep going;
          the above cases end in a continue or goto. */
     case TARGET_WAITKIND_FORKED:
+    case TARGET_WAITKIND_VFORKED:
       stop_signal = TARGET_SIGNAL_TRAP;
       pending_follow.kind = ecs->ws.kind;
 
-      /* Ignore fork events reported for the parent; we're only
-         interested in reacting to forks of the child.  Note that
-         we expect the child's fork event to be available if we
-         waited for it now. */
-      if (ptid_equal (inferior_ptid, ecs->ptid))
-       {
-         pending_follow.fork_event.saw_parent_fork = 1;
-         pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
-         pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
-         prepare_to_wait (ecs);
-         return;
-       }
-      else
-       {
-         pending_follow.fork_event.saw_child_fork = 1;
-         pending_follow.fork_event.child_pid = PIDGET (ecs->ptid);
-         pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
-       }
+      pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
+      pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
 
-      stop_pc = read_pc_pid (ecs->ptid);
-      ecs->saved_inferior_ptid = inferior_ptid;
-      inferior_ptid = ecs->ptid;
-      /* The second argument of bpstat_stop_status is meant to help
-         distinguish between a breakpoint trap and a singlestep trap.
-         This is only important on targets where DECR_PC_AFTER_BREAK
-         is non-zero.  The prev_pc test is meant to distinguish between
-         singlestepping a trap instruction, and singlestepping thru a
-         jump to the instruction following a trap instruction. */
-
-      stop_bpstat = bpstat_stop_status (&stop_pc,
-                                       currently_stepping (ecs) &&
-                                       prev_pc !=
-                                       stop_pc - DECR_PC_AFTER_BREAK);
-      ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
-      inferior_ptid = ecs->saved_inferior_ptid;
-      goto process_event_stop_test;
+      stop_pc = read_pc ();
 
-      /* If this a platform which doesn't allow a debugger to touch a
-         vfork'd inferior until after it exec's, then we'd best keep
-         our fingers entirely off the inferior, other than continuing
-         it.  This has the unfortunate side-effect that catchpoints
-         of vforks will be ignored.  But since the platform doesn't
-         allow the inferior be touched at vfork time, there's really
-         little choice. */
-    case TARGET_WAITKIND_VFORKED:
-      stop_signal = TARGET_SIGNAL_TRAP;
-      pending_follow.kind = ecs->ws.kind;
+      /* Assume that catchpoints are not really software breakpoints.  If
+        some future target implements them using software breakpoints then
+        that target is responsible for fudging DECR_PC_AFTER_BREAK.  Thus
+        we pass 1 for the NOT_A_SW_BREAKPOINT argument, so that
+        bpstat_stop_status will not decrement the PC.  */
 
-      /* Is this a vfork of the parent?  If so, then give any
-         vfork catchpoints a chance to trigger now.  (It's
-         dangerous to do so if the child canot be touched until
-         it execs, and the child has not yet exec'd.  We probably
-         should warn the user to that effect when the catchpoint
-         triggers...) */
-      if (ptid_equal (ecs->ptid, inferior_ptid))
-       {
-         pending_follow.fork_event.saw_parent_fork = 1;
-         pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
-         pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;
-       }
+      stop_bpstat = bpstat_stop_status (&stop_pc, 1);
 
-      /* If we've seen the child's vfork event but cannot really touch
-         the child until it execs, then we must continue the child now.
-         Else, give any vfork catchpoints a chance to trigger now. */
-      else
+      ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
+
+      /* If no catchpoint triggered for this, then keep going.  */
+      if (ecs->random_signal)
        {
-         pending_follow.fork_event.saw_child_fork = 1;
-         pending_follow.fork_event.child_pid = PIDGET (ecs->ptid);
-         pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid;
-         target_post_startup_inferior (pid_to_ptid
-                                       (pending_follow.fork_event.
-                                        child_pid));
+         stop_signal = TARGET_SIGNAL_0;
+         keep_going (ecs);
+         return;
        }
-
-      stop_pc = read_pc ();
-      /* The second argument of bpstat_stop_status is meant to help
-         distinguish between a breakpoint trap and a singlestep trap.
-         This is only important on targets where DECR_PC_AFTER_BREAK
-         is non-zero.  The prev_pc test is meant to distinguish between
-         singlestepping a trap instruction, and singlestepping thru a
-         jump to the instruction following a trap instruction. */
-
-      stop_bpstat = bpstat_stop_status (&stop_pc,
-                                       currently_stepping (ecs) &&
-                                       prev_pc !=
-                                       stop_pc - DECR_PC_AFTER_BREAK);
-      ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
       goto process_event_stop_test;
 
     case TARGET_WAITKIND_EXECD:
       stop_signal = TARGET_SIGNAL_TRAP;
 
+      /* NOTE drow/2002-12-05: This code should be pushed down into the
+        target_wait function.  Until then following vfork on HP/UX 10.20
+        is probably broken by this.  Of course, it's broken anyway.  */
       /* Is this a target which reports multiple exec events per actual
          call to exec()?  (HP-UX using ptrace does, for example.)  If so,
          ignore all but the last one.  Just resume the exec'r, and wait
@@ -1591,36 +1381,6 @@ handle_inferior_event (struct execution_control_state *ecs)
        savestring (ecs->ws.value.execd_pathname,
                    strlen (ecs->ws.value.execd_pathname));
 
-      /* Did inferior_ptid exec, or did a (possibly not-yet-followed)
-         child of a vfork exec?
-
-         ??rehrauer: This is unabashedly an HP-UX specific thing.  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 (pending_follow.kind == TARGET_WAITKIND_VFORKED)
-       {
-         pending_follow.fork_event.saw_child_exec = 1;
-
-         /* On some targets, 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 (ecs->ptid, 1, TARGET_SIGNAL_0);
-         /* We expect the parent vfork event to be available now. */
-         prepare_to_wait (ecs);
-         return;
-       }
-
       /* This causes the eventpoints and symbol table to be reset.  Must
          do this now, before trying to determine whether to stop. */
       follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
@@ -1629,19 +1389,25 @@ handle_inferior_event (struct execution_control_state *ecs)
       stop_pc = read_pc_pid (ecs->ptid);
       ecs->saved_inferior_ptid = inferior_ptid;
       inferior_ptid = ecs->ptid;
-      /* The second argument of bpstat_stop_status is meant to help
-         distinguish between a breakpoint trap and a singlestep trap.
-         This is only important on targets where DECR_PC_AFTER_BREAK
-         is non-zero.  The prev_pc test is meant to distinguish between
-         singlestepping a trap instruction, and singlestepping thru a
-         jump to the instruction following a trap instruction. */
-
-      stop_bpstat = bpstat_stop_status (&stop_pc,
-                                       currently_stepping (ecs) &&
-                                       prev_pc !=
-                                       stop_pc - DECR_PC_AFTER_BREAK);
+
+      /* Assume that catchpoints are not really software breakpoints.  If
+        some future target implements them using software breakpoints then
+        that target is responsible for fudging DECR_PC_AFTER_BREAK.  Thus
+        we pass 1 for the NOT_A_SW_BREAKPOINT argument, so that
+        bpstat_stop_status will not decrement the PC.  */
+
+      stop_bpstat = bpstat_stop_status (&stop_pc, 1);
+
       ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
       inferior_ptid = ecs->saved_inferior_ptid;
+
+      /* If no catchpoint triggered for this, then keep going.  */
+      if (ecs->random_signal)
+       {
+         stop_signal = TARGET_SIGNAL_0;
+         keep_going (ecs);
+         return;
+       }
       goto process_event_stop_test;
 
       /* These syscall events are returned on HP-UX, as part of its
@@ -1703,13 +1469,15 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       /* We had an event in the inferior, but we are not interested
          in handling it at this level. The lower layers have already
-         done what needs to be done, if anything. This case can
-         occur only when the target is async or extended-async. One
-         of the circumstamces for this to happen is when the
-         inferior produces output for the console. The inferior has
-         not stopped, and we are ignoring the event. */
+         done what needs to be done, if anything.
+        
+        One of the possible circumstances for this is when the
+        inferior produces output for the console. The inferior has
+        not stopped, and we are ignoring the event.  Another possible
+        circumstance is any event which the lower level knows will be
+        reported multiple times without an intervening resume.  */
     case TARGET_WAITKIND_IGNORE:
-      ecs->wait_some_more = 1;
+      prepare_to_wait (ecs);
       return;
     }
 
@@ -2078,54 +1846,8 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   else
     ecs->random_signal = 1;
-  /* If a fork, vfork or exec event was seen, then there are two
-     possible responses we can make:
-
-     1. If a catchpoint triggers for the event (ecs->random_signal == 0),
-     then we must stop now and issue a prompt.  We will resume
-     the inferior when the user tells us to.
-     2. If no catchpoint triggers for the event (ecs->random_signal == 1),
-     then we must resume the inferior now and keep checking.
-
-     In either case, we must take appropriate steps to "follow" the
-     the fork/vfork/exec when the inferior is resumed.  For example,
-     if follow-fork-mode is "child", then we must detach from the
-     parent inferior and follow the new child inferior.
-
-     In either case, setting pending_follow causes the next resume()
-     to take the appropriate following action. */
-process_event_stop_test:
-  if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
-    {
-      if (ecs->random_signal)  /* I.e., no catchpoint triggered for this. */
-       {
-         trap_expected = 1;
-         stop_signal = TARGET_SIGNAL_0;
-         keep_going (ecs);
-         return;
-       }
-    }
-  else if (ecs->ws.kind == TARGET_WAITKIND_VFORKED)
-    {
-      if (ecs->random_signal)  /* I.e., no catchpoint triggered for this. */
-       {
-         stop_signal = TARGET_SIGNAL_0;
-         keep_going (ecs);
-         return;
-       }
-    }
-  else if (ecs->ws.kind == TARGET_WAITKIND_EXECD)
-    {
-      pending_follow.kind = ecs->ws.kind;
-      if (ecs->random_signal)  /* I.e., no catchpoint triggered for this. */
-       {
-         trap_expected = 1;
-         stop_signal = TARGET_SIGNAL_0;
-         keep_going (ecs);
-         return;
-       }
-    }
 
+process_event_stop_test:
   /* For the program's own signals, act according to
      the signal handling tables.  */
 
@@ -2243,7 +1965,7 @@ process_event_stop_test:
          set_longjmp_resume_breakpoint (jmp_buf_pc, get_current_frame ());
        else
 #endif /* 0 */
-         set_longjmp_resume_breakpoint (jmp_buf_pc, NULL);
+         set_longjmp_resume_breakpoint (jmp_buf_pc, null_frame_id);
        ecs->handling_longjmp = 1;      /* FIXME */
        keep_going (ecs);
        return;
@@ -2536,7 +2258,7 @@ process_event_stop_test:
 
          check_for_old_step_resume_breakpoint ();
          step_resume_breakpoint =
-           set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+           set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
          if (breakpoints_inserted)
            insert_breakpoints ();
        }
@@ -2592,7 +2314,7 @@ process_event_stop_test:
               step_frame_id; I don't think anyone thought to try it.  */
            check_for_old_step_resume_breakpoint ();
            step_resume_breakpoint =
-             set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+             set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
            if (breakpoints_inserted)
              insert_breakpoints ();
          }
@@ -2701,7 +2423,7 @@ process_event_stop_test:
              xxx.section = find_pc_overlay (xxx.pc);
              check_for_old_step_resume_breakpoint ();
              step_resume_breakpoint =
-               set_momentary_breakpoint (xxx, NULL, bp_step_resume);
+               set_momentary_breakpoint (xxx, null_frame_id, bp_step_resume);
              insert_breakpoints ();
              keep_going (ecs);
              return;
@@ -2779,7 +2501,7 @@ process_event_stop_test:
             is where the new fp value is established.  */
          check_for_old_step_resume_breakpoint ();
          step_resume_breakpoint =
-           set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+           set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
          if (breakpoints_inserted)
            insert_breakpoints ();
 
@@ -2893,7 +2615,7 @@ check_sigtramp2 (struct execution_control_state *ecs)
       /* We perhaps could set the frame if we kept track of what the
          frame corresponding to prev_pc was.  But we don't, so don't.  */
       through_sigtramp_breakpoint =
-       set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp);
+       set_momentary_breakpoint (sr_sal, null_frame_id, bp_through_sigtramp);
       if (breakpoints_inserted)
        insert_breakpoints ();
 
@@ -2951,7 +2673,7 @@ step_into_function (struct execution_control_state *ecs)
          established.  */
       check_for_old_step_resume_breakpoint ();
       step_resume_breakpoint =
-       set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
+       set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
       if (breakpoints_inserted)
        insert_breakpoints ();
 
@@ -2984,13 +2706,12 @@ step_over_function (struct execution_control_state *ecs)
 
   check_for_old_step_resume_breakpoint ();
   step_resume_breakpoint =
-    set_momentary_breakpoint (sr_sal, get_current_frame (), bp_step_resume);
+    set_momentary_breakpoint (sr_sal, get_frame_id (get_current_frame ()),
+                             bp_step_resume);
 
   if (frame_id_p (step_frame_id)
       && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
-    /* FIXME: cagney/2002-12-01: Someone should modify the breakpoint
-       code so that it uses a frame ID, instead of a frame address.  */
-    step_resume_breakpoint->frame = step_frame_id.base;
+    step_resume_breakpoint->frame_id = step_frame_id;
 
   if (breakpoints_inserted)
     insert_breakpoints ();
@@ -3001,30 +2722,6 @@ stop_stepping (struct execution_control_state *ecs)
 {
   if (target_has_execution)
     {
-      /* Are we stopping for a vfork event?  We only stop when we see
-         the child's event.  However, we may not yet have seen the
-         parent's event.  And, inferior_ptid is still set to the
-         parent's pid, until we resume again and follow either the
-         parent or child.
-
-         To ensure that we can really touch inferior_ptid (aka, the
-         parent process) -- which calls to functions like read_pc
-         implicitly do -- wait on the parent if necessary. */
-      if ((pending_follow.kind == TARGET_WAITKIND_VFORKED)
-         && !pending_follow.fork_event.saw_parent_fork)
-       {
-         ptid_t parent_ptid;
-
-         do
-           {
-             if (target_wait_hook)
-               parent_ptid = target_wait_hook (pid_to_ptid (-1), &(ecs->ws));
-             else
-               parent_ptid = target_wait (pid_to_ptid (-1), &(ecs->ws));
-           }
-         while (!ptid_equal (parent_ptid, inferior_ptid));
-       }
-
       /* Assuming the inferior still exists, set these up for next
          time, just like we did above if we didn't break out of the
          loop.  */
@@ -3283,8 +2980,12 @@ normal_stop (void)
   /* Make sure that the current_frame's pc is correct.  This
      is a correction for setting up the frame info before doing
      DECR_PC_AFTER_BREAK */
-  if (target_has_execution && get_current_frame ())
-    (get_current_frame ())->pc = read_pc ();
+  if (target_has_execution)
+    /* FIXME: cagney/2002-12-06: Has the PC changed?  Thanks to
+       DECR_PC_AFTER_BREAK, the program counter can change.  Ask the
+       frame code to check for this and sort out any resultant mess.
+       DECR_PC_AFTER_BREAK needs to just go away.  */
+    deprecated_update_frame_pc_hack (get_current_frame (), read_pc ());
 
   if (target_has_execution && breakpoints_inserted)
     {
This page took 0.039777 seconds and 4 git commands to generate.