[PATCH v6 2/2] gdb: add shadowed field in '-stack-list-locals/variables' mi commands
Aktemur, Tankut Baris
tankut.baris.aktemur@intel.com
Mon Sep 23 13:45:01 GMT 2024
On Wednesday, November 22, 2023 9:13 AM, Ijaz, Abdul B wrote:
> From: "Ijaz, Abdul B" <abdul.b.ijaz@intel.com>
>
> For C/C++/Fortran 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 GDB now prints location information
> for shadowed variables and add 'shadowed' field also in '-stack-list-locals'
> and '-stack-list-variables' mi commands for super-block shadowed variable.
>
> Suppose we have test.c file
>
> 1:int x = 42;
> 2: {
> 3: int x = 99;
> 4: int y = 52;
> 4: x = 99; /* break here */
> 5: }
>
> The "-stack-list-locals" and "-stack-list-variables" mi commands at the
> "break here" line gives the following output:
>
> Before the change:
>
> ~~~
> (gdb)
> -stack-list-locals 0
> ^done,locals=[name="x",name="y",name="x"]
> (gdb)
> -stack-list-locals 1
> ^done,locals=[{name="x",value="99"},{name="y",value="52"},{name="x",value="42"}]
> (gdb)
> -stack-list-locals 2
> ^done,locals=[{name="x",type="int",value="99"},{name="y",type="int",value="52"},{name="x",ty
> pe="int",value="42"}]
> (gdb)
> -stack-list-variables 0
> ^done,variables=[{name="x"},{name="y"},{name="x"}]
> (gdb)
> -stack-list-variables 1
> ^done,variables=[{name="x",value="99"},{name="y",value="52"},{name="x",value="42"}]
> (gdb)
> -stack-list-variables 2
> ^done,variables=[{name="x",type="int",value="99"},{name="y",type="int",value="52"},{name="x"
> ,type="int",value="42"}]
> ~~~
>
> With this patch we obtain:
>
> ~~~
> (gdb)
> -stack-list-locals 0
> ^done,locals=[name="x",name="y",name="x"]
> (gdb)
> -stack-list-locals 1
> ^done,locals=[{name="x",value="99",file="test.c",line="4"},{name="y",value="52"},{name="x",v
> alue="42",file="test.c",line="2",shadowed="true"}]
> (gdb)
> -stack-list-locals 2
> ^done,locals=[{name="x",type="int",value="99",file="test.c",line="4"},{name="y",type="int",v
> alue="52"},{name="x",type="int",value="42",file="test.c",line="2",shadowed="true"}]
> (gdb)
> -stack-list-variables 0
> ^done,variables=[{name="x",file="test.c",line="4"},{name="y"},{name="x",file="test.c",line="
> 2",shadowed="true"}]
> (gdb)
> -stack-list-variables 1
> ^done,variables=[{name="x",value="99",file="test.c",line="4"},{name="y",value="52"},{name="x
> ",value="42",file="test.c",line="2",shadowed="true"}]
> (gdb)
> -stack-list-variables 2
> ^done,variables=[{name="x",type="int",value="99",file="test.c",line="4"},{name="y",type="int
> ",value="52"},{name="x",type="int",value="42",file="test.c",line="2",shadowed="true"}]
> ~~~
> ---
> gdb/doc/gdb.texinfo | 14 +++
> gdb/mi/mi-cmd-stack.c | 66 +++++++++-
> gdb/testsuite/gdb.mi/mi-var-shadowing.c | 48 ++++++++
> gdb/testsuite/gdb.mi/mi-var-shadowing.exp | 141 ++++++++++++++++++++++
> 4 files changed, 265 insertions(+), 4 deletions(-)
> create mode 100644 gdb/testsuite/gdb.mi/mi-var-shadowing.c
> create mode 100644 gdb/testsuite/gdb.mi/mi-var-shadowing.exp
>
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 6efcc5a8dc9..348844bbb8d 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -34772,6 +34772,20 @@ If the @code{--skip-unavailable} option is specified, local
> variables
> and arguments that are not available are not listed. Partially
> available arguments and local variables are still displayed, however.
>
> +@smallexample
> +1: int x = 3;
> +2: @{
> +3: int x = 4; // breakpt
> +4: @}
> +(gdb) -stack-list-variables 2
> +^done,variables=[@{name="x",type="int",value="4",file="name.c",line="3"@},@{name="x",type="
> int",value="3",file="name.c",line="1",shadowed="true"@}]
> +@end smallexample
If we had stopped at line "breakpt", the " = 4" assignment would not have
taken place, yet. So, instead of seeing "4", seeing garbage is more likely.
It would help if "// breakpt" was removed after the second definition line.
Something like:
+@smallexample
+1: int x = 3;
+2: @{
+3: int x = 4;
+4: x = 99; // breakpt
+5: @}
> +
> +A variable is shadowed when there's another variable by the same
> +name which is declared within an inner scope (decision block,
> +method, or inner class). For such cases, its location for the
> +outermost scope is followed by @samp{shadowed} attribute.
> +
> @subsubheading Example
>
> @smallexample
> diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
> index e473be7d465..21638796b63 100644
> --- a/gdb/mi/mi-cmd-stack.c
> +++ b/gdb/mi/mi-cmd-stack.c
> @@ -38,6 +38,8 @@
> #include "gdbsupport/gdb-safe-ctype.h"
> #include "inferior.h"
> #include "observable.h"
> +#include "include/libiberty.h"
> +#include <unordered_set>
>
> enum what_to_list { locals, arguments, all };
>
> @@ -491,7 +493,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)
> + enum print_values values, int skip_unavailable,
> + const std::unordered_set<std::string> *shadowed_vars,
> + std::unordered_set<std::string> &printed_vars)
I would repeat my comment that gave in the previous patch.
Why not pass shadowed_vars as a (const) ref?
> {
> struct ui_out *uiout = current_uiout;
>
> @@ -520,6 +524,18 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
> tuple_emitter.emplace (uiout, nullptr);
>
> string_file stb;
> + const char *name = arg->sym->print_name ();
> + bool already_printed = !printed_vars.insert (name).second;
> + printed_vars.insert (name);
This line seems redundant.
Thanks,
-Baris
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
More information about the Gdb-patches
mailing list