From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14217 invoked by alias); 5 Jan 2007 09:01:07 -0000 Received: (qmail 13718 invoked by uid 22791); 5 Jan 2007 09:01:03 -0000 X-Spam-Check-By: sourceware.org Received: from zigzag.lvk.cs.msu.su (HELO zigzag.lvk.cs.msu.su) (158.250.17.23) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 05 Jan 2007 09:00:56 +0000 Received: from Debian-exim by zigzag.lvk.cs.msu.su with spam-scanned (Exim 4.50) id 1H2kwQ-0006lM-Sq for gdb-patches@sources.redhat.com; Fri, 05 Jan 2007 12:00:52 +0300 Received: from localhost ([127.0.0.1] helo=ip6-localhost) by zigzag.lvk.cs.msu.su with esmtp (Exim 4.50) id 1H2kwG-0006jG-GK; Fri, 05 Jan 2007 12:00:37 +0300 From: Vladimir Prus Subject: Re: [mi] [ada] varobjs for registers 2 To: Eli Zaretskii , gdb-patches@sources.redhat.com Date: Fri, 05 Jan 2007 09:01:00 -0000 References: <200612202137.29038.vladimir@codesourcery.com> User-Agent: KNode/0.10.2 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart1230712.DVuoQyRfoS" Content-Transfer-Encoding: 7Bit Message-Id: Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-01/txt/msg00175.txt.bz2 --nextPart1230712.DVuoQyRfoS Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8Bit Content-length: 1658 Eli Zaretskii wrote: >> From: Vladimir Prus >> Date: Wed, 20 Dec 2006 21:37:28 +0300 >> >> 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? > > Thanks. > > The patch for the manual is approved, but please take care of these > minor problems: > >> +This command is intended to efficiently create a number of variable >> +objects---for example for registers, or for local variables. Using >> +the @code{-var-create} command would not be ideal, because it must be >> +issued once for every variable object. > > Please add a cross-reference to the description of -var-create here. Is Using the @code{-var-create} (@pxref{-var-list-children}) command the right texinfo way to do a reference? >> +a list of tuples. Each tuple describes a single variable object in >> +the same was as for the @code{-var-create} command: > ^^^^^^^^^^^^^^^^^^^ > Something's wrong here. It meant to be: the same way as for the @code{-var-create} command: Revised patch attached. In addition to the changes you've suggested, I've reworded the first paragraph to more explicitly document that -var-list tries to return previously-created varobjs, as Nick and I discussed. OK? - Volodya --nextPart1230712.DVuoQyRfoS Content-Type: text/x-diff; name="varobj_for_registers__gdb_mainline.diff" Content-Transfer-Encoding: 8Bit Content-Disposition: attachment; filename="varobj_for_registers__gdb_mainline.diff" Content-length: 11339 --- 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 #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 --nextPart1230712.DVuoQyRfoS--