public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* [RFC] Change displayed line when execution direction is reversed
@ 2022-06-15 12:25 Bruno Larsen
  2022-06-15 12:34 ` Christian Biesinger
  2022-06-17 12:07 ` Pedro Alves
  0 siblings, 2 replies; 10+ messages in thread
From: Bruno Larsen @ 2022-06-15 12:25 UTC (permalink / raw)
  To: gdb

Hello all,

I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?

Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
-- 
Cheers!
Bruno Larsen


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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-15 12:25 [RFC] Change displayed line when execution direction is reversed Bruno Larsen
@ 2022-06-15 12:34 ` Christian Biesinger
  2022-06-15 12:39   ` Bruno Larsen
  2022-06-17 12:07 ` Pedro Alves
  1 sibling, 1 reply; 10+ messages in thread
From: Christian Biesinger @ 2022-06-15 12:34 UTC (permalink / raw)
  To: Bruno Larsen; +Cc: Reuben Thomas via Gdb

My personal opinion:
In general, the state of the program when gdb is stopped is the state
at the start of the displayed line (I concede that it gets more
complicated when "step"ping)
This change would make it so the state is the state at the end of the
displayed line.

I think that could be confusing? Perhaps could be mitigated by
printing a message explaining that in some way.

Christian

On Wed, Jun 15, 2022 at 8:26 AM Bruno Larsen via Gdb <gdb@sourceware.org> wrote:
>
> Hello all,
>
> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
>
> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
> --
> Cheers!
> Bruno Larsen
>

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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-15 12:34 ` Christian Biesinger
@ 2022-06-15 12:39   ` Bruno Larsen
  2022-06-15 12:47     ` Christian Biesinger
  0 siblings, 1 reply; 10+ messages in thread
From: Bruno Larsen @ 2022-06-15 12:39 UTC (permalink / raw)
  To: Christian Biesinger; +Cc: Reuben Thomas via Gdb

It would only happen if the user explicitly used the command `set exec-direction reverse`. If the previous line was printed right after this command is run, I imagine the user would understand what is going on through context. That said, I'm open to suggestions on other messages or documentations of the feature to avoid confusion.

Cheers!
Bruno Larsen

On 6/15/22 09:34, Christian Biesinger wrote:
> My personal opinion:
> In general, the state of the program when gdb is stopped is the state
> at the start of the displayed line (I concede that it gets more
> complicated when "step"ping)
> This change would make it so the state is the state at the end of the
> displayed line.
> 
> I think that could be confusing? Perhaps could be mitigated by
> printing a message explaining that in some way.
> 
> Christian
> 
> On Wed, Jun 15, 2022 at 8:26 AM Bruno Larsen via Gdb <gdb@sourceware.org> wrote:
>>
>> Hello all,
>>
>> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
>>
>> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
>> --
>> Cheers!
>> Bruno Larsen
>>
> 


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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-15 12:39   ` Bruno Larsen
@ 2022-06-15 12:47     ` Christian Biesinger
  2022-06-15 12:49       ` Bruno Larsen
  0 siblings, 1 reply; 10+ messages in thread
From: Christian Biesinger @ 2022-06-15 12:47 UTC (permalink / raw)
  To: Bruno Larsen; +Cc: Reuben Thomas via Gdb

Sorry, just to clarify, you are not suggesting a change when using
"reverse-next" without "set exec-direction reverse"?

Christian

On Wed, Jun 15, 2022 at 8:39 AM Bruno Larsen <blarsen@redhat.com> wrote:
>
> It would only happen if the user explicitly used the command `set exec-direction reverse`. If the previous line was printed right after this command is run, I imagine the user would understand what is going on through context. That said, I'm open to suggestions on other messages or documentations of the feature to avoid confusion.
>
> Cheers!
> Bruno Larsen
>
> On 6/15/22 09:34, Christian Biesinger wrote:
> > My personal opinion:
> > In general, the state of the program when gdb is stopped is the state
> > at the start of the displayed line (I concede that it gets more
> > complicated when "step"ping)
> > This change would make it so the state is the state at the end of the
> > displayed line.
> >
> > I think that could be confusing? Perhaps could be mitigated by
> > printing a message explaining that in some way.
> >
> > Christian
> >
> > On Wed, Jun 15, 2022 at 8:26 AM Bruno Larsen via Gdb <gdb@sourceware.org> wrote:
> >>
> >> Hello all,
> >>
> >> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
> >>
> >> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
> >> --
> >> Cheers!
> >> Bruno Larsen
> >>
> >
>

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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-15 12:47     ` Christian Biesinger
@ 2022-06-15 12:49       ` Bruno Larsen
  2022-06-15 12:57         ` Christian Biesinger
  0 siblings, 1 reply; 10+ messages in thread
