[gdb/ada] Handle artificial local symbols
authorTom de Vries <tdevries@suse.de>
Sat, 18 Sep 2021 07:25:49 +0000 (09:25 +0200)
committerTom de Vries <tdevries@suse.de>
Sat, 18 Sep 2021 07:25:49 +0000 (09:25 +0200)
With current master and gcc 7.5.0/8.5.0, we have this timeout:
...
(gdb) print s^M
Multiple matches for s^M
[0] cancel^M
[1] s at src/gdb/testsuite/gdb.ada/interface/foo.adb:20^M
[2] s at src/gdb/testsuite/gdb.ada/interface/foo.adb:?^M
> FAIL: gdb.ada/interface.exp: print s (timeout)
...

[ The FAIL doesn't reproduce with gcc 9.3.1.  This difference in
behaviour bisects to gcc commit d70ba0c10de.

The FAIL with earlier gcc bisects to gdb commit ba8694b650b. ]

The FAIL is caused by gcc generating this debug info describing a named
artificial variable:
...
 <2><1204>: Abbrev Number: 31 (DW_TAG_variable)
    <1205>   DW_AT_name        : s.14
    <1209>   DW_AT_type        : <0x1213>
    <120d>   DW_AT_artificial  : 1
    <120d>   DW_AT_location    : 5 byte block: 91 e0 7d 23 18   \
      (DW_OP_fbreg: -288; DW_OP_plus_uconst: 24)
...

An easy way to fix this would be to simply not put named artificial variables
into the symbol table.  However, that causes regressions for Ada.  It relies
on being able to get the value from such variables, using a named reference.

Fix this instead by marking the symbol as artificial, and:
- ignoring such symbols in ada_resolve_variable, which fixes the FAIL
- ignoring such ada symbols in do_print_variable_and_value, which prevents
  them from showing up in "info locals"

Note that a fix for the latter was submitted here (
https://sourceware.org/pipermail/gdb-patches/2008-January/054994.html ), and
this patch borrows from it.

Tested on x86_64-linux.

Co-Authored-By: Joel Brobecker <brobecker@adacore.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28180

gdb/ada-lang.c
gdb/dwarf2/read.c
gdb/language.h
gdb/stack.c
gdb/symtab.h
gdb/testsuite/gdb.ada/interface.exp

index 6680a4fd65769eab77bc1eb87bb193ce31bd9ebd..487d92be5c9240bb879d2572b89ebb7aaa224e6d 100644 (file)
@@ -3539,6 +3539,17 @@ ada_resolve_variable (struct symbol *sym, const struct block *block,
         candidates.end ());
     }
 
+  /* Filter out artificial symbols.  */
+  candidates.erase
+    (std::remove_if
+     (candidates.begin (),
+      candidates.end (),
+      [] (block_symbol &bsym)
+      {
+       return bsym.symbol->artificial;
+      }),
+     candidates.end ());
+
   int i;
   if (candidates.empty ())
     error (_("No definition found for %s"), sym->print_name ());
@@ -13027,6 +13038,12 @@ public:
     return language_defn::read_var_value (var, var_block, frame);
   }
 
+  /* See language.h.  */
+  virtual bool symbol_printing_suppressed (struct symbol *symbol) const override
+  {
+    return symbol->artificial;
+  }
+
   /* See language.h.  */
   void language_arch_info (struct gdbarch *gdbarch,
                           struct language_arch_info *lai) const override
index 192df2ac84374e1528e598d9bcb50e59ae8b3302..3c81ac6b7b51be892882536128741f5d25ae4dfd 100644 (file)
@@ -21700,6 +21700,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
          sym->set_linkage_name (linkagename);
        }
 
+      /* Handle DW_AT_artificial.  */
+      attr = dwarf2_attr (die, DW_AT_artificial, cu);
+      if (attr != nullptr)
+       sym->artificial = attr->as_boolean ();
+
       /* Default assumptions.
         Use the passed type or decode it from the die.  */
       SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
index 21ed47b35807f606240c0c6df95eb5f486548bf1..40d22d205596950d31021d5cece83044ad80b111 100644 (file)
@@ -327,6 +327,14 @@ struct language_defn
     return {};
   }
 
+  /* Return true if SYMBOL represents an entity that is not
+     supposed to be seen by the user.  To be used to filter symbols
+     during printing.  */
+  virtual bool symbol_printing_suppressed (struct symbol *symbol) const
+  {
+    return false;
+  }
+
   /* The per-architecture (OS/ABI) language information.  */
 
   virtual void language_arch_info (struct gdbarch *,
index 516e4d45696f4b7c85ab679e29d03b3c9de331b7..7c4cf9491cc28653d5e34954a1f791f9d3d1fabc 100644 (file)
@@ -2322,6 +2322,8 @@ do_print_variable_and_value (const char *print_name,
   if (p->treg.has_value ()
       && !treg_matches_sym_type_name (*p->treg, sym))
     return;
+  if (language_def (sym->language ())->symbol_printing_suppressed (sym))
+    return;
 
   frame = frame_find_by_id (p->frame_id);
   if (frame == NULL)
index fd8dd62a40691b0d90b308d885200a30b72e1a48..5182f51672e39e7dfa7bec7bed7701935576b7bd 100644 (file)
@@ -1122,7 +1122,8 @@ struct symbol : public general_symbol_info, public allocate_on_obstack
       is_argument (0),
       is_inlined (0),
       maybe_copied (0),
-      subclass (SYMBOL_NONE)
+      subclass (SYMBOL_NONE),
+      artificial (false)
     {
       /* We can't use an initializer list for members of a base class, and
         general_symbol_info needs to stay a POD type.  */
@@ -1192,6 +1193,10 @@ struct symbol : public general_symbol_info, public allocate_on_obstack
 
   ENUM_BITFIELD (symbol_subclass_kind) subclass : 2;
 
+  /* Whether this symbol is artificial.  */
+
+  bool artificial : 1;
+
   /* Line number of this symbol's definition, except for inlined
      functions.  For an inlined function (class LOC_BLOCK and
      SYMBOL_INLINED set) this is the line number of the function's call
index 68b51917e8d212257cfe43482aad0ec2be69350b..2dfcd8e8afde18132e1fddd18614de062e8e8f82 100644 (file)
@@ -33,3 +33,10 @@ gdb_test "print r" \
 
 gdb_test "print s" \
          "= \\(x => 1, y => 2, w => 3, h => 4\\)"
+
+set cmd "info locals"
+gdb_test $cmd \
+    [multi_line \
+        $cmd \
+        "r = \[^\r\n\]*" \
+        "s = \[^\r\n\]*"]