Teach -data-list-register-values to not include unavailable registers

This patch adds an option --skip-unavailable to MI command
-data-list-register-values, so that unavailable registers are not
displayed (on the context of traceframes).

The old -data-list-register-values command behaves like

  -data-list-register-values x 0 8
  ^done,register-values=[{number="0",value="<unavailable>"},{number="8",value="0x80483de"}]

With this patch, an option --skip-unavailable is added,

  -data-list-register-values --skip-unavailable x 0 8
  ^done,register-values=[{number="8",value="0x80483de"}]

gdb:

2013-06-20  Pedro Alves  <pedro@codesourcery.com>
	    Yao Qi  <yao@codesourcery.com>

	* NEWS: Mention the new option '--skip-unavailable' of command
	-data-list-register-values.
	* mi/mi-main.c (mi_cmd_data_list_register_values): Accept the
	--skip-unavailable option.  Adjust to use output_register.
	(output_register): Add new 'skip_unavailable' parameter.
	Handle it.

gdb/doc:

2013-06-20  Pedro Alves  <pedro@codesourcery.com>

	* gdb.texinfo (GDB/MI Data Manipulation)
	<-data-list-register-values>: Document the --skip-unavailable
	option.

gdb/testsuite:

2013-06-20  Yao Qi  <yao@codesourcery.com>

	* gdb.trace/mi-trace-unavailable.exp: Set tracepoint on 'foo'
	and set an action.
	(test_trace_unavailable): Test command -data-list-register-values
	in the context of traceframe and with option --skip-unavailable.
	* gdb.trace/trace-unavailable.c (foo): New.
	(main): Call it.
	* gdb.mi/gdb2549.exp: Update matching pattern.
This commit is contained in:
Yao Qi
2013-06-20 00:39:11 +00:00
parent 181ff4a40d
commit c898adb7b2
9 changed files with 124 additions and 17 deletions

View File

@ -1,3 +1,13 @@
2013-06-20 Pedro Alves <pedro@codesourcery.com>
Yao Qi <yao@codesourcery.com>
* NEWS: Mention the new option '--skip-unavailable' of command
-data-list-register-values.
* mi/mi-main.c (mi_cmd_data_list_register_values): Accept the
--skip-unavailable option. Adjust to use output_register.
(output_register): Add new 'skip_unavailable' parameter.
Handle it.
2013-06-19 Mike Frysinger <vapier@gentoo.org> 2013-06-19 Mike Frysinger <vapier@gentoo.org>
* Makefile.in (HFILES_NO_SRCDIR): Add common/i386-cpuid.h and * Makefile.in (HFILES_NO_SRCDIR): Add common/i386-cpuid.h and

View File

@ -76,6 +76,10 @@ show range-stepping
** The new command -dprintf-insert sets a dynamic printf breakpoint. ** The new command -dprintf-insert sets a dynamic printf breakpoint.
** The command -data-list-register-values now accepts an optional
"--skip-unavailable" option. When used, only the available registers
are displayed.
* New system-wide configuration scripts * New system-wide configuration scripts
A GDB installation now provides scripts suitable for use as system-wide A GDB installation now provides scripts suitable for use as system-wide
configuration scripts for the following systems: configuration scripts for the following systems:

View File

@ -1,3 +1,9 @@
2013-06-20 Pedro Alves <pedro@codesourcery.com>
* gdb.texinfo (GDB/MI Data Manipulation)
<-data-list-register-values>: Document the --skip-unavailable
option.
2013-06-07 Yao Qi <yao@codesourcery.com> 2013-06-07 Yao Qi <yao@codesourcery.com>
* gdb.texinfo (Symbols): Add kindex and cindex for * gdb.texinfo (Symbols): Add kindex and cindex for

View File

@ -32726,13 +32726,16 @@ For the PPC MBX board:
@subsubheading Synopsis @subsubheading Synopsis
@smallexample @smallexample
-data-list-register-values @var{fmt} [ ( @var{regno} )*] -data-list-register-values
[ @code{--skip-unavailable} ] @var{fmt} [ ( @var{regno} )*]
@end smallexample @end smallexample
Display the registers' contents. @var{fmt} is the format according to Display the registers' contents. @var{fmt} is the format according to
which the registers' contents are to be returned, followed by an optional which the registers' contents are to be returned, followed by an optional
list of numbers specifying the registers to display. A missing list of list of numbers specifying the registers to display. A missing list of
numbers indicates that the contents of all the registers must be returned. numbers indicates that the contents of all the registers must be
returned. The @code{--skip-unavailable} option indicates that only
the available registers are to be returned.
Allowed formats for @var{fmt} are: Allowed formats for @var{fmt} are:

View File

