* [RFA] Resubmit reverse debugging [5/5]
@ 2008-10-08 2:23 Michael Snyder
2008-10-08 18:15 ` Thiago Jung Bauermann
2008-10-17 19:48 ` Michael Snyder
0 siblings, 2 replies; 13+ messages in thread
From: Michael Snyder @ 2008-10-08 2:23 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 27 bytes --]
User interface plus docs.
[-- Attachment #2: reverse.txt --]
[-- Type: text/plain, Size: 13330 bytes --]
2008-10-07 Michael Snyder <msnyder@vmware.com>
User interface for reverse execution.
* Makefile.in (reverse.c): New file.
* reverse.c: New file. User interface for reverse execution.
2008-10-07 Michael Snyder <msnyder@vmware.com>
* doc/gdb.texinfo: Add documentation for reverse execution.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1052
diff -u -p -r1.1052 Makefile.in
--- Makefile.in 2 Oct 2008 17:39:08 -0000 1.1052
+++ Makefile.in 8 Oct 2008 01:35:12 -0000
@@ -514,7 +514,7 @@ ALL_TARGET_OBS = \
xcoffread.o \
prologue-value.o \
symfile-mem.o \
- corelow.o
+ corelow.o
# Host-dependent makefile fragment comes in here.
@host_makefile_frag@
@@ -639,7 +639,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
objfiles.c osabi.c observer.c \
p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
prologue-value.c \
- regcache.c reggroups.c remote.c remote-fileio.c \
+ regcache.c reggroups.c remote.c remote-fileio.c reverse.c \
scm-exp.c scm-lang.c scm-valprint.c \
sentinel-frame.c \
serial.c ser-base.c ser-unix.c \
@@ -778,7 +778,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
findcmd.o \
std-regs.o \
signals.o \
- exec.o bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
+ exec.o reverse.o \
+ bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
dbxread.o coffread.o coff-pe-read.o \
dwarf2read.o mipsread.o stabsread.o corefile.o \
dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
Index: reverse.c
===================================================================
RCS file: reverse.c
diff -N reverse.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ reverse.c 8 Oct 2008 01:35:12 -0000
@@ -0,0 +1,144 @@
+/* Reverse execution and reverse debugging.
+
+ Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "target.h"
+#include "top.h"
+#include "cli/cli-cmds.h"
+#include "cli/cli-decode.h"
+#include "inferior.h"
+
+/* User interface:
+ reverse-step, reverse-next etc. */
+
+static void exec_direction_default (void *notused)
+{
+ /* Return execution direction to default state. */
+ execution_direction = EXEC_FORWARD;
+}
+
+/* exec_reverse_once -- accepts an arbitrary gdb command (string),
+ and executes it with exec-direction set to 'reverse'.
+
+ Used to implement reverse-next etc. commands. */
+
+static void
+exec_reverse_once (char *cmd, char *args, int from_tty)
+{
+ /* String buffer for command consing. */
+ char reverse_command[512];
+ enum exec_direction_kind dir = execution_direction;
+ struct cleanup *old_chain;
+
+ if (dir == EXEC_ERROR)
+ error (_("Target %s does not support this command."), target_shortname);
+
+ if (dir == EXEC_REVERSE)
+ error (_("Already in reverse mode. Use '%s' or 'set exec-dir forward'."),
+ cmd);
+
+ if (!target_can_execute_reverse)
+ error (_("Target %s does not support this command."), target_shortname);
+
+ old_chain = make_cleanup (exec_direction_default, NULL);
+ sprintf (reverse_command, "%s %s", cmd, args ? args : "");
+
+ execution_direction = EXEC_REVERSE;
+ execute_command (reverse_command, from_tty);
+ do_cleanups (old_chain);
+}
+
+static void
+reverse_step (char *args, int from_tty)
+{
+ exec_reverse_once ("step", args, from_tty);
+}
+
+static void
+reverse_stepi (char *args, int from_tty)
+{
+ exec_reverse_once ("stepi", args, from_tty);
+}
+
+static void
+reverse_next (char *args, int from_tty)
+{
+ exec_reverse_once ("next", args, from_tty);
+}
+
+static void
+reverse_nexti (char *args, int from_tty)
+{
+ exec_reverse_once ("nexti", args, from_tty);
+}
+
+static void
+reverse_continue (char *args, int from_tty)
+{
+ exec_reverse_once ("continue", args, from_tty);
+}
+
+static void
+reverse_finish (char *args, int from_tty)
+{
+ exec_reverse_once ("finish", args, from_tty);
+}
+
+void
+_initialize_reverse (void)
+{
+ add_com ("reverse-step", class_run, reverse_step, _("\
+Step program backward until it reaches the beginning of another source line.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rs", "reverse-step", class_alias, 1);
+
+ add_com ("reverse-next", class_run, reverse_next, _("\
+Step program backward, proceeding through subroutine calls.\n\
+Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
+when they do, the call is treated as one instruction.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rn", "reverse-next", class_alias, 1);
+
+ add_com ("reverse-stepi", class_run, reverse_stepi, _("\
+Step backward exactly one instruction.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rsi", "reverse-stepi", class_alias, 0);
+
+ add_com ("reverse-nexti", class_run, reverse_nexti, _("\
+Step backward one instruction, but proceed through called subroutines.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rni", "reverse-nexti", class_alias, 0);
+
+ add_com ("reverse-continue", class_run, reverse_continue, _("\
+Continue program being debugged but run it in reverse.\n\
+If proceeding from breakpoint, a number N may be used as an argument,\n\
+which means to set the ignore count of that breakpoint to N - 1 (so that\n\
+the breakpoint won't break until the Nth time it is reached)."));
+ add_com_alias ("rc", "reverse-continue", class_alias, 0);
+
+ add_com ("reverse-finish", class_run, reverse_finish, _("\
+Execute backward until just before selected stack frame is called."));
+}
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.527
diff -u -p -r1.527 gdb.texinfo
--- doc/gdb.texinfo 6 Oct 2008 22:23:18 -0000 1.527
+++ doc/gdb.texinfo 8 Oct 2008 01:35:13 -0000
@@ -143,6 +143,7 @@ software in general. We will miss him.
* Commands:: @value{GDBN} commands
* Running:: Running programs under @value{GDBN}
* Stopping:: Stopping and continuing
+* Reverse Execution:: Running programs backward
* Stack:: Examining the stack
* Source:: Examining source files
* Data:: Examining data
@@ -4850,6 +4851,126 @@ When such an event happens, a system cal
prematurely, even though your program does not appear to stop.
+@node Reverse Execution
+@chapter Running programs backward
+@cindex reverse execution
+@cindex running programs backward
+
+When you are debugging a program, it is not unusual to realize that
+you have gone too far, and some event of interest has already happened.
+If the target environment supports it, @value{GDBN} can allow you to
+``rewind'' the program by running it backward.
+
+A target environment that supports reverse execution should be able
+to ``undo'' the changes in machine state that have taken place as the
+program was executing normally. Variables, registers etc.@: should
+revert to their previous values. Obviously this requires a great
+deal of sophistication on the part of the target environment; not
+all target environments can support reverse execution.
+
+When a program is executed in reverse, the instructions that
+have most recently been executed are ``un-executed'', in reverse
+order. The program counter runs backward, following the previous
+thread of execution in reverse. As each instruction is ``un-executed'',
+the values of memory and/or registers that were changed by that
+instruction are reverted to their previous states. After executing
+a piece of source code in reverse, all side effects of that code
+should be ``undone'', and all variables should be returned to their
+prior values@footnote{
+Note that some side effects are easier to undo than others. For instance,
+memory and registers are relatively easy, but device I/O is hard. Some
+targets may be able undo things like device I/O, and some may not.
+
+The contract between @value{GDBN} and the reverse executing target
+requires only that the target do something reasonable when
+@value{GDBN} tells it to execute backwards, and then report the
+results back to @value{GDBN}. Whatever the target reports back to
+@value{GDBN}, @value{GDBN} will report back to the user. @value{GDBN}
+assumes that the memory and registers that the target reports are in a
+consistant state, but @value{GDBN} accepts whatever it is given.
+}.
+
+If you are debugging in a target environment that supports
+reverse execution, @value{GDBN} provides the following commands.
+
+@table @code
+@kindex reverse-continue
+@kindex rc @r{(@code{reverse-continue})}
+@item reverse-continue @r{[}@var{ignore-count}@r{]}
+@itemx rc @r{[}@var{ignore-count}@r{]}
+Beginning at the point where your program last stopped, start executing
+in reverse. Reverse execution will stop for breakpoints and synchronous
+exceptions (signals), just like normal execution. Behavior of
+asynchronous signals depends on the target environment.
+
+@kindex reverse-step
+@kindex rs @r{(@code{step})}
+@item reverse-step @r{[}@var{count}@r{]}
+Run the program backward until control reaches the start of a
+different source line; then stop it, and return control to @value{GDBN}.
+
+Like the @code{step} command, @code{reverse-step} will only stop
+at the beginning of a source line. It ``un-executes'' the previously
+executed source line. If the previous source line included calls to
+debuggable functions, @code{reverse-step} will step (backward) into
+the called function, stopping at the beginning of the @emph{last}
+statement in the called function (typically a return statement).
+
+Also, as with the @code{step} command, if non-debuggable functions are
+called, @code{reverse-step} will run thru them backward without stopping.
+
+@kindex reverse-stepi
+@kindex rsi @r{(@code{reverse-stepi})}
+@item reverse-stepi @r{[}@var{count}@r{]}
+Reverse-execute one machine instruction. Note that the instruction
+to be reverse-executed is @emph{not} the one pointed to by the program
+counter, but the instruction executed prior to that one. For instance,
+if the last instruction was a jump, @code{reverse-stepi} will take you
+back from the destination of the jump to the jump instruction itself.
+
+@kindex reverse-next
+@kindex rn @r{(@code{reverse-next})}
+@item reverse-next @r{[}@var{count}@r{]}
+Run backward to the beginning of the previous line executed in
+the current (innermost) stack frame. If the line contains function
+calls, they will be ``un-executed'' without stopping. Starting from
+the first line of a function, @code{reverse-next} will take you back
+to the caller of that function, @emph{before} the function was called,
+just as the normal @code{next} command would take you from the last
+line of a function back to its return to its caller
+@footnote{Unles the code is too heavily optimized.}.
+
+@kindex reverse-nexti
+@kindex rni @r{(@code{reverse-nexti})}
+@item reverse-nexti @r{[}@var{count}@r{]}
+Like @code{nexti}, @code{reverse-nexti} executes a single instruction
+in reverse, except that called functions are ``un-executed'' atomically.
+That is, if the previously executed instruction was a return from
+another instruction, @code{reverse-nexti} will continue to execute
+in reverse until the call to that function (from the current stack
+frame) is reached.
+
+@kindex reverse-finish
+@item reverse-finish
+Just as the @code{finish} command takes you to the point where the
+current function returns, @code{reverse-finish} takes you to the point
+where it was called. Instead of ending up at the end of the current
+function invocation, you end up at the beginning.
+
+@kindex set exec-direction
+@item set exec-direction
+Set the direction of target execution.
+@itemx set exec-direction reverse
+@cindex execute forward or backward in time
+@value{GDBN} will perform all execution commands in reverse, until the
+exec-direction mode is changed to ``forward''. Affected commands include
+@code{step, stepi, next, nexti, continue, and finish}. The @code{return}
+command cannot be used in reverse mode.
+@item set exec-direction forward
+@value{GDBN} will perform all execution commands in the normal fashion.
+This is the default.
+@end table
+
@node Stack
@chapter Examining the Stack
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 2:23 [RFA] Resubmit reverse debugging [5/5] Michael Snyder
@ 2008-10-08 18:15 ` Thiago Jung Bauermann
2008-10-08 19:16 ` Eli Zaretskii
` (3 more replies)
2008-10-17 19:48 ` Michael Snyder
1 sibling, 4 replies; 13+ messages in thread
From: Thiago Jung Bauermann @ 2008-10-08 18:15 UTC (permalink / raw)
To: Michael Snyder; +Cc: gdb-patches
El mar, 07-10-2008 a las 19:20 -0700, Michael Snyder escribió:
> +static void
> +exec_reverse_once (char *cmd, char *args, int from_tty)
> +{
> + /* String buffer for command consing. */
> + char reverse_command[512];
<snip>
> + sprintf (reverse_command, "%s %s", cmd, args ? args : "");
> +
> + execution_direction = EXEC_REVERSE;
> + execute_command (reverse_command, from_tty);
> + do_cleanups (old_chain);
That fixed-length buffer being written with sprintf doesn't look good...
What do you think about using xstrprintf instead? That will remove the
possibility of buffer overflow, and also remove an arbitrary limit.
> + add_com ("reverse-next", class_run, reverse_next, _("\
> +Step program backward, proceeding through subroutine calls.\n\
> +Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
> +when they do, the call is treated as one instruction.\n\
> +Argument N means do this N times (or till program stops for another reason).")
> + );
> + add_com_alias ("rn", "reverse-next", class_alias, 1);
What about adding "previous" and either "pr" or "pre" as alias to
reverse-next? Sounds more natural to me than "reverse-next". Similarly,
"previousi" and "pri" or "prei".
I'd also half-seriously suggest adding a "step-back" alias on the same
grounds. :-)
--
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 18:15 ` Thiago Jung Bauermann
@ 2008-10-08 19:16 ` Eli Zaretskii
2008-10-09 4:23 ` Pedro Alves
2008-10-08 20:14 ` Thiago Jung Bauermann
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2008-10-08 19:16 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: msnyder, gdb-patches
> From: Thiago Jung Bauermann <bauerman@br.ibm.com>
> Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
> Date: Wed, 08 Oct 2008 15:14:23 -0300
>
> > + add_com ("reverse-next", class_run, reverse_next, _("\
> > +Step program backward, proceeding through subroutine calls.\n\
> > +Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
> > +when they do, the call is treated as one instruction.\n\
> > +Argument N means do this N times (or till program stops for another reason).")
> > + );
> > + add_com_alias ("rn", "reverse-next", class_alias, 1);
>
> What about adding "previous" and either "pr" or "pre" as alias to
> reverse-next?
Please, not "pr". The .gdbinit file that comes with Emacs defines a
user command named "pr" that prints any Lisp object. This command is
central to debugging Emacs, so re-learning its name would be a hassle.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 18:15 ` Thiago Jung Bauermann
2008-10-08 19:16 ` Eli Zaretskii
@ 2008-10-08 20:14 ` Thiago Jung Bauermann
2008-10-08 20:55 ` Michael Snyder
2008-10-08 20:27 ` Michael Snyder
2008-10-08 21:06 ` Michael Snyder
3 siblings, 1 reply; 13+ messages in thread
From: Thiago Jung Bauermann @ 2008-10-08 20:14 UTC (permalink / raw)
To: Michael Snyder; +Cc: gdb-patches
El mié, 08-10-2008 a las 15:14 -0300, Thiago Jung Bauermann escribió:
> El mar, 07-10-2008 a las 19:20 -0700, Michael Snyder escribió:
> > +static void
> > +exec_reverse_once (char *cmd, char *args, int from_tty)
> > +{
> > + /* String buffer for command consing. */
> > + char reverse_command[512];
> <snip>
> > + sprintf (reverse_command, "%s %s", cmd, args ? args : "");
> > +
> > + execution_direction = EXEC_REVERSE;
> > + execute_command (reverse_command, from_tty);
> > + do_cleanups (old_chain);
>
> That fixed-length buffer being written with sprintf doesn't look good...
> What do you think about using xstrprintf instead? That will remove the
> possibility of buffer overflow, and also remove an arbitrary limit.
By the way, the string manipulation can be avoided if you pass a
function pointer to exec_reverse_once. Then you can call it passing
next_command, continue_command and all others. It seems cleaner to me,
what do you think?
Also, will there be anything added to reverse.c in the future? If not,
IMHO it's easier just to put these command definitions and setup in
infcmd.c, next to their forward counterparts.
--
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 18:15 ` Thiago Jung Bauermann
2008-10-08 19:16 ` Eli Zaretskii
2008-10-08 20:14 ` Thiago Jung Bauermann
@ 2008-10-08 20:27 ` Michael Snyder
2008-10-08 20:43 ` Thiago Jung Bauermann
2008-12-15 12:29 ` Tomas Holmberg
2008-10-08 21:06 ` Michael Snyder
3 siblings, 2 replies; 13+ messages in thread
From: Michael Snyder @ 2008-10-08 20:27 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: gdb-patches
Thiago Jung Bauermann wrote:
> El mar, 07-10-2008 a las 19:20 -0700, Michael Snyder escribió:
>> +static void
>> +exec_reverse_once (char *cmd, char *args, int from_tty)
>> +{
>> + /* String buffer for command consing. */
>> + char reverse_command[512];
> <snip>
>> + sprintf (reverse_command, "%s %s", cmd, args ? args : "");
>> +
>> + execution_direction = EXEC_REVERSE;
>> + execute_command (reverse_command, from_tty);
>> + do_cleanups (old_chain);
>
> That fixed-length buffer being written with sprintf doesn't look good...
> What do you think about using xstrprintf instead? That will remove the
> possibility of buffer overflow, and also remove an arbitrary limit.
Sure, I'll look into it.
>> + add_com ("reverse-next", class_run, reverse_next, _("\
>> +Step program backward, proceeding through subroutine calls.\n\
>> +Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
>> +when they do, the call is treated as one instruction.\n\
>> +Argument N means do this N times (or till program stops for another reason).")
>> + );
>> + add_com_alias ("rn", "reverse-next", class_alias, 1);
>
> What about adding "previous" and either "pr" or "pre" as alias to
> reverse-next? Sounds more natural to me than "reverse-next". Similarly,
> "previousi" and "pri" or "prei".
>
> I'd also half-seriously suggest adding a "step-back" alias on the same
> grounds. :-)
Lots of people have alternate suggestions for command names.
The present set is as close to convergence as we were able to
get in several previous rounds of discussion.
I don't want the feature to be held up by this discussion,
so I'm just saying "aliases are easy to add later".
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 20:27 ` Michael Snyder
@ 2008-10-08 20:43 ` Thiago Jung Bauermann
2008-12-15 12:29 ` Tomas Holmberg
1 sibling, 0 replies; 13+ messages in thread
From: Thiago Jung Bauermann @ 2008-10-08 20:43 UTC (permalink / raw)
To: Michael Snyder; +Cc: gdb-patches
El mié, 08-10-2008 a las 13:24 -0700, Michael Snyder escribió:
> Lots of people have alternate suggestions for command names.
> The present set is as close to convergence as we were able to
> get in several previous rounds of discussion.
Ok, I'll look at those discussions to get some background info.
> I don't want the feature to be held up by this discussion,
> so I'm just saying "aliases are easy to add later".
Fine by me, I surely don't want to delay inclusion of this great
feature!
--
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 20:14 ` Thiago Jung Bauermann
@ 2008-10-08 20:55 ` Michael Snyder
0 siblings, 0 replies; 13+ messages in thread
From: Michael Snyder @ 2008-10-08 20:55 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: gdb-patches
Thiago Jung Bauermann wrote:
>
> Also, will there be anything added to reverse.c in the future? If not,
> IMHO it's easier just to put these command definitions and setup in
> infcmd.c, next to their forward counterparts.
My thought is that it's better to guess "yes" than "no" to your
question. There are some number of things we already know that
we haven't addressed (async, multi-threads...), and any number
that we may not have thought of yet.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 18:15 ` Thiago Jung Bauermann
` (2 preceding siblings ...)
2008-10-08 20:27 ` Michael Snyder
@ 2008-10-08 21:06 ` Michael Snyder
2008-10-08 21:14 ` Thiago Jung Bauermann
3 siblings, 1 reply; 13+ messages in thread
From: Michael Snyder @ 2008-10-08 21:06 UTC (permalink / raw)
To: Thiago Jung Bauermann; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 766 bytes --]
Thiago Jung Bauermann wrote:
> El mar, 07-10-2008 a las 19:20 -0700, Michael Snyder escribió:
>> +static void
>> +exec_reverse_once (char *cmd, char *args, int from_tty)
>> +{
>> + /* String buffer for command consing. */
>> + char reverse_command[512];
> <snip>
>> + sprintf (reverse_command, "%s %s", cmd, args ? args : "");
>> +
>> + execution_direction = EXEC_REVERSE;
>> + execute_command (reverse_command, from_tty);
>> + do_cleanups (old_chain);
>
> That fixed-length buffer being written with sprintf doesn't look good...
> What do you think about using xstrprintf instead? That will remove the
> possibility of buffer overflow, and also remove an arbitrary limit.
How about this? (the function pointer idea I leave for a future
enhancement):
[-- Attachment #2: xstrprintf.txt --]
[-- Type: text/plain, Size: 1122 bytes --]
Index: reverse.c
===================================================================
RCS file: /cvs/src/src/gdb/Attic/reverse.c,v
retrieving revision 1.1.10.6
diff -u -p -r1.1.10.6 reverse.c
--- reverse.c 8 Oct 2008 00:26:28 -0000 1.1.10.6
+++ reverse.c 8 Oct 2008 21:03:59 -0000
@@ -44,8 +44,7 @@ static void exec_direction_default (void
static void
exec_reverse_once (char *cmd, char *args, int from_tty)
{
- /* String buffer for command consing. */
- char reverse_command[512];
+ char *reverse_command;
enum exec_direction_kind dir = execution_direction;
struct cleanup *old_chain;
@@ -59,9 +58,9 @@ exec_reverse_once (char *cmd, char *args
if (!target_can_execute_reverse)
error (_("Target %s does not support this command."), target_shortname);
+ reverse_command = xstrprintf ("%s %s", cmd, args ? args : "");
old_chain = make_cleanup (exec_direction_default, NULL);
- sprintf (reverse_command, "%s %s", cmd, args ? args : "");
-
+ make_cleanup (xfree, reverse_command);
execution_direction = EXEC_REVERSE;
execute_command (reverse_command, from_tty);
do_cleanups (old_chain);
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 21:06 ` Michael Snyder
@ 2008-10-08 21:14 ` Thiago Jung Bauermann
0 siblings, 0 replies; 13+ messages in thread
From: Thiago Jung Bauermann @ 2008-10-08 21:14 UTC (permalink / raw)
To: Michael Snyder; +Cc: gdb-patches
El mié, 08-10-2008 a las 14:03 -0700, Michael Snyder escribió:
> How about this? (the function pointer idea I leave for a future
> enhancement):
Looks good. Thanks.
--
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 19:16 ` Eli Zaretskii
@ 2008-10-09 4:23 ` Pedro Alves
2008-10-09 8:41 ` Eli Zaretskii
0 siblings, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2008-10-09 4:23 UTC (permalink / raw)
To: gdb-patches, Eli Zaretskii; +Cc: Thiago Jung Bauermann, msnyder
On Wednesday 08 October 2008 20:15:16, Eli Zaretskii wrote:
> > From: Thiago Jung Bauermann <bauerman@br.ibm.com>
> > What about adding "previous" and either "pr" or "pre" as alias to
> > reverse-next?
>
> Please, not "pr". The .gdbinit file that comes with Emacs defines a
> user command named "pr" that prints any Lisp object. This command is
> central to debugging Emacs, so re-learning its name would be a hassle.
This argument isn't valid. User defined commands override
GDB's built-in commands, so you'd not lose anything.
pr wouldn't even collide with anything current:
(gdb) pr
Ambiguous command "pr": print, print-object, printf, process.
--
Pedro Alves
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-09 4:23 ` Pedro Alves
@ 2008-10-09 8:41 ` Eli Zaretskii
0 siblings, 0 replies; 13+ messages in thread
From: Eli Zaretskii @ 2008-10-09 8:41 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches, bauerman, msnyder
> From: Pedro Alves <pedro@codesourcery.com>
> Date: Thu, 9 Oct 2008 05:22:43 +0100
> Cc: Thiago Jung Bauermann <bauerman@br.ibm.com>,
> msnyder@vmware.com
>
> On Wednesday 08 October 2008 20:15:16, Eli Zaretskii wrote:
> > > From: Thiago Jung Bauermann <bauerman@br.ibm.com>
> > > What about adding "previous" and either "pr" or "pre" as alias to
> > > reverse-next?
> >
> > Please, not "pr". The .gdbinit file that comes with Emacs defines a
> > user command named "pr" that prints any Lisp object. This command is
> > central to debugging Emacs, so re-learning its name would be a hassle.
>
> This argument isn't valid. User defined commands override
> GDB's built-in commands, so you'd not lose anything.
I know about the overriding, and I'm sorry for not making myself clear
about that (somehow, I thought it was obvious). My problem was not
with the technical aspects, but with human aspects. Like this, for
example:
> (gdb) pr
> Ambiguous command "pr": print, print-object, printf, process.
Exactly! Right now, if I forget that I'm not debugging Emacs (yes, it
happens ;-) and type "pr" out of habit, I get the above response, or
something similar. With the proposed alias, I might get the
`previous' command actually _executed_, to my surprise and annoyance.
Another problem is that I will lose the alias when I'm debugging
Emacs. Not good, IMO.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 2:23 [RFA] Resubmit reverse debugging [5/5] Michael Snyder
2008-10-08 18:15 ` Thiago Jung Bauermann
@ 2008-10-17 19:48 ` Michael Snyder
1 sibling, 0 replies; 13+ messages in thread
From: Michael Snyder @ 2008-10-17 19:48 UTC (permalink / raw)
To: Michael Snyder; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 26 bytes --]
Committed, as attached:
[-- Attachment #2: final5.txt --]
[-- Type: text/plain, Size: 14492 bytes --]
2008-10-17 Michael Snyder <msnyder@vmware.com>
User interface for reverse execution.
* Makefile.in (reverse.c): New file.
* reverse.c: New file. User interface for reverse execution.
2008-10-17 Michael Snyder <msnyder@vmware.com>
* gdb.texinfo: Add documentation for reverse execution.
Index: reverse.c
===================================================================
RCS file: reverse.c
diff -N reverse.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ reverse.c 17 Oct 2008 19:35:12 -0000
@@ -0,0 +1,143 @@
+/* Reverse execution and reverse debugging.
+
+ Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "defs.h"
+#include "gdb_string.h"
+#include "target.h"
+#include "top.h"
+#include "cli/cli-cmds.h"
+#include "cli/cli-decode.h"
+#include "inferior.h"
+
+/* User interface:
+ reverse-step, reverse-next etc. */
+
+static void exec_direction_default (void *notused)
+{
+ /* Return execution direction to default state. */
+ execution_direction = EXEC_FORWARD;
+}
+
+/* exec_reverse_once -- accepts an arbitrary gdb command (string),
+ and executes it with exec-direction set to 'reverse'.
+
+ Used to implement reverse-next etc. commands. */
+
+static void
+exec_reverse_once (char *cmd, char *args, int from_tty)
+{
+ char *reverse_command;
+ enum exec_direction_kind dir = execution_direction;
+ struct cleanup *old_chain;
+
+ if (dir == EXEC_ERROR)
+ error (_("Target %s does not support this command."), target_shortname);
+
+ if (dir == EXEC_REVERSE)
+ error (_("Already in reverse mode. Use '%s' or 'set exec-dir forward'."),
+ cmd);
+
+ if (!target_can_execute_reverse)
+ error (_("Target %s does not support this command."), target_shortname);
+
+ reverse_command = xstrprintf ("%s %s", cmd, args ? args : "");
+ old_chain = make_cleanup (exec_direction_default, NULL);
+ make_cleanup (xfree, reverse_command);
+ execution_direction = EXEC_REVERSE;
+ execute_command (reverse_command, from_tty);
+ do_cleanups (old_chain);
+}
+
+static void
+reverse_step (char *args, int from_tty)
+{
+ exec_reverse_once ("step", args, from_tty);
+}
+
+static void
+reverse_stepi (char *args, int from_tty)
+{
+ exec_reverse_once ("stepi", args, from_tty);
+}
+
+static void
+reverse_next (char *args, int from_tty)
+{
+ exec_reverse_once ("next", args, from_tty);
+}
+
+static void
+reverse_nexti (char *args, int from_tty)
+{
+ exec_reverse_once ("nexti", args, from_tty);
+}
+
+static void
+reverse_continue (char *args, int from_tty)
+{
+ exec_reverse_once ("continue", args, from_tty);
+}
+
+static void
+reverse_finish (char *args, int from_tty)
+{
+ exec_reverse_once ("finish", args, from_tty);
+}
+
+void
+_initialize_reverse (void)
+{
+ add_com ("reverse-step", class_run, reverse_step, _("\
+Step program backward until it reaches the beginning of another source line.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rs", "reverse-step", class_alias, 1);
+
+ add_com ("reverse-next", class_run, reverse_next, _("\
+Step program backward, proceeding through subroutine calls.\n\
+Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
+when they do, the call is treated as one instruction.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rn", "reverse-next", class_alias, 1);
+
+ add_com ("reverse-stepi", class_run, reverse_stepi, _("\
+Step backward exactly one instruction.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rsi", "reverse-stepi", class_alias, 0);
+
+ add_com ("reverse-nexti", class_run, reverse_nexti, _("\
+Step backward one instruction, but proceed through called subroutines.\n\
+Argument N means do this N times (or till program stops for another reason).")
+ );
+ add_com_alias ("rni", "reverse-nexti", class_alias, 0);
+
+ add_com ("reverse-continue", class_run, reverse_continue, _("\
+Continue program being debugged but run it in reverse.\n\
+If proceeding from breakpoint, a number N may be used as an argument,\n\
+which means to set the ignore count of that breakpoint to N - 1 (so that\n\
+the breakpoint won't break until the Nth time it is reached)."));
+ add_com_alias ("rc", "reverse-continue", class_alias, 0);
+
+ add_com ("reverse-finish", class_run, reverse_finish, _("\
+Execute backward until just before selected stack frame is called."));
+}
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1055
diff -u -p -r1.1055 Makefile.in
--- Makefile.in 16 Oct 2008 03:53:58 -0000 1.1055
+++ Makefile.in 17 Oct 2008 19:35:12 -0000
@@ -641,7 +641,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
objfiles.c osabi.c observer.c \
p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
prologue-value.c \
- regcache.c reggroups.c remote.c remote-fileio.c \
+ regcache.c reggroups.c remote.c remote-fileio.c reverse.c \
scm-exp.c scm-lang.c scm-valprint.c \
sentinel-frame.c \
serial.c ser-base.c ser-unix.c \
@@ -780,7 +780,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
findcmd.o \
std-regs.o \
signals.o \
- exec.o bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
+ exec.o reverse.o \
+ bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
dbxread.o coffread.o coff-pe-read.o \
dwarf2read.o mipsread.o stabsread.o corefile.o \
dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.528
diff -u -p -r1.528 gdb.texinfo
--- doc/gdb.texinfo 16 Oct 2008 03:54:00 -0000 1.528
+++ doc/gdb.texinfo 17 Oct 2008 19:35:12 -0000
@@ -143,6 +143,7 @@ software in general. We will miss him.
* Commands:: @value{GDBN} commands
* Running:: Running programs under @value{GDBN}
* Stopping:: Stopping and continuing
+* Reverse Execution:: Running programs backward
* Stack:: Examining the stack
* Source:: Examining source files
* Data:: Examining data
@@ -4850,6 +4851,126 @@ When such an event happens, a system cal
prematurely, even though your program does not appear to stop.
+@node Reverse Execution
+@chapter Running programs backward
+@cindex reverse execution
+@cindex running programs backward
+
+When you are debugging a program, it is not unusual to realize that
+you have gone too far, and some event of interest has already happened.
+If the target environment supports it, @value{GDBN} can allow you to
+``rewind'' the program by running it backward.
+
+A target environment that supports reverse execution should be able
+to ``undo'' the changes in machine state that have taken place as the
+program was executing normally. Variables, registers etc.@: should
+revert to their previous values. Obviously this requires a great
+deal of sophistication on the part of the target environment; not
+all target environments can support reverse execution.
+
+When a program is executed in reverse, the instructions that
+have most recently been executed are ``un-executed'', in reverse
+order. The program counter runs backward, following the previous
+thread of execution in reverse. As each instruction is ``un-executed'',
+the values of memory and/or registers that were changed by that
+instruction are reverted to their previous states. After executing
+a piece of source code in reverse, all side effects of that code
+should be ``undone'', and all variables should be returned to their
+prior values@footnote{
+Note that some side effects are easier to undo than others. For instance,
+memory and registers are relatively easy, but device I/O is hard. Some
+targets may be able undo things like device I/O, and some may not.
+
+The contract between @value{GDBN} and the reverse executing target
+requires only that the target do something reasonable when
+@value{GDBN} tells it to execute backwards, and then report the
+results back to @value{GDBN}. Whatever the target reports back to
+@value{GDBN}, @value{GDBN} will report back to the user. @value{GDBN}
+assumes that the memory and registers that the target reports are in a
+consistant state, but @value{GDBN} accepts whatever it is given.
+}.
+
+If you are debugging in a target environment that supports
+reverse execution, @value{GDBN} provides the following commands.
+
+@table @code
+@kindex reverse-continue
+@kindex rc @r{(@code{reverse-continue})}
+@item reverse-continue @r{[}@var{ignore-count}@r{]}
+@itemx rc @r{[}@var{ignore-count}@r{]}
+Beginning at the point where your program last stopped, start executing
+in reverse. Reverse execution will stop for breakpoints and synchronous
+exceptions (signals), just like normal execution. Behavior of
+asynchronous signals depends on the target environment.
+
+@kindex reverse-step
+@kindex rs @r{(@code{step})}
+@item reverse-step @r{[}@var{count}@r{]}
+Run the program backward until control reaches the start of a
+different source line; then stop it, and return control to @value{GDBN}.
+
+Like the @code{step} command, @code{reverse-step} will only stop
+at the beginning of a source line. It ``un-executes'' the previously
+executed source line. If the previous source line included calls to
+debuggable functions, @code{reverse-step} will step (backward) into
+the called function, stopping at the beginning of the @emph{last}
+statement in the called function (typically a return statement).
+
+Also, as with the @code{step} command, if non-debuggable functions are
+called, @code{reverse-step} will run thru them backward without stopping.
+
+@kindex reverse-stepi
+@kindex rsi @r{(@code{reverse-stepi})}
+@item reverse-stepi @r{[}@var{count}@r{]}
+Reverse-execute one machine instruction. Note that the instruction
+to be reverse-executed is @emph{not} the one pointed to by the program
+counter, but the instruction executed prior to that one. For instance,
+if the last instruction was a jump, @code{reverse-stepi} will take you
+back from the destination of the jump to the jump instruction itself.
+
+@kindex reverse-next
+@kindex rn @r{(@code{reverse-next})}
+@item reverse-next @r{[}@var{count}@r{]}
+Run backward to the beginning of the previous line executed in
+the current (innermost) stack frame. If the line contains function
+calls, they will be ``un-executed'' without stopping. Starting from
+the first line of a function, @code{reverse-next} will take you back
+to the caller of that function, @emph{before} the function was called,
+just as the normal @code{next} command would take you from the last
+line of a function back to its return to its caller
+@footnote{Unles the code is too heavily optimized.}.
+
+@kindex reverse-nexti
+@kindex rni @r{(@code{reverse-nexti})}
+@item reverse-nexti @r{[}@var{count}@r{]}
+Like @code{nexti}, @code{reverse-nexti} executes a single instruction
+in reverse, except that called functions are ``un-executed'' atomically.
+That is, if the previously executed instruction was a return from
+another instruction, @code{reverse-nexti} will continue to execute
+in reverse until the call to that function (from the current stack
+frame) is reached.
+
+@kindex reverse-finish
+@item reverse-finish
+Just as the @code{finish} command takes you to the point where the
+current function returns, @code{reverse-finish} takes you to the point
+where it was called. Instead of ending up at the end of the current
+function invocation, you end up at the beginning.
+
+@kindex set exec-direction
+@item set exec-direction
+Set the direction of target execution.
+@itemx set exec-direction reverse
+@cindex execute forward or backward in time
+@value{GDBN} will perform all execution commands in reverse, until the
+exec-direction mode is changed to ``forward''. Affected commands include
+@code{step, stepi, next, nexti, continue, and finish}. The @code{return}
+command cannot be used in reverse mode.
+@item set exec-direction forward
+@value{GDBN} will perform all execution commands in the normal fashion.
+This is the default.
+@end table
+
@node Stack
@chapter Examining the Stack
@@ -24565,6 +24686,22 @@ breakpoint at @var{addr}.
Don't use this packet. Use the @samp{Z} and @samp{z} packets instead
(@pxref{insert breakpoint or watchpoint packet}).
+@item bc
+@cindex @samp{bc} packet
+Backward continue. Execute the target system in reverse. No parameter.
+@xref{Reverse Execution}, for more information.
+
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
+
+@item bs
+@cindex @samp{bs} packet
+Backward single step. Execute one instruction in reverse. No parameter.
+@xref{Reverse Execution}, for more information.
+
+Reply:
+@xref{Stop Reply Packets}, for the reply specifications.
+
@item c @r{[}@var{addr}@r{]}
@cindex @samp{c} packet
Continue. @var{addr} is address to resume. If @var{addr} is omitted,
@@ -25182,6 +25319,16 @@ hex.
The packet indicates that the loaded libraries have changed.
@value{GDBN} should use @samp{qXfer:libraries:read} to fetch a new
list of loaded libraries. @var{r} is ignored.
+
+@cindex replay log events, remote reply
+@item replaylog
+The packet indicates that the target cannot continue replaying
+logged execution events, because it has reached the end (or the
+beginning when executing backward) of the log. The value of @var{r}
+will be either @samp{begin} or @samp{end}. @xref{Reverse Execution},
+for more information.
+
+
@end table
@item W @var{AA}
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFA] Resubmit reverse debugging [5/5]
2008-10-08 20:27 ` Michael Snyder
2008-10-08 20:43 ` Thiago Jung Bauermann
@ 2008-12-15 12:29 ` Tomas Holmberg
1 sibling, 0 replies; 13+ messages in thread
From: Tomas Holmberg @ 2008-12-15 12:29 UTC (permalink / raw)
To: Michael Snyder; +Cc: Thiago Jung Bauermann, gdb-patches
>> What about adding "previous" and either "pr" or "pre" as alias to
>> reverse-next? Sounds more natural to me than "reverse-next". Similarly,
>> "previousi" and "pri" or "prei".
>>
>> I'd also half-seriously suggest adding a "step-back" alias on the same
>> grounds. :-)
>
> Lots of people have alternate suggestions for command names.
> The present set is as close to convergence as we were able to
> get in several previous rounds of discussion.
>
> I don't want the feature to be held up by this discussion,
> so I'm just saying "aliases are easy to add later".
I would like to continue the discussion about alias name for the too
long reverse commands. I am not sure that the gdb-patches list is the
right place for having this discussion.
My new command alias suggestions are in the right column:
reverse-continue - reverse
reverse-finish - uncall
reverse-next - previous, prev
reverse-nexti - previousi, previ
reverse-step - unstep
reverse-stepi - unstepi
The main reasons for the new alias names is to better describe what
the commands actually do and distinguish them from the "forward"
debugging commands. The reverse- commands implies that running a
program in reverse is only a special mode of running it forward. This
is no longer true and the support for running in reverse will increase
in the future.
/Tomas Holmberg
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-12-15 12:29 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-08 2:23 [RFA] Resubmit reverse debugging [5/5] Michael Snyder
2008-10-08 18:15 ` Thiago Jung Bauermann
2008-10-08 19:16 ` Eli Zaretskii
2008-10-09 4:23 ` Pedro Alves
2008-10-09 8:41 ` Eli Zaretskii
2008-10-08 20:14 ` Thiago Jung Bauermann
2008-10-08 20:55 ` Michael Snyder
2008-10-08 20:27 ` Michael Snyder
2008-10-08 20:43 ` Thiago Jung Bauermann
2008-12-15 12:29 ` Tomas Holmberg
2008-10-08 21:06 ` Michael Snyder
2008-10-08 21:14 ` Thiago Jung Bauermann
2008-10-17 19:48 ` Michael Snyder
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox