Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* STEP_SKIPS_DELAY question, sort of
@ 2004-05-21 17:14 Orjan Friberg
  2004-05-21 20:25 ` Andrew Cagney
  0 siblings, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-05-21 17:14 UTC (permalink / raw)
  To: gdb-patches

I'm facing a problem with the CRIS target which is related to what 
STEP_SKIPS_DELAY is aiming to solve,.  The problem occurs when 
single-stepping past a breakpoint set on an instruction with a delay 
slot, because execution resumes at the instruction *preceding* the delay 
slot.  Here's an illustration of what happens:

0x0  ba foo  (branch instruction)
0x2  nop     (delay slot)
If there's a breakpoint (implemented in CRIS with a "break" instruction) 
at address 0x0, the following happens when single-stepping (hardware 
assisted):

(1) We end up in the delay slot at address 0x2.
(2) GDB re-inserts the break instruction at address 0x0.
(3) Execution resumes at address 0x0, and we hit the breakpoint again.
Besides STEP_SKIPS_DELAY having a fixed offset of 4 bytes between 
instruction and its associated delay slot, it's concerned with a 
breakpoint being set in the delay slot, which isn't the case here.

Basically, what I'm looking for is a way to say "don't re-insert a 
breakpoint on an instruction that's going to be restarted when we resume 
execution".  I'm thinking other architectures have faced similar issues, 
but I couldn't find anything.

(The alternatives I could think of are (1) fudging the address we report 
as being stopped at, to trick GDB into stepping one more time before 
re-insterting the breakpoint, or (2) automatically single-step past the 
delay slot (without reporting to GDB), both of which may be confusing 
for a user.)

--
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-21 17:14 STEP_SKIPS_DELAY question, sort of Orjan Friberg
@ 2004-05-21 20:25 ` Andrew Cagney
  2004-05-24  9:15   ` Orjan Friberg
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Cagney @ 2004-05-21 20:25 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

I'm facing a problem with the CRIS target which is related to what STEP_SKIPS_DELAY is aiming to solve,.  The problem occurs when single-stepping past a breakpoint set on an instruction with a delay slot, because execution resumes at the instruction *preceding* the delay slot.  Here's an illustration of what happens:

0x0  ba foo  (branch instruction)
0x2  nop     (delay slot)
If there's a breakpoint (implemented in CRIS with a "break" instruction) at address 0x0, the following happens when single-stepping (hardware assisted):

(1) We end up in the delay slot at address 0x2.
(2) GDB re-inserts the break instruction at address 0x0.
(3) Execution resumes at address 0x0, and we hit the breakpoint again.
Besides STEP_SKIPS_DELAY having a fixed offset of 4 bytes between instruction and its associated delay slot, it's concerned with a breakpoint being set in the delay slot, which isn't the case here.

Basically, what I'm looking for is a way to say "don't re-insert a breakpoint on an instruction that's going to be restarted when we resume execution".  I'm thinking other architectures have faced similar issues, but I couldn't find anything.

(The alternatives I could think of are (1) fudging the address we report as being stopped at, to trick GDB into stepping one more time before re-insterting the breakpoint, or (2) automatically single-step past the delay slot (without reporting to GDB), both of which may be confusing for a user.)
Earlier MIPS variants (at least) needed STEP_SKIPS_DELAY.  When at 
``0x0'', a hardware single-step would end up at ``foo''.  That isn't 
your problem.

Since your hardware can single-step into a delay slot, can it also 
resume from the delay slot?  An example of this is SPARC with its 
constantly shuffling PC/N[ext]PC -- the inferior is resumed with PC==0x2 
N[ext]PC==foo.

Andrew




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-21 20:25 ` Andrew Cagney
@ 2004-05-24  9:15   ` Orjan Friberg
  2004-05-24 18:15     ` Andrew Cagney
  0 siblings, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-05-24  9:15 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Andrew Cagney wrote:
Earlier MIPS variants (at least) needed STEP_SKIPS_DELAY.  When at 
``0x0'', a hardware single-step would end up at ``foo''.  That isn't 
your problem.

Since your hardware can single-step into a delay slot, can it also 
resume from the delay slot?  An example of this is SPARC with its 
constantly shuffling PC/N[ext]PC -- the inferior is resumed with PC==0x2 
N[ext]PC==foo.
I'm not sure I understand what you mean by "can resume" - it can resume 
from a delay slot, but when doing so the branch instruction (and the 
delay slot) is re-executed.  I don't have an NPC, and AFAIK there's no 
information in the CPU registers that tells me whether the branch is 
taken or not (which seems consistent with the fact that the 
branch-instruction is re-executed).

Maybe this can be stated in even simpler terms than "don't re-insert a 
breakpoint on an instruction that's going to be restarted when we resume 
execution".  Rather, "single-step twice before re-inserting a breakpoint 
we're currently stopped at".