@ -103,7 +103,8 @@ static void mi_execute_async_cli_command (char *cli_command,
char **argv, int argc); char **argv, int argc);
static int register_changed_p (int regnum, struct regcache *, static int register_changed_p (int regnum, struct regcache *,
struct regcache *); struct regcache *);
static void output_register (struct frame_info *, int regnum, int format); static void output_register (struct frame_info *, int regnum, int format,
int skip_unavailable);
/* Command implementations. FIXME: Is this libgdb? No. This is the MI /* Command implementations. FIXME: Is this libgdb? No. This is the MI
layer that calls libgdb. Any operation used in the below should be layer that calls libgdb. Any operation used in the below should be
@ -1073,6 +1074,17 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc)
int regnum, numregs, format; int regnum, numregs, format;
int i; int i;
struct cleanup *list_cleanup; struct cleanup *list_cleanup;
int skip_unavailable = 0;
int oind = 0;
enum opt
{
SKIP_UNAVAILABLE,
};
static const struct mi_opt opts[] =
{
{"-skip-unavailable", SKIP_UNAVAILABLE, 0},
{ 0, 0, 0 }
};
/* Note that the test for a valid register must include checking the /* Note that the test for a valid register must include checking the
gdbarch_register_name because gdbarch_num_regs may be allocated gdbarch_register_name because gdbarch_num_regs may be allocated
@ -1081,11 +1093,28 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc)
will change depending upon the particular processor being will change depending upon the particular processor being
debugged. */ debugged. */
if (argc == 0) while (1)
error (_("-data-list-register-values: Usage: " {
"-data-list-register-values <format> [<regnum1>...<regnumN>]")); char *oarg;
int opt = mi_getopt ("-data-list-register-values", argc, argv,
opts, &oind, &oarg);
format = (int) argv[0][0]; if (opt < 0)
break;
switch ((enum opt) opt)
{
case SKIP_UNAVAILABLE:
skip_unavailable = 1;
break;
}
}
if (argc - oind < 1)
error (_("-data-list-register-values: Usage: "
"-data-list-register-values [--skip-unavailable] <format>"
" [<regnum1>...<regnumN>]"));
format = (int) argv[oind][0];
frame = get_selected_frame (NULL); frame = get_selected_frame (NULL);
gdbarch = get_frame_arch (frame); gdbarch = get_frame_arch (frame);
@ -1093,7 +1122,7 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc)
list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values"); list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");
if (argc == 1) if (argc - oind == 1)
{ {
/* No args, beside the format: do all the regs. */ /* No args, beside the format: do all the regs. */
for (regnum = 0; for (regnum = 0;
@ -1104,12 +1133,12 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc)
|| *(gdbarch_register_name (gdbarch, regnum)) == '\0') || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
continue; continue;
output_register (frame, regnum, format); output_register (frame, regnum, format, skip_unavailable);
} }
} }
/* Else, list of register #s, just do listed regs. */ /* Else, list of register #s, just do listed regs. */
for (i = 1; i < argc; i++) for (i = 1 + oind; i < argc; i++)
{ {
regnum = atoi (argv[i]); regnum = atoi (argv[i]);
@ -1117,31 +1146,35 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc)
&& regnum < numregs && regnum < numregs
&& gdbarch_register_name (gdbarch, regnum) != NULL && gdbarch_register_name (gdbarch, regnum) != NULL
&& *gdbarch_register_name (gdbarch, regnum) != '\000') && *gdbarch_register_name (gdbarch, regnum) != '\000')
output_register (frame, regnum, format); output_register (frame, regnum, format, skip_unavailable);
else else
error (_("bad register number")); error (_("bad register number"));
} }
do_cleanups (list_cleanup); do_cleanups (list_cleanup);
} }
/* Output register REGNUM's contents in the desired FORMAT. */ /* Output one register REGNUM's contents in the desired FORMAT. If
SKIP_UNAVAILABLE is true, skip the register if it is
unavailable. */
static void static void
output_register (struct frame_info *frame, int regnum, int format) output_register (struct frame_info *frame, int regnum, int format,
int skip_unavailable)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct ui_out *uiout = current_uiout; struct ui_out *uiout = current_uiout;
struct value *val; struct value *val = get_frame_register_value (frame, regnum);
struct cleanup *tuple_cleanup; struct cleanup *tuple_cleanup;
if (skip_unavailable && !value_entirely_available (val))
return;
tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
ui_out_field_int (uiout, "number", regnum); ui_out_field_int (uiout, "number", regnum);
if (format == 'N') if (format == 'N')
format = 0; format = 0;
val = get_frame_register_value (frame, regnum);
if (value_optimized_out (val)) if (value_optimized_out (val))
error (_("Optimized out")); error (_("Optimized out"));

View File

@ -1,3 +1,13 @@
2013-06-20 Yao Qi <yao@codesourcery.com>
* gdb.trace/mi-trace-unavailable.exp: Set tracepoint on 'foo'
and set an action.
(test_trace_unavailable): Test command -data-list-register-values
in the context of traceframe and with option --skip-unavailable.
* gdb.trace/trace-unavailable.c (foo): New.
(main): Call it.
* gdb.mi/gdb2549.exp: Update matching pattern.
2013-06-19 Mike Frysinger <vapier@gentoo.org> 2013-06-19 Mike Frysinger <vapier@gentoo.org>
* gdb.arch/i386-avx.c (have_avx): Change __get_cpuid call to i386_cpuid. * gdb.arch/i386-avx.c (have_avx): Change __get_cpuid call to i386_cpuid.

View File

@ -40,7 +40,7 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
proc register_tests_no_exec { } { proc register_tests_no_exec { } {
# Test the generic IDT chip. # Test the generic IDT chip.
mi_gdb_test "111-data-list-register-values" \ mi_gdb_test "111-data-list-register-values" \
".*111\\^error,msg=\"-data-list-register-values: Usage: -data-list-register-values <format> \\\[<regnum1>...<regnumN>\\\]\"" \ ".*111\\^error,msg=\"-data-list-register-values: Usage: -data-list-register-values \\\[--skip-unavailable\\\] <format> \\\[<regnum1>...<regnumN>\\\]\"" \
"wrong arguments" "wrong arguments"
mi_gdb_test "111-data-list-register-values x" \ mi_gdb_test "111-data-list-register-values x" \

View File

@ -52,6 +52,14 @@ mi_gdb_test "-break-insert -a bar" \
mi_gdb_test "-break-commands 3 \"collect array\" \"collect j\" \"end\" " \ mi_gdb_test "-break-commands 3 \"collect array\" \"collect j\" \"end\" " \
{\^done} "set action" {\^done} "set action"
mi_gdb_test "-break-insert -a foo" \
"\\^done,bkpt=\{number=\"${decimal}\",type=\"tracepoint\".*\"\}" \
"insert tracepoint on foo"
# Collect 'main' to make sure no registers are collected except PC.
mi_gdb_test "-break-commands 4 \"collect main\" \"end\" " \
{\^done} "set action on tracepoint 4"
mi_gdb_test "-trace-start" {.*\^done} "trace start" mi_gdb_test "-trace-start" {.*\^done} "trace start"
mi_send_resuming_command "exec-continue" "continuing to marker" mi_send_resuming_command "exec-continue" "continuing to marker"
mi_expect_stop \ mi_expect_stop \
@ -96,6 +104,34 @@ proc test_trace_unavailable { data_source } {
".*\\^done,variables=\\\[\{name=\"j\",arg=\"1\",type=\"int\",value=\"4\"\},\{name=\"s\",arg=\"1\",type=\"char \\\*\",value=\"<unavailable>\"\},\{name=\"array\",type=\"unsigned char \\\[2\\\]\"\},\{name=\"i\",type=\"int\",value=\"<unavailable>\"\}\\\]" \ ".*\\^done,variables=\\\[\{name=\"j\",arg=\"1\",type=\"int\",value=\"4\"\},\{name=\"s\",arg=\"1\",type=\"char \\\*\",value=\"<unavailable>\"\},\{name=\"array\",type=\"unsigned char \\\[2\\\]\"\},\{name=\"i\",type=\"int\",value=\"<unavailable>\"\}\\\]" \
"-stack-list-variables --simple-values" "-stack-list-variables --simple-values"
mi_gdb_test "-trace-find frame-number 1" \
".*\\^done,found=\"1\",tracepoint=\"${decimal}\",traceframe=\"1\",frame=\{.*" \
"-trace-find frame-number 1"
set pcnum 0
if [is_amd64_regs_target] {
set pcnum 16
} elseif [is_x86_like_target] {
set pcnum 8
} else {
# Other ports support tracepoint should define the number
# of its own pc register.
}
if { $pcnum != 0 } {
global hex
# Test that register 0 and PC are displayed, and register
# 0 is unavailable.
mi_gdb_test "-data-list-register-values x 0 ${pcnum}" \
".*\\^done,register-values=\\\[\{number=\"0\",value=\"<unavailable>\"\},\{number=\"${pcnum}\",value=\"${hex}\"\}\\\]" \
"-data-list-register-values x"
# Test that only available register PC is displayed.
mi_gdb_test "-data-list-register-values --skip-unavailable x 0 ${pcnum}" \
".*\\^done,register-values=\\\[\{number=\"${pcnum}\",value=\"${hex}\"\}\\\]" \
"-data-list-register-values --skip-unavailable x"
}
# Don't issue command '-trace-find none' to return from # Don't issue command '-trace-find none' to return from
# tfind mode (examining trace frames) on purpose, in order # tfind mode (examining trace frames) on purpose, in order
# to test that GDB is able to clear its tracing-related local state # to test that GDB is able to clear its tracing-related local state

View File

@ -25,6 +25,10 @@ bar (int j, char *s)
array[1] = 'd'; array[1] = 'd';
} }
static void
foo (void)
{}
static void static void
marker (void) marker (void)
{} {}
@ -35,6 +39,7 @@ main (void)
char s[4]; char s[4];
bar (4, s); bar (4, s);
foo ();
marker (); marker ();
return 0; return 0;
} }