From: Bruno Larsen @ 2022-06-15 12:49 UTC (permalink / raw)
  To: Christian Biesinger; +Cc: Reuben Thomas via Gdb

You are correct. I would only want to print differently when the user explicitly changes the direction. Otherwise it would get confusing very quickly, as you mentioned.

Cheers!
Bruno Larsen

On 6/15/22 09:47, Christian Biesinger wrote:
> Sorry, just to clarify, you are not suggesting a change when using
> "reverse-next" without "set exec-direction reverse"?
> 
> Christian
> 
> On Wed, Jun 15, 2022 at 8:39 AM Bruno Larsen <blarsen@redhat.com> wrote:
>>
>> It would only happen if the user explicitly used the command `set exec-direction reverse`. If the previous line was printed right after this command is run, I imagine the user would understand what is going on through context. That said, I'm open to suggestions on other messages or documentations of the feature to avoid confusion.
>>
>> Cheers!
>> Bruno Larsen
>>
>> On 6/15/22 09:34, Christian Biesinger wrote:
>>> My personal opinion:
>>> In general, the state of the program when gdb is stopped is the state
>>> at the start of the displayed line (I concede that it gets more
>>> complicated when "step"ping)
>>> This change would make it so the state is the state at the end of the
>>> displayed line.
>>>
>>> I think that could be confusing? Perhaps could be mitigated by
>>> printing a message explaining that in some way.
>>>
>>> Christian
>>>
>>> On Wed, Jun 15, 2022 at 8:26 AM Bruno Larsen via Gdb <gdb@sourceware.org> wrote:
>>>>
>>>> Hello all,
>>>>
>>>> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
>>>>
>>>> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
>>>> --
>>>> Cheers!
>>>> Bruno Larsen
>>>>
>>>
>>
> 


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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-15 12:49       ` Bruno Larsen
@ 2022-06-15 12:57         ` Christian Biesinger
  0 siblings, 0 replies; 10+ messages in thread
From: Christian Biesinger @ 2022-06-15 12:57 UTC (permalink / raw)
  To: Bruno Larsen; +Cc: Reuben Thomas via Gdb

In that case I think this change makes a lot of sense!

(I was not aware of that option until just now, heh)

Christian

