Skip to content
Commit 573d8bb0 authored by Tom de Vries's avatar Tom de Vries
Browse files

[gdb/symtab] Return correct reader for top-level CU in cooked_indexer::ensure_cu_exists

With the test-case included in this patch, we run into:
...
$ gdb -q -batch $exec
Dwarf Error: Could not find abbrev number 3 in CU at offset 0xdb \
  [in module $exec]
...

The debug info consists of two CUs:
...
  Compilation Unit @ offset 0xb2:
   Length:        0x25 (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: <0xe8>
 <1><d4>: Abbrev Number: 3 (DW_TAG_subprogram)
    <d5>   DW_AT_name        : main
 <1><da>: Abbrev Number: 0
  Compilation Unit @ offset 0xdb:
   Length:        0xf (32-bit)
   Version:       4
   Abbrev Offset: 0x86
   Pointer Size:  8
 <0><e6>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <e7>   DW_AT_language    : 2	(non-ANSI C)
 <1><e8>: Abbrev Number: 2 (DW_TAG_subprogram)
    <e9>   DW_AT_specification: <0xd4>
 <1><ed>: Abbrev Number: 0
...
where:
- DIE 0xbf in CU@0xb2 contains an inter-CU reference to
- DIE 0xe8 in CU@0xdb, which contains an inter-CU reference to
- DIE 0xd4 back in CU@0xb2.

The dwarf error is caused by this bit of code in
cooked_indexer::ensure_cu_exists:
...
  if (per_cu == m_per_cu)
    return reader;
...

The dwarf error happens as follows:
- a cutu_reader A is created for CU@0xb2
- using cutu_reader A, the cooked index reader starts indexing dies, with
  m_per_cu set to CU@0xb2
- while indexing it scans the attributes of DIE 0xbf and encounters the
  inter-CU reference to DIE 0xe8
- it calls cooked_indexer::ensure_cu_exists, which creates a cutu_reader B for
  CU@0xdb and returns it
- using cutu_reader B, it continues scanning attributes of DIE 0xe8 and
  encounters the inter-CU reference to DIE 0xd4
- it calls cooked_indexer::ensure_cu_exists, the problematic bit is triggered
  and cutu_reader B is returned
- using cutu_reader B, it continues scanning attributes of DIE 0xd4
- this goes wrong because:
  - the attributes of the DIE are encoded using the abbreviation table at
    offset 0x6c, while
  - the decoding is done using cutu_reader B which uses the abbreviation table
    at offset 0x86.

Fix this by removing the problematic if clause.

Since cutu_reader A is not preserved in m_index_storage,
cooked_indexer::ensure_cu_exists cannot find it there and creates a duplicate
cutu_reader C for CU@0xb2.  Fix this in process_psymtab_comp_unit by preserving
the cutu_reader A as well in m_index_storage.

Tested on x86_64-linux and aarch64-linux.

PR symtab/32081
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32081



Approved-By: default avatarTom Tromey <tom@tromey.com>
Reported-By: default avatarAndreas Schwab <schwab@linux-m68k.org>
parent 50f8a398
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment