diff options
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 54c538a..d7f893d 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1225,6 +1225,9 @@ struct die_info type derived from this DIE. */ unsigned char building_fullname : 1; + /* True if this die is in process. PR 16581. */ + unsigned char in_process : 1; + /* Abbrev number */ unsigned int abbrev; @@ -8008,11 +8011,28 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu) } } +/* Reset the in_process bit of a die. */ + +static void +reset_die_in_process (void *arg) +{ + struct die_info *die = arg; + die->in_process = 0; +} + /* Process a die and its children. */ static void process_die (struct die_info *die, struct dwarf2_cu *cu) { + struct cleanup *in_process; + + /* We should only be processing those not already in process. */ + gdb_assert (!die->in_process); + + die->in_process = 1; + in_process = make_cleanup (reset_die_in_process,die); + switch (die->tag) { case DW_TAG_padding: @@ -8100,6 +8120,8 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) new_symbol (die, NULL, cu); break; } + + do_cleanups (in_process); } /* DWARF name computation. */ @@ -10967,8 +10989,12 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) if (offsetp >= offsets_end || offsetp->sect_off > origin_child_die->offset.sect_off) { - /* Found that ORIGIN_CHILD_DIE is really not referenced. */ - process_die (origin_child_die, origin_cu); + /* Found that ORIGIN_CHILD_DIE is really not referenced. + Check whether we're already processing ORIGIN_CHILD_DIE. + This can happen with mutually referenced abstract_origins. + PR 16581. */ + if (!origin_child_die->in_process) + process_die (origin_child_die, origin_cu); } origin_child_die = sibling_die (origin_child_die); } |