*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 664351ef77bb632d6e273873565543540c20332e..f8644420e14c49b4262f6ff78ec5e06647a5a7f1 100644 (file)
@@ -2,7 +2,7 @@
    process.
 
    Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
    Foundation, Inc.
 
    This file is part of GDB.
@@ -66,7 +66,7 @@ static int restore_selected_frame (void *);
 
 static void build_infrun (void);
 
-static int follow_fork ();
+static int follow_fork (void);
 
 static void set_schedlock_func (char *args, int from_tty,
                                struct cmd_list_element *c);
@@ -377,7 +377,7 @@ static const char *follow_fork_mode_string = follow_fork_mode_parent;
 \f
 
 static int
-follow_fork ()
+follow_fork (void)
 {
   const char *follow_mode = follow_fork_mode_string;
   int follow_child = (follow_mode == follow_fork_mode_child);
@@ -1172,7 +1172,7 @@ context_switch (struct execution_control_state *ecs)
 void
 handle_inferior_event (struct execution_control_state *ecs)
 {
-  CORE_ADDR tmp;
+  CORE_ADDR real_stop_pc;
   int stepped_after_stopped_by_watchpoint;
   int sw_single_step_trap_p = 0;
 
@@ -1326,78 +1326,32 @@ 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;
 
       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.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.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:
@@ -1435,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
@@ -1886,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.  */
 
@@ -2493,19 +2407,19 @@ process_event_stop_test:
          function.  That's what tells us (a) whether we want to step
          into it at all, and (b) what prologue we want to run to
          the end of, if we do step into it.  */
-      tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
-      if (tmp != 0)
-       ecs->stop_func_start = tmp;
+      real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
+      if (real_stop_pc != 0)
+       ecs->stop_func_start = real_stop_pc;
       else
        {
-         tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc);
-         if (tmp)
+         real_stop_pc = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc);
+         if (real_stop_pc)
            {
              struct symtab_and_line xxx;
              /* Why isn't this s_a_l called "sr_sal", like all of the
                 other s_a_l's where this code is duplicated?  */
              init_sal (&xxx);  /* initialize to zeroes */
-             xxx.pc = tmp;
+             xxx.pc = real_stop_pc;
              xxx.section = find_pc_overlay (xxx.pc);
              check_for_old_step_resume_breakpoint ();
              step_resume_breakpoint =
@@ -2568,19 +2482,17 @@ process_event_stop_test:
      we want to proceed through the trampoline when stepping.  */
   if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name))
     {
-      CORE_ADDR tmp;
-
       /* Determine where this trampoline returns.  */
-      tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
+      real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
 
       /* Only proceed through if we know where it's going.  */
-      if (tmp)
+      if (real_stop_pc)
        {
          /* And put the step-breakpoint there and go until there. */
          struct symtab_and_line sr_sal;
 
          init_sal (&sr_sal);   /* initialize to zeroes */
-         sr_sal.pc = tmp;
+         sr_sal.pc = real_stop_pc;
          sr_sal.section = find_pc_overlay (sr_sal.pc);
          /* Do not specify what the fp should be when we stop
             since on some machines the prologue
@@ -3071,7 +2983,7 @@ normal_stop (void)
        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_current_frame_pc_hack (read_pc ());
+    deprecated_update_frame_pc_hack (get_current_frame (), read_pc ());
 
   if (target_has_execution && breakpoints_inserted)
     {
@@ -3179,7 +3091,7 @@ normal_stop (void)
             LOCATION: Print only location
             SRC_AND_LOC: Print location and source line */
          if (do_frame_printing)
-           show_and_print_stack_frame (deprecated_selected_frame, -1, source_flag);
+           print_stack_frame (deprecated_selected_frame, -1, source_flag);
 
          /* Display the auto-display expressions.  */
          do_displays ();
@@ -3195,10 +3107,10 @@ normal_stop (void)
 
   if (stop_stack_dummy)
     {
-      /* Pop the empty frame that contains the stack dummy.
-         POP_FRAME ends with a setting of the current frame, so we
-         can use that next. */
-      POP_FRAME;
+      /* Pop the empty frame that contains the stack dummy.  POP_FRAME
+         ends with a setting of the current frame, so we can use that
+         next. */
+      frame_pop (get_current_frame ());
       /* Set stop_pc to what it was before we called the function.
          Can't rely on restore_inferior_status because that only gets
          called if we don't stop in the called function.  */
This page took 0.028024 seconds and 4 git commands to generate.