btrace: control memory access during replay
authorMarkus Metzger <markus.t.metzger@intel.com>
Wed, 5 Mar 2014 14:38:11 +0000 (15:38 +0100)
committerMarkus Metzger <markus.t.metzger@intel.com>
Fri, 23 May 2014 07:07:53 +0000 (09:07 +0200)
The btrace record target does not trace data.  We therefore do not allow
accessing read-write memory during replay.

In some cases, this might be useful to advanced users, though, who we assume
to know what they are doing.

Add a set|show command pair to turn this memory access restriction off.

* record-btrace.c (record_btrace_allow_memory_access): Remove.
(replay_memory_access_read_only, replay_memory_access_read_write)
(replay_memory_access_types, replay_memory_access)
(set_record_btrace_cmdlist, show_record_btrace_cmdlist)
(cmd_set_record_btrace, cmd_show_record_btrace)
(cmd_show_replay_memory_access): New.
(record_btrace_xfer_partial, record_btrace_insert_breakpoint)
(record_btrace_remove_breakpoint): Replace
record_btrace_allow_memory_access with replay_memory_access.
(_initialize_record_btrace): Add commands.
* NEWS: Announce it.

testsuite/
* gdb.btrace/data.exp: Test it.

doc/
* gdb.texinfo (Process Record and Replay): Document it.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/record-btrace.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.btrace/data.exp

index 2418b45e78690e29cbcb1a35a2ef7370a1598b09..a6050859243550c998b6ea3c3c3781870f858a5c 100644 (file)
@@ -1,3 +1,17 @@
+2014-05-23  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * record-btrace.c (record_btrace_allow_memory_access): Remove.
+       (replay_memory_access_read_only, replay_memory_access_read_write)
+       (replay_memory_access_types, replay_memory_access)
+       (set_record_btrace_cmdlist, show_record_btrace_cmdlist)
+       (cmd_set_record_btrace, cmd_show_record_btrace)
+       (cmd_show_replay_memory_access): New.
+       (record_btrace_xfer_partial, record_btrace_insert_breakpoint)
+       (record_btrace_remove_breakpoint): Replace
+       record_btrace_allow_memory_access with replay_memory_access.
+       (_initialize_record_btrace): Add commands.
+       * NEWS: Announce it.
+
 2014-05-22  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
 
        * aarch64-linux-nat.c (asm/ptrace.h): Include.
index 4663650253e6731756d557e42350c0a333029565..5a0a76e2ffe5fb7731429adab59b4e7df0045270 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -67,6 +67,10 @@ set auto-connect-native-target
   native target for the run, attach, etc. commands when not connected
   to any target yet.  See also "target native" below.
 
+set record btrace replay-memory-access (read-only|read-write)
+show record btrace replay-memory-access
+  Control what memory accesses are allowed during replay.
+
 * New features in the GDB remote stub, GDBserver
 
   ** New option --debug-format=option1[,option2,...] allows one to add
index 18588f6c7bee1def9ea2143919bbbcd286195594..25bdc32b03bde38036caa21035b696a6a14cd795 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-23  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * gdb.texinfo (Process Record and Replay): Document "set/show btrace
+       replay-memory-access".
+
 2014-05-21  Pedro Alves  <palves@redhat.com>
 
        * gdb.texinfo (Starting): Document "set/show
index 47d4bb71f6b971e76d79cb0531e6cc6f293f3a8e..cc188aec4785d9bfaadd0387d5e0b51b4a3f56ed 100644 (file)
@@ -6451,6 +6451,28 @@ results.
 @item show record full memory-query
 Show the current setting of @code{memory-query}.
 
