https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87362
--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #12)
> Created attachment 44740 [details]
> patch
>
> "Final" patch. Still runs into the SYMBOL_LANGUAGE issue but I failed to
> create a small reproducer (genchecksum is the smallest for now). That is, a
> simple
> mix of a C and a C++ TU isn't enough to provoke the error.
>
> #1 0x000000000065bf90 in dw2_add_symbol_to_list (symbol=0x12b7900,
> listhead=0xfec888 <local_symbols>)
> at /space/rguenther/src/binutils-gdb/gdb/dwarf2read.c:9713
> 9713 gdb_assert ((*listhead) == NULL
> (top-gdb) p *(*listhead)->symbol[0]
> $2 = {ginfo = {name = 0x1254db2 "errnum", value = {ivalue = 0, block = 0x0,
> bytes = 0x0, address = 0x0, common_block = 0x0, chain = 0x0},
> language_specific = {obstack = 0x0, demangled_name = 0x0},
> language = language_cplus, ada_mangled = 0, section = -1},
> type = 0x12b4f20, owner = {symtab = 0x1260d50, arch = 0x1260d50},
> domain = VAR_DOMAIN, aclass_index = 18, is_objfile_owned = 1,
> is_argument = 0, is_inlined = 0, subclass = SYMBOL_NONE, line = 54,
> aux_value = 0x12b5170, hash_next = 0x0}
> (top-gdb) p *symbol
> $3 = {ginfo = {name = 0x1254db9 "errstr", value = {ivalue = 0, block = 0x0,
> bytes = 0x0, address = 0x0, common_block = 0x0, chain = 0x0},
> language_specific = {obstack = 0x0, demangled_name = 0x0},
> language = language_c, ada_mangled = 0, section = -1}, type = 0x12b4dc0,
> owner = {symtab = 0x0, arch = 0x0}, domain = VAR_DOMAIN, aclass_index =
> 13,
> is_objfile_owned = 1, is_argument = 0, is_inlined = 0,
> subclass = SYMBOL_NONE, line = 56, aux_value = 0x0, hash_next = 0x0}
>
> I notice that above "errnum" is language_cplus but it is
> DW_TAG_formal_parameter
> of xstrerror whose early debug language is C. xstrerror is instantiated
> in a CU marked as C++ by GCC (unifying C and C++ to C++).
>
> What I see though is
>
> <1><2599>: Abbrev Number: 3 (DW_TAG_subprogram)
> <259a> DW_AT_abstract_origin: <0x2434>
> <259e> DW_AT_low_pc : 0x401300
> <25a6> DW_AT_high_pc : 0x28
> <25ae> DW_AT_frame_base : 1 byte block: 9c
> (DW_OP_call_frame_cfa)
> <25b0> DW_AT_GNU_all_call_sites: 1
> <25b0> DW_AT_sibling : <0x2657>
> <2><25b4>: Abbrev Number: 4 (DW_TAG_formal_parameter)
> <25b5> DW_AT_abstract_origin: <0x2440>
> <25b9> DW_AT_location : 0xf35 (location list)
> <25bd> DW_AT_GNU_locviews: 0xf2b
> <2><25c1>: Abbrev Number: 5 (DW_TAG_variable)
> <25c2> DW_AT_abstract_origin: <0x244c>
> <25c6> DW_AT_location : 0xfae (location list)
> <25ca> DW_AT_GNU_locviews: 0xfaa
> <2><25ce>: Abbrev Number: 7 (DW_TAG_lexical_block)
> <25cf> DW_AT_abstract_origin: <0x2434>
> <25d3> DW_AT_low_pc : 0x401310
> <25db> DW_AT_high_pc : 0x16
> <25e3> DW_AT_sibling : <0x2642>
> <3><25e7>: Abbrev Number: 4 (DW_TAG_formal_parameter)
> <25e8> DW_AT_abstract_origin: <0x2440>
> <25ec> DW_AT_location : 0xfef (location list)
> <25f0> DW_AT_GNU_locviews: 0xfed
>
> where this abstract origin looks odd. Maybe gdb is confused by that so I'll
> try to debug this.
OK, so the BLOCK structure we have here is
{ Scope block #0 Originating from :#0
char * errstr;
{ Scope block #7 Originating from : static char * xstrerror (int);
int errnum;
{ Scope block #8 Originating from :#0
char * errstr;
}
}
}
which results from early inlining the partial inlining tail... The
abstract origin of #7 is <function_decl 0x7ffff6a84400 xstrerror.part.0>
whose abstract origin is <function_decl 0x7ffff6a84300 xstrerror>.
Somehow this scope isn't marked as inlined_function_outer_scope_p.
We do not have an early debug representative for that BLOCK (of course...)
Then when creating the BLOCK we do
else if (BLOCK_ABSTRACT_ORIGIN (stmt))
{
/* If this is an inlined instance, create a new lexical die for
anything below to attach DW_AT_abstract_origin to. */
if (old_die)
{
stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
equate_block_to_die (stmt, stmt_die);
old_die = NULL;
}
tree origin = block_ultimate_origin (stmt);
if (origin != NULL_TREE && origin != stmt)
add_abstract_origin_attribute (stmt_die, origin);
and here block_ultimate_origin "kills" us, refering back to $self.
Using abstract origins for cloning doesn't seem such a great idea in the
end... Well, if this is the underlying issue of gdb's un-happiness. At
least disabling early inlining "fixes" it for what gdb is concerned.
A small testcase would be nice to have for the gdb folks to investigate
but technically there is nothing wrong with the DWARF above?