--
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-24  9:15   ` Orjan Friberg
@ 2004-05-24 18:15     ` Andrew Cagney
  2004-05-25 11:53       ` Orjan Friberg
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Cagney @ 2004-05-24 18:15 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

Andrew Cagney wrote:

Earlier MIPS variants (at least) needed STEP_SKIPS_DELAY.  When at ``0x0'', a hardware single-step would end up at ``foo''.  That isn't your problem.

Since your hardware can single-step into a delay slot, can it also resume from the delay slot?  An example of this is SPARC with its constantly shuffling PC/N[ext]PC -- the inferior is resumed with PC==0x2 N[ext]PC==foo.


I'm not sure I understand what you mean by "can resume" - it can resume from a delay slot, but when doing so the branch instruction (and the delay slot) is re-executed.  I don't have an NPC, and AFAIK there's no information in the CPU registers that tells me whether the branch is taken or not (which seems consistent with the fact that the branch-instruction is re-executed).
Ok, I'm starting to understand the wierdness

The SPARC (using PC/NextPC) resumes from the delay slot so re-inserting 
the breakpoint is safe - that branch instruction is never re-executed. 
Your architecture isn't like this.



I think there is still some missing information.  Given:
  N+0: branch foo
  N+2: nop
and PC==N+0, exactly what state information is available after doing a 
single hardware single-step (PC and status registers)?

- If I understand things correctly, one h/w single-step gets PC==N+2 and 
two h/w single-steps gets PC==foo.  For that to work there must be some 
additional state information lurking somewhere - a bit indicating 
stopped in delay slot perhaphs?

- If there were a breakpoint at N+2, what state information would be 
available then.  If the breakpoint were then yanked, where would a 
single-step end up - again additional state information is needed to 
make this work?

Maybe this can be stated in even simpler terms than "don't re-insert a breakpoint on an instruction that's going to be restarted when we resume execution".  Rather, "single-step twice before re-inserting a breakpoint we're currently stopped at". 
GDB needs to know that its in such a state.

Andrew




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-24 18:15     ` Andrew Cagney
@ 2004-05-25 11:53       ` Orjan Friberg
  2004-05-25 21:14         ` Andrew Cagney
  0 siblings, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-05-25 11:53 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Andrew Cagney wrote:
I think there is still some missing information.  Given:
  N+0: branch foo
  N+2: nop
and PC==N+0, exactly what state information is available after doing a 
single hardware single-step (PC and status registers)?
State information is only PC (see below) and SPC (single-step PC). 
There's no information in the status registers regarding branch 
taken/not taken.

(The h/w single-step procedure works like this: after the instruction 
pointed out by the SPC has been executed, a single-step exception is 
given, and the SPC is updated to the next instruction.)

- If I understand things correctly, one h/w single-step gets PC==N+2 and 
two h/w single-steps gets PC==foo.  For that to work there must be some 
additional state information lurking somewhere - a bit indicating 
stopped in delay slot perhaphs?
One h/w single-step actually gets PC==N+1, which I then adjust to N+2 
before reporting it to GDB.  So, (yes) the bit indicating stopped in a 
delay slot is the lowest bit of the PC.

- If there were a breakpoint at N+2, what state information would be 
available then.  If the breakpoint were then yanked, where would a 
single-step end up - again additional state information is needed to 
make this work?
With a breakpoint at N+2, PC==N+1 (again, interrupted in delay slot, 
will resume execution at N) and PC is reported as N+2.  For a 
single-step at this point, SPC is set up with N+2, so a single-step 
exception fires after the delay slot has been executed.

(The decrementation of the PC when executing a break instruction is 
handled by the stub itself, which becomes a bit of a kludge when we're 
stopped in a delay slot.)

What could be implemented relatively easily is to automatically 
single-step again if we end up in a delay-slot due to a single-step (not 
due to a breakpoint though).  This would, in some sense, break the 
"stepi" command since we would step two instructions instead of one in 
those cases.

Maybe this can be stated in even simpler terms than "don't re-insert a 
breakpoint on an instruction that's going to be restarted when we 
resume execution".  Rather, "single-step twice before re-inserting a 
breakpoint we're currently stopped at". 


GDB needs to know that its in such a state.
Yeah, I had a look at resume/handle_inferior_event, and it certainly 
wasn't obvious to me how that kind of mechanism should be implemented.

--
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-25 11:53       ` Orjan Friberg
@ 2004-05-25 21:14         ` Andrew Cagney
  2004-05-26  9:39           ` Orjan Friberg
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Cagney @ 2004-05-25 21:14 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

Ok,

When given:

  N+0: branch foo
  N+2: nop
PC=N (or N+1)
SPC=N+2
would this result in a double single-step leaving PC==foo?  If it does 
then you've at least got STEP_SKIPS_DELAY like behavior.

It still fixes single-step but that's a, er, later step.

Andrew



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-25 21:14         ` Andrew Cagney
@ 2004-05-26  9:39           ` Orjan Friberg
  2004-05-26 17:39             ` Andrew Cagney
  2004-06-07 12:12             ` Orjan Friberg
  0 siblings, 2 replies; 19+ messages in thread
From: Orjan Friberg @ 2004-05-26  9:39 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Andrew Cagney wrote:
Ok,

When given:

  N+0: branch foo
  N+2: nop
PC=N (or N+1)
SPC=N+2
would this result in a double single-step leaving PC==foo?  If it does 
then you've at least got STEP_SKIPS_DELAY like behavior.
Actually, both when PC=N (at the branch instruction) and when PC=N+1 (in 
the delay slot) a *single* single-step will leave us at PC==foo - the 
single-step exception fires after the instruction pointed out by SPC has 
been executed.

I'll go and have a closer look at STEP_SKIPS_DELAY.

--
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-26  9:39           ` Orjan Friberg
@ 2004-05-26 17:39             ` Andrew Cagney
  2004-06-07 12:12             ` Orjan Friberg
  1 sibling, 0 replies; 19+ messages in thread
From: Andrew Cagney @ 2004-05-26 17:39 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

Andrew Cagney wrote:

Ok,

When given:

  N+0: branch foo
  N+2: nop
PC=N (or N+1)
SPC=N+2
would this result in a double single-step leaving PC==foo?  If it does then you've at least got STEP_SKIPS_DELAY like behavior.


Actually, both when PC=N (at the branch instruction) and when PC=N+1 (in the delay slot) a *single* single-step will leave us at PC==foo - the single-step exception fires after the instruction pointed out by SPC has been executed.

I'll go and have a closer look at STEP_SKIPS_DELAY. 
We'll likely need to change that a bit but thats ok.

Andrew




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-05-26  9:39           ` Orjan Friberg
  2004-05-26 17:39             ` Andrew Cagney
@ 2004-06-07 12:12             ` Orjan Friberg
  2004-06-07 12:42               ` Orjan Friberg
  1 sibling, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-06-07 12:12 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Orjan Friberg wrote:
> 
> I'll go and have a closer look at STEP_SKIPS_DELAY.

Short recap: the MIPS checks if there's a breakpoint in the delay slot of the 
instruction where GDB is about to resume execution.  If so, GDB single-steps 
that instruction before re-inserting the breakpoint.

For CRISv32, if there's a breakpoint on an instruction which has a delay slot, 
we cannot re-insert the breakpoint when we're stopped in the delay slot (after 
making one single-step), because the previous instruction will be re-executed 
when returning from the delay slot.

I tried implementing a fix in handle_inferior_event (the MIPS fix is in 
proceed).  It seemed easier to step one more time when we find out that we need 
to, rather than to determine beforehand that we're going to have to step twice 
(and I couldn't determine how to pass that information).

The concept patch below illustrates what I'm trying to do; by setting 
another_trap in the execution control state, by the time we get to keep_going we 
won't insert the breakpoint and we'll instead continue single-stepping. 
Comments?  Is this the right approach at all?

Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.156
diff -u -r1.156 infrun.c
--- infrun.c    11 May 2004 23:30:31 -0000      1.156
+++ infrun.c    7 Jun 2004 11:44:19 -0000
@@ -1975,7 +1975,17 @@
        /* Don't even think about breakpoints if just proceeded over a
           breakpoint.  */
        if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected)
-       bpstat_clear (&stop_bpstat);
+       {
+         bpstat_clear (&stop_bpstat);
+
+         /* If we stepped into a delay slot, and the preceding instruction
+            will be re-executed when resuming, step again before re-inserting
+            the breakpoint.  */
+         if (STEP_SKIPS_IN_DELAY_P
+             && breakpoint_here_p (read_pc () - 2)
+             && STEP_SKIPS_IN_DELAY (read_pc ()))
+           ecs->another_trap = 1;
+       }
        else
         {
           /* See if there is a breakpoint at the current PC.  */


-- 
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-07 12:12             ` Orjan Friberg
@ 2004-06-07 12:42               ` Orjan Friberg
  2004-06-07 13:09                 ` Orjan Friberg
  0 siblings, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-06-07 12:42 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Orjan Friberg wrote:
> 
> I tried implementing a fix in handle_inferior_event (the MIPS fix is in 
> proceed).  It seemed easier to step one more time when we find out that 
> we need to, rather than to determine beforehand that we're going to have 
> to step twice (and I couldn't determine how to pass that information).
> 
> The concept patch below illustrates what I'm trying to do; by setting 
> another_trap in the execution control state, by the time we get to 
> keep_going we won't insert the breakpoint and we'll instead continue 
> single-stepping. Comments?  Is this the right approach at all?

Gah.  Please ignore the previous patch (and sorry); what I posted only 
works when doing a continue when stopped at the branch instruction. 
Doing a step (which leaves us in the delay slot) followed by another 
step (or continue for that matter) prematurely inserts the breakpoint.

-- 
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-07 12:42               ` Orjan Friberg
@ 2004-06-07 13:09                 ` Orjan Friberg
  2004-06-07 15:08                   ` Andrew Cagney
  0 siblings, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-06-07 13:09 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Orjan Friberg wrote:
> 
> Gah.  Please ignore the previous patch (and sorry); what I posted only 
> works when doing a continue when stopped at the branch instruction. 
> Doing a step (which leaves us in the delay slot) followed by another 
> step (or continue for that matter) prematurely inserts the breakpoint.

Ok, second try (still concept patch though): the change in proceed is needed for 
when we resume from the delay slot - in that case we need to single-step again 
before re-inserting the breakpoint (similar to the MIPS case).  The change in 
handle_inferior_event (and I'll happily agree it's far more questionable) is 
needed for when we resume at the branch instruction itself.  Comments?

Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.156
diff -u -p -r1.156 infrun.c
--- infrun.c    11 May 2004 23:30:31 -0000      1.156
+++ infrun.c    7 Jun 2004 12:59:10 -0000
@@ -748,6 +748,14 @@ proceed (CORE_ADDR addr, enum target_sig
           && breakpoint_here_p (read_pc () + 4)
           && STEP_SKIPS_DELAY (read_pc ()))
         oneproc = 1;
+
+      /* If we stepped into a delay slot, and the preceding instruction
+        will be re-executed when resuming, step again before re-inserting
+        the breakpoint.  */
+      if (STEP_SKIPS_IN_DELAY_P
+         && breakpoint_here_p (read_pc () - 2)
+         && STEP_SKIPS_IN_DELAY (read_pc ()))
+       oneproc = 1;
      }
    else
      {
@@ -1975,7 +1983,17 @@ handle_inferior_event (struct execution_
        /* Don't even think about breakpoints if just proceeded over a
           breakpoint.  */
        if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected)
-       bpstat_clear (&stop_bpstat);
+       {
+         bpstat_clear (&stop_bpstat);
+
+         /* If we stepped into a delay slot, and the preceding instruction
+            will be re-executed when resuming, step again before re-inserting
+            the breakpoint.  */
+         if (STEP_SKIPS_IN_DELAY_P
+             && breakpoint_here_p (read_pc () - 2)
+             && STEP_SKIPS_IN_DELAY (read_pc ()))
+           ecs->another_trap = 1;
+       }
        else
         {
           /* See if there is a breakpoint at the current PC.  */

-- 
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-07 13:09                 ` Orjan Friberg
@ 2004-06-07 15:08                   ` Andrew Cagney
  2004-06-09  9:48                     ` Orjan Friberg
  0 siblings, 1 reply; 19+ messages in thread
From: Andrew Cagney @ 2004-06-07 15:08 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

> Orjan Friberg wrote:
> 
>>
>> Gah.  Please ignore the previous patch (and sorry); what I posted only works when doing a continue when stopped at the branch instruction. Doing a step (which leaves us in the delay slot) followed by another step (or continue for that matter) prematurely inserts the breakpoint.
> 
> 
> Ok, second try (still concept patch though): the change in proceed is needed for when we resume from the delay slot - in that case we need to single-step again before re-inserting the breakpoint (similar to the MIPS case).  The change in handle_inferior_event (and I'll happily agree it's far more questionable) is needed for when we resume at the branch instruction itself.  Comments?

Can this new mechanism somehow superseed STEP_SKIPS_DELAY - it seems to 
be the exact oposite but there could be common ground here.

> Index: infrun.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/infrun.c,v
> retrieving revision 1.156
> diff -u -p -r1.156 infrun.c
> --- infrun.c    11 May 2004 23:30:31 -0000      1.156
> +++ infrun.c    7 Jun 2004 12:59:10 -0000
> @@ -748,6 +748,14 @@ proceed (CORE_ADDR addr, enum target_sig
>           && breakpoint_here_p (read_pc () + 4)
>           && STEP_SKIPS_DELAY (read_pc ()))
>         oneproc = 1;
> +
> +      /* If we stepped into a delay slot, and the preceding instruction
> +        will be re-executed when resuming, step again before re-inserting
> +        the breakpoint.  */
> +      if (STEP_SKIPS_IN_DELAY_P
> +         && "
> +         && STEP_SKIPS_IN_DELAY (read_pc ()))
> +       oneproc = 1;
>      }
>    else
>      {

They both seem to be asking the question: "given PC and a list of 
breakpoints, should the inferior be h/w single-stepped?".  That would 
mean pushing the alternative:
   breakpoint_here_p (read_pc () - 2)
   breakpoint_here_p (read_pc () + 4)
calls into that architecture method.

> @@ -1975,7 +1983,17 @@ handle_inferior_event (struct execution_
>        /* Don't even think about breakpoints if just proceeded over a
>           breakpoint.  */
>        if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected)
> -       bpstat_clear (&stop_bpstat);
> +       {
> +         bpstat_clear (&stop_bpstat);
> +
> +         /* If we stepped into a delay slot, and the preceding instruction
> +            will be re-executed when resuming, step again before re-inserting
> +            the breakpoint.  */
> +         if (STEP_SKIPS_IN_DELAY_P
> +             && breakpoint_here_p (read_pc () - 2)
> +             && STEP_SKIPS_IN_DELAY (read_pc ()))
> +           ecs->another_trap = 1;
> +       }
>        else
>         {
>           /* See if there is a breakpoint at the current PC.  */
> 

I'm just not sure how this bit of logic should fit in.  I'm guessing its 
the second half of the state m/c sequence:

1. step off breakpoint at `PC'
2. step through delay

Andrew



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-07 15:08                   ` Andrew Cagney
@ 2004-06-09  9:48                     ` Orjan Friberg
  2004-06-09 16:00                       ` Andrew Cagney
  0 siblings, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-06-09  9:48 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Andrew Cagney wrote:
> 
> Can this new mechanism somehow superseed STEP_SKIPS_DELAY - it seems to 
> be the exact oposite but there could be common ground here.

[proceed patch snipped]

> They both seem to be asking the question: "given PC and a list of 
> breakpoints, should the inferior be h/w single-stepped?".  That would 
> mean pushing the alternative:
>   breakpoint_here_p (read_pc () - 2)
>   breakpoint_here_p (read_pc () + 4)
> calls into that architecture method.

Agreed.  (STEP_SKIPS_IN_DELAY was just to have something to put in the patch.)

What about using the name STEP_SKIPS_DELAY for both, and introducing a 
DELAY_SIZE which  would return a positive value (meaning the diff from the 
current pc to the delay slot) or a negative (meaning the diff from the delay 
slot to the instruction preceding it)?  Or does the word "size" imply an 
absolute value?

[handle_inferior_event patch snipped]

> I'm just not sure how this bit of logic should fit in.  I'm guessing its 
> the second half of the state m/c sequence:
> 
> 1. step off breakpoint at `PC'
> 2. step through delay

Unless I missed something on the way, the procedure when doing a continue from a
breakpoint that sits on the branch instruction is this:

1. proceed decides it needs to step once before continuing (since read_pc () == 
stop_pc && breakpoint_here_p (read_pc ()))
2. resume is called, with step = 1
3. target is single-stepped
4. handle_inferior_event is called (at which point we're stopped in the delay slot)

It is at this point we need to single-step again (before inserting breakpoints 
again), so I set ecs->another_trap.  Then:

5. keep_going is called, and since ecs->anther_trap is set, it doesn't call 
insert_breakpoints.
6. resume is called again, with step = 1
7. target is single-stepped
8. handle_inferior_event is called again (but doesn't set ecs->another_trap this 
time)
9. keep_going is called, and inserts the breakpoints again

I can't say where would be a better place to put the decision of whether to 
single-step again.  Any suggestions?

-- 
Orjan Friberg
Axis Communications



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-09  9:48                     ` Orjan Friberg
@ 2004-06-09 16:00                       ` Andrew Cagney
  2004-06-14 12:09                         ` Orjan Friberg
  2004-10-01 11:26                         ` Orjan Friberg
  0 siblings, 2 replies; 19+ messages in thread
From: Andrew Cagney @ 2004-06-09 16:00 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

> Andrew Cagney wrote:
> 
>>
>> Can this new mechanism somehow superseed STEP_SKIPS_DELAY - it seems to be the exact oposite but there could be common ground here.
> 
> 
> [proceed patch snipped]
> 
>> They both seem to be asking the question: "given PC and a list of breakpoints, should the inferior be h/w single-stepped?".  That would mean pushing the alternative:
>>   breakpoint_here_p (read_pc () - 2)
>>   breakpoint_here_p (read_pc () + 4)
>> calls into that architecture method.
> 
> 
> Agreed.  (STEP_SKIPS_IN_DELAY was just to have something to put in the patch.)
> 
> What about using the name STEP_SKIPS_DELAY for both, and introducing a DELAY_SIZE which  would return a positive value (meaning the diff from the current pc to the delay slot) or a negative (meaning the diff from the delay slot to the instruction preceding it)?  Or does the word "size" imply an absolute value?

If the:
 >>   breakpoint_here_p (read_pc () - 2)
and
 >>   breakpoint_here_p (read_pc () + 4)
logic is moved to the per-architecture STEP_SKIPS_DELAY I don't think 
DELAY_SIZE is needed.

I also think this needs a new macro name that better reflects what the 
test is doing.  But I've no good ideas :-/ (SINGLE_STEP_THROUGH_DELAY (pc)?)

> [handle_inferior_event patch snipped]
> 
>> I'm just not sure how this bit of logic should fit in.  I'm guessing its the second half of the state m/c sequence:
>>
>> 1. step off breakpoint at `PC'
>> 2. step through delay
> 
> 
> Unless I missed something on the way, the procedure when doing a continue from a
> breakpoint that sits on the branch instruction is this:
> 
> 1. proceed decides it needs to step once before continuing (since read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
> 2. resume is called, with step = 1
> 3. target is single-stepped
> 4. handle_inferior_event is called (at which point we're stopped in the delay slot)

yes (step off breakpoint at `PC')

> It is at this point we need to single-step again (before inserting breakpoints again), so I set ecs->another_trap.  Then:
> 
> 5. keep_going is called, and since ecs->anther_trap is set, it doesn't call insert_breakpoints.
> 6. resume is called again, with step = 1
> 7. target is single-stepped
> 8. handle_inferior_event is called again (but doesn't set ecs->another_trap this time)
> 9. keep_going is called, and inserts the breakpoints again

ok (step through delay)

> I can't say where would be a better place to put the decision of whether to single-step again.  Any suggestions?

Can a simple, separate, more explicit logic like:
	if (we just did a step and STEP_SKIPS_DELAY (pc))
	  set up for another step
	  return;
work?  The [handle_inferior_event patch snipped] was nested within other 
logic and that's not good from a readability / maintainability point of 
view.

Andrew



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-09 16:00                       ` Andrew Cagney
@ 2004-06-14 12:09                         ` Orjan Friberg
  2004-06-16 14:53                           ` Orjan Friberg
  2004-10-01 11:26                         ` Orjan Friberg
  1 sibling, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-06-14 12:09 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Andrew Cagney wrote:
> 
> If the:
>  >>   breakpoint_here_p (read_pc () - 2)
> and
>  >>   breakpoint_here_p (read_pc () + 4)
> logic is moved to the per-architecture STEP_SKIPS_DELAY I don't think 
> DELAY_SIZE is needed.
> 
> I also think this needs a new macro name that better reflects what the 
> test is doing.  But I've no good ideas :-/ (SINGLE_STEP_THROUGH_DELAY 
> (pc)?)

SINGLE_STEP_THROUGH_DELAY sounds fine to me.

> Can a simple, separate, more explicit logic like:
>     if (we just did a step and STEP_SKIPS_DELAY (pc))
>       set up for another step
>       return;
> work?  The [handle_inferior_event patch snipped] was nested within other 
> logic and that's not good from a readability / maintainability point of 
> view.

Agreed; it wasn't clear from the context where I put the patch why it was there. 
  I'll come back with a proper patch once I've gotten around to do some more 
serious testing.

-- 
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-14 12:09                         ` Orjan Friberg
@ 2004-06-16 14:53                           ` Orjan Friberg
  2004-06-24 18:25                             ` Andrew Cagney
  0 siblings, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-06-16 14:53 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Orjan Friberg wrote:
> Andrew Cagney wrote:
>>
>> I also think this needs a new macro name that better reflects what the 
>> test is doing.  But I've no good ideas :-/ (SINGLE_STEP_THROUGH_DELAY 
>> (pc)?)

I'm facing a slightly different situation than the MIPS case when implementing 
SINGLE_STEP_THROUGH_DELAY, because the size of the instruction that the delay 
slot belongs to may be 2, 4, or 6 bytes.  (For MIPS, it seems the size of that 
instruction is always 4 bytes.)

So, I have to find out the size of the preceding instruction (since I want to do 
the single-step thingy when we're stopped in the delay slot), but I can't find 
anything in the opcodes directory that would let me do that.

The thing is, this information (whether I'm in a delay slot, and the address of 
the instruction the delay slot belongs to) is available in a register.  Besides 
the fact that this triggers sending a 'g' packet to the remote target, is it 
wrong to deduce this information from the registers content rather than reading 
from the program's text segment?

Basically, my implementation would look like this:

int
cris_single_step_through_delay (CORE_ADDR pc)
{
   ULONGEST erp;
   int ret = 0;
   regcache_cooked_read_unsigned (current_regcache, ERP_REGNUM, &erp);
   if (erp & 0x1)
     /* In delay slot - check if there's a breakpoint at the preceding
        instruction.  */
     if (breakpoint_here_p (erp & ~0x1))
       ret = 1;
   return ret;
}

-- 
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-16 14:53                           ` Orjan Friberg
@ 2004-06-24 18:25                             ` Andrew Cagney
  0 siblings, 0 replies; 19+ messages in thread
From: Andrew Cagney @ 2004-06-24 18:25 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

> Orjan Friberg wrote:
> 
>> Andrew Cagney wrote:
>>
>>>
>>> I also think this needs a new macro name that better reflects what the test is doing.  But I've no good ideas :-/ (SINGLE_STEP_THROUGH_DELAY (pc)?)
> 
> 
> I'm facing a slightly different situation than the MIPS case when implementing SINGLE_STEP_THROUGH_DELAY, because the size of the instruction that the delay slot belongs to may be 2, 4, or 6 bytes.  (For MIPS, it seems the size of that instruction is always 4 bytes.)
> 
> So, I have to find out the size of the preceding instruction (since I want to do the single-step thingy when we're stopped in the delay slot), but I can't find anything in the opcodes directory that would let me do that.
> 
> The thing is, this information (whether I'm in a delay slot, and the address of the instruction the delay slot belongs to) is available in a register.  Besides the fact that this triggers sending a 'g' packet to the remote target, is it wrong to deduce this information from the registers content rather than reading from the program's text segment?
> 
> Basically, my implementation would look like this:
> 
> int
> cris_single_step_through_delay (CORE_ADDR pc)
> {
>   ULONGEST erp;
>   int ret = 0;
>   regcache_cooked_read_unsigned (current_regcache, ERP_REGNUM, &erp);
>   if (erp & 0x1)
>     /* In delay slot - check if there's a breakpoint at the preceding
>        instruction.  */
>     if (breakpoint_here_p (erp & ~0x1))
>       ret = 1;
>   return ret;
> } 

Ah! (sorry for the delay).  Sounds like a "struct frame_info 
*this_frame" is the parameter you need then.  This will let it work for 
any frame (especially a frame interrupted by a signal handler).

Andrew



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-06-09 16:00                       ` Andrew Cagney
  2004-06-14 12:09                         ` Orjan Friberg
@ 2004-10-01 11:26                         ` Orjan Friberg
  2004-10-25 20:18                           ` Andrew Cagney
  1 sibling, 1 reply; 19+ messages in thread
From: Orjan Friberg @ 2004-10-01 11:26 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Andrew Cagney wrote:
> 
> Can a simple, separate, more explicit logic like:
>     if (we just did a step and STEP_SKIPS_DELAY (pc))
>       set up for another step
>       return;
> work?  The [handle_inferior_event patch snipped] was nested within other 
> logic and that's not good from a readability / maintainability point of 
> view.

Now that I've done a lot more testing, I'm picking this up again.  (Below is 
just the infrun.c part; gdbarch.sh obviously needs a patch, and mips-tdep.c 
needs to have its current STEP_SKIPS_DELAY implementation converted - I'll post 
a complete patch if this part is approved of.)

A few things:
* I'm not sure how to reliably detect the situation "stepping off a breakpoint" 
in handle_inferior_event.  I used stop_signal == TARGET_SIGNAL_TRAP && 
trap_expected && currently_stepping (ecs)); could that be too inclusive?.
* Distinguishing between "step" and "continue" (using step_range_end) is not 
necessary for it to work, but explicitly returning in the "continue" case is 
making things a bit clearer.
* As the comment suggests, in the "step" case we don't want to preclude the 
stop_after_trap check - I assume that whatever is in the delay slot could 
potentially correspond to a single line of code (if nothing else, then at least 
an asm("...") construct.)

Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.177
diff -u -r1.177 infrun.c
--- infrun.c    13 Sep 2004 18:26:28 -0000      1.177
+++ infrun.c    1 Oct 2004 11:22:42 -0000
@@ -721,17 +721,12 @@

        if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
         oneproc = 1;
-
-#ifndef STEP_SKIPS_DELAY
-#define STEP_SKIPS_DELAY(pc) (0)
-#define STEP_SKIPS_DELAY_P (0)
-#endif
-      /* Check breakpoint_here_p first, because breakpoint_here_p is fast
-         (it just checks internal GDB data structures) and STEP_SKIPS_DELAY
-         is slow (it needs to read memory from the target).  */
-      if (STEP_SKIPS_DELAY_P
-         && breakpoint_here_p (read_pc () + 4)
-         && STEP_SKIPS_DELAY (read_pc ()))
+
+      /* If we stepped into something that needs to be stepped again before
+        before re-inserting the breakpoint, then do so.  */
+      else if (gdbarch_single_step_through_delay_p (current_gdbarch)
+              && gdbarch_single_step_through_delay (current_gdbarch,
+                                                    get_current_frame ()))
         oneproc = 1;
      }
    else
@@ -1793,6 +1788,35 @@
    stopped_by_random_signal = 0;
    breakpoints_failed = 0;

+  if (gdbarch_single_step_through_delay_p (current_gdbarch)
+      && stop_signal == TARGET_SIGNAL_TRAP && trap_expected
+      && currently_stepping (ecs))
+    {
+      /* We are in the process of stepping off a breakpoint.  If we stepped
+        into something that needs to be stepped again before re-inserting
+        the breakpoint, then do so.  */
+      int step_through_delay
+       = gdbarch_single_step_through_delay (current_gdbarch,
+                                            get_current_frame ());
+      if (step_range_end == 0 && step_through_delay)
+       {
+         /* The user issued a continue when stopped at a breakpoint.
+            Set up for another trap and get out of here.  */
+         ecs->another_trap = 1;
+         keep_going (ecs);
+         return;
+       }
+      else if (step_through_delay)
+       {
+         /* The user issued a step when stopped at a breakpoint.
+            Maybe we should stop, maybe we should not - the delay slot
+            *might* correspond to a line of source.  In any case, don't decide
+            that here, just set ecs->another_trap, making sure we
+            single-step again before breakpoints are re-inserted.  */
+         ecs->another_trap = 1;
+       }
+    }
+
    /* Look at the cause of the stop, and decide what to do.
       The alternatives are:
       1) break; to really stop and return to the debugger,

-- 
Orjan Friberg
Axis Communications


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: STEP_SKIPS_DELAY question, sort of
  2004-10-01 11:26                         ` Orjan Friberg
@ 2004-10-25 20:18                           ` Andrew Cagney
  0 siblings, 0 replies; 19+ messages in thread
From: Andrew Cagney @ 2004-10-25 20:18 UTC (permalink / raw)
  To: Orjan Friberg; +Cc: gdb-patches

Sorry, picking up old threads.

Orjan Friberg wrote:
> Andrew Cagney wrote:
> 
>>
>> Can a simple, separate, more explicit logic like:
>>     if (we just did a step and STEP_SKIPS_DELAY (pc))
>>       set up for another step
>>       return;
>> work?  The [handle_inferior_event patch snipped] was nested within 
>> other logic and that's not good from a readability / maintainability 
>> point of view.
> 
> 
> Now that I've done a lot more testing, I'm picking this up again.  
> (Below is just the infrun.c part; gdbarch.sh obviously needs a patch, 
> and mips-tdep.c needs to have its current STEP_SKIPS_DELAY 
> implementation converted - I'll post a complete patch if this part is 
> approved of.)
> 
> A few things:
> * I'm not sure how to reliably detect the situation "stepping off a 
> breakpoint" in handle_inferior_event.  I used stop_signal == 
> TARGET_SIGNAL_TRAP && trap_expected && currently_stepping (ecs)); could 
> that be too inclusive?.

I think this is sufficient.  Can you add something mentioning "stepping 
off a breakpoint" to the comment - that makes the intent clear.

> * Distinguishing between "step" and "continue" (using step_range_end) is 
> not necessary for it to work, but explicitly returning in the "continue" 
> case is making things a bit clearer.

Always a good idea.

Andrew


> * As the comment suggests, in the "step" case we don't want to preclude 
> the stop_after_trap check - I assume that whatever is in the delay slot 
> could potentially correspond to a single line of code (if nothing else, 
> then at least an asm("...") construct.)
> 
> Index: infrun.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/infrun.c,v
> retrieving revision 1.177
> diff -u -r1.177 infrun.c
> --- infrun.c    13 Sep 2004 18:26:28 -0000      1.177
> +++ infrun.c    1 Oct 2004 11:22:42 -0000
> @@ -721,17 +721,12 @@
> 
>        if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
>         oneproc = 1;
> -
> -#ifndef STEP_SKIPS_DELAY
> -#define STEP_SKIPS_DELAY(pc) (0)
> -#define STEP_SKIPS_DELAY_P (0)
> -#endif
> -      /* Check breakpoint_here_p first, because breakpoint_here_p is fast
> -         (it just checks internal GDB data structures) and 
> STEP_SKIPS_DELAY
> -         is slow (it needs to read memory from the target).  */
> -      if (STEP_SKIPS_DELAY_P
> -         && breakpoint_here_p (read_pc () + 4)
> -         && STEP_SKIPS_DELAY (read_pc ()))
> +
> +      /* If we stepped into something that needs to be stepped again 
> before
> +        before re-inserting the breakpoint, then do so.  */
> +      else if (gdbarch_single_step_through_delay_p (current_gdbarch)
> +              && gdbarch_single_step_through_delay (current_gdbarch,
> +                                                    get_current_frame ()))
>         oneproc = 1;
>      }
>    else
> @@ -1793,6 +1788,35 @@
>    stopped_by_random_signal = 0;
>    breakpoints_failed = 0;
> 
> +  if (gdbarch_single_step_through_delay_p (current_gdbarch)
> +      && stop_signal == TARGET_SIGNAL_TRAP && trap_expected
> +      && currently_stepping (ecs))
> +    {
> +      /* We are in the process of stepping off a breakpoint.  If we 
> stepped
> +        into something that needs to be stepped again before re-inserting
> +        the breakpoint, then do so.  */
> +      int step_through_delay
> +       = gdbarch_single_step_through_delay (current_gdbarch,
> +                                            get_current_frame ());
> +      if (step_range_end == 0 && step_through_delay)
> +       {
> +         /* The user issued a continue when stopped at a breakpoint.
> +            Set up for another trap and get out of here.  */
> +         ecs->another_trap = 1;
> +         keep_going (ecs);
> +         return;
> +       }
> +      else if (step_through_delay)
> +       {
> +         /* The user issued a step when stopped at a breakpoint.
> +            Maybe we should stop, maybe we should not - the delay slot
> +            *might* correspond to a line of source.  In any case, don't 
> decide
> +            that here, just set ecs->another_trap, making sure we
> +            single-step again before breakpoints are re-inserted.  */
> +         ecs->another_trap = 1;
> +       }
> +    }
> +
>    /* Look at the cause of the stop, and decide what to do.
>       The alternatives are:
>       1) break; to really stop and return to the debugger,
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2004-10-25 20:18 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-21 17:14 STEP_SKIPS_DELAY question, sort of Orjan Friberg
2004-05-21 20:25 ` Andrew Cagney
2004-05-24  9:15   ` Orjan Friberg
2004-05-24 18:15     ` Andrew Cagney
2004-05-25 11:53       ` Orjan Friberg
2004-05-25 21:14         ` Andrew Cagney
2004-05-26  9:39           ` Orjan Friberg
2004-05-26 17:39             ` Andrew Cagney
2004-06-07 12:12             ` Orjan Friberg
2004-06-07 12:42               ` Orjan Friberg
2004-06-07 13:09                 ` Orjan Friberg
2004-06-07 15:08                   ` Andrew Cagney
2004-06-09  9:48                     ` Orjan Friberg
2004-06-09 16:00                       ` Andrew Cagney
2004-06-14 12:09                         ` Orjan Friberg
2004-06-16 14:53                           ` Orjan Friberg
2004-06-24 18:25                             ` Andrew Cagney
2004-10-01 11:26                         ` Orjan Friberg
2004-10-25 20:18                           ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox