While looking at PR symtab/31478 (a problem in the cooked indexer with invalid
dwarf) it occurred to me that I could trigger a similar problem using:
...
Compilation Unit @ offset 0xb2:
Length: 0x1f (32-bit)
Version: 4
Abbrev Offset: 0x6c
Pointer Size: 8
<0><bd>: Abbrev Number: 1 (DW_TAG_compile_unit)
<be> DW_AT_language : 2 (non-ANSI C)
<1><bf>: Abbrev Number: 2 (DW_TAG_subprogram)
<c0> DW_AT_low_pc : 0x4004a7
<c8> DW_AT_high_pc : 0x4004b2
<d0> DW_AT_specification: <0xd5>
<1><d4>: Abbrev Number: 0
Compilation Unit @ offset 0xd5:
Length: 0x7 (32-bit)
Version: 4
Abbrev Offset: 0x7f
Pointer Size: 8
...
and indeed I get:
...
$ gdb -q -batch outputs/gdb.dwarf2/dw2-inter-cu-error-2/dw2-inter-cu-error-2
Fatal signal: Segmentation fault
...
The problem is that we're calling prepare_one_comp_unit with cu == nullptr and
comp_unit_die == nullptr here in cooked_indexer::ensure_cu_exists:
...
cutu_reader new_reader (per_cu, per_objfile, nullptr, nullptr, false,
m_index_storage->get_abbrev_cache ());
prepare_one_comp_unit (new_reader.cu, new_reader.comp_unit_die,
language_minimal);
...
Fix this by bailing out for various types of dummy CUs:
...
if (new_reader.dummy_p || new_reader.comp_unit_die == nullptr
|| !new_reader.comp_unit_die->has_children)
return nullptr;
...
Also make sure in scan_attributes that this triggers a dwarf error:
...
$ gdb -q -batch dw2-inter-cu-error-2
DWARF Error: cannot follow reference to DIE at 0xd5 \
[in module dw2-inter-cu-error-2]
...
With target board readnow, the test-case triggers an assertion failure in
follow_die_offset, so fix this by throwing the same dwarf error.
While we're at it, make the other check for dummy CUs in
cooked_indexer::ensure_cu_exists more robust by adding an intermediate test
for comp_unit_die:
...
- if (result->dummy_p || !result->comp_unit_die->has_children)
+ if (result->dummy_p || result->comp_unit_die == nullptr
+ || !result->comp_unit_die->has_children)
return nullptr;
...
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>