This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [discuss] Support for reverse-execution


Eli Zaretskii wrote:

What I have done is add a new variable, step_direction, that can either
be STEP_DIR_FORWARD or STEP_DIR_REVERSE.

I'd prefer STEP_FORWARD and STEP_BACKWARD.

Ok.


To implement "rnext" I had to add a new target-specific function that
tries to figure out the address of the call instruction based on the
last executed instruction and the instruction to be executed, IF the
current instruction can be identified as a return insn.
Sorry, I'm confused. Isn't it right that if I'm stepping backwards
through code such as this:


    i += 1;
    foo (i);
  =>i = 0;

where "=>" shows the current source line, then typing `rnext' once
will get me to this:

    i += 1;
  =>foo (i);
    i = 0;

which means I'm now before the CALL insn that calls `foo'?  If so,
what ``return insn'' were you talking about?  If it's the return
instruction that returns from `foo', then that insn is inside the code
generatedfor `foo', which GDB won't see.  What am I missing?

When you're single stepping backwards you can end up almost anywhere in the code. Take this scenario (in pseudo-PPC-assembler):

(1)  foo (i);
     0:   80 7f 00 08     lwz     r3,8(r31)
     4:   48 00 00 01     bl      X <foo>
     8:                   nop
(2)  i = 0;
     c:   38 00 00 00     li      r0,0
    10:   90 1f 00 08     stw     r0,8(r31)

<foo>:
    ....
    4c:   4e 80 00 20     blr

You start with PC = c, and single steps backwards.  You end up on
the nop-insn.  This is inside the single step range of line 1. So
you single step another instruction backwards, and suddenly you
stop at PC = 4c, which is far outside the stepping range.  To detect
if this was due to a "return from subroutine" you inspect the current
instruction, blr, and if it happens to be return insn you can deduct
the address of the call insn that called "foo". Since PowerPC does
not have any delay slots, it's "safe" to assume that the insn _before_
the LAST stop_pc (== prev_pc) is the call insn.

So to skip the subroutine call, you set a breakpoint on 0x4
(prev_pc - 4 = 8 - 4 = 4) and do a reverse-continue.  When the
breakpoint hits, you continue stepping until you reach the start
of the stepping range.


+  add_com ("rnext", class_run, rnext_command,
+           "Step program until it reaches the previous source line.\n\

"Go backwards until the program reaches the source line before the current one."

Ok.



+ add_com_alias ("rn", "rnext", class_run, 1);

Do we want another alias called "previous"?

I think so, and maybe also "prev" and/or "pre".


+extern enum step_direction_kind step_direction;

Yuk! a global variable!

I though it was OK since other variables in this context are global, such as step_range_start and step_frame_id.

+ if (step_direction == STEP_DIR_FORWARD)
+ target_resume (resume_ptid, step, sig);
+ else
+ {
+ target_reverse (resume_ptid, step);
+ }

I'd prefer that target_resume accepted the direction argument. Is there something that I'm missing that makes this hard or impossible?

I don't think so. You just need to update more targets, though.


~j


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]