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

Vladimir Prus
2007-01-05T09:06:12Z

[-- Attachment #1: Type: text/plain, Size: 1618 bytes --]

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.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: varobj_for_registers__gdb_mainline.diff --]
[-- Type: text/x-diff; name="varobj_for_registers__gdb_mainline.diff", Size: 11339 bytes --]

--- 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);
+}
\f
/* 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