A customer reported a crash in the DWARF reader.
Investigation showed that the crash occurred in an unusual scenario: a
function was lexically scoped within some other function -- but the
inner function inlined the outer function and referred to its DIE via
DW_AT_abstract_origin. With the executable in question,
inherit_abstract_dies could eventually call read_lexical_block_scope,
which in turn could recurse into process_die, to process a DIE that
was already being read, triggering an assert.
This came up once before; see:
https://www.sourceware.org/ml/gdb-patches/2014-02/msg00652.html
However, in this case, I don't have an easy way to reproduce. So,
there is no test case.
I did experiment with the failing executable. This patch fixes the
bug and doesn't seem to cause other issues. For example, I can still
set breakpoints on the relevant functions.
gdb/ChangeLog
2020-05-08 Tom Tromey <tromey@adacore.com>
* dwarf2/read.c (read_lexical_block_scope): Don't process a DIE
already being processed.
+2020-05-08 Tom Tromey <tromey@adacore.com>
+
+ * dwarf2/read.c (read_lexical_block_scope): Don't process a DIE
+ already being processed.
+
2020-05-08 Tom Tromey <tom@tromey.com>
* printcmd.c (struct display) <next>: Remove.
for (child_die = die->child;
child_die != NULL && child_die->tag;
child_die = child_die->sibling)
- process_die (child_die, cu);
+ {
+ /* We might already be processing this DIE. This can happen
+ in an unusual circumstance -- where a subroutine A
+ appears lexically in another subroutine B, but A actually
+ inlines B. The recursion is broken here, rather than in
+ inherit_abstract_dies, because it seems better to simply
+ drop concrete children here. */
+ if (!child_die->in_process)
+ process_die (child_die, cu);
+ }
return;
case PC_BOUNDS_INVALID:
return;