* [RFC] reverse-step, reverse-next
@ 2005-09-07 22:44 Michael Snyder
2005-09-08 21:41 ` Stan Shebs
2005-09-17 22:19 ` Daniel Jacobowitz
0 siblings, 2 replies; 4+ messages in thread
From: Michael Snyder @ 2005-09-07 22:44 UTC (permalink / raw)
To: GDB Patches; +Cc: jrydberg
This isn't for submission, just for discussion. This is something
that Johan Rydberg (of Virtutech) and I have been working on.
I'd like to hear what everybody thinks about this
bit of infrun implementation for the reverse debugging
that we discussed a few months ago.
This part is enough to get step and next to work in reverse,
based solely on the assumption that the backend (or someone)
provides an interface "get_exec_direction ()", which returns
forward or reverse. It's also assumed that the backend will
know which direction to go (leaving user-interface issues
out of the picture). One can imagine either a "set direction"
interface, or a "reverse-step/reverse-continue".
This is actually tested and working with the Simics simulator.
It steps and nexts backwards like a champ.
The only other bit of explanation that might be required
is that "NO_HISTORY" means you were going backward and
the target ran out of state data (you reached the beginning
of time).
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.178
diff -p -r1.178 infrun.c
*** infrun.c 27 Sep 2004 17:58:08 -0000 1.178
--- infrun.c 5 Sep 2005 00:38:53 -0000
*************** enum inferior_stop_reason
*** 897,903 ****
/* Inferior exited. */
EXITED,
/* Inferior received signal, and user asked to be notified. */
! SIGNAL_RECEIVED
};
/* This structure contains what used to be local variables in
--- 897,905 ----
/* Inferior exited. */
EXITED,
/* Inferior received signal, and user asked to be notified. */
! SIGNAL_RECEIVED,
! /* Reverse execution -- target ran out of history (FIXME: general?) */
! NO_HISTORY
};
/* This structure contains what used to be local variables in
*************** handle_inferior_event (struct execution_
*** 1516,1521 ****
--- 1518,1528 ----
stop_signal = ecs->ws.value.sig;
break;
+ case TARGET_WAITKIND_NO_HISTORY:
+ print_stop_reason (NO_HISTORY, 0);
+ stop_stepping (ecs);
+ return;
+
/* We had an event in the inferior, but we are not interested
in handling it at this level. The lower layers have already
done what needs to be done, if anything.
*************** process_event_stop_test:
*** 2073,2078 ****
--- 2080,2096 ----
keep_going (ecs);
return;
}
+ if (stop_pc == ecs->stop_func_start &&
+ get_exec_direction () == EXEC_REVERSE)
+ {
+ /* We are stepping over a function call in reverse, and
+ just hit the step-resume breakpoint at the start
+ address of the function. Go back to single-stepping,
+ which should take us back to the function call. */
+ ecs->another_trap = 1;
+ keep_going (ecs);
+ return;
+ }
break;
case BPSTAT_WHAT_THROUGH_SIGTRAMP:
*************** process_event_stop_test:
*** 2237,2243 ****
within it! */
if (stop_pc >= step_range_start && stop_pc < step_range_end)
{
! keep_going (ecs);
return;
}
--- 2255,2272 ----
within it! */
if (stop_pc >= step_range_start && stop_pc < step_range_end)
{
! if (stop_pc == step_range_start &&
! get_exec_direction () == EXEC_REVERSE)
! {
! /* When stepping backward, stop at beginning of line range. */
! stop_step = 1;
! print_stop_reason (END_STEPPING_RANGE, 0);
! stop_stepping (ecs);
! }
! else
! {
! keep_going (ecs);
! }
return;
}
*************** process_event_stop_test:
*** 2319,2335 ****
/* We're doing a "next", set a breakpoint at callee's return
address (the address at which the caller will
resume). */
! insert_step_resume_breakpoint_at_frame (get_prev_frame
(get_current_f\rame ()));
keep_going (ecs);
return;
}
#endif
if (step_over_calls == STEP_OVER_ALL)
{
! /* We're doing a "next", set a breakpoint at callee's return
! address (the address at which the caller will
! resume). */
! insert_step_resume_breakpoint_at_frame (get_prev_frame
(get_current_f\rame ()));
keep_going (ecs);
return;
}
--- 2348,2388 ----
/* We're doing a "next", set a breakpoint at callee's return
address (the address at which the caller will
resume). */
! insert_step_resume_breakpoint_at_frame
! (get_prev_frame (get_current_frame ()));
keep_going (ecs);
return;
}
#endif
if (step_over_calls == STEP_OVER_ALL)
{
! /* We're doing a "next".
!
! Normal (forward) execution: set a breakpoint at the
! callee's return address (the address at which the caller
! will resume).
!
! Reverse (backward) execution. set the step-resume
! breakpoint at the start of the function that we just
! stepped into (backwards), and continue to there. When we
! get there, we'll need to single-step back to the
! caller. */
!
! if (get_exec_direction () == EXEC_FORWARD)
! {
! insert_step_resume_breakpoint_at_frame
! (get_prev_frame (get_current_frame ()));
! }
! else
! {
! /* FIXME: I'm not sure if we've handled the frame for
! recursion. */
!
!
! struct symtab_and_line sr_sal;
! init_sal (&sr_sal);
! sr_sal.pc = ecs->stop_func_start;
! insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
! }
keep_going (ecs);
return;
}
*************** process_event_stop_test:
*** 2384,2392 ****
return;
}
! /* Set a breakpoint at callee's return address (the address at
! which the caller will resume). */
! insert_step_resume_breakpoint_at_frame (get_prev_frame
(get_current_fra\me ()));
keep_going (ecs);
return;
}
--- 2437,2459 ----
return;
}
! if (get_exec_direction () == EXEC_FORWARD)
! {
! /* Set a breakpoint at callee's return address (the address
! at which the caller will resume). */
! insert_step_resume_breakpoint_at_frame
! (get_prev_frame (get_current_frame ()));
! }
! else
! {
! /* Set a breakpoint at callee's start address.
! From there we can step once and be back in the caller. */
! /* FIXME: I'm not sure we've handled the frame for recursion. */
! struct symtab_and_line sr_sal;
! init_sal (&sr_sal);
! sr_sal.pc = ecs->stop_func_start;
! insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
! }
keep_going (ecs);
return;
}
*************** step_into_function (struct execution_con
*** 2568,2574 ****
--- 2635,2668 ----
if (s && s->language != language_asm)
ecs->stop_func_start = SKIP_PROLOGUE (ecs->stop_func_start);
+ /* If we're going backward, we just stepped into the
+ return of a function. Instead of continuing thru
+ the prologue, we want to continue back thru the epilogue. */
+ /* FIXME: Should we just split this out into a separate fn? */
+ if (get_exec_direction () == EXEC_REVERSE)
+ {
+ ecs->sal = find_pc_line (stop_pc, 0);
+
+ /* OK, we're just gonna keep stepping here. */
+ if (ecs->sal.pc == stop_pc)
+ {
+ /* We're there already. Just stop stepping now. */
+ stop_step = 1;
+ print_stop_reason (END_STEPPING_RANGE, 0);
+ stop_stepping (ecs);
+ return;
+ }
+ /* Else just reset the step range and keep going.
+ No step-resume breakpoint, they don't work for
+ epilogues, which can have multiple entry paths. */
+ step_range_start = ecs->sal.pc;
+ step_range_end = ecs->sal.end;
+ keep_going (ecs);
+ return;
+ }
+ /* else... */
ecs->sal = find_pc_line (ecs->stop_func_start, 0);
+
/* Use the step_resume_break to step until the end of the prologue,
even if that involves jumps (as it seems to on the vax under
4.2). */
*************** step_into_function (struct execution_con
*** 2615,2620 ****
--- 2709,2715 ----
{
/* Put the step-breakpoint there and go until there. */
init_sal (&sr_sal); /* initialize to zeroes */
+
sr_sal.pc = ecs->stop_func_start;
sr_sal.section = find_pc_overlay (ecs->stop_func_start);
*************** print_stop_reason (enum inferior_stop_re
*** 2855,2860 ****
annotate_signal_string_end ();
ui_out_text (uiout, ".\n");
break;
+ case NO_HISTORY:
+ /* Reverse execution: target ran out of history data. */
+ ui_out_text (uiout, "\nNo more reverse-execution history.\n");
+ break;
default:
internal_error (__FILE__, __LINE__,
"print_stop_reason: unrecognized enum value");
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] reverse-step, reverse-next
2005-09-07 22:44 [RFC] reverse-step, reverse-next Michael Snyder
@ 2005-09-08 21:41 ` Stan Shebs
2005-09-09 22:39 ` Michael Snyder
2005-09-17 22:19 ` Daniel Jacobowitz
1 sibling, 1 reply; 4+ messages in thread
From: Stan Shebs @ 2005-09-08 21:41 UTC (permalink / raw)
To: Michael Snyder; +Cc: GDB Patches, jrydberg
Michael Snyder wrote:
> This isn't for submission, just for discussion. This is something
> that Johan Rydberg (of Virtutech) and I have been working on.
>
> I'd like to hear what everybody thinks about this
> bit of infrun implementation for the reverse debugging
> that we discussed a few months ago.
>
Seems plausible to me. I've actually been experimenting with
a reverse execution prototype based on GDB managing all the
checkpoints, rather than pushing them down into the target as
Simics apparently does, and while GDB-managed checkpoints are
more powerful in some ways (random access to arbitrary states,
general undo), it's also looking rather more complicated.
> This part is enough to get step and next to work in reverse,
> based solely on the assumption that the backend (or someone)
> provides an interface "get_exec_direction ()", which returns
> forward or reverse. It's also assumed that the backend will
> know which direction to go (leaving user-interface issues
> out of the picture). One can imagine either a "set direction"
> interface, or a "reverse-step/reverse-continue".
Presumably there is a set_exec_direction, and both it and
get_exec_direction are target vector entries?
BTW, I have a little discussion of usage models for reverse
execution that I'm planning to post on Monday.
Stan
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] reverse-step, reverse-next
2005-09-08 21:41 ` Stan Shebs
@ 2005-09-09 22:39 ` Michael Snyder
0 siblings, 0 replies; 4+ messages in thread
From: Michael Snyder @ 2005-09-09 22:39 UTC (permalink / raw)
To: Stan Shebs; +Cc: GDB Patches, jrydberg
Stan Shebs wrote:
> Michael Snyder wrote:
>
>> This isn't for submission, just for discussion. This is something
>> that Johan Rydberg (of Virtutech) and I have been working on.
>>
>> I'd like to hear what everybody thinks about this
>> bit of infrun implementation for the reverse debugging
>> that we discussed a few months ago.
>>
> Seems plausible to me. I've actually been experimenting with
> a reverse execution prototype based on GDB managing all the
> checkpoints, rather than pushing them down into the target as
> Simics apparently does, and while GDB-managed checkpoints are
> more powerful in some ways (random access to arbitrary states,
> general undo), it's also looking rather more complicated.
Yeah, I consider this sort of abstract and modular.
My patch here makes no assumptions about how a backend
does reverse execution. The backend could, for instance,
call into a separate module such as yours that manages
checkpoints. Another backend might do it by direct request
to the target -- a la Simics.
>> This part is enough to get step and next to work in reverse,
>> based solely on the assumption that the backend (or someone)
>> provides an interface "get_exec_direction ()", which returns
>> forward or reverse. It's also assumed that the backend will
>> know which direction to go (leaving user-interface issues
>> out of the picture). One can imagine either a "set direction"
>> interface, or a "reverse-step/reverse-continue".
>
>
> Presumably there is a set_exec_direction,
Presumably. ;-)
> and both it and
> get_exec_direction are target vector entries?
For instance. But again, this infrun code makes no assumptions.
So that decision is orthogonal -- an implementation detail.
This code would be equally useful whether
(a) the direction was set by a modal "set direction" command,
or
(b) the direction was set by a "reverse-step" command.
> BTW, I have a little discussion of usage models for reverse
> execution that I'm planning to post on Monday.
Looking forward to it.
I, in turn, have a patch to implement "reverse-finish",
which I thought I'd post a little while after this one.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] reverse-step, reverse-next
2005-09-07 22:44 [RFC] reverse-step, reverse-next Michael Snyder
2005-09-08 21:41 ` Stan Shebs
@ 2005-09-17 22:19 ` Daniel Jacobowitz
1 sibling, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2005-09-17 22:19 UTC (permalink / raw)
To: Michael Snyder; +Cc: GDB Patches, jrydberg
On Wed, Sep 07, 2005 at 03:44:37PM -0700, Michael Snyder wrote:
> This isn't for submission, just for discussion. This is something
> that Johan Rydberg (of Virtutech) and I have been working on.
>
> I'd like to hear what everybody thinks about this
> bit of infrun implementation for the reverse debugging
> that we discussed a few months ago.
>
> This part is enough to get step and next to work in reverse,
> based solely on the assumption that the backend (or someone)
> provides an interface "get_exec_direction ()", which returns
> forward or reverse. It's also assumed that the backend will
> know which direction to go (leaving user-interface issues
> out of the picture). One can imagine either a "set direction"
> interface, or a "reverse-step/reverse-continue".
>
> This is actually tested and working with the Simics simulator.
> It steps and nexts backwards like a champ.
>
> The only other bit of explanation that might be required
> is that "NO_HISTORY" means you were going backward and
> the target ran out of state data (you reached the beginning
> of time).
The whole thing looks generally plausible to me, too.
My only comment is that all the twisty bits of infrun that you're
modifying are crying out in the night for someone to gut them and
replace them with something more legible. And hopefully to think about
backwards execution while doing that. But in the mean time, that's a
bit much to ask of anyone.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2005-09-17 22:19 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-07 22:44 [RFC] reverse-step, reverse-next Michael Snyder
2005-09-08 21:41 ` Stan Shebs
2005-09-09 22:39 ` Michael Snyder
2005-09-17 22:19 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox