This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [mi] [ada] varobjs for registers 2


Daniel Jacobowitz wrote:

> On Wed, Dec 20, 2006 at 09:37:28PM +0300, Vladimir Prus wrote:
>> 
>> This is a second revision of the patch to add MI command that
>> creates varobjs for registers. The command is renamed to -var-list
>> and used like:
>> 
>> -var-list --registers
>> 
>> There are now docs and tests. The created variable objects no longer
>> have 'public' pseudo-fields, no matter what the language of the program
>> is.
>> 
>> Along the way, I've promoted a private function in ada-lang.c to
>> language.c, so I'd appreciate if Ada maintainers take a quick look.
>> 
>> OK?
> 
> Before I look at this, is it the latest version?  You and Nick had an
> active discussion about this while I was on vacation.

I think only manual changes were done, but just in case, the most recent
version I have is attached.

- Volodya

        Implement the -var-list command, with initial support
        for listing registers.
        * mi/mi-cmds.h (mi_cmd_var_list): New.
        * mi/mi-cmds.c: Register "var-list".
        * mi/mi-cmd-var.c (create_varobj_in_frame): New function.
        (mi_cmd_var_create): Use the above.
        (restore_language_mode): New.
        (mi_cmd_var_list): New.
        * language.h (restore_language): Declare.
        * language.c (restore_language): New function.
        * ada-lang.c (restore_language): Remove.
        (lookup_symbol_in_language): Adjust.
        * Makefile (mi-cmd-var.o): Update dependencies.

        doc/
        * gdb.texinfo (GDB/MI Variable Objects): Document
        -var-list.

        testsuite/
        * gdb.mi/mi-var-cmd.exp: Test for -var-list.
--- gdb/ada-lang.c	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/ada-lang.c	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -4210,13 +4210,7 @@ add_symbols_from_enclosing_procs (struct
 {
 }
 
-/* FIXME: The next two routines belong in symtab.c */
-
-static void
-restore_language (void *lang)
-{
-  set_language ((enum language) lang);
-}
+/* FIXME: The next routine belongs in symtab.c */
 
 /* As for lookup_symbol, but performed as if the current language 
    were LANG. */
@@ -4226,10 +4220,10 @@ lookup_symbol_in_language (const char *n
                            domain_enum domain, enum language lang,
                            int *is_a_field_of_this, struct symtab **symtab)
 {
+  enum language prev_lang = set_language (lang);
   struct cleanup *old_chain
-    = make_cleanup (restore_language, (void *) current_language->la_language);
+    = make_cleanup (restore_language, &prev_lang);
   struct symbol *result;
-  set_language (lang);
   result = lookup_symbol (name, block, domain, is_a_field_of_this, symtab);
   do_cleanups (old_chain);
   return result;
--- gdb/doc/gdb.texinfo	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/doc/gdb.texinfo	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -19600,6 +19600,8 @@ access this functionality:
 
 @item @code{-var-create}
 @tab create a variable object
+@item @code{-var-list}
+@tab create special kinds of variable objects
 @item @code{-var-delete}
 @tab delete the variable object and/or its children
 @item @code{-var-set-format}
@@ -19678,6 +19680,45 @@ the @value{GDBN} CLI:
 @end smallexample
 
 
+@subheading The @code{-var-list} Command
+@findex -var-list
+
+@subsubheading Synopsis
+
+@smallexample
+ -var-list --@var{kind} @{@var{frame-addr} | "*"@}
+@end smallexample
+
+Returns all variable objects of the specified kind, creating them
+if necessary. This command is intended to efficiently obtain a number 
+of variable objects---for example for registers, or for local variables.  Using 
+the @code{-var-create} (@pxref{-var-list-children}) command would 
+not be ideal, because it must be issued once for every variable
+object. In addition, subsequent @code{-var-list} invocations generally 
+try to return variable objects that were created and returned on
+previous invocation, which additionally improves performance.
+
+At the moment the only defined kind is ``registers''. 
+
+The @var{frame-addr} parameter the same semantics as for
+@code{-var-create}.  For registers, any frame but the current must
+be used with caution, as @value{GDBN} can determine the value in the parent
+frames only for a few registers.
+
+@subsubheading Result
+
+The MI result record includes the @samp{result} field whose value is
+a list of tuples.  Each tuple describes a single variable object in
+the same way as for the @code{-var-create} command:
+
+@smallexample
+^done,registers=[
+    {name="var1",exp="$eax",
+     numchild="0",value="16",type="int"},....
+@end smallexample
+
+
+
 @subheading The @code{-var-delete} Command
 @findex -var-delete
 
--- gdb/testsuite/gdb.mi/mi-var-cmd.exp	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/testsuite/gdb.mi/mi-var-cmd.exp	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -599,5 +599,9 @@ mi_gdb_test "-var-update selected_a" \
 	"\\^done,changelist=\\\[\{name=\"selected_a\",in_scope=\"true\",new_type=\"int\",new_num_children=\"0\"\}\\\]" \
 	"update selected_a in do_special_tests"
 
+mi_gdb_test "-var-list --registers *" \
+    "\\^done,result=\\\[{name=\".*\",exp=\".*\",numchild=\".*\",value=\".*\",type=\".*\"},.*" \
+    "create list of registers"
+
 mi_gdb_exit
 return 0
--- gdb/mi/mi-cmds.h	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/mi/mi-cmds.h	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -105,6 +105,7 @@ extern mi_cmd_argv_ftype mi_cmd_thread_l
 extern mi_cmd_argv_ftype mi_cmd_thread_select;
 extern mi_cmd_argv_ftype mi_cmd_var_assign;
 extern mi_cmd_argv_ftype mi_cmd_var_create;
+extern mi_cmd_argv_ftype mi_cmd_var_list;
 extern mi_cmd_argv_ftype mi_cmd_var_delete;
 extern mi_cmd_argv_ftype mi_cmd_var_evaluate_expression;
 extern mi_cmd_argv_ftype mi_cmd_var_info_expression;
--- gdb/mi/mi-cmds.c	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/mi/mi-cmds.c	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -153,6 +153,7 @@ struct mi_cmd mi_cmds[] =
   { "trace-stop", { NULL, 0 }, NULL, NULL },
   { "var-assign", { NULL, 0 }, 0, mi_cmd_var_assign},
   { "var-create", { NULL, 0 }, 0, mi_cmd_var_create},
+  { "var-list", { NULL, 0 }, 0, mi_cmd_var_list},
   { "var-delete", { NULL, 0 }, 0, mi_cmd_var_delete},
   { "var-evaluate-expression", { NULL, 0 }, 0, mi_cmd_var_evaluate_expression},
   { "var-info-expression", { NULL, 0 }, 0, mi_cmd_var_info_expression},
--- gdb/mi/mi-cmd-var.c	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/mi/mi-cmd-var.c	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -29,6 +29,7 @@
 #include "value.h"
 #include <ctype.h>
 #include "gdb_string.h"
+#include "language.h"
 
 const char mi_no_values[] = "--no-values";
 const char mi_simple_values[] = "--simple-values";
@@ -68,16 +69,39 @@ print_varobj (struct varobj *var, enum p
 
 /* VAROBJ operations */
 
+static struct varobj *
+create_varobj_in_frame (char *name, char *expression, char *frame)
+{
+  CORE_ADDR frameaddr = 0;
+  struct cleanup *cleanup;
+  enum varobj_type var_type;
+
+  if (strcmp (frame, "*") == 0)
+    var_type = USE_CURRENT_FRAME;
+  else if (strcmp (frame, "@") == 0)
+    var_type = USE_SELECTED_FRAME;  
+  else
+    {
+      var_type = USE_SPECIFIED_FRAME;
+      frameaddr = string_to_core_addr (frame);
+    }
+
+  if (varobjdebug)
+    fprintf_unfiltered (gdb_stdlog,
+		    "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n",
+			name, frame, paddr (frameaddr), expression);
+
+  return varobj_create (name, expression, frameaddr, var_type);
+}
+
 enum mi_cmd_result
 mi_cmd_var_create (char *command, char **argv, int argc)
 {
-  CORE_ADDR frameaddr = 0;
   struct varobj *var;
   char *name;
   char *frame;
   char *expr;
   struct cleanup *old_cleanups;
-  enum varobj_type var_type;
 
   if (argc != 3)
     {
@@ -105,22 +129,7 @@ mi_cmd_var_create (char *command, char *
   else if (!isalpha (*name))
     error (_("mi_cmd_var_create: name of object must begin with a letter"));
 
-  if (strcmp (frame, "*") == 0)
-    var_type = USE_CURRENT_FRAME;
-  else if (strcmp (frame, "@") == 0)
-    var_type = USE_SELECTED_FRAME;  
-  else
-    {
-      var_type = USE_SPECIFIED_FRAME;
-      frameaddr = string_to_core_addr (frame);
-    }
-
-  if (varobjdebug)
-    fprintf_unfiltered (gdb_stdlog,
-		    "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n",
-			name, frame, paddr (frameaddr), expr);
-
-  var = varobj_create (name, expr, frameaddr, var_type);
+  var = create_varobj_in_frame (name, expr, frame);
 
   if (var == NULL)
     error (_("mi_cmd_var_create: unable to create variable object"));
@@ -131,6 +140,84 @@ mi_cmd_var_create (char *command, char *
   return MI_CMD_DONE;
 }
 
+static void restore_language_mode (void *p)
+{
+  enum language_mode *mode = p;
+  language_mode = *mode;
+}
+
+enum mi_cmd_result
+mi_cmd_var_list (char *command, char **argv, int argc)
+{
+  int regnum, numregs;
+  struct cleanup *cleanup;
+  char *what;
+  char *frame;
+  enum language prev_lang;
+  enum language_mode prev_lang_mode;
+
+  if (argc < 2)
+    error (_("mi_cmd_var_list: Usage: --WHAT FRAME."));
+  
+  what = argv[0];
+
+  if (strcmp (what, "--registers") != 0)
+    error (_("mi_cmd_var_list: invalid kind of object requested."));
+
+  frame = xstrdup (argv[1]);
+  cleanup = make_cleanup (xfree, frame);
+
+
+  /* Force C language for registers, to avoid 'public' pseudo-fields
+     that make no sense for registers.  */
+  prev_lang = set_language (language_c);
+  make_cleanup (restore_language, &prev_lang);
+  /* Also switch the language mode to manual.  Otherwise,
+     when varobj_create calls select_frame, the language
+     will be automatically switched.  */
+  prev_lang_mode = language_mode;
+  language_mode = language_mode_manual;
+  make_cleanup (restore_language_mode, &prev_lang_mode);
+
+  /* Note that the test for a valid register must include checking the
+     REGISTER_NAME because NUM_REGS may be allocated for the union of
+     the register sets within a family of related processors.  In this
+     case, some entries of REGISTER_NAME will change depending upon
+     the particular processor being debugged.  */
+
+  numregs = NUM_REGS + NUM_PSEUDO_REGS;
+
+  make_cleanup_ui_out_list_begin_end (uiout, "result");
+
+  for (regnum = 0; regnum < numregs; regnum++)
+    {
+      if (REGISTER_NAME (regnum) != NULL
+	  && *(REGISTER_NAME (regnum)) != '\0')
+	{
+	  char *name;
+	  char *expression;
+	  struct varobj *var;
+	  struct cleanup *cleanup_child;
+
+	  name = varobj_gen_name ();
+	  make_cleanup (xfree, name);
+
+	  expression = xstrprintf ("$%s", REGISTER_NAME (regnum));
+	  make_cleanup (xfree, expression);
+
+	  var = create_varobj_in_frame (name, expression, frame);
+
+	  cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+	  print_varobj (var, PRINT_ALL_VALUES, 1 /* print expression */);
+	  do_cleanups (cleanup_child);
+	}
+    }
+
+  do_cleanups (cleanup);
+  return MI_CMD_DONE;
+}
+
+
 enum mi_cmd_result
 mi_cmd_var_delete (char *command, char **argv, int argc)
 {
--- gdb/language.c	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/language.c	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -401,6 +401,14 @@ set_language (enum language lang)
 
   return prev_language;
 }
+
+void
+restore_language (void *arg)
+{
+  enum language *lang_p = arg;
+
+  set_language (*lang_p);
+}
 
 /* This page contains functions that update the global vars
    language, type and range. */
--- gdb/language.h	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/language.h	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -472,4 +472,10 @@ extern void default_print_array_index (s
                                        int format,
                                        enum val_prettyprint pretty);
 
+/* Cast 'lang' to 'enum language *', dererence it, and
+   set the current language to the value.  
+
+   This function is intended to be used as cleanup function.  */
+extern void restore_language (void *lang);
+
 #endif /* defined (LANGUAGE_H) */
--- gdb/Makefile.in	(/mirrors/gdb_mainline)	(revision 3057)
+++ gdb/Makefile.in	(/patches/gdb/varobj_for_registers/gdb_mainline)	(revision 3057)
@@ -3113,7 +3113,7 @@ mi-cmd-stack.o: $(srcdir)/mi/mi-cmd-stac
 	$(stack_h) $(dictionary_h) $(gdb_string_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-stack.c
 mi-cmd-var.o: $(srcdir)/mi/mi-cmd-var.c $(defs_h) $(mi_cmds_h) $(ui_out_h) \
-	$(mi_out_h) $(varobj_h) $(value_h) $(gdb_string_h)
+	$(mi_out_h) $(varobj_h) $(value_h) $(gdb_string_h) $(language_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-var.c
 mi-console.o: $(srcdir)/mi/mi-console.c $(defs_h) $(mi_console_h) \
 	$(gdb_string_h)

Property changes on: 
___________________________________________________________________
Name: csl:base
 +/all/mirrors/gdb_mainline
Name: svk:merge
 +e7755896-6108-0410-9592-8049d3e74e28:/mirrors/gdb/trunk:157978


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]