aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read.h
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2021-06-16 12:44:30 +0200
committerTom de Vries <tdevries@suse.de>2021-06-16 12:44:30 +0200
commit8457e5ecc45295bc9550c4f705a276d5ca90d908 (patch)
treee877a0000327703f00927fed1b6affd5fdc29fe8 /gdb/dwarf2/read.h
parentbb32eac5a90b2b141fed4ce490aded74134f1d75 (diff)
downloadfsf-binutils-gdb-8457e5ecc45295bc9550c4f705a276d5ca90d908.zip
fsf-binutils-gdb-8457e5ecc45295bc9550c4f705a276d5ca90d908.tar.gz
fsf-binutils-gdb-8457e5ecc45295bc9550c4f705a276d5ca90d908.tar.bz2
[gdb/symtab] Fix infinite recursion in dwarf2_cu::get_builder(), again
This is another attempt at fixing the problem described in commit 4cf88725da1 "[gdb/symtab] Fix infinite recursion in dwarf2_cu::get_builder()", which was reverted in commit 3db19b2d724. First off, some context. A DWARF CU can be viewed as a symbol table: toplevel children of a CU DIE represent symbol table entries for that CU. Furthermore, there is a hierarchy: a symbol table entry such as a function itself has a symbol table containing parameters and local variables. The dwarf reader maintains a notion of current symbol table (that is: the symbol table a new symbol needs to be entered into) in dwarf2_cu member list_in_scope. A problem then presents itself when reading inter-CU references: - a new symbol read from a CU B needs to be entered into the symbol table of another CU A. - the notion of current symbol table is tracked on a per-CU basis. This is addressed in inherit_abstract_dies by temporarily overwriting the list_in_scope for CU B with the one for CU A. The current symbol table is one aspect of the current dwarf reader context that is tracked, but there are more, f.i. ones that are tracked via the dwarf2_cu member m_builder, f.i. m_builder->m_local_using_directives. A similar problem exists in relation to inter-CU references, but a different solution was chosen: - to keep track of an ancestor field in dwarf2_cu, which is updated when traversing inter-CU references, and - to use the ancestor field in dwarf2_cu::get_builder to return the m_builder in scope. There is no actual concept of a CU having an ancestor, it just marks the most recent CU from which a CU was inter-CU-referenced. Consequently, when following inter-CU references from a CU A to another CU B and back to CU A, the ancestors form a cycle, which causes dwarf2_cu::get_builder to hang or segfault, as reported in PR26327. ISTM that the ancestor implementation is confusing and fragile, and should go. Furthermore, it seems that keeping track of the m_builder in scope can be handled simply with a per-objfile variable. Fix the hang / segfault by: - keeping track of the m_builder in scope using a new variable per_obj->sym_cu, and - using it in dwarf2_cu::get_builder. Tested on x86_64-linux (openSUSE Leap 15.2), no regressions for config: - using default gcc version 7.5.0 (with 5 unexpected FAILs) - gcc 10.3.0 and target board unix/-flto/-O0/-flto-partition=none/-ffat-lto-objects (with 1000 unexpected FAILs) gdb/ChangeLog: 2021-06-16 Tom de Vries <tdevries@suse.de> PR symtab/26327 * dwarf2/cu.h (dwarf2_cu::ancestor): Remove. (dwarf2_cu::get_builder): Declare and move ... * dwarf2/cu.c (dwarf2_cu::get_builder): ... here. Use sym_cu instead of ancestor. Assert return value is non-null. * dwarf2/read.c (read_file_scope): Set per_objfile->sym_cu. (follow_die_offset, follow_die_sig_1): Remove setting of ancestor. (dwarf2_per_objfile): Add sym_cu field.
Diffstat (limited to 'gdb/dwarf2/read.h')
-rw-r--r--gdb/dwarf2/read.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index ae1608f..ee454ad 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -579,6 +579,9 @@ struct dwarf2_per_objfile
/* Table containing line_header indexed by offset and offset_in_dwz. */
htab_up line_header_hash;
+ /* The CU containing the m_builder in scope. */
+ dwarf2_cu *sym_cu = nullptr;
+
private:
/* Hold the corresponding compunit_symtab for each CU or TU. This
is indexed by dwarf2_per_cu_data::index. A NULL value means