]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2006-03-31 Michael Snyder <msnyder@redhat.com> msnyder-reverse-20060331-branch
authorMichael Snyder <msnyder@vmware.com>
Fri, 31 Mar 2006 21:36:27 +0000 (21:36 +0000)
committerMichael Snyder <msnyder@vmware.com>
Fri, 31 Mar 2006 21:36:27 +0000 (21:36 +0000)
User interface for reverse execution.
* Makefile.in (reverse.c): New file.
* reverse.c: New file.  User interface for reverse execution.

gdb/ChangeLog
gdb/Makefile.in
gdb/reverse.c [new file with mode: 0644]

index cb7b6362aaa164d5e4438aac89f99d3f4e790c3c..6a220350f965ae33e32ba2814b6a8a559555fdfb 100644 (file)
        * infrun.c: Make sure to check for EXEC_REVERSE not EXEC_FORWARD,
        since targets that don't implement execdir will return EXEC_ERROR.
 
+2006-03-31  Michael Snyder  <msnyder@redhat.com>
+
+       User interface for reverse execution.
+       * Makefile.in (reverse.c): New file.
+       * reverse.c: New file.  User interface for reverse execution.
+
 2006-03-31  Andrew Stubbs  <andrew.stubbs@st.com>
 
        * value.h (struct internalvar): Add field 'endian'.
index 644e9d9dd8a5a69413cfa512587ead11cf72551b..769f5582d4a3b0c181f2a9929e266941473336e1 100644 (file)
@@ -543,7 +543,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c  \
        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 \
@@ -927,7 +927,8 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
        signals.o \
        kod.o kod-cisco.o \
        gdb-events.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 elfread.o \
        dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \
        dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
@@ -2493,6 +2494,8 @@ remote-st.o: remote-st.c $(defs_h) $(gdbcore_h) $(target_h) $(gdb_string_h) \
 remote-utils.o: remote-utils.c $(defs_h) $(gdb_string_h) $(gdbcmd_h) \
        $(target_h) $(serial_h) $(gdbcore_h) $(inferior_h) $(remote_utils_h) \
        $(regcache_h)
+reverse.o: reverse.c $(defs_h) $(gdb_string_h) $(target_h) $(cli_cmds_h) \
+       $(cli_decode_h) $(top_h)
 rom68k-rom.o: rom68k-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
        $(serial_h) $(regcache_h) $(value_h) $(m68k_tdep_h)
 rs6000-nat.o: rs6000-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
diff --git a/gdb/reverse.c b/gdb/reverse.c
new file mode 100644 (file)
index 0000000..0c0d8ac
--- /dev/null
@@ -0,0 +1,197 @@
+/* Reverse execution and reverse debugging.
+
+   Copyright (C) 2006 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"
+
+/* User interface for reverse debugging:
+   Set exec-direction / show exec-direction commands
+   (returns error unles target implements to_set_execdir method).  */
+
+static const char exec_forward[] = "forward";
+static const char exec_reverse[] = "reverse";
+static const char *exec_direction = exec_forward;
+static const char *exec_direction_names[] = {
+  exec_forward,
+  exec_reverse,
+  NULL
+};
+
+static void
+set_exec_direction_func (char *args, int from_tty, 
+                        struct cmd_list_element *cmd)
+{
+  if (target_get_execution_direction () != EXEC_ERROR)
+    {
+      enum exec_direction_kind dir = EXEC_ERROR;
+
+      if (!strcmp (exec_direction, exec_forward))
+       dir = EXEC_FORWARD;
+      else if (!strcmp (exec_direction, exec_reverse))
+       dir = EXEC_REVERSE;
+
+      if (target_set_execution_direction (dir) != EXEC_ERROR)
+       return;
+    }
+  error (_("Target `%s' does not support execution-direction."),
+        target_shortname);
+}
+
+static void
+show_exec_direction_func (struct ui_file *out, int from_tty, 
+                         struct cmd_list_element *cmd, const char *value)
+{
+  enum exec_direction_kind dir = target_get_execution_direction ();
+
+  switch (dir) {
+  case EXEC_FORWARD:
+    fprintf_filtered (out, "Forward.\n");
+    break;
+  case EXEC_REVERSE:
+    fprintf_filtered (out, "Reverse.\n");
+    break;
+  case EXEC_ERROR:
+  default:
+    error (_("Target `%s' does not support execution-direction."),
+          target_shortname);
+    break;
+  }
+}
+
+/* User interface:
+   reverse-step, reverse-next etc.
+   (returns error unles target implements to_set_execdir method).  */
+
+static void execdir_default (void *notused)
+{
+  /* Return execution direction to default state.  */
+  target_set_execution_direction (EXEC_FORWARD);
+}
+
+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 = target_get_execution_direction ();
+
+  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_set_execution_direction (EXEC_REVERSE) == EXEC_ERROR)
+    error (_("Target %s does not support this command."), target_shortname);
+
+  make_cleanup (execdir_default, NULL);
+  sprintf (reverse_command, "%s %s", cmd, args ? args : "");
+  execute_command (reverse_command, from_tty);
+}
+
+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_setshow_enum_cmd ("exec-direction", class_run, exec_direction_names,
+                       &exec_direction, "Set direction of execution.\n\
+Options are 'forward' or 'reverse'.",
+                       "Show direction of execution (forward/reverse).",
+                       "Tells gdb whether to execute forward or backward.",
+                       set_exec_direction_func, show_exec_direction_func,
+                       &setlist, &showlist);
+
+  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, running 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."));
+}