[gdb/ada] Handle artificial local symbols
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 ba8694b650
. ]
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
This commit is contained in:
parent
10c21d953d
commit
2c71f639a0
6 changed files with 45 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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\]*"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue