2001-07-07 Ben Elliston <bje@redhat.com>
[deliverable/binutils-gdb.git] / gdb / infrun.c
index a500e97948af077d9c1a7487de7996cc1eb68520..8b126db6523a0718c403325be55a6b060814a23c 100644 (file)
@@ -1617,7 +1617,17 @@ 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;
-       stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
+       /* 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;
@@ -1666,7 +1676,17 @@ handle_inferior_event (struct execution_control_state *ecs)
          }
 
        stop_pc = read_pc ();
-       stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
+       /* 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;
 
@@ -1731,7 +1751,17 @@ 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;
-       stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
+       /* 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;
@@ -1840,7 +1870,8 @@ handle_inferior_event (struct execution_control_state *ecs)
 
                /* Saw a breakpoint, but it was hit by the wrong thread.
                   Just continue. */
-               write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->ptid);
+               if (DECR_PC_AFTER_BREAK)
+                 write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->ptid);
 
                remove_status = remove_breakpoints ();
                /* Did we fail to remove breakpoints?  If so, try
@@ -1852,7 +1883,9 @@ handle_inferior_event (struct execution_control_state *ecs)
                   then either :-) or execs. */
                if (remove_status != 0)
                  {
-                   write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, ecs->ptid);
+                   /* FIXME!  This is obviously non-portable! */
+                   write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, 
+                                 ecs->ptid);
                    /* We need to restart all the threads now,
                     * unles we're running in scheduler-locked mode. 
                     * Use currently_stepping to determine whether to 
@@ -2016,7 +2049,8 @@ handle_inferior_event (struct execution_control_state *ecs)
           includes evaluating watchpoints, things will come to a
           stop in the correct manner.  */
 
-       write_pc (stop_pc - DECR_PC_AFTER_BREAK);
+       if (DECR_PC_AFTER_BREAK)
+         write_pc (stop_pc - DECR_PC_AFTER_BREAK);
 
        remove_breakpoints ();
        registers_changed ();
@@ -2097,6 +2131,14 @@ handle_inferior_event (struct execution_control_state *ecs)
        else
          {
            /* See if there is a breakpoint at the current 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,
            /* Pass TRUE if our reason for stopping is something other
@@ -2106,6 +2148,7 @@ handle_inferior_event (struct execution_control_state *ecs)
               sigtramp, which is detected by a new stack pointer value
               below any usual function calling stack adjustments.  */
                (currently_stepping (ecs)
+                && prev_pc != stop_pc - DECR_PC_AFTER_BREAK
                 && !(step_range_end
                      && INNER_THAN (read_sp (), (step_sp - 16))))
              );
@@ -2712,11 +2755,16 @@ handle_inferior_event (struct execution_control_state *ecs)
       {
        /* It's a subroutine call.  */
 
-       if (step_over_calls == STEP_OVER_NONE)
+       if ((step_over_calls == STEP_OVER_NONE)
+           || ((step_range_end == 1)
+               && in_prologue (prev_pc, ecs->stop_func_start)))
          {
            /* I presume that step_over_calls is only 0 when we're
               supposed to be stepping at the assembly language level
               ("stepi").  Just stop.  */
+           /* Also, maybe we just did a "nexti" inside a prolog,
+               so we thought it was a subroutine call but it was not.
+               Stop as well.  FENN */
            stop_step = 1;
            print_stop_reason (END_STEPPING_RANGE, 0);
            stop_stepping (ecs);
@@ -3260,7 +3308,7 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
       /* Print a message only if not in the middle of doing a "step n"
         operation for n > 1 */
       if (!step_multi || !stop_step)
-       if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+       if (ui_out_is_mi_like_p (uiout))
          ui_out_field_string (uiout, "reason", "end-stepping-range");
 #endif
       break;
@@ -3272,7 +3320,7 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
       /* The inferior was terminated by a signal. */
 #ifdef UI_OUT
       annotate_signalled ();
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        ui_out_field_string (uiout, "reason", "exited-signalled");
       ui_out_text (uiout, "\nProgram terminated with signal ");
       annotate_signal_name ();
@@ -3306,7 +3354,7 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
       annotate_exited (stop_info);
       if (stop_info)
        {
-         if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+         if (ui_out_is_mi_like_p (uiout))
            ui_out_field_string (uiout, "reason", "exited");
          ui_out_text (uiout, "\nProgram exited with code ");
          ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) stop_info);
@@ -3314,7 +3362,7 @@ print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
        }
       else
        {
-         if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+         if (ui_out_is_mi_like_p (uiout))
            ui_out_field_string (uiout, "reason", "exited-normally");
          ui_out_text (uiout, "\nProgram exited normally.\n");
        }
@@ -3500,12 +3548,12 @@ and/or watchpoints.\n");
 #ifdef UI_OUT
          /* For mi, have the same behavior every time we stop:
              print everything but the source line. */
-         if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+         if (ui_out_is_mi_like_p (uiout))
            source_flag = LOC_AND_ADDRESS;
 #endif
 
 #ifdef UI_OUT
-         if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+         if (ui_out_is_mi_like_p (uiout))
            ui_out_field_int (uiout, "thread-id",
                              pid_to_thread_id (inferior_ptid));
 #endif
This page took 0.025954 seconds and 4 git commands to generate.