Teach -data-list-register-values to not include unavailable registers
authorYao Qi <yao@codesourcery.com>
Thu, 20 Jun 2013 00:39:11 +0000 (00:39 +0000)
committerYao Qi <yao@codesourcery.com>
Thu, 20 Jun 2013 00:39:11 +0000 (00:39 +0000)
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.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/mi/mi-main.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.mi/gdb2549.exp
gdb/testsuite/gdb.trace/mi-trace-unavailable.exp
gdb/testsuite/gdb.trace/trace-unavailable.c

index 340b66bd16f5af20364a04627d8a830dcda9d9a1..1d19fe6a058fc1eb1f49fb43557b9af6e6fbcd8a 100644 (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>
 
        * Makefile.in (HFILES_NO_SRCDIR): Add common/i386-cpuid.h and
index eea99173f7dccb92d0d6f7842dd9db4ba26698bb..ed1c32f312437b100b63eb4ca34c71ac19a2b886 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -76,6 +76,10 @@ show range-stepping
 
   ** 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
   A GDB installation now provides scripts suitable for use as system-wide
   configuration scripts for the following systems:
index 04e6f30fab19983ca959c1f8dc6b188eab71fa0d..eeb096d99cf43c8792ad1b5bbc721e480ef80627 100644 (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>
 
        * gdb.texinfo (Symbols): Add kindex and cindex for
index e6ec4ffa5612a1b9a56387b9af15308dc719f133..d25cdae3a58143eb7b0e304df3f41e6c83ff8430 100644 (file)
@@ -32726,13 +32726,16 @@ For the PPC MBX board:
 @subsubheading Synopsis
 
 @smallexample
- -data-list-register-values @var{fmt} [ ( @var{regno} )*]
+ -data-list-register-values
+    [ @code{--skip-unavailable} ] @var{fmt} [ ( @var{regno} )*]
 @end smallexample
 
 Display the registers' contents.  @var{fmt} is the format according to
 which the registers' contents are to be returned, followed by an optional
 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:
 
index 956fc5cc58040fc4812dfe8c12785be3dbef9a6a..127f6ff82ec19996938e2b1fde0df4921c2fbb3c 100644 (file)
@@ -103,7 +103,8 @@ static void mi_execute_async_cli_command (char *cli_command,
                                          char **argv, int argc);
 static int register_changed_p (int regnum, 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
    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 i;
   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
      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
      debugged.  */
 
-  if (argc == 0)
+  while (1)
+    {
+      char *oarg;
+      int opt = mi_getopt ("-data-list-register-values", argc, argv,
+                          opts, &oind, &oarg);
+
+      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 <format> [<regnum1>...<regnumN>]"));
+            "-data-list-register-values [--skip-unavailable] <format>"
+            " [<regnum1>...<regnumN>]"));
 
-  format = (int) argv[0][0];
+  format = (int) argv[oind][0];
 
   frame = get_selected_frame (NULL);
   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");
 
-  if (argc == 1)
+  if (argc - oind == 1)
     {
       /* No args, beside the format: do all the regs.  */
       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')
            continue;
 
-         output_register (frame, regnum, format);
+         output_register (frame, regnum, format, skip_unavailable);
        }
     }
 
   /* 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]);
 
@@ -1117,31 +1146,35 @@ mi_cmd_data_list_register_values (char *command, char **argv, int argc)
          && regnum < numregs
          && gdbarch_register_name (gdbarch, regnum) != NULL
          && *gdbarch_register_name (gdbarch, regnum) != '\000')
-       output_register (frame, regnum, format);
+       output_register (frame, regnum, format, skip_unavailable);
       else
        error (_("bad register number"));
     }
   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
-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 ui_out *uiout = current_uiout;
-  struct value *val;
+  struct value *val = get_frame_register_value (frame, regnum);
   struct cleanup *tuple_cleanup;
 
+  if (skip_unavailable && !value_entirely_available (val))
+    return;
+
   tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
   ui_out_field_int (uiout, "number", regnum);
 
   if (format == 'N')
     format = 0;
 
-  val = get_frame_register_value (frame, regnum);
-
   if (value_optimized_out (val))
     error (_("Optimized out"));
 
index 5e359e220b94d1fafff4ec6ab0fc9b37562f47e7..da75aa5ff0801cbb60e939aa6ba10c3ba2d2d607 100644 (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>
 
        * gdb.arch/i386-avx.c (have_avx): Change __get_cpuid call to i386_cpuid.
index 48c3bb39ccdef21958165dc9d5934f45f21a8932..5c1fede6f9cd165597a34734bfd1177ea41ad9bd 100644 (file)
@@ -40,7 +40,7 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
 proc register_tests_no_exec { } {
        # Test the generic IDT chip.
        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"
 
        mi_gdb_test "111-data-list-register-values x" \
index 3098f9aa5fcc80d669ecb0cf7b2508f8b30a956b..42f6e326c2e2e33ca832d00f89e04a7f22e97359 100644 (file)
@@ -52,6 +52,14 @@ mi_gdb_test "-break-insert -a bar" \
 mi_gdb_test "-break-commands 3 \"collect array\" \"collect j\" \"end\" " \
     {\^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_send_resuming_command "exec-continue" "continuing to marker"
 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>\"\}\\\]" \
            "-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
        # tfind mode (examining trace frames) on purpose, in order
        # to test that GDB is able to clear its tracing-related local state
index 9b3e230292e0f846a0dc0ef58d45cd158cadf7e5..407c0691a05ea51556cbdb8ccbf3741aea3a9238 100644 (file)
@@ -25,6 +25,10 @@ bar (int j, char *s)
   array[1] = 'd';
 }
 
+static void
+foo (void)
+{}
+
 static void
 marker (void)
 {}
@@ -35,6 +39,7 @@ main (void)
   char s[4];
 
   bar (4, s);
+  foo ();
   marker ();
   return 0;
 }