aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read.c
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2020-05-11 15:03:54 +0200
committerTom de Vries <tdevries@suse.de>2020-05-11 15:03:54 +0200
commit3ee6bb113afd87a408dd8551768d801d04556ffd (patch)
tree1ac50c4cd4a53134da0db04d0e45ed1f21160695 /gdb/dwarf2/read.c
parent3b646889b0f71fda1e46bde8206d4d6aba7f5387 (diff)
downloadgdb-3ee6bb113afd87a408dd8551768d801d04556ffd.zip
gdb-3ee6bb113afd87a408dd8551768d801d04556ffd.tar.gz
gdb-3ee6bb113afd87a408dd8551768d801d04556ffd.tar.bz2
[gdb/symtab] Fix incomplete CU list assert in .debug_names
Consider the following two-file test-case: ... $ cat main.c extern int foo (void); int main (void) { int sum, a, b; sum = a + b + foo (); return sum; } $ cat foo.c int foo (void) { return 3; } ... Compiled like this: ... $ clang-10 -gdwarf-5 -gpubnames -c main.c $ clang-10 -gdwarf-5 -c foo.c $ clang-10 -gdwarf-5 -gpubnames main.o foo.o ... When loading this exec into gdb, we run into this assert: ... $ gdb a.out Reading symbols from a.out... warning: Section .debug_aranges in a.out entry at offset 0 \ debug_info_offset 0 does not exists, ignoring .debug_aranges. src/gdb/dwarf2/read.c:6949: \ internal-error: cutu_reader::cutu_reader(dwarf2_per_cu_data*, \ abbrev_table*, int, bool): \ Assertion `this_cu->length == cu->header.get_length ()' failed. ... The problem is that the determined length of the CU: ... (gdb) p /x this_cu->length $4 = 0x26a ... does not match the actual length: ... (gdb) p /x cu->header.get_length () $5 = 0x59 ... The length of the CU is determined in create_cus_from_debug_names_list, and set based on this list in the .debug_names section: ... Compilation Unit offsets [ CU[0]: 0x000000c7 ] ... and it is assumed that this is a complete list, so the size of the CU is calculated using the end of the .debug_section at 0x331, making it 0x331 - 0xc7 == 0x26a. However, the CU list is not complete: ... $ llvm-dwarfdump -debug-info a.out \ | grep "Compile Unit" \ | sed 's/Compile Unit.*//' 0x00000000: 0x0000002e: 0x000000a5: 0x000000c7: 0x00000120: 0x00000157: 0x0000030f: ... In particular, because the CU for foo.c is there at 0x120 (the rest of the CUs is due to openSUSE having debug info for various linked in objects). Fix the assert by not assuming to know the length of CUs in create_cus_from_debug_names_list (if the .debug_names is not produced by GDB), and setting it to 0, and setting it later to the actual length. Note that this does not fix the .debug_aranges warning, that's PR25969. Build and tested on x86_64-linux, with native and debug-names. gdb/ChangeLog: 2020-05-11 Tom de Vries <tdevries@suse.de> PR symtab/25941 * dwarf2/read.c (create_cus_from_debug_names_list): Initialize CUs with length 0, if not gdb-produced. (cutu_reader::cutu_reader): Set CU length to actual length if 0. gdb/testsuite/ChangeLog: 2020-05-11 Tom de Vries <tdevries@suse.de> PR symtab/25941 * gdb.dwarf2/clang-debug-names.exp.in: New include exp file, factored out of ... * gdb.dwarf2/clang-debug-names.exp: ... here. * gdb.dwarf2/clang-debug-names-2.exp: New file. Include clang-debug-names.exp.in. * gdb.dwarf2/clang-debug-names-2-foo.c: New test. * gdb.dwarf2/clang-debug-names-2.c: New test.
Diffstat (limited to 'gdb/dwarf2/read.c')
-rw-r--r--gdb/dwarf2/read.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 4c8a071..27bf40a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -5022,6 +5022,26 @@ create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
dwarf2_section_info &section,
bool is_dwz)
{
+ if (!map.augmentation_is_gdb)
+ {
+ for (uint32_t i = 0; i < map.cu_count; ++i)
+ {
+ sect_offset sect_off
+ = (sect_offset) (extract_unsigned_integer
+ (map.cu_table_reordered + i * map.offset_size,
+ map.offset_size,
+ map.dwarf5_byte_order));
+ /* We don't know the length of the CU, because the CU list in a
+ .debug_names index can be incomplete, so we can't use the start of
+ the next CU as end of this CU. We create the CUs here with length 0,
+ and in cutu_reader::cutu_reader we'll fill in the actual length. */
+ dwarf2_per_cu_data *per_cu
+ = create_cu_from_index_list (dwarf2_per_objfile, &section, is_dwz,
+ sect_off, 0);
+ dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+ }
+ }
+
sect_offset sect_off_prev;
for (uint32_t i = 0; i <= map.cu_count; ++i)
{
@@ -6946,7 +6966,10 @@ cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
rcuh_kind::COMPILE);
gdb_assert (this_cu->sect_off == cu->header.sect_off);
- gdb_assert (this_cu->length == cu->header.get_length ());
+ if (this_cu->length == 0)
+ this_cu->length = cu->header.get_length ();
+ else
+ gdb_assert (this_cu->length == cu->header.get_length ());
this_cu->dwarf_version = cu->header.version;
}
}