From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14594 invoked by alias); 21 May 2014 07:01:57 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 14395 invoked by uid 89); 21 May 2014 07:01:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mga03.intel.com Received: from mga03.intel.com (HELO mga03.intel.com) (143.182.124.21) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 21 May 2014 07:01:28 +0000 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 21 May 2014 00:01:26 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by azsmga001.ch.intel.com with ESMTP; 21 May 2014 00:01:23 -0700 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id s4L71Nfo010750; Wed, 21 May 2014 08:01:23 +0100 Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id s4L71MnY004286; Wed, 21 May 2014 09:01:22 +0200 Received: (from mmetzger@localhost) by ulvlx001.iul.intel.com with œ id s4L71ME1004282; Wed, 21 May 2014 09:01:22 +0200 From: Markus Metzger To: palves@redhat.com Cc: gdb-patches@sourceware.org, Eli Zaretskii Subject: [PATCH v3 1/3] btrace: control memory access during replay Date: Wed, 21 May 2014 07:01:00 -0000 Message-Id: <1400655682-4014-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes X-SW-Source: 2014-05/txt/msg00457.txt.bz2 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. CC: Eli Zaretskii 2014-05-21 Markus Metzger * 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/NEWS | 4 ++ gdb/doc/gdb.texinfo | 22 ++++++++++ gdb/record-btrace.c | 88 ++++++++++++++++++++++++++++++++++----- gdb/testsuite/gdb.btrace/data.exp | 10 ++++- 4 files changed, 112 insertions(+), 12 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index b23c8a0..62e0adc 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -61,6 +61,10 @@ maint ada show ignore-descriptive-types the user manual for more details on descriptive types and the intended usage of this option. +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 diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 6092ff4..b9e7964 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -6400,6 +6400,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 diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index d768225..f43436d 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -42,8 +42,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. */ @@ -815,7 +829,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) { @@ -869,18 +884,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); @@ -896,18 +912,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); @@ -1938,6 +1955,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. */ @@ -1950,6 +1993,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); diff --git a/gdb/testsuite/gdb.btrace/data.exp b/gdb/testsuite/gdb.btrace/data.exp index 64c5443..91d8d8b 100644 --- a/gdb/testsuite/gdb.btrace/data.exp +++ b/gdb/testsuite/gdb.btrace/data.exp @@ -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" -- 1.8.3.1