On Wed, Jun 15, 2022 at 8:50 AM Bruno Larsen <blarsen@redhat.com> wrote:
>
> You are correct. I would only want to print differently when the user explicitly changes the direction. Otherwise it would get confusing very quickly, as you mentioned.
>
> Cheers!
> Bruno Larsen
>
> On 6/15/22 09:47, Christian Biesinger wrote:
> > Sorry, just to clarify, you are not suggesting a change when using
> > "reverse-next" without "set exec-direction reverse"?
> >
> > Christian
> >
> > On Wed, Jun 15, 2022 at 8:39 AM Bruno Larsen <blarsen@redhat.com> wrote:
> >>
> >> It would only happen if the user explicitly used the command `set exec-direction reverse`. If the previous line was printed right after this command is run, I imagine the user would understand what is going on through context. That said, I'm open to suggestions on other messages or documentations of the feature to avoid confusion.
> >>
> >> Cheers!
> >> Bruno Larsen
> >>
> >> On 6/15/22 09:34, Christian Biesinger wrote:
> >>> My personal opinion:
> >>> In general, the state of the program when gdb is stopped is the state
> >>> at the start of the displayed line (I concede that it gets more
> >>> complicated when "step"ping)
> >>> This change would make it so the state is the state at the end of the
> >>> displayed line.
> >>>
> >>> I think that could be confusing? Perhaps could be mitigated by
> >>> printing a message explaining that in some way.
> >>>
> >>> Christian
> >>>
> >>> On Wed, Jun 15, 2022 at 8:26 AM Bruno Larsen via Gdb <gdb@sourceware.org> wrote:
> >>>>
> >>>> Hello all,
> >>>>
> >>>> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
> >>>>
> >>>> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
> >>>> --
> >>>> Cheers!
> >>>> Bruno Larsen
> >>>>
> >>>
> >>
> >
>

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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-15 12:25 [RFC] Change displayed line when execution direction is reversed Bruno Larsen
  2022-06-15 12:34 ` Christian Biesinger
@ 2022-06-17 12:07 ` Pedro Alves
  2022-06-17 13:03   ` Bruno Larsen
  1 sibling, 1 reply; 10+ messages in thread
From: Pedro Alves @ 2022-06-17 12:07 UTC (permalink / raw)
  To: Bruno Larsen, gdb

On 2022-06-15 13:25, Bruno Larsen via Gdb wrote:
> Hello all,
> 
> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
> 
> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.

How do you know which line that would be?  E.g.:

 if (foo)
   func ();
 else
   bar ();
 qux = 0; // stopped here.

Say you're stopped at the "stopped here" line, and flip execution direction to reverse.  Which line would gdb show as next line?


Also, showing a different line would result in the current PC (p $pc, info registers) etc. printing an
address for a line totally unrelated to the line that GDB is displaying, no?  Same for "break" with no
arguments, etc.  Worse, what happens when you print variables?  The block scope used is the one for the
current PC, while gdb would display a different source line as current line?

I don't see off hand how this can work.  Can you detail it?

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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-17 12:07 ` Pedro Alves
@ 2022-06-17 13:03   ` Bruno Larsen
  2022-06-17 13:44     ` Pedro Alves
  0 siblings, 1 reply; 10+ messages in thread
From: Bruno Larsen @ 2022-06-17 13:03 UTC (permalink / raw)
  To: Pedro Alves, gdb


On 6/17/22 09:07, Pedro Alves wrote:
> On 2022-06-15 13:25, Bruno Larsen via Gdb wrote:
>> Hello all,
>>
>> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
>>
>> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
> 
> How do you know which line that would be?  E.g.:
> 
>   if (foo)
>     func ();
>   else
>     bar ();
>   qux = 0; // stopped here.
> 
> Say you're stopped at the "stopped here" line, and flip execution direction to reverse.  Which line would gdb show as next line?

I'm not sure of the how yet, but the plan would be to show the correct line (in this case, if foo == true, show func (), otherwise show bar ()).

My first plan would be to add a way to query which PC should be used to calculate the line, so regular targets just return the current PC and
recorded targets can see the PC of the previous instruction, then use that to identify the source line. This system sounds easy enough in my head,
but without any testing I can't say for certain that it works (and with the current knowledge, it'd take me some time to test it), so if you can
think of problems this would have, or a better idea, I'm all ears!

> 
> 
> Also, showing a different line would result in the current PC (p $pc, info registers) etc. printing an
> address for a line totally unrelated to the line that GDB is displaying, no?  Same for "break" with no
> arguments, etc.  Worse, what happens when you print variables?  The block scope used is the one for the
> current PC, while gdb would display a different source line as current line?

Let me try and explain with an example GDB session. Say the program is:

   int main(){
     int x = 2;
     x += 2;
     x *= x;
     x /= 2;
     return 0;
   }

Currently, GDB does this:

(gdb) start
2           int x = 2;
(gdb) display x
1: x = 32767
(gdb) n
3           x += 2;
1: x = 2
(gdb)
4           x *= x;
1: x = 4
(gdb)
5           x /= 2;
1: x = 16
(gdb)
6           return 0;
1: x = 8
(gdb) set exec-direction reverse
(gdb) n
5           x /= 2;
1: x = 16
(gdb)
4           x *= x;
1: x = 4
(gdb)
3           x += 2;
1: x = 2

As we move forward, we see what the inferior will do next, and we see the value of x at the start of the line.
However, as soon as we move backwards, we are now seeing what we have just done, and the final result of having
done it, i.e. the state at the start of the line.

If my idea is implemented, the session would look like this

(gdb) start
2           int x = 2;
(gdb) display x
1: x = 32767
(gdb) n
3           x += 2;
1: x = 2
(gdb)
4           x *= x;
1: x = 4
(gdb)
5           x /= 2;
1: x = 16
(gdb)
6           return 0;
1: x = 8
(gdb) set exec-direction reverse
5           x /= 2;
(gdb) n
4           x *= x;
1: x = 16
(gdb)
3           x += 2;
1: x = 4
(gdb)
2           int x = 2;
1: x = 2

Now, going forward works the same, but going backwards, I see what the inferior will undo next (which is the opposite
operation than what is written), and I see the state of the inferior right before undoing the line. This would make
the most difference when showing a function call (so I know I need to "step" instead of "next) or when I will lose
state through an assignment operation.


The break with no arguments can cause some confusion if the user changes execution direction often.
To make things more clear, we could perhaps print

   Breakpoint 1 at 0x401186: file 16678.c, end of line 3.

instead of printing

   Breakpoint 1 at 0x401186: file 16678.c, line 4.

so that if the execution direction is reset to forward, the user isn't caught by surprise.

> 
> I don't see off hand how this can work.  Can you detail it?
> 

One final detail, just to make sure you are aware, this change would only apply when the user explicitly uses
"set exec-direction reverse". Nothing would change for "reverse-next" or similar.  Does this make more sense?


Cheers!
Bruno Larsen


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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-17 13:03   ` Bruno Larsen
@ 2022-06-17 13:44     ` Pedro Alves
  2022-06-17 19:35       ` Bruno Larsen
  0 siblings, 1 reply; 10+ messages in thread
From: Pedro Alves @ 2022-06-17 13:44 UTC (permalink / raw)
  To: Bruno Larsen, gdb

On 2022-06-17 14:03, Bruno Larsen wrote:
> 
> On 6/17/22 09:07, Pedro Alves wrote:
>> On 2022-06-15 13:25, Bruno Larsen via Gdb wrote:
>>> Hello all,
>>>
>>> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
>>>
>>> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
>>
>> How do you know which line that would be?  E.g.:
>>
>>   if (foo)
>>     func ();
>>   else
>>     bar ();
>>   qux = 0; // stopped here.
>>
>> Say you're stopped at the "stopped here" line, and flip execution direction to reverse.  Which line would gdb show as next line?
> 
> I'm not sure of the how yet, but the plan would be to show the correct line (in this case, if foo == true, show func (), otherwise show bar ()).
> 
> My first plan would be to add a way to query which PC should be used to calculate the line, so regular targets just return the current PC and
> recorded targets can see the PC of the previous instruction, then use that to identify the source line. 

But you don't even know whether the user will do "step" or "next", or "stepi".  What if the user does stepi, and the instruction we reverse
step to is still in the "stopped here" line?


> This system sounds easy enough in my head,
> but without any testing I can't say for certain that it works (and with the current knowledge, it'd take me some time to test it), so if you can
> think of problems this would have, or a better idea, I'm all ears!
> 

One problem is that there's no generic way to ask the target backend "if I reverse the instruction at the current PC, what would the
PC be?".  Remember that remote targets can also reverse execute themselves.

Another problem is that you don't need just the PC -- for printing the variables in scope you need to fully unwind the
whole state.


>>
>>
>> Also, showing a different line would result in the current PC (p $pc, info registers) etc. printing an
>> address for a line totally unrelated to the line that GDB is displaying, no?  Same for "break" with no
>> arguments, etc.  Worse, what happens when you print variables?  The block scope used is the one for the
>> current PC, while gdb would display a different source line as current line?
> 
> Let me try and explain with an example GDB session. Say the program is:
> 
>   int main(){
>     int x = 2;
>     x += 2;
>     x *= x;
>     x /= 2;
>     return 0;
>   }
> 
> Currently, GDB does this:
> 
> (gdb) start
> 2           int x = 2;
> (gdb) display x
> 1: x = 32767
> (gdb) n
> 3           x += 2;
> 1: x = 2
> (gdb)
> 4           x *= x;
> 1: x = 4
> (gdb)
> 5           x /= 2;
> 1: x = 16
> (gdb)
> 6           return 0;
> 1: x = 8
> (gdb) set exec-direction reverse
> (gdb) n
> 5           x /= 2;
> 1: x = 16
> (gdb)
> 4           x *= x;
> 1: x = 4
> (gdb)
> 3           x += 2;
> 1: x = 2
> 
> As we move forward, we see what the inferior will do next, and we see the value of x at the start of the line.
> However, as soon as we move backwards, we are now seeing what we have just done, and the final result of having
> done it, i.e. the state at the start of the line.
> 
> If my idea is implemented, the session would look like this
> 
> (gdb) start
> 2           int x = 2;
> (gdb) display x
> 1: x = 32767
> (gdb) n
> 3           x += 2;
> 1: x = 2
> (gdb)
> 4           x *= x;
> 1: x = 4
> (gdb)
> 5           x /= 2;
> 1: x = 16
> (gdb)
> 6           return 0;
> 1: x = 8
> (gdb) set exec-direction reverse
> 5           x /= 2;
> (gdb) n
> 4           x *= x;
> 1: x = 16
> (gdb)
> 3           x += 2;
> 1: x = 4
> (gdb)
> 2           int x = 2;
> 1: x = 2
> 
> Now, going forward works the same, but going backwards, I see what the inferior will undo next (which is the opposite
> operation than what is written), and I see the state of the inferior right before undoing the line. 

This is blatantly assuming that "what the inferior will undo next" is the effect of undoing one source line.  But
you have no way to knowing that.  The user may type "next 2", or "stepi" or some other execution command, breaking
the paradigm.  And what if you have multiple function calls in the same line?

> This would make
> the most difference when showing a function call (so I know I need to "step" instead of "next) or when I will lose
> state through an assignment operation.

You kind of cheated as your example doesn't have a function call.  :-)  Can you do a similar mock GDB
session for the example I pasted earlier?  Here again:

  if (foo)
    foo ();
  else
    bar ();
  qux = 0; // stopped here.

if stopped at the "stopped here" line, and you do "set execution-direction reverse", then would
gdb present the next line as the last line of ... (and I'm going to assume you could figure out
which branch would be taken and it would be the then branch), the foo() function's source code?
(as if you knew the user would do "step", or would you present the next line as line of
the "foo()" call, as if you knew the user would do "next" ?

> 
> 
> The break with no arguments can cause some confusion if the user changes execution direction often.
> To make things more clear, we could perhaps print
> 
>   Breakpoint 1 at 0x401186: file 16678.c, end of line 3.
> 
> instead of printing
> 
>   Breakpoint 1 at 0x401186: file 16678.c, line 4.
> 
> so that if the execution direction is reset to forward, the user isn't caught by surprise.
> 
>>
>> I don't see off hand how this can work.  Can you detail it?
>>
> 
> One final detail, just to make sure you are aware, this change would only apply when the user explicitly uses
> "set exec-direction reverse". Nothing would change for "reverse-next" or similar.  Does this make more sense?
> 

No, sorry.

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

* Re: [RFC] Change displayed line when execution direction is reversed
  2022-06-17 13:44     ` Pedro Alves
@ 2022-06-17 19:35       ` Bruno Larsen
  0 siblings, 0 replies; 10+ messages in thread
From: Bruno Larsen @ 2022-06-17 19:35 UTC (permalink / raw)
  To: Pedro Alves, gdb


On 6/17/22 10:44, Pedro Alves wrote:
> On 2022-06-17 14:03, Bruno Larsen wrote:
>>
>> On 6/17/22 09:07, Pedro Alves wrote:
>>> On 2022-06-15 13:25, Bruno Larsen via Gdb wrote:
>>>> Hello all,
>>>>
>>>> I was doing some reverse debugging and noticed that setting the execution direction to reverse does not change how GDB displays lines. The problem with this is that the user doesn't see what will be executed if a step is taken, which makes the user experience quite annoying. How would the community feel if GDB printed the previous line, instead of current line, when the execution direction is reversed?
>>>>
>>>> Sorry if this is the wrong list. It didn't feel like a bug, and I don't have a patch yet, so this felt like the best place to send.
>>>
>>> How do you know which line that would be?  E.g.:
>>>
>>>    if (foo)
>>>      func ();
>>>    else
>>>      bar ();
>>>    qux = 0; // stopped here.
>>>
>>> Say you're stopped at the "stopped here" line, and flip execution direction to reverse.  Which line would gdb show as next line?
>>
>> I'm not sure of the how yet, but the plan would be to show the correct line (in this case, if foo == true, show func (), otherwise show bar ()).
>>
>> My first plan would be to add a way to query which PC should be used to calculate the line, so regular targets just return the current PC and
>> recorded targets can see the PC of the previous instruction, then use that to identify the source line.
> 
> But you don't even know whether the user will do "step" or "next", or "stepi".  What if the user does stepi, and the instruction we reverse
> step to is still in the "stopped here" line?

Well, we could see if we are stopped at the start of an address range, and if so, we print the "previously executed" range (more
deliberation below), if not we print the current range. This way, GDB will always undo something expected, and it sort of assumes
the next instruction will be the the same as the previous one.

> 
> 
>> This system sounds easy enough in my head,
>> but without any testing I can't say for certain that it works (and with the current knowledge, it'd take me some time to test it), so if you can
>> think of problems this would have, or a better idea, I'm all ears!
>>
> 
> One problem is that there's no generic way to ask the target backend "if I reverse the instruction at the current PC, what would the
> PC be?".  Remember that remote targets can also reverse execute themselves.

Yeah, this is a wrench in my simple plan, I might need to give some more thought about the actual implementation.

> 
> Another problem is that you don't need just the PC -- for printing the variables in scope you need to fully unwind the
> whole state.

It really shouldn't be any different. we'd want to print the same variables as if we were printing the "correct" line, which is to say
how currently local variables look.
> 
> 
>>>
>>>
>>> Also, showing a different line would result in the current PC (p $pc, info registers) etc. printing an
>>> address for a line totally unrelated to the line that GDB is displaying, no?  Same for "break" with no
>>> arguments, etc.  Worse, what happens when you print variables?  The block scope used is the one for the
>>> current PC, while gdb would display a different source line as current line?
>>
>> Let me try and explain with an example GDB session. Say the program is:
>>
>>    int main(){
>>      int x = 2;
>>      x += 2;
>>      x *= x;
>>      x /= 2;
>>      return 0;
>>    }
>>
>> Currently, GDB does this:
>>
>> (gdb) start
>> 2           int x = 2;
>> (gdb) display x
>> 1: x = 32767
>> (gdb) n
>> 3           x += 2;
>> 1: x = 2
>> (gdb)
>> 4           x *= x;
>> 1: x = 4
>> (gdb)
>> 5           x /= 2;
>> 1: x = 16
>> (gdb)
>> 6           return 0;
>> 1: x = 8
>> (gdb) set exec-direction reverse
>> (gdb) n
>> 5           x /= 2;
>> 1: x = 16
>> (gdb)
>> 4           x *= x;
>> 1: x = 4
>> (gdb)
>> 3           x += 2;
>> 1: x = 2
>>
>> As we move forward, we see what the inferior will do next, and we see the value of x at the start of the line.
>> However, as soon as we move backwards, we are now seeing what we have just done, and the final result of having
>> done it, i.e. the state at the start of the line.
>>
>> If my idea is implemented, the session would look like this
>>
>> (gdb) start
>> 2           int x = 2;
>> (gdb) display x
>> 1: x = 32767
>> (gdb) n
>> 3           x += 2;
>> 1: x = 2
>> (gdb)
>> 4           x *= x;
>> 1: x = 4
>> (gdb)
>> 5           x /= 2;
>> 1: x = 16
>> (gdb)
>> 6           return 0;
>> 1: x = 8
>> (gdb) set exec-direction reverse
>> 5           x /= 2;
>> (gdb) n
>> 4           x *= x;
>> 1: x = 16
>> (gdb)
>> 3           x += 2;
>> 1: x = 4
>> (gdb)
>> 2           int x = 2;
>> 1: x = 2
>>
>> Now, going forward works the same, but going backwards, I see what the inferior will undo next (which is the opposite
>> operation than what is written), and I see the state of the inferior right before undoing the line.
> 
> This is blatantly assuming that "what the inferior will undo next" is the effect of undoing one source line.  But
> you have no way to knowing that.  The user may type "next 2", or "stepi" or some other execution command, breaking
> the paradigm.

It's the same paradigm that GDB uses for forward stepping, though. currently we see what the inferior will do next,
but if the user uses "next 2" or "stepi", the exact execution doesn't match what was shown.  Maybe the paradign can be
described better as Executing in reverse should behave similarly to executing forward

And also, while this new paradigm isn't bulletproof, it would be better than seeing what the inferior has just done
so we can next forward to reverse step into the function we missed, or need to constantly check the source code to
follow along.

>                And what if you have multiple function calls in the same line?

GDB already has some troubles with this, if we go by gdb.base/skip.exp, maybe jumping back to main on some occasions
and the degenerate clang case of jumping straight into a different function after a return statement.

Ideally, we'd want to print that a function call will happen, if the user "step"s, we go into it, and stepping out
will show the multiple functions again.

> 
>> This would make
>> the most difference when showing a function call (so I know I need to "step" instead of "next) or when I will lose
>> state through an assignment operation.
> 
> You kind of cheated as your example doesn't have a function call.  :-)  Can you do a similar mock GDB
> session for the example I pasted earlier?  Here again:

Ah yes, the old flaw of "works in my head" and me forgetting that I can't send it on an e-mail.

> 
>    if (foo)
>      foo ();
>    else
>      bar ();
>    qux = 0; // stopped here.
> 
> if stopped at the "stopped here" line, and you do "set execution-direction reverse", then would
> gdb present the next line as the last line of ... (and I'm going to assume you could figure out
> which branch would be taken and it would be the then branch), the foo() function's source code?
> (as if you knew the user would do "step", or would you present the next line as line of
> the "foo()" call, as if you knew the user would do "next" ?

I would want it to print the function name, so "foo ()", because what the inferior will do next is entering that
function.  The user may now step into the function, as they would when executing forward. I know that getting this
information is not trivial, I would need to see how it could be done quicker, but a very naive system would be
using reverse next to get the PC and moving back to where you were.

I'm not suggesting doing this, but it should help understanding. I hope this makes sense now.


Cheers!
Bruno Larsen
> 
>>
>>
>> The break with no arguments can cause some confusion if the user changes execution direction often.
>> To make things more clear, we could perhaps print
>>
>>    Breakpoint 1 at 0x401186: file 16678.c, end of line 3.
>>
>> instead of printing
>>
>>    Breakpoint 1 at 0x401186: file 16678.c, line 4.
>>
>> so that if the execution direction is reset to forward, the user isn't caught by surprise.
>>
>>>
>>> I don't see off hand how this can work.  Can you detail it?
>>>
>>
>> One final detail, just to make sure you are aware, this change would only apply when the user explicitly uses
>> "set exec-direction reverse". Nothing would change for "reverse-next" or similar.  Does this make more sense?
>>
> 
> No, sorry.
> 


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

end of thread, other threads:[~2022-06-17 19:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-15 12:25 [RFC] Change displayed line when execution direction is reversed Bruno Larsen
2022-06-15 12:34 ` Christian Biesinger
2022-06-15 12:39   ` Bruno Larsen
2022-06-15 12:47     ` Christian Biesinger
2022-06-15 12:49       ` Bruno Larsen
2022-06-15 12:57         ` Christian Biesinger
2022-06-17 12:07 ` Pedro Alves
2022-06-17 13:03   ` Bruno Larsen
2022-06-17 13:44     ` Pedro Alves
2022-06-17 19:35       ` Bruno Larsen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).