Re: [PATCH 1/2 version 3] fix for gdb.reverse/finish-precsave.exp and gdb.reverse/finish-reverse.exp

Ulrich Weigand via Gdb-patches
2023-01-25T14:12:08Z

Pedro Alves <pedro@palves.net> wrote:

> > 11 func1 (argc); func2 (argc);
> > 0x000055555555515f <+15>: mov -0x4(%rbp),%edi
> > 0x0000555555555162 <+18>: call 0x555555555130 <func1>
> > 0x0000555555555167 <+23>: mov -0x4(%rbp),%edi
> > => 0x000055555555516a <+26>: call 0x555555555140 <func2>
> >
> > 12 }
> > 0x000055555555516f <+31>: xor %eax,%eax
> > 0x0000555555555171 <+33>: add $0x10,%rsp
> > 0x0000555555555175 <+37>: pop %rbp
> > 0x0000555555555176 <+38>: ret
> > End of assembler dump.
> > (gdb) reverse-step
> > func1 (i=1) at reverse.c:3
> > 3 }
> > (gdb)
> >
> >We can see that GDB stopped on the call instruction instead. So a user that finished from func1 or reverse-finished from func2 may see different inferior states.

>Seeing different inferior states is expected, as finish and reverse-finish are not the exact mirror of one another, like step
>and reverse-step are. The exact reversal of finish would be the equivalent of being stopped at a function call return insn after
>a "finish" (and the command could only be used while stopped there), and stepping back into the function up until the point
>where you had typed "finish" and stopping there. Obviously impossible to implement. So we made "reverse-finish" do something
>sensible, such as stepping backwards up until the call site.

Hi Pedro,

I certainly agree with you that reverse-step needs to be fixed,
and this explains at least part of the problems we were seeing.

However, I do think there is still another issue specific to
reverse-finish, along the lines Bruno pointed out. And in fact,
I do think that there is (or at least should be!) a well-defined
symmetry between finish and reverse-finish:

The effect of "finish" is: skip until the end of the current
function and then do a "step". (Semantically equivalently,
do a series of "next" until you leave the current function.)

Similarly, the effect of "reverse-finish" *should* be: reverse-skip
until the beginning of the current function and then do a reverse-step.
(Or semantically equivalent, do a series of "reverse-next" until you
leave the current function.)

However, the actual implementation of reverse-finish is subtly but
significantly different: it reverse-skips until the beginning of the
current function and then does a reverse-stepi (not reverse-step).

This has the at least surprising, but IMO even incorrect, effect
that when on the first line of a function, "reverse-finish" ends
up in a different place than "reverse-step". I believe they
ought to end up in the same place.

This was one of the primary intentions behind Carl's patch: change
reverse-finish so it does a reverse-step instead of a reverse-stepi.
(Of course, for this to be useful, reverse-step itself needs to work
correctly - which it doesn't right now as you point out.)

Bye,
Ulrich