2001-06-28 Michael Snyder <msnyder@redhat.com>
authorMichael Snyder <msnyder@vmware.com>
Thu, 28 Jun 2001 21:34:03 +0000 (21:34 +0000)
committerMichael Snyder <msnyder@vmware.com>
Thu, 28 Jun 2001 21:34:03 +0000 (21:34 +0000)
* infrun.c (handle_inferior_event): Replace prev_pc test in all
calls to bpstat_stop_status (removed in 1999-09-24).  This test
helps distinguish stepping over a breakpoint trap from stepping
thru a jump to the instruction after a breakpoint trap.
(handle_inferior_event): Don't bother writing the PC if
DECR_PC_AFTER_BREAK is zero (optimization).
* breakpoint.c (bpstat_stop_status): Add comment explaining the
purpose and usage of the "not_a_breakpoint" argument in computing
the breakpoint address.

gdb/ChangeLog
gdb/breakpoint.c
gdb/infrun.c

index ae7934a41b507387069d6f591408b64a22651b84..22de49948dbd0c4e55af246025395222b2be5ac0 100644 (file)
@@ -1,3 +1,15 @@
+2001-06-28  Michael Snyder  <msnyder@redhat.com>
+
+       * infrun.c (handle_inferior_event): Replace prev_pc test in all
+       calls to bpstat_stop_status (removed in 1999-09-24).  This test
+       helps distinguish stepping over a breakpoint trap from stepping
+       thru a jump to the instruction after a breakpoint trap.
+       (handle_inferior_event): Don't bother writing the PC if
+       DECR_PC_AFTER_BREAK is zero (optimization).
+       * breakpoint.c (bpstat_stop_status): Add comment explaining the
+       purpose and usage of the "not_a_breakpoint" argument in computing
+       the breakpoint address.
+
 2001-06-28  Andrew Cagney  <ac131313@redhat.com>
 
        From 2000-12-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>:
index 20f7251d3f1d6e30510a5554d6adc2dcff4717c3..cee302e8faf7230f03431a89ef52e45803a6792b 100644 (file)
@@ -2409,7 +2409,12 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
   "Error evaluating expression for watchpoint %d\n";
   char message[sizeof (message1) + 30 /* slop */ ];
 
-  /* Get the address where the breakpoint would have been.  */
+  /* Get the address where the breakpoint would have been.  
+     The "not_a_breakpoint" argument is meant to distinguish 
+     between a breakpoint trap event and a trace/singlestep
+     trap event.  For a trace/singlestep trap event, we would
+     not want to subtract DECR_PC_AFTER_BREAK from the PC. */
+
   bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P () ? 
                    0 : DECR_PC_AFTER_BREAK);
 
index a500e97948af077d9c1a7487de7996cc1eb68520..972b0930a74497ccbbc3eba98d343c554f3ac7b9 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))))
              );