[binutils-gdb] gdb: add shadowed field in '-stack-list-locals/variables' mi commands
Abdul Basit Ijaz via Gdb-cvs <[email protected]> Fri, 17 Jul 2026 17:39:36 +0000 (GMT)
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D6972c12631dc= 51de151b04fc31b0eaa91d3ccc05 commit 6972c12631dc51de151b04fc31b0eaa91d3ccc05 Author: Ijaz, Abdul B <[email protected]> Date: Fri Sep 15 15:18:07 2023 +0200 gdb: add shadowed field in '-stack-list-locals/variables' mi commands =20 For C/C++/Fortran languages GDB prints same name variable multiple time= s in case of variable shadowing and it is confusing for user to identify whi= ch variable belongs to the current scope. So GDB now prints location info= rmation for shadowed variables and add 'shadowed' field also in '-stack-list-lo= cals' and '-stack-list-variables' mi commands for super-block shadowed variab= le. =20 Suppose we have test.c file =20 1:int x =3D 3; 2: { 3: int x =3D 4; 4: int y =3D 5; 5: x =3D 99; /* break here */ 6: } =20 The "-stack-list-locals" and "-stack-list-variables" mi commands at the "break here" line gives the following output: =20 Before the change: =20 ~~~ (gdb) -stack-list-locals 0 ^done,locals=3D[name=3D"x",name=3D"y",name=3D"x"] (gdb) -stack-list-locals 1 ^done,locals=3D[{name=3D"x",value=3D"4"},{name=3D"y",value=3D"5"},{name= =3D"x",value=3D"3"}] (gdb) -stack-list-locals 2 ^done,locals=3D[{name=3D"x",type=3D"int",value=3D"4"},{name=3D"y",type= =3D"int",value=3D"5"},{name=3D"x",type=3D"int",value=3D"3"}] (gdb) -stack-list-variables 0 ^done,variables=3D[{name=3D"x"},{name=3D"y"},{name=3D"x"}] (gdb) -stack-list-variables 1 ^done,variables=3D[{name=3D"x",value=3D"4"},{name=3D"y",value=3D"5"},{n= ame=3D"x",value=3D"3"}] (gdb) -stack-list-variables 2 ^done,variables=3D[{name=3D"x",type=3D"int",value=3D"4"},{name=3D"y",ty= pe=3D"int",value=3D"5"},{name=3D"x",type=3D"int",value=3D"3"}] ~~~ =20 With this patch we obtain: =20 ~~~ (gdb) -stack-list-locals 0 ^done,locals=3D[name=3D"x",name=3D"y",name=3D"x"] (gdb) -stack-list-locals 1 ^done,locals=3D[{name=3D"x",value=3D"4",filename=3D"../test.c",fullname= =3D"/home/src/test.c",line=3D"3"},{name=3D"y",value=3D"5"},{name=3D"x",valu= e=3D"3",filename=3D"../test.c",fullname=3D"/home/src/test.c",line=3D"1",sha= dowed=3D"true"}] (gdb) -stack-list-locals 2 ^done,locals=3D[{name=3D"x",type=3D"int",value=3D"4",filename=3D"../tes= t.c",fullname=3D"/home/src/test.c",line=3D"3"},{name=3D"y",type=3D"int",val= ue=3D"5"},{name=3D"x",type=3D"int",value=3D"3",filename=3D"../test.c",fulln= ame=3D"/home/src/test.c",line=3D"1",shadowed=3D"true"}] (gdb) -stack-list-variables 0 ^done,variables=3D[{name=3D"x",filename=3D"../test.c",fullname=3D"/home= /src/test.c",line=3D"3"},{name=3D"y"},{name=3D"x",filename=3D"../test.c",fu= llname=3D"/home/src/test.c",line=3D"1",shadowed=3D"true"}] (gdb) -stack-list-variables 1 ^done,variables=3D[{name=3D"x",value=3D"4",filename=3D"../test.c",fulln= ame=3D"/home/src/test.c",line=3D"3"},{name=3D"y",value=3D"5"},{name=3D"x",v= alue=3D"3",filename=3D"../test.c",fullname=3D"/home/src/test.c",line=3D"1",= shadowed=3D"true"}] (gdb) -stack-list-variables 2 ^done,variables=3D[{name=3D"x",type=3D"int",value=3D"4",filename=3D"../= test.c",fullname=3D"/home/src/test.c",line=3D"3"},{name=3D"y",type=3D"int",= value=3D"5"},{name=3D"x",type=3D"int",value=3D"3",filename=3D"../test.c",fu= llname=3D"/home/src/test.c",line=3D"1",shadowed=3D"true"}] ~~~ =20 Reviewed-By: Guinevere Larsen <[email protected]> Approved-By: Andrew Burgess <[email protected]> Diff: --- gdb/NEWS | 4 + gdb/doc/gdb.texinfo | 22 +++++ gdb/mi/mi-cmd-stack.c | 142 +++++++++++++++++++++-----= --- gdb/testsuite/gdb.mi/mi-var-shadowing.c | 50 +++++++++++ gdb/testsuite/gdb.mi/mi-var-shadowing.exp | 144 ++++++++++++++++++++++++++= ++++ 5 files changed, 325 insertions(+), 37 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 5410acc8303..8f40ca5cb11 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -593,6 +593,10 @@ multi-wp-addr in qSupported multiple times, and the same mapping was being reused. In all other cases, this field will have the value 'false'. =20 +** GDB now shows the "shadowed", "filename", "fullname" and "line" + fields in the output of '-stack-list-locals/variables' mi + commands for variables that are shadowed, or which are shadowing. + * Support for stabs debugging format and the a.out/dbx object format is deprecated, and will be removed in GDB 18. =20 diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d2fbe61d8fc..0030698dcee 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -35585,6 +35585,28 @@ If the @code{--skip-unavailable} option is specifi= ed, local variables and arguments that are not available are not listed. Partially available arguments and local variables are still displayed, however. =20 +@smallexample +@group +1: int x =3D 3; +2: @{ +3: int x =3D 4; +4: int y =3D 5; +5: x =3D 99; // breakpoint-line +6: @} +@end group +@group +(gdb) -stack-list-variables 2 +^done,variables=3D[@{name=3D"x",type=3D"int",value=3D"4", +filename=3D"name.c",fullname=3D"/home/src/name.c",line=3D"3"@}, +@{name=3D"y",type=3D"int",value=3D"5"@},@{name=3D"x",type=3D"int", +value=3D"3",filename=3D"name.c",fullname=3D"/home/src/name.c", +line=3D"1",shadowed=3D"true"@}] +@end group +@end smallexample + +The location information and @samp{shadowed} attributes are only added +when variable shadowing is detected (@pxref{shadowed variables}). + @subsubheading Example =20 @smallexample diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c index 280a08d121e..37a470701af 100644 --- a/gdb/mi/mi-cmd-stack.c +++ b/gdb/mi/mi-cmd-stack.c @@ -32,6 +32,8 @@ #include "mi-parse.h" #include <optional> #include "inferior.h" +#include "source.h" +#include "gdbsupport/unordered_map.h" =20 enum what_to_list { locals, arguments, all }; =20 @@ -490,7 +492,9 @@ mi_cmd_stack_list_variables (const char *command, const= char *const *argv, static void list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, enum print_values values, int skip_unavailable, - const frame_print_options &fp_opts) + const frame_print_options &fp_opts, + const gdb::unordered_set<std::string> *shadowed_vars, + gdb::unordered_set<std::string> &printed_vars) { struct ui_out *uiout =3D current_uiout; =20 @@ -514,12 +518,25 @@ list_arg_or_local (const struct frame_arg *arg, enum = what_to_list what, arg->val->type ()->length ())))) return; =20 + string_file stb; + const char *name =3D arg->sym->print_name (); + /* To distinguish innermost variable from the rest in the shadowed_vars + this boolean is needed. */ + bool already_printed =3D !printed_vars.insert (name).second; + bool shadowed =3D shadowed_vars->find (name) !=3D shadowed_vars->end (); + + /* In case of Rust language it is possible to declare variable with + same name multiple times and only latest declaration of variable + is accessible. So print only the first instance and there is no + need of printing duplicates. */ + if (get_lang_vars_shadowing_option (current_language->la_language) + =3D=3D lang_vars_shadowing::HIDE && shadowed && already_printed) + return; + std::optional<ui_out_emit_tuple> tuple_emitter; if (values !=3D PRINT_NO_VALUES || what =3D=3D all) tuple_emitter.emplace (uiout, nullptr); =20 - string_file stb; - stb.puts (arg->sym->print_name ()); if (arg->entry_kind =3D=3D print_entry_values_only) stb.puts ("@entry"); @@ -560,6 +577,67 @@ list_arg_or_local (const struct frame_arg *arg, enum w= hat_to_list what, } uiout->field_stream ("value", stb); } + + /* Only for C/C++/Fortran/Ada languages, in case of variables shadowing + print shadowed field after the superblock variable and only location + of the variables in the innerblock. */ + if (get_lang_vars_shadowing_option (current_language->la_language) + =3D=3D lang_vars_shadowing::PRINT && shadowed + && !(values =3D=3D PRINT_NO_VALUES && what =3D=3D locals)) + { + if (arg->sym->symtab () !=3D nullptr) + { + symtab *symtab =3D arg->sym->symtab (); + + uiout->field_string ("filename", + symtab_to_filename_for_display (symtab)); + uiout->field_string ("fullname", symtab_to_fullname (symtab)); + uiout->field_unsigned ("line", arg->sym->line ()); + } + + if (already_printed) + uiout->field_string ("shadowed", "true"); + } +} + +/* Returns true if address_class can be printed, otherwise returns false. = */ + +static bool +can_print_aclass (struct symbol *sym, enum what_to_list what) +{ + bool print_me =3D false; + + switch (sym->loc_class ()) + { + default: + case LOC_UNDEF: /* catches errors */ + case LOC_CONST: /* constant */ + case LOC_TYPEDEF: /* local typedef */ + case LOC_LABEL: /* local label */ + case LOC_BLOCK: /* local function */ + case LOC_CONST_BYTES: /* loc. byte seq. */ + case LOC_UNRESOLVED: /* unresolved static */ + case LOC_OPTIMIZED_OUT: /* optimized out */ + print_me =3D false; + break; + + case LOC_ARG: /* argument */ + case LOC_REF_ARG: /* reference arg */ + case LOC_REGPARM_ADDR: /* indirect register arg */ + case LOC_LOCAL: /* stack local */ + case LOC_STATIC: /* static */ + case LOC_REGISTER: /* register */ + case LOC_COMPUTED: /* computed location */ + if (what =3D=3D all) + print_me =3D true; + else if (what =3D=3D locals) + print_me =3D !sym->is_argument (); + else + print_me =3D sym->is_argument (); + break; + } + + return print_me; } =20 /* Print a list of the objects for the frame FI in a certain form, @@ -573,9 +651,10 @@ list_args_or_locals (const frame_print_options &fp_opt= s, enum what_to_list what, enum print_values values, const frame_info_ptr &fi, int skip_unavailable) { - const struct block *block; + const struct block *block, *orig_block; const char *name_of_result; struct ui_out *uiout =3D current_uiout; + gdb::unordered_set<std::string> collected_vars, shadowed_vars, printed_v= ars; =20 block =3D get_frame_block (fi, 0); =20 @@ -596,42 +675,31 @@ list_args_or_locals (const frame_print_options &fp_op= ts, =20 ui_out_emit_list list_emitter (uiout, name_of_result); =20 - while (block !=3D 0) + orig_block =3D block; + /* Stored list of shadowed variables later help in identifying them + from the rest. */ + while (block !=3D nullptr) { for (struct symbol *sym : block_iterator_range (block)) { - int print_me =3D 0; - - switch (sym->loc_class ()) + if (can_print_aclass (sym, what)) { - default: - case LOC_UNDEF: /* catches errors */ - case LOC_CONST: /* constant */ - case LOC_TYPEDEF: /* local typedef */ - case LOC_LABEL: /* local label */ - case LOC_BLOCK: /* local function */ - case LOC_CONST_BYTES: /* loc. byte seq. */ - case LOC_UNRESOLVED: /* unresolved static */ - case LOC_OPTIMIZED_OUT: /* optimized out */ - print_me =3D 0; - break; - - case LOC_ARG: /* argument */ - case LOC_REF_ARG: /* reference arg */ - case LOC_REGPARM_ADDR: /* indirect register arg */ - case LOC_LOCAL: /* stack local */ - case LOC_STATIC: /* static */ - case LOC_REGISTER: /* register */ - case LOC_COMPUTED: /* computed location */ - if (what =3D=3D all) - print_me =3D 1; - else if (what =3D=3D locals) - print_me =3D !sym->is_argument (); - else - print_me =3D sym->is_argument (); - break; + const char *name =3D sym->print_name (); + if (!collected_vars.insert (name).second) + shadowed_vars.insert (name); } - if (print_me) + } + if (block->function ()) + break; + block =3D block->superblock (); + } + + block =3D orig_block; + while (block !=3D 0) + { + for (struct symbol *sym : block_iterator_range (block)) + { + if (can_print_aclass (sym, what)) { struct frame_arg arg, entryarg; =20 @@ -657,10 +725,10 @@ list_args_or_locals (const frame_print_options &fp_op= ts, =20 if (arg.entry_kind !=3D print_entry_values_only) list_arg_or_local (&arg, what, values, skip_unavailable, - fp_opts); + fp_opts, &shadowed_vars, printed_vars); if (entryarg.entry_kind !=3D print_entry_values_no) list_arg_or_local (&entryarg, what, values, skip_unavailable, - fp_opts); + fp_opts, &shadowed_vars, printed_vars); } } =20 diff --git a/gdb/testsuite/gdb.mi/mi-var-shadowing.c b/gdb/testsuite/gdb.mi= /mi-var-shadowing.c new file mode 100644 index 00000000000..875e753b485 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-shadowing.c @@ -0,0 +1,50 @@ +/* Copyright (C) 2023-2026 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. = */ + +#include <stdlib.h> + +int +shadowing (void) +{ + int a =3D 100; /* entry bp */ + unsigned int val1 =3D 1; /* val1-d1 */ + unsigned int val2 =3D 2; /* val2-d1 */ + a =3D 101; /* bp for locals 1 */ + { + unsigned int val2 =3D 3; /* val2-d2 */ + unsigned int val3 =3D 4; /* val3-d1 */ + a =3D 102; /* bp for locals 2 */ + { + unsigned int val1 =3D 5; /* val1-d2 */ + a =3D 103; /* bp for locals 3 */ + { + unsigned int val1 =3D 6; /* val1-d3 */ + unsigned int val2 =3D 7; /* val2-d3 */ + unsigned int val3 =3D 8; /* val3-d2 */ + a =3D 104; /* bp for locals 4 */ + } + } + } + a =3D 105; + + return 0; /* bp for locals 5 */ +} + +int +main (void) +{ + shadowing (); + return 0; +} diff --git a/gdb/testsuite/gdb.mi/mi-var-shadowing.exp b/gdb/testsuite/gdb.= mi/mi-var-shadowing.exp new file mode 100644 index 00000000000..3c0dbc2884c --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-shadowing.exp @@ -0,0 +1,144 @@ +# Copyright 2023-2026 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +load_lib mi-support.exp +set MIFLAGS "-i=3Dmi" + +gdb_exit +if [mi_gdb_start] { + continue +} + +standard_testfile + +set opts {debug} +if [build_executable ${testfile}.exp ${testfile} ${srcfile} $opts] { + return +} + +mi_delete_breakpoints +mi_gdb_reinitialize_dir $srcdir/$subdir +mi_gdb_load ${binfile} +mi_runto main + +set bp_line1 [gdb_get_line_number "bp for locals 1"] +set bp_line2 [gdb_get_line_number "bp for locals 2"] +set bp_line3 [gdb_get_line_number "bp for locals 3"] +set bp_line4 [gdb_get_line_number "bp for locals 4"] +set bp_line5 [gdb_get_line_number "bp for locals 5"] + +set val1_d1 [gdb_get_line_number "val1-d1"] +set val1_d2 [gdb_get_line_number "val1-d2"] +set val1_d3 [gdb_get_line_number "val1-d3"] +set val2_d1 [gdb_get_line_number "val2-d1"] +set val2_d2 [gdb_get_line_number "val2-d2"] +set val2_d3 [gdb_get_line_number "val2-d3"] +set val3_d1 [gdb_get_line_number "val3-d1"] +set val3_d2 [gdb_get_line_number "val3-d2"] +set a_line [gdb_get_line_number "entry bp"] + +set fullname "${fullname_syntax}$srcfile" +set filename "\[^\r\n\]+$srcfile" + +set stack_test1_regx "\\^done,(locals|variables)=3D\\\[\{name=3D\"a\",type= =3D\"int\",value=3D\"$decimal\"\},\{name=3D\"val1\",type=3D\"unsigned int\"= ,value=3D\"1\"\},{name=3D\"val2\",type=3D\"unsigned int\",value=3D\"2\"\}\\= \]" +set stack_test2_regx "\\^done,(locals|variables)=3D\\\[\{name=3D\"val2\",t= ype=3D\"unsigned int\",value=3D\"3\",filename=3D\"$filename\",fullname=3D\"= $fullname\",line=3D\"$val2_d2\"\},\{name=3D\"val3\",type=3D\"unsigned int\"= ,value=3D\"4\"\},\{name=3D\"a\",type=3D\"int\",value=3D\"101\"\},\{name=3D\= "val1\",type=3D\"unsigned int\",value=3D\"1\"\},\{name=3D\"val2\",type=3D\"= unsigned int\",value=3D\"2\",filename=3D\"$filename\",fullname=3D\"$fullnam= e\",line=3D\"$val2_d1\",shadowed=3D\"true\"\}\\\]" +set stack_test3_regx "\\^done,(locals|variables)=3D\\\[\{name=3D\"val1\",t= ype=3D\"unsigned int\",value=3D\"5\",filename=3D\"$filename\",fullname=3D\"= $fullname\",line=3D\"$val1_d2\"\},\{name=3D\"val2\",type=3D\"unsigned int\"= ,value=3D\"3\",filename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$= val2_d2\"\},\{name=3D\"val3\",type=3D\"unsigned int\",value=3D\"4\"\},\{nam= e=3D\"a\",type=3D\"int\",value=3D\"102\"\},\{name=3D\"val1\",type=3D\"unsig= ned int\",value=3D\"1\",filename=3D\"$filename\",fullname=3D\"$fullname\",l= ine=3D\"$val1_d1\",shadowed=3D\"true\"\},\{name=3D\"val2\",type=3D\"unsigne= d int\",value=3D\"2\",filename=3D\"$filename\",fullname=3D\"$fullname\",lin= e=3D\"$val2_d1\",shadowed=3D\"true\"\}\\\]" +set stack_test4_regx "\\^done,(locals|variables)=3D\\\[\{name=3D\"val1\",t= ype=3D\"unsigned int\",value=3D\"6\",filename=3D\"$filename\",fullname=3D\"= $fullname\",line=3D\"$val1_d3\"\},\{name=3D\"val2\",type=3D\"unsigned int\"= ,value=3D\"7\",filename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$= val2_d3\"\},\{name=3D\"val3\",type=3D\"unsigned int\",value=3D\"8\",filenam= e=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$val3_d2\"\},\{name=3D\= "val1\",type=3D\"unsigned int\",value=3D\"5\",filename=3D\"$filename\",full= name=3D\"$fullname\",line=3D\"$val1_d2\",shadowed=3D\"true\"\},\{name=3D\"v= al2\",type=3D\"unsigned int\",value=3D\"3\",filename=3D\"$filename\",fullna= me=3D\"$fullname\",line=3D\"$val2_d2\",shadowed=3D\"true\"\},\{name=3D\"val= 3\",type=3D\"unsigned int\",value=3D\"4\",filename=3D\"$filename\",fullname= =3D\"$fullname\",line=3D\"$val3_d1\",shadowed=3D\"true\"\},\{name=3D\"a\",t= ype=3D\"int\",value=3D\"103\"\},\{name=3D\"val1\",type=3D\"unsigned int\",v= alue=3D\"1\",filename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$va= l1_d1\",shadowed=3D\"true\"\},\{name=3D\"val2\",type=3D\"unsigned int\",val= ue=3D\"2\",filename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$val2= _d1\",shadowed=3D\"true\"\}\\\]" +set stack_test5_regx "\\^done,(locals|variables)=3D\\\[\{name=3D\"a\",type= =3D\"int\",value=3D\"105\"\},\{name=3D\"val1\",type=3D\"unsigned int\",valu= e=3D\"1\"\},\{name=3D\"val2\",type=3D\"unsigned int\",value=3D\"2\"\}\\\]" + +mi_gdb_test \ + "-break-insert --source ${srcfile} --line ${bp_line1}" \ + "\\^done.*source ${srcfile} \\-line ${bp_line1}.*" \ + "bp at outermost level" +mi_execute_to "exec-continue" "breakpoint-hit" ".*" ".*" ".*" "${bp_line1}= " \ + { "" "disp=3D\"keep\"" } "continue to outermost level" +mi_gdb_test "-stack-list-locals 0" \ + "\\^done,locals=3D\\\[name=3D\"a\",name=3D\"val1\",name=3D\"val2\"\\\]= " \ + "-stack-list-locals 0 at outermost level" +mi_gdb_test "-stack-list-variables 0" \ + "\\^done,variables=3D\\\[{name=3D\"a\"},{name=3D\"val1\"},{name=3D\"va= l2\"}\\\]" \ + "-stack-list-variables 0 at outermost level" +mi_gdb_test "-stack-list-locals 2" "${stack_test1_regx}" \ + "-stack-list-locals 2 at outermost level" +mi_gdb_test "-stack-list-variables 2" "${stack_test1_regx}" \ + "-stack-list-variables 2 at outermost level" + +mi_gdb_test \ + "-break-insert --source ${srcfile} --line ${bp_line2}" \ + "\\^done.*source ${srcfile} \\-line ${bp_line2}.*" \ + "bp at first level" +mi_execute_to "exec-continue" "breakpoint-hit" ".*" ".*" ".*" "${bp_line2}= " \ + { "" "disp=3D\"keep\"" } "continue to first level" +mi_gdb_test "-stack-list-locals 0" \ + "\\^done,locals=3D\\\[name=3D\"val2\",name=3D\"val3\",name=3D\"a\",nam= e=3D\"val1\",name=3D\"val2\"\\\]" \ + "-stack-list-locals 0 at first level" +mi_gdb_test "-stack-list-variables 0" \ + "\\^done,variables=3D\\\[{name=3D\"val2\",filename=3D\"$filename\",ful= lname=3D\"$fullname\",line=3D\"$val2_d2\"},{name=3D\"val3\"},{name=3D\"a\"}= ,{name=3D\"val1\"},{name=3D\"val2\",filename=3D\"$filename\",fullname=3D\"$= fullname\",line=3D\"$val2_d1\",shadowed=3D\"true\"\}\\\]" \ + "-stack-list-variables 0 at first level" +mi_gdb_test "-stack-list-locals 2" "${stack_test2_regx}" \ + "-stack-list-locals 2 at first level" +mi_gdb_test "-stack-list-variables 2" "${stack_test2_regx}" \ + "-stack-list-variables 2 at first level" + +mi_gdb_test \ + "-break-insert --source ${srcfile} --line ${bp_line3}" \ + "\\^done.*source ${srcfile} \\-line ${bp_line3}.*" \ + "bp at second level" +mi_execute_to "exec-continue" "breakpoint-hit" ".*" ".*" ".*" "${bp_line3}= " \ + { "" "disp=3D\"keep\"" } "continue to second level" +mi_gdb_test "-stack-list-locals 0" \ + "\\^done,locals=3D\\\[name=3D\"val1\",name=3D\"val2\",name=3D\"val3\"= ,name=3D\"a\",name=3D\"val1\",name=3D\"val2\"\\\]" \ + "-stack-list-locals 0 at second level" +mi_gdb_test "-stack-list-variables 0" \ + "\\^done,variables=3D\\\[{name=3D\"val1\",filename=3D\"$filename\",fu= llname=3D\"$fullname\",line=3D\"$val1_d2\"},{name=3D\"val2\",filename=3D\"$= filename\",fullname=3D\"$fullname\",line=3D\"$val2_d2\"},{name=3D\"val3\"},= {name=3D\"a\"},{name=3D\"val1\",filename=3D\"$filename\",fullname=3D\"$full= name\",line=3D\"$val1_d1\",shadowed=3D\"true\"\},{name=3D\"val2\",filename= =3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$val2_d1\",shadowed=3D\"= true\"\}\\\]" \ + "-stack-list-variables 0 at second level" +mi_gdb_test "-stack-list-locals 2" "${stack_test3_regx}" \ + "-stack-list-locals 2 at second level" +mi_gdb_test "-stack-list-variables 2" "${stack_test3_regx}" \ + "-stack-list-variables 2 at second level" + +mi_gdb_test \ + "-break-insert --source ${srcfile} --line ${bp_line4}" \ + "\\^done.*source ${srcfile} \\-line ${bp_line4}.*" \ + "bp at third level" +mi_execute_to "exec-continue" "breakpoint-hit" ".*" ".*" ".*" "${bp_line4}= " \ + { "" "disp=3D\"keep\"" } "continue to third level" +mi_gdb_test "-stack-list-locals 0" \ + "\\^done,locals=3D\\\[name=3D\"val1\",name=3D\"val2\",name=3D\"val3\",= name=3D\"val1\",name=3D\"val2\",name=3D\"val3\",name=3D\"a\",name=3D\"val1\= ",name=3D\"val2\"\\\]" \ + "-stack-list-locals 0 at third level" +mi_gdb_test "-stack-list-variables 0" \ + "\\^done,variables=3D\\\[{name=3D\"val1\",filename=3D\"$filename\",ful= lname=3D\"$fullname\",line=3D\"$val1_d3\"},{name=3D\"val2\",filename=3D\"$f= ilename\",fullname=3D\"$fullname\",line=3D\"$val2_d3\"},{name=3D\"val3\",fi= lename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$val3_d2\"},{name= =3D\"val1\",filename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$val= 1_d2\",shadowed=3D\"true\"\},\{name=3D\"val2\",filename=3D\"$filename\",ful= lname=3D\"$fullname\",line=3D\"$val2_d2\",shadowed=3D\"true\"\},\{name=3D\"= val3\",filename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$val3_d1\= ",shadowed=3D\"true\"\},{name=3D\"a\"},{name=3D\"val1\",filename=3D\"$filen= ame\",fullname=3D\"$fullname\",line=3D\"$val1_d1\",shadowed=3D\"true\"\},{n= ame=3D\"val2\",filename=3D\"$filename\",fullname=3D\"$fullname\",line=3D\"$= val2_d1\",shadowed=3D\"true\"\}\\\]" \ + "-stack-list-variables 0 at third level" +mi_gdb_test "-stack-list-locals 2" "${stack_test4_regx}" \ + "-stack-list-locals 2 at third level" +mi_gdb_test "-stack-list-variables 2" "${stack_test4_regx}" \ + "-stack-list-variables 2 at third level" + +mi_gdb_test \ + "-break-insert --source ${srcfile} --line ${bp_line5}" \ + "\\^done.*source ${srcfile} \\-line ${bp_line5}.*" \ + "bp at outermost level last" +mi_execute_to "exec-continue" "breakpoint-hit" ".*" ".*" ".*" "${bp_line5}= " \ + { "" "disp=3D\"keep\"" } "continue to outermost level last" +mi_gdb_test "-stack-list-locals 0" \ + "\\^done,locals=3D\\\[name=3D\"a\",name=3D\"val1\",name=3D\"val2\"\\\]= " \ + "-stack-list-locals 0 at outermost level last" +mi_gdb_test "-stack-list-variables 0" \ + "\\^done,variables=3D\\\[{name=3D\"a\"},{name=3D\"val1\"},{name=3D\"va= l2\"}\\\]" \ + "-stack-list-variables at outermost level last" +mi_gdb_test "-stack-list-locals 2" "${stack_test5_regx}" \ + "-stack-list-locals 2 at outermost level last" +mi_gdb_test "-stack-list-variables 2" "${stack_test5_regx}" \ + "-stack-list-variables 2 at outermost level last"