When running test-case gdb.cp/cpexprs-debug-types/cpexprs-debug-types with target board cc-with-debug-names on a system with gcc 12.1.1 (defaulting to dwarf 5), I run into: ... (gdb) file /data/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.cp/cpexprs-debug-types/cpexprs-debug-types^M Reading symbols from /data/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.cp/cpexprs-debug-types/cpexprs-debug-types...^M warning: Section .debug_aranges in /data/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.cp/cpexprs-debug-types/cpexprs-debug-types has duplicate debug_info_offset 0x0, ignoring .debug_aranges.^M /data/vries/gdb_versions/devel/src/gdb/dwarf2/read.h:309: internal-error: set_length: Assertion `m_length == length' failed.^M A problem internal to GDB has been detected,^M further debugging may prove unreliable.^M ----- Backtrace -----^M ERROR: Couldn't load cpexprs-debug-types into GDB (GDB internal error). ... The problem is three-fold. 1. The .debug_names index is rejected in dwarf2_read_debug_names because: ... if (map->tu_count != 0) { /* We can only handle a single .debug_types when we have an index. */ if (per_bfd->types.size () != 1) return false; ... there are TUs so the tu_count is > 0 but there's no .debug_types section (dwarf 5 puts the TUs in the .debug_info section) so the "per_bfd->types.size () != 1" test fails. 2. After the index is rejected, we fall back to the cooked index, part of which is building up all_comp_units. The assumption there is that we start from scratch, but in fact all_comp_units already has some elements, added when reading the index. This leads to the complaints and eventually the assert. 3. The complaint is misleading. It's issued during read_addrmap_from_aranges, but the actual code does this: ... std::unordered_map<sect_offset, dwarf2_per_cu_data *, gdb::hash_enum<sect_offset>> debug_info_offset_to_per_cu; for (const auto &per_cu : per_bfd->all_comp_units) { /* A TU will not need aranges, and skipping them here is an easy way of ignoring .debug_types -- and possibly seeing a duplicate section offset -- entirely. The same applies to units coming from a dwz file. */ if (per_cu->is_debug_types || per_cu->is_dwz) continue; const auto insertpair = debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu.get ()); if (!insertpair.second) { warning (_("Section .debug_aranges in %s has duplicate " "debug_info_offset %s, ignoring .debug_aranges."), objfile_name (objfile), sect_offset_str (per_cu->sect_off)); return false; } } ... What the code really does is find duplicate offsets for CUs in all_comp_units. Which I suppose also means that duplicate debug_info_offsets in .debug_aranges are not actually detected. Not sure if that is a big problem. Note that the variable, debug_info_offset_to_per_cu is used in this complaint: ... const auto per_cu_it = debug_info_offset_to_per_cu.find (sect_offset (debug_info_offset)); if (per_cu_it == debug_info_offset_to_per_cu.cend ()) { warning (_("Section .debug_aranges in %s entry at offset %s " "debug_info_offset %s does not exists, " "ignoring .debug_aranges."), objfile_name (objfile), plongest (entry_addr - section->buffer), pulongest (debug_info_offset)); return false; } ... and its usage here matches what we store in the variable.
This addresses problem 2, both for .debug_names and .gdb_index: ... diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index bcd01107377..3b4409fa8ca 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -2696,7 +2696,10 @@ dwarf2_read_gdb_index /* We can only handle a single .debug_types when we have an index. */ if (per_bfd->types.size () != 1) - return 0; + { + per_bfd->all_comp_units.clear (); + return 0; + } dwarf2_section_info *section = &per_bfd->types[0]; @@ -4701,7 +4704,10 @@ dwarf2_read_debug_names (dwarf2_per_objfile *per_objfile) /* We can only handle a single .debug_types when we have an index. */ if (per_bfd->types.size () != 1) - return false; + { + per_bfd->all_comp_units.clear (); + return false; + } dwarf2_section_info *section = &per_bfd->types[0]; @@ -7206,6 +7212,7 @@ static void create_all_comp_units (dwarf2_per_objfile *per_objfile) { htab_up types_htab; + gdb_assert (per_objfile->per_bfd->all_comp_units.empty ()); read_comp_units_from_section (per_objfile, &per_objfile->per_bfd->info, &per_objfile->per_bfd->abbrev, 0, ... Also adds an assert to detect the problem asap. A similar assert is already present in create_cus_from_index and create_cus_from_debug_names.
Zooming in on the actual assert, we have: ... #6 0x0000000000714063 in dwarf2_per_cu_data::set_length (this=0x2cf2cd0, length=34, strict_p=true) at /home/vries/gdb_versions/devel/src/gdb/dwarf2/read.h:309 309 gdb_assert (m_length == length); (gdb) p m_length $5 = 12611 (gdb) p this->sect_off $7 = (unknown: 0x6d) ... So initially, during index reading we assign length 12611 to the CU at 0x6d, but during create_all_comp_units we find that it's actually 34, which looks correct given the TU at offset 0x8f ... CU table: [ 0] 0x0 [ 1] 0x2e [ 2] 0x6d [ 3] 0x31b0 [ 4] 0x7d53 [ 5] 0x7f0b TU table: [ 0] 0x8f [ 1] 0x1eb [ 2] 0x371 [ 3] 0x4b0 [ 4] 0x4f6 [ 5] 0x53c ... The initial 12611 length corresponds to 0x31b0 - 0x6d. So that looks like another bug, which normally doesn't surface because we reject the .debug_names index if it has TUs in the .debug_info section.
(In reply to Tom de Vries from comment #2) > Zooming in on the actual assert, we have: This fixes the length discrepancy: ... diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 143bcfb5374..490cc3dd0b2 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -4590,7 +4590,8 @@ create_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd, dwarf2_section_info §ion, bool is_dwz) { - if (!map.augmentation_is_gdb) + if (!map.augmentation_is_gdb + || (map.tu_count > 0 && per_bfd->types.size () == 0)) { for (uint32_t i = 0; i < map.cu_count; ++i) { ... and makes the assert disappear. But in combination with the "[gdbsupport] Use task size in parallel_for_each" patch we run instead into: ... /home/vries/gdb_versions/devel/src/gdb/dwarf2/read.h:298: internal-error: length: Assertion `m_length != 0' failed. ... because we still have those duplicates.
(In reply to Tom de Vries from comment #0) > When running test-case gdb.cp/cpexprs-debug-types/cpexprs-debug-types with > target board cc-with-debug-names on a system with gcc 12.1.1 (defaulting to > dwarf 5), I run into: > ... > (gdb) file > /data/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.cp/cpexprs- > debug-types/cpexprs-debug-types^M > Reading symbols from > /data/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.cp/cpexprs- > debug-types/cpexprs-debug-types...^M > warning: Section .debug_aranges in > /data/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.cp/cpexprs- > debug-types/cpexprs-debug-types has duplicate debug_info_offset 0x0, > ignoring .debug_aranges.^M > /data/vries/gdb_versions/devel/src/gdb/dwarf2/read.h:309: internal-error: > set_length: Assertion `m_length == length' failed.^M > A problem internal to GDB has been detected,^M > further debugging may prove unreliable.^M > ----- Backtrace -----^M > ERROR: Couldn't load cpexprs-debug-types into GDB (GDB internal error). > ... > > The problem is three-fold. > > 1. > The .debug_names index is rejected in dwarf2_read_debug_names because: > ... > if (map->tu_count != 0) > { > /* We can only handle a single .debug_types when we have an > index. */ > if (per_bfd->types.size () != 1) > return false; > ... > there are TUs so the tu_count is > 0 but there's no .debug_types section > (dwarf 5 puts the TUs in the .debug_info section) so the > "per_bfd->types.size () != 1" test fails. > Filed as PR29385.
Created attachment 14222 [details] Tentative patch for the misleading warning
(In reply to Tom de Vries from comment #1) > This addresses problem 2, both for .debug_names and .gdb_index: > ... > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c > index bcd01107377..3b4409fa8ca 100644 > --- a/gdb/dwarf2/read.c > +++ b/gdb/dwarf2/read.c > @@ -2696,7 +2696,10 @@ dwarf2_read_gdb_index > /* We can only handle a single .debug_types when we have an > index. */ > if (per_bfd->types.size () != 1) > - return 0; > + { > + per_bfd->all_comp_units.clear (); > + return 0; > + } > > dwarf2_section_info *section = &per_bfd->types[0]; > > @@ -4701,7 +4704,10 @@ dwarf2_read_debug_names (dwarf2_per_objfile > *per_objfile) > > /* We can only handle a single .debug_types when we have an > index. */ > if (per_bfd->types.size () != 1) > - return false; > + { > + per_bfd->all_comp_units.clear (); > + return false; > + } > > dwarf2_section_info *section = &per_bfd->types[0]; > > @@ -7206,6 +7212,7 @@ static void > create_all_comp_units (dwarf2_per_objfile *per_objfile) > { > htab_up types_htab; > + gdb_assert (per_objfile->per_bfd->all_comp_units.empty ()); > > read_comp_units_from_section (per_objfile, &per_objfile->per_bfd->info, > &per_objfile->per_bfd->abbrev, 0, > ... > > Also adds an assert to detect the problem asap. A similar assert is already > present in create_cus_from_index and create_cus_from_debug_names. https://sourceware.org/pipermail/gdb-patches/2022-July/190891.html
(In reply to Tom de Vries from comment #5) > Created attachment 14222 [details] > Tentative patch for the misleading warning https://sourceware.org/pipermail/gdb-patches/2022-July/190894.html
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=263ad5cc818ef8f7700c82f2aecd2a929dbd3be5
(In reply to Tom de Vries from comment #7) > (In reply to Tom de Vries from comment #5) > > Created attachment 14222 [details] > > Tentative patch for the misleading warning > > https://sourceware.org/pipermail/gdb-patches/2022-July/190894.html https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=75337cbc1476b7eb403fe0e73c52bf080b5996c8