[RFC 6/7] [gdb/symtab] Add DW_TAG_inlined_subroutine entries in the cooked index for c++
Tom de Vries
tdevries@suse.de
Fri Aug 25 15:55:45 GMT 2023
Test-case gdb.cp/breakpoint-locs.exp has two DW_TAG_inlined_subroutine entries
at 0x140 and 0x227 representing N1::C1::baz. The two are similar, and the
first one is:
...
<1><d3>: Abbrev Number: 2 (DW_TAG_namespace)
<d4> DW_AT_name : N1
<2><dd>: Abbrev Number: 3 (DW_TAG_class_type)
<de> DW_AT_name : C1
<3><e8>: Abbrev Number: 4 (DW_TAG_subprogram)
<e9> DW_AT_external : 1
<e9> DW_AT_name : baz
<ef> DW_AT_linkage_name: _ZN2N12C13bazEv
<f3> DW_AT_accessibility: 1 (public)
<f4> DW_AT_declaration : 1
<1><125>: Abbrev Number: 8 (DW_TAG_subprogram)
<126> DW_AT_specification: <0xf5>
<12a> DW_AT_low_pc : 0x4004d7
<132> DW_AT_high_pc : 0x10
<13a> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<13c> DW_AT_GNU_all_call_sites: 1
<2><140>: Abbrev Number: 9 (DW_TAG_inlined_subroutine)
<141> DW_AT_abstract_origin: <0x173>
<145> DW_AT_low_pc : 0x4004db
<14d> DW_AT_high_pc : 0x9
<1><173>: Abbrev Number: 12 (DW_TAG_subprogram)
<174> DW_AT_specification: <0xe8>
<178> DW_AT_inline : 3 (declared as inline and inlined)
...
but the cooked index doesn't add an entry for it because in
cooked_indexer::index_dies we don't recurse into the children of a
DW_TAG_subprogram for c++:
...
case DW_TAG_subprogram:
if ((m_language == language_fortran
|| m_language == language_ada)
&& this_entry != nullptr)
{
info_ptr = recurse (reader, info_ptr, this_entry, true);
...
Doing so yields the following entries:
...
[6] ((cooked_index_entry *) 0x7faa98005370)
name: baz
canonical: baz
qualified: N1::foo::baz
DWARF tag: DW_TAG_inlined_subroutine
flags: 0x0 []
DIE offset: 0x140
parent: ((cooked_index_entry *) 0x7faa98005310) [foo]
...
[20] ((cooked_index_entry *) 0x7faa80002fc0)
name: baz
canonical: baz
qualified: N1::bar::baz
DWARF tag: DW_TAG_inlined_subroutine
flags: 0x0 []
DIE offset: 0x227
parent: ((cooked_index_entry *) 0x7faa80002f60) [bar]
...
The entries have incorrect qualified names N1::foo::baz and N1::bar::baz, due
to an incorrect parent field. Indeed in DIE terms the parent is foo/bar, but
we use the parent field to track encapsulating scopes, so fix this by ignoring
the actual DIE parent.
That gives us the qualified name baz in both cases. Adding some debugging in
handle_deferred_dies shows us why:
...
0x00000000000000d4 0x36b5f10 (0xd3)
0x00000000000000de 0x36b5f40 (0xdd)
0x00000000000000f5 0x36b5f10 (0xd3)
0x0000000000000101 0x0
0x0000000000000126 0x36b5fd0 (0x125)
0x0000000000000173 0x0
0x0000000000000174 0x36b6060 (0x173)
0x0000000000000187 0x0
Resolve deferred: 0x140 -> 0x173: no parent
...
We try to find the find the parent of 0x140, by looking up the parent of 0x173
in m_die_range_map, which is nullptr, in other words no parent.
Fix this by recording more parent relations in m_die_range_map, such that we
have:
...
0x00000000000000d4 0x33882e0 (0xd3)
0x00000000000000de 0x3388310 (0xdd)
0x00000000000000f5 0x33882e0 (0xd3)
0x0000000000000101 0x0
0x0000000000000125 0x33882e0 (0xd3)
0x0000000000000126 0x33883a0 (0x125)
0x0000000000000173 0x3388310 (0xdd)
0x0000000000000174 0x3388430 (0x173)
0x0000000000000187 0x0
Resolve deferred: 0x140 -> 0x173: 0xdd
...
This gives us the desired outcome of N1::C1::baz for both DIEs.
Tested on x86_64-linux.
---
gdb/dwarf2/read.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 40248890c38..5ce0786e5bd 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -16582,6 +16582,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
cooked_index_flag flags = IS_STATIC;
sect_offset sibling {};
const cooked_index_entry *this_parent_entry = parent_entry;
+ if (abbrev->tag == DW_TAG_inlined_subroutine)
+ this_parent_entry = nullptr;
info_ptr = scan_attributes (reader->cu->per_cu, reader, info_ptr,
info_ptr, abbrev, &name, &linkage_name,
&flags, &sibling, &this_parent_entry,
@@ -16606,9 +16608,13 @@ cooked_indexer::index_dies (cutu_reader *reader,
this_die, name, defer, abbrev->tag, flags
});
else
- this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
- name, this_parent_entry,
- m_per_cu);
+ {
+ CORE_ADDR addr = form_addr (this_die, reader->cu->per_cu->is_dwz);
+ set_parent (addr, addr, this_parent_entry);
+ this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
+ name, this_parent_entry,
+ m_per_cu);
+ }
}
if (linkage_name != nullptr)
@@ -16669,7 +16675,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
case DW_TAG_subprogram:
if ((m_language == language_fortran
- || m_language == language_ada)
+ || m_language == language_ada
+ || m_language == language_cplus)
&& this_entry != nullptr)
{
info_ptr = recurse (reader, info_ptr, this_entry, true);
--
2.35.3
More information about the Gdb-patches
mailing list