btrace: control memory access during replay

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.
This commit is contained in:
Markus Metzger 2014-03-05 15:38:11 +01:00
parent 4c6bdb4026
commit 67b5c0c1a4
7 changed files with 136 additions and 13 deletions

View 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.

View file

@ -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

View 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

View 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

View 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);

View 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.

View 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\]*"
# stop replaying and try again
gdb_test "record goto end"
# 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" ".*main\.3.*"
gdb_test "print glob" "1"