From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 0A0823858023 for ; Thu, 12 Oct 2023 09:39:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0A0823858023 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1697103596; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XcRoN5Ho0FbE+YlF6jE2qfcLsw+5FfP2umm+W1fM7SE=; b=CrnKaHbqXhdc0mGaW1l7qwrJpAV5TokpQWJdYxtLf1dLJIitmBU1sUzn8FKx/Yq0i52rsr PrDmoNXR5tORv+q9vInfJItBLuAfiVMIKIxygDOizzQVwMcg51l3t/jy4MCBdzUZy2D604 r78MpuoVxaq7e+dBcIh9Z7fSPqZAir8= Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-613-sbRqyFnUMD-PFdWYlARJGQ-1; Thu, 12 Oct 2023 05:39:55 -0400 X-MC-Unique: sbRqyFnUMD-PFdWYlARJGQ-1 Received: by mail-ed1-f69.google.com with SMTP id 4fb4d7f45d1cf-53e119e615aso512871a12.0 for ; Thu, 12 Oct 2023 02:39:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697103594; x=1697708394; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=XcRoN5Ho0FbE+YlF6jE2qfcLsw+5FfP2umm+W1fM7SE=; b=Sn7llEQbvLmUWLJsdX2roRTQFORHqbQ0oJ/N36tUMDVzPO9qu8uudd9MHmwQ2jrrFW KFfl6p+6OpkLYXM2ppru+h4YqyukN0/NSn5LYEOnBs4wpdYDzF4TM01h6NeYqI8xPfN6 X9ompJssFlBNPohN0/8c+AXWbMdCplQmubMrzE1DRmUMmirzZnt1NrU1JpEpGymlIOik fiqtAZjY/50w0oZ37H6qfzDdL+B6c59dmpMPsXyx+MuS5ynqupT7PL0ukn1km02rkhZ+ yVIX4U+kVGh3sWMkhRNMNW/nEsJC4w4HRmpIX5EJLOXA2j6s+dFQwPoTVHWVQJKzgpe/ q1ig== X-Gm-Message-State: AOJu0YyCd/jjtT5CGU4B4USP6IC1IcL9dScZ8wDskkmgX/Nb4qwldZBM LAjhs+4Sb44nCPVbMHTqzNFIOqm9kF7EmktWeeoQ4VszQ/YrRwo/h3FSiuQYMWBcbXLO4fPRp1d 2ifvMAQTBJ8Xib4hCjb1umQ== X-Received: by 2002:a05:6402:2037:b0:534:2e37:dfd4 with SMTP id ay23-20020a056402203700b005342e37dfd4mr19392972edb.1.1697103594038; Thu, 12 Oct 2023 02:39:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE6b10F+hTW5X1i60dKjk8ZGJqFs2k3WEbtvJty5Nn3q6NlKqMW936D+mRhxDxe0z2wi28iPA== X-Received: by 2002:a05:6402:2037:b0:534:2e37:dfd4 with SMTP id ay23-20020a056402203700b005342e37dfd4mr19392953edb.1.1697103593504; Thu, 12 Oct 2023 02:39:53 -0700 (PDT) Received: from [192.168.0.129] (ip-94-112-227-180.bb.vodafone.cz. [94.112.227.180]) by smtp.gmail.com with ESMTPSA id r19-20020a056402035300b00522828d438csm9981874edw.7.2023.10.12.02.39.52 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 12 Oct 2023 02:39:53 -0700 (PDT) Message-ID: <4f25e938-4729-4b1a-50fd-ce5ae7623d3f@redhat.com> Date: Thu, 12 Oct 2023 11:39:52 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 Subject: Re: [PATCH v4 1/2] gdb: add annotation in 'info locals' command for variables shadowing case To: Abdul Basit Ijaz , gdb-patches@sourceware.org Cc: lsix@lancelotsix.com, pedro@palves.net References: <20230919164700.19891-1-abdul.b.ijaz@intel.com> <20230919164700.19891-2-abdul.b.ijaz@intel.com> From: Guinevere Larsen In-Reply-To: <20230919164700.19891-2-abdul.b.ijaz@intel.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,BODY_8BITS,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,NICE_REPLY_A,RCVD_IN_BARRACUDACENTRAL,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 19/09/2023 18:46, Abdul Basit Ijaz via Gdb-patches wrote: > From: "Ijaz, Abdul B" > > For C/C++/Fortran/Ada languages GDB prints same name variable multiple > times in case of variable shadowing and it is confusing for user to identify > which variable belongs to the current scope. So for such cases add location > info to the innermost listed variables and for super block variables add > "shadowed" annotation in the form of "". > > Suppose we have > > 1:int x = 42; > 2: { > 3: int x = 99; > 4: int y = 52; > 5: x = 99; /* break here */ > 6: } > > Currently: > > (gdb) info locals > x = 99 > x = 42 > y = 52 > > After applying this patch, we obtain: > > (gdb) info locals > x = 99 > y = 52 > x = 42 > > The patch adds the location annotations by keeping track of inner block > and already printed variables to identify shadowing. So, GDB now prints > "" for shadowed super-block variables and > "" for innermost declarations of such variables only. > > The location annotations are printed for shadowed variables in case of > C/C++/Fortran/Ada languages. In Rust, it is possible to declare a > variable with the same name many times. So in this case, just the first > instance of the variable is printed. Thanks for working on this! This patch seems to have slipped through the cracks and needs a small rebase, but the conflict was pretty trivial to resolve locally (inferior.h is also being added to printcmd.c) I see a failure on the newly added test on my fedora37 machine: Breakpoint 1, var_reuse::main () at ../../../downstream-gdb/gdb/testsuite/gdb.rust/var_reuse.rs:19 19          let _y = 8;       // set breakpoint here (gdb) info local _x _x = 0 (gdb) FAIL: gdb.rust/var_reuse.exp: print local _x variable I don't think this is related to the conflict, but I don't really have the time to diagnose what is going on. > --- > gdb/doc/gdb.texinfo | 13 +++ > gdb/printcmd.c | 11 ++- > gdb/stack.c | 64 +++++++++++-- > gdb/stack.h | 3 +- > gdb/testsuite/gdb.ada/var_shadowing.exp | 38 ++++++++ > .../gdb.ada/var_shadowing/var_shadowing.adb | 30 +++++++ > gdb/testsuite/gdb.base/var-shadowing.c | 49 ++++++++++ > gdb/testsuite/gdb.base/var-shadowing.exp | 90 +++++++++++++++++++ > gdb/testsuite/gdb.base/var-shadowing2.c | 16 ++++ > gdb/testsuite/gdb.rust/var_reuse.exp | 32 +++++++ > gdb/testsuite/gdb.rust/var_reuse.rs | 20 +++++ > gdb/tracepoint.c | 3 +- > gdb/value.h | 4 +- > 13 files changed, 362 insertions(+), 11 deletions(-) > create mode 100644 gdb/testsuite/gdb.ada/var_shadowing.exp > create mode 100644 gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb > create mode 100755 gdb/testsuite/gdb.base/var-shadowing.c > create mode 100755 gdb/testsuite/gdb.base/var-shadowing.exp > create mode 100644 gdb/testsuite/gdb.base/var-shadowing2.c > create mode 100755 gdb/testsuite/gdb.rust/var_reuse.exp > create mode 100755 gdb/testsuite/gdb.rust/var_reuse.rs > > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index 9b7e06f3156..6a22bbf2531 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -8831,6 +8831,19 @@ The optional flag @samp{-q}, which stands for @samp{quiet}, disables > printing header information and messages explaining why no local variables > have been printed. > > +@smallexample > +1: int x = 3; > +2: @{ > +3: int x = 4; // breakpt > +4: @} > +(gdb) info locals > +x = 4 > +x = 3 > +@end smallexample > + > +If a variable is shadowed, then location information is printed and for > +the outermost scope variables "shadowed" string is printed as well. > + > @item info locals [-q] [-t @var{type_regexp}] [@var{regexp}] > Like @kbd{info locals}, but only print the local variables selected > with the provided regexp(s). > diff --git a/gdb/printcmd.c b/gdb/printcmd.c > index 8d7d04231fe..83008e5c3f3 100644 > --- a/gdb/printcmd.c > +++ b/gdb/printcmd.c > @@ -55,6 +55,7 @@ > #include "gdbsupport/gdb_optional.h" > #include "gdbsupport/gdb-safe-ctype.h" > #include "gdbsupport/rsp-low.h" > +#include "include/libiberty.h" > > /* Chain containing all defined memory-tag subcommands. */ > > @@ -2401,7 +2402,8 @@ clear_dangling_display_expressions (struct objfile *objfile) > void > print_variable_and_value (const char *name, struct symbol *var, > frame_info_ptr frame, > - struct ui_file *stream, int indent) > + struct ui_file *stream, int indent, > + bool shadowed, bool printed) > { > > if (!name) > @@ -2414,6 +2416,7 @@ print_variable_and_value (const char *name, struct symbol *var, > { > struct value *val; > struct value_print_options opts; > + const char *file_name = lbasename (var->owner.symtab->filename); > > /* READ_VAR_VALUE needs a block in order to deal with non-local > references (i.e. to handle nested functions). In this context, we > @@ -2424,6 +2427,12 @@ print_variable_and_value (const char *name, struct symbol *var, > opts.deref_ref = true; > common_val_print_checked (val, stream, indent, &opts, current_language); > > + if (shadowed) > + /* Print location and shadowed variable information. */ > + fprintf_styled (stream, metadata_style.style (), > + _("\t<%s:%d%s>"), file_name, > + var->line (), printed ? ", shadowed" : ""); > + > /* common_val_print invalidates FRAME when a pretty printer calls inferior > function. */ > frame = NULL; > diff --git a/gdb/stack.c b/gdb/stack.c > index 0b35d62f82f..0173e7341e9 100644 > --- a/gdb/stack.c > +++ b/gdb/stack.c > @@ -56,6 +56,7 @@ > #include "cli/cli-option.h" > #include "cli/cli-style.h" > #include "gdbsupport/buildargv.h" > +#include > > /* The possible choices of "set print frame-arguments", and the value > of this setting. */ > @@ -2211,10 +2212,16 @@ backtrace_command_completer (struct cmd_list_element *ignore, > > static void > iterate_over_block_locals (const struct block *b, > - iterate_over_block_arg_local_vars_cb cb) > + iterate_over_block_arg_local_vars_cb cb, > + const std::unordered_set *shadowed_vars, > + std::unordered_set &printed_vars) > { > for (struct symbol *sym : block_iterator_range (b)) > { > + const char *name = sym->print_name (); > + bool already_printed = !printed_vars.insert (name).second; > + bool shadowed = shadowed_vars->find (name) != shadowed_vars->end (); > + > switch (sym->aclass ()) > { > case LOC_CONST: > @@ -2227,7 +2234,25 @@ iterate_over_block_locals (const struct block *b, > break; > if (sym->domain () == COMMON_BLOCK_DOMAIN) > break; > - cb (sym->print_name (), sym); > + /* Only for C/C++/Fortran/Ada languages, in case of variables > + shadowing print annotation after > + the superblock variable. Iteration of block starts from inner > + block which is printed only with location information. */ > + if ((current_language->la_language == language_c > + || current_language->la_language == language_cplus > + || current_language->la_language == language_fortran > + || current_language->la_language == language_ada) > + && shadowed) > + cb (name, sym, true, already_printed); > + /* 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. */ > + else if (current_language->la_language == language_rust > + && shadowed && already_printed) > + break; > + else > + cb (name, sym, false, false); > break; > > default: > @@ -2244,9 +2269,31 @@ void > iterate_over_block_local_vars (const struct block *block, > iterate_over_block_arg_local_vars_cb cb) > { > + std::unordered_set collected_vars, shadowed_vars, printed_vars; > + const struct block *orig_block = block; > + > + /* Iterate over all the local variables in a block and store the list of > + shadowed variables to later distinguish them from other variables. */ > + while (block != nullptr) > + { > + for (struct symbol *sym : block_iterator_range (block)) > + { > + if (!sym->is_argument ()) > + { > + const char *name = sym->print_name (); > + if (!collected_vars.insert (name).second) > + shadowed_vars.insert (name); > + } > + } > + if (block->function ()) > + break; > + block = block->superblock (); > + } > + > + block = orig_block; > while (block) > { > - iterate_over_block_locals (block, cb); > + iterate_over_block_locals (block, cb, &shadowed_vars, printed_vars); > /* After handling the function's top-level block, stop. Don't > continue to its superblock, the block of per-file > symbols. */ > @@ -2268,14 +2315,16 @@ struct print_variable_and_value_data > struct ui_file *stream; > int values_printed; > > - void operator() (const char *print_name, struct symbol *sym); > + void operator() (const char *print_name, struct symbol *sym, bool shadowed, > + bool printed); > }; > > /* The callback for the locals and args iterators. */ > > void > print_variable_and_value_data::operator() (const char *print_name, > - struct symbol *sym) > + struct symbol *sym, > + bool shadowed, bool printed) > { > frame_info_ptr frame; > > @@ -2295,7 +2344,8 @@ print_variable_and_value_data::operator() (const char *print_name, > return; > } > > - print_variable_and_value (print_name, sym, frame, stream, num_tabs); > + print_variable_and_value (print_name, sym, frame, stream, num_tabs, shadowed, > + printed); > > /* print_variable_and_value invalidates FRAME. */ > frame = NULL; > @@ -2478,7 +2528,7 @@ iterate_over_block_arg_vars (const struct block *b, > struct symbol *sym2 > = lookup_symbol_search_name (sym->search_name (), > b, VAR_DOMAIN).symbol; > - cb (sym->print_name (), sym2); > + cb (sym->print_name (), sym2, false, false); > } > } > } > diff --git a/gdb/stack.h b/gdb/stack.h > index 1b0c2b342a4..72d843b66fb 100644 > --- a/gdb/stack.h > +++ b/gdb/stack.h > @@ -24,7 +24,8 @@ gdb::unique_xmalloc_ptr find_frame_funname (frame_info_ptr frame, > enum language *funlang, > struct symbol **funcp); > > -typedef gdb::function_view > +typedef gdb::function_view + bool shadowed, bool printed)> > iterate_over_block_arg_local_vars_cb; > > void iterate_over_block_arg_vars (const struct block *block, > diff --git a/gdb/testsuite/gdb.ada/var_shadowing.exp b/gdb/testsuite/gdb.ada/var_shadowing.exp > new file mode 100644 > index 00000000000..da279da258d > --- /dev/null > +++ b/gdb/testsuite/gdb.ada/var_shadowing.exp > @@ -0,0 +1,38 @@ > +# Copyright 2023 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 . > + > +load_lib "ada.exp" > + > +require allow_ada_tests > + > +standard_ada_testfile var_shadowing > + > +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" } { > + return -1 > +} > + > +clean_restart ${testfile} > + > +set i_level1 [gdb_get_line_number "I-Level1" ${testdir}/var_shadowing.adb] > +set i_level2 [gdb_get_line_number "I-Level2" ${testdir}/var_shadowing.adb] > +set i_level3 [gdb_get_line_number "I-Level3" ${testdir}/var_shadowing.adb] > +set bp_location [gdb_get_line_number "BREAK" ${testdir}/var_shadowing.adb] > +runto "var_shadowing.adb:$bp_location" > + > +gdb_test "info locals" [multi_line \ > + "i = 111\t<$testfile.adb:$i_level3>" \ > + "i = 11\t<$testfile.adb:$i_level2, shadowed>" \ > + "i = 1\t<$testfile.adb:$i_level1, shadowed>" \ > +] "info locals at innermost level" > diff --git a/gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb b/gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb > new file mode 100644 > index 00000000000..93cef5f0d6c > --- /dev/null > +++ b/gdb/testsuite/gdb.ada/var_shadowing/var_shadowing.adb > @@ -0,0 +1,30 @@ > +-- Copyright 2023 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 . > + > +with Ada.Text_IO; use Ada.Text_IO; > + > +procedure Varshadow is > + I : Integer := 1; -- I-Level1 > +begin > + declare > + I : Integer := 11; -- I-Level2 > + begin > + declare > + I : Integer := 111; -- I-Level3 > + begin > + Put_Line ("hello"); -- BREAK > + end; > + end; > +end; > diff --git a/gdb/testsuite/gdb.base/var-shadowing.c b/gdb/testsuite/gdb.base/var-shadowing.c > new file mode 100755 > index 00000000000..18963514bbf > --- /dev/null > +++ b/gdb/testsuite/gdb.base/var-shadowing.c > @@ -0,0 +1,49 @@ > +/* Copyright (C) 2023 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 . */ > + > +#include > + > +void > +shadowing (void) > +{ > + int a; /* bp for entry */ > + unsigned int val1 = 1; /* val1-d1 */ > + unsigned int val2 = 2; /* val2-d1 */ > + a = 101; /* bp for locals 1 */ > + { > + unsigned int val2 = 3; /* val2-d2 */ > + unsigned int val3 = 4; /* val3-d1 */ > + a = 102; /* bp for locals 2 */ > + { > + unsigned int val1 = 5; /* val1-d2 */ > + a = 103; /* bp for locals 3 */ > + { > + #include "var-shadowing2.c" > + unsigned int val1 = 6; /* val1-d3 */ > + unsigned int val2 = 7; /* val2-d3 */ > + unsigned int val3 = 8; /* val3-d2 */ > + a = 104; /* bp for locals 4 */ > + } > + } > + } > + a = 0; /* bp for locals 5 */ > +} > + > +int > +main (void) > +{ > + shadowing (); > + return 0; > +} > diff --git a/gdb/testsuite/gdb.base/var-shadowing.exp b/gdb/testsuite/gdb.base/var-shadowing.exp > new file mode 100755 > index 00000000000..c7e1e9eae2e > --- /dev/null > +++ b/gdb/testsuite/gdb.base/var-shadowing.exp > @@ -0,0 +1,90 @@ > +# Copyright 2023 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 . > + > +standard_testfile > +if [prepare_for_testing "failed to prepare" $testfile $srcfile] { > + return -1 > +} > + > +if ![runto_main] { > + untested "failed to run to main" > + return -1 > +} > + > +set bp_line1 [gdb_get_line_number "bp for locals 1" ${srcfile}] > +set bp_line2 [gdb_get_line_number "bp for locals 2" ${srcfile}] > +set bp_line3 [gdb_get_line_number "bp for locals 3" ${srcfile}] > +set bp_line4 [gdb_get_line_number "bp for locals 4" ${srcfile}] > +set bp_line5 [gdb_get_line_number "bp for locals 5" ${srcfile}] > + > +set val1_d1 [gdb_get_line_number "val1-d1" ${srcfile}] > +set val1_d2 [gdb_get_line_number "val1-d2" ${srcfile}] > +set val1_d3 [gdb_get_line_number "val1-d3" ${srcfile}] > +set val2_d1 [gdb_get_line_number "val2-d1" ${srcfile}] > +set val2_d2 [gdb_get_line_number "val2-d2" ${srcfile}] > +set val2_d3 [gdb_get_line_number "val2-d3" ${srcfile}] > +set val3_d1 [gdb_get_line_number "val3-d1" ${srcfile}] > +set val3_d2 [gdb_get_line_number "val3-d2" ${srcfile}] > +set a_line [gdb_get_line_number "bp for entry" ${srcfile}] > + > +gdb_breakpoint $srcfile:$bp_line1 > +gdb_test "continue" ".*bp for locals 1.*" "continue to outermost level" > +gdb_test "info locals" [multi_line \ > + "val1 = 1" \ > + "val2 = 2" \ > + ] "info locals at outermost level" > + > +gdb_breakpoint $srcfile:$bp_line2 > +gdb_test "continue" ".*bp for locals 2.*" "continue to first level" > +gdb_test "info locals" [multi_line \ > + "val2 = 3\t<$srcfile:$val2_d2>" \ > + "val3 = 4" \ > + "a = 101" \ > + "val1 = 1" \ > + "val2 = 2\t<$srcfile:$val2_d1, shadowed>" \ > + ] "info locals first level" > + > +gdb_breakpoint $srcfile:$bp_line3 > +gdb_test "continue" ".*bp for locals 3.*" "continue to second level" > +gdb_test "info locals" [multi_line \ > + "val1 = 5\t<$srcfile:$val1_d2>" \ > + "val2 = 3\t<$srcfile:$val2_d2>" \ > + "val3 = 4" \ > + "a = 102" \ > + "val1 = 1\t<$srcfile:$val1_d1, shadowed>" \ > + "val2 = 2\t<$srcfile:$val2_d1, shadowed>" \ > + ] "info locals second level" > + > +gdb_breakpoint $srcfile:$bp_line4 > +gdb_test "continue" ".*bp for locals 4.*" "continue to innermost level" > +gdb_test "info locals" [multi_line \ > + "a = 999\t<${testfile}2.c:16>" \ > + "val1 = 6\t<$srcfile:$val1_d3>" \ > + "val2 = 7\t<$srcfile:$val2_d3>" \ > + "val3 = 8\t<$srcfile:$val3_d2>" \ > + "val1 = 5\t<$srcfile:$val1_d2, shadowed>" \ > + "val2 = 3\t<$srcfile:$val2_d2, shadowed>" \ > + "val3 = 4\t<$srcfile:$val3_d1, shadowed>" \ > + "a = 103\t<$srcfile:$a_line, shadowed>" \ > + "val1 = 1\t<$srcfile:$val1_d1, shadowed>" \ > + "val2 = 2\t<$srcfile:$val2_d1, shadowed>" \ > + ] "info locals at innermost level" > + > +gdb_breakpoint $srcfile:$bp_line5 > +gdb_test "continue" ".*bp for locals 5.*" "continue to outermost level last" > +gdb_test "info locals" [multi_line \ > + "val1 = 1" \ > + "val2 = 2" \ > + ] "info locals at outermost level last" > diff --git a/gdb/testsuite/gdb.base/var-shadowing2.c b/gdb/testsuite/gdb.base/var-shadowing2.c > new file mode 100644 > index 00000000000..9bc55f95a84 > --- /dev/null > +++ b/gdb/testsuite/gdb.base/var-shadowing2.c > @@ -0,0 +1,16 @@ > +/* Copyright (C) 2023 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 . */ > + > +int a = 999; > diff --git a/gdb/testsuite/gdb.rust/var_reuse.exp b/gdb/testsuite/gdb.rust/var_reuse.exp > new file mode 100755 > index 00000000000..58b85518f55 > --- /dev/null > +++ b/gdb/testsuite/gdb.rust/var_reuse.exp > @@ -0,0 +1,32 @@ > +# Copyright 2023 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 . > + > +load_lib rust-support.exp > +require allow_rust_tests > +require {can_compile rust} > + > +standard_testfile .rs > +if {[prepare_for_testing "failed to prepare" \ > + $testfile $srcfile {debug rust}]} { > + return -1 > +} > + > +set line [gdb_get_line_number "set breakpoint here"] > +if {![runto ${srcfile}:$line]} { > + untested "could not run to breakpoint" > + return -1 > +} > + > +gdb_test "info local _x" "_x = 12" "print local _x variable" > diff --git a/gdb/testsuite/gdb.rust/var_reuse.rs b/gdb/testsuite/gdb.rust/var_reuse.rs > new file mode 100755 > index 00000000000..03be7981ff1 > --- /dev/null > +++ b/gdb/testsuite/gdb.rust/var_reuse.rs > @@ -0,0 +1,20 @@ > +// Copyright (C) 2023 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 . > + > +fn main() { > + let _x = 5; > + let _x = _x + 7; > + let _y = 8; // set breakpoint here > +} > diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c > index 205380476b3..02669b3d909 100644 > --- a/gdb/tracepoint.c > +++ b/gdb/tracepoint.c > @@ -1048,7 +1048,8 @@ collection_list::add_local_symbols (struct gdbarch *gdbarch, CORE_ADDR pc, > int count = 0; > > auto do_collect_symbol = [&] (const char *print_name, > - struct symbol *sym) > + struct symbol *sym, > + bool shadowed, bool printed) > { > collect_symbol (sym, gdbarch, frame_regno, > frame_offset, pc, trace_string); > diff --git a/gdb/value.h b/gdb/value.h > index 1d5a0018f92..879fce544c3 100644 > --- a/gdb/value.h > +++ b/gdb/value.h > @@ -1537,7 +1537,9 @@ extern void print_variable_and_value (const char *name, > struct symbol *var, > frame_info_ptr frame, > struct ui_file *stream, > - int indent); > + int indent, > + bool shadowed, > + bool printed); > > extern void typedef_print (struct type *type, struct symbol *news, > struct ui_file *stream); -- Cheers, Guinevere Larsen She/Her/Hers