+@kindex set record btrace
+The @code{btrace} record target does not trace data.  As a
+convenience, when replaying, @value{GDBN} reads read-only memory off
+the live program directly, assuming that the addresses of the
+read-only areas don't change.  This for example makes it possible to
+disassemble code while replaying, but not to print variables.
+In some cases, being able to inspect variables might be useful.
+You can use the following command for that:
+
+@item set record btrace replay-memory-access
+Control the behavior of the @code{btrace} recording method when
+accessing memory during replay.  If @code{read-only} (the default),
+@value{GDBN} will only allow accesses to read-only memory.
+If @code{read-write}, @value{GDBN} will allow accesses to read-only
+and to read-write memory.  Beware that the accessed memory corresponds
+to the live target and not necessarily to the current replay
+position.
+
+@kindex show record btrace
+@item show record btrace replay-memory-access
+Show the current setting of @code{replay-memory-access}.
+
 @kindex info record
 @item info record
 Show various statistics about the recording depending on the recording
index 2304020f80c1ca55a7f2ce173e2975abd83609ee..166e78edace1bc4d96bd8a8b0944b4cc251eb005 100644 (file)
@@ -43,8 +43,22 @@ static struct target_ops record_btrace_ops;
 /* A new thread observer enabling branch tracing for the new thread.  */
 static struct observer *record_btrace_thread_observer;
 
-/* Temporarily allow memory accesses.  */
-static int record_btrace_allow_memory_access;
+/* Memory access types used in set/show record btrace replay-memory-access.  */
+static const char replay_memory_access_read_only[] = "read-only";
+static const char replay_memory_access_read_write[] = "read-write";
+static const char *const replay_memory_access_types[] =
+{
+  replay_memory_access_read_only,
+  replay_memory_access_read_write,
+  NULL
+};
+
+/* The currently allowed replay memory access type.  */
+static const char *replay_memory_access = replay_memory_access_read_only;
+
+/* Command lists for "set/show record btrace".  */
+static struct cmd_list_element *set_record_btrace_cmdlist;
+static struct cmd_list_element *show_record_btrace_cmdlist;
 
 /* Print a record-btrace debug message.  Use do ... while (0) to avoid
    ambiguities when used in if statements.  */
@@ -816,7 +830,8 @@ record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
   struct target_ops *t;
 
   /* Filter out requests that don't make sense during replay.  */
-  if (!record_btrace_allow_memory_access && record_btrace_is_replaying (ops))
+  if (replay_memory_access == replay_memory_access_read_only
+      && record_btrace_is_replaying (ops))
     {
       switch (object)
        {
@@ -870,18 +885,19 @@ record_btrace_insert_breakpoint (struct target_ops *ops,
                                 struct bp_target_info *bp_tgt)
 {
   volatile struct gdb_exception except;
-  int old, ret;
+  const char *old;
+  int ret;
 
   /* Inserting breakpoints requires accessing memory.  Allow it for the
      duration of this function.  */
-  old = record_btrace_allow_memory_access;
-  record_btrace_allow_memory_access = 1;
+  old = replay_memory_access;
+  replay_memory_access = replay_memory_access_read_write;
 
   ret = 0;
   TRY_CATCH (except, RETURN_MASK_ALL)
     ret = ops->beneath->to_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
 
-  record_btrace_allow_memory_access = old;
+  replay_memory_access = old;
 
   if (except.reason < 0)
     throw_exception (except);
@@ -897,18 +913,19 @@ record_btrace_remove_breakpoint (struct target_ops *ops,
                                 struct bp_target_info *bp_tgt)
 {
   volatile struct gdb_exception except;
-  int old, ret;
+  const char *old;
+  int ret;
 
   /* Removing breakpoints requires accessing memory.  Allow it for the
      duration of this function.  */
-  old = record_btrace_allow_memory_access;
-  record_btrace_allow_memory_access = 1;
+  old = replay_memory_access;
+  replay_memory_access = replay_memory_access_read_write;
 
   ret = 0;
   TRY_CATCH (except, RETURN_MASK_ALL)
     ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
 
-  record_btrace_allow_memory_access = old;
+  replay_memory_access = old;
 
   if (except.reason < 0)
     throw_exception (except);
@@ -1939,6 +1956,32 @@ cmd_record_btrace_start (char *args, int from_tty)
   execute_command ("target record-btrace", from_tty);
 }
 
+/* The "set record btrace" command.  */
+
+static void
+cmd_set_record_btrace (char *args, int from_tty)
+{
+  cmd_show_list (set_record_btrace_cmdlist, from_tty, "");
+}
+
+/* The "show record btrace" command.  */
+
+static void
+cmd_show_record_btrace (char *args, int from_tty)
+{
+  cmd_show_list (show_record_btrace_cmdlist, from_tty, "");
+}
+
+/* The "show record btrace replay-memory-access" command.  */
+
+static void
+cmd_show_replay_memory_access (struct ui_file *file, int from_tty,
+                              struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (gdb_stdout, _("Replay memory access is %s.\n"),
+                   replay_memory_access);
+}
+
 void _initialize_record_btrace (void);
 
 /* Initialize btrace commands.  */
@@ -1951,6 +1994,29 @@ _initialize_record_btrace (void)
           &record_cmdlist);
   add_alias_cmd ("b", "btrace", class_obscure, 1, &record_cmdlist);
 
+  add_prefix_cmd ("btrace", class_support, cmd_set_record_btrace,
+                 _("Set record options"), &set_record_btrace_cmdlist,
+                 "set record btrace ", 0, &set_record_cmdlist);
+
+  add_prefix_cmd ("btrace", class_support, cmd_show_record_btrace,
+                 _("Show record options"), &show_record_btrace_cmdlist,
+                 "show record btrace ", 0, &show_record_cmdlist);
+
+  add_setshow_enum_cmd ("replay-memory-access", no_class,
+                       replay_memory_access_types, &replay_memory_access, _("\
+Set what memory accesses are allowed during replay."), _("\
+Show what memory accesses are allowed during replay."),
+                          _("Default is READ-ONLY.\n\n\
+The btrace record target does not trace data.\n\
+The memory therefore corresponds to the live target and not \
+to the current replay position.\n\n\
+When READ-ONLY, allow accesses to read-only memory during replay.\n\
+When READ-WRITE, allow accesses to read-only and read-write memory during \
+replay."),
+                          NULL, cmd_show_replay_memory_access,
+                          &set_record_btrace_cmdlist,
+                          &show_record_btrace_cmdlist);
+
   init_record_btrace_ops ();
   add_target (&record_btrace_ops);
 
index 1473d9681b1f242a7bf3c7acfb6251637ad78e41..fdbae2573e922f112f2f2a45f7d11f6103591b8b 100644 (file)
@@ -1,3 +1,7 @@
+2014-05-23  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * gdb.btrace/data.exp: Test memory access during btrace replay.
+
 2014-05-22  Simon Marchi  <simon.marchi@ericsson.com>
 
        * lib/mi-support.exp (mi_run_cmd_full): Add comments.
index 64c5443ae450df0615d3f8169267551a85622533..91d8d8bd7d758a8ea8a550040d50a9f6f5cc18f6 100644 (file)
@@ -40,6 +40,14 @@ gdb_test "reverse-step" ".*test\.4.*"
 gdb_test "print glob" "unavailable\[^\\\r\\\n\]*"
 gdb_test "print loc" "unavailable\[^\\\r\\\n\]*"
 
+# we can read memory if we explicitly allow it.
+gdb_test_no_output "set record btrace replay-memory-access read-write"
+gdb_test "print glob" "1"
+
+# we can't if we don't explicitly allow it.
+gdb_test_no_output "set record btrace replay-memory-access read-only"
+gdb_test "print glob" "unavailable\[^\\\r\\\n\]*"
+
 # stop replaying and try again
-gdb_test "record goto end"
+gdb_test "record goto end" ".*main\.3.*"
 gdb_test "print glob" "1"