mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-06 12:09:26 +08:00
[gdb/symtab] Fix Dwarf Error: cannot find DIE
When loading the debug info package libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug from openSUSE Leap 15.2, we run into a dwarf error: ... $ gdb -q -batch libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug Dwarf Error: Cannot not find DIE at 0x18a936e7 \ [from module libLLVM.so.10-10.0.1-lp152.30.4.x86_64.debug] ... The DIE @ 0x18a936e7 does in fact exist, and is part of a CU @ 0x18a23e52. No error message is printed when using -readnow. What happens is the following: - a dwarf2_per_cu_data P is created for the CU. - a dwarf2_cu A is created for the same CU. - another dwarf2_cu B is created for the same CU. - the dwarf2_cu B is set in per_objfile->m_dwarf2_cus, such that per_objfile->get_cu (P) returns B. - P->load_all_dies is set to 1. - all dies are read into the A->partial_dies htab - dwarf2_cu A is destroyed. - we try to find the partial_die for the DIE @ 0x18a936e7 in B->partial_dies. We can't find it, but do not try to load all dies, because P->load_all_dies is already set to 1. - an error message is generated. The question is why we're creating dwarf2_cu A and B for the same CU. The dwarf2_cu A is created here: ... (gdb) bt #0 dwarf2_cu::dwarf2_cu (this=0x79a9660, per_cu=0x23c0b30, per_objfile=0x1ad01b0) at dwarf2/cu.c:38 #1 0x0000000000675799 in cutu_reader::cutu_reader (this=0x7fffffffd040, this_cu=0x23c0b30, per_objfile=0x1ad01b0, abbrev_table=0x0, existing_cu=0x0, skip_partial=false) at dwarf2/read.c:6487 #2 0x0000000000676eb3 in process_psymtab_comp_unit (this_cu=0x23c0b30, per_objfile=0x1ad01b0, want_partial_unit=false, pretend_language=language_minimal) at dwarf2/read.c:7028 ... And the dwarf2_cu B is created here: ... (gdb) bt #0 dwarf2_cu::dwarf2_cu (this=0x885e8c0, per_cu=0x23c0b30, per_objfile=0x1ad01b0) at dwarf2/cu.c:38 #1 0x0000000000675799 in cutu_reader::cutu_reader (this=0x7fffffffcc50, this_cu=0x23c0b30, per_objfile=0x1ad01b0, abbrev_table=0x0, existing_cu=0x0, skip_partial=false) at dwarf2/read.c:6487 #2 0x0000000000678118 in load_partial_comp_unit (this_cu=0x23c0b30, per_objfile=0x1ad01b0, existing_cu=0x0) at dwarf2/read.c:7436 #3 0x000000000069721d in find_partial_die (sect_off=(unknown: 0x18a55054), offset_in_dwz=0, cu=0x0) at dwarf2/read.c:19391 #4 0x000000000069755b in partial_die_info::fixup (this=0x9096900, cu=0xa6a85f0) at dwarf2/read.c:19512 #5 0x0000000000697586 in partial_die_info::fixup (this=0x8629bb0, cu=0xa6a85f0) at dwarf2/read.c:19516 #6 0x00000000006787b1 in scan_partial_symbols (first_die=0x8629b40, lowpc=0x7fffffffcf58, highpc=0x7fffffffcf50, set_addrmap=0, cu=0x79a9660) at dwarf2/read.c:7563 #7 0x0000000000678878 in scan_partial_symbols (first_die=0x796ebf0, lowpc=0x7fffffffcf58, highpc=0x7fffffffcf50, set_addrmap=0, cu=0x79a9660) at dwarf2/read.c:7580 #8 0x0000000000676b82 in process_psymtab_comp_unit_reader (reader=0x7fffffffd040, info_ptr=0x7fffc1b3f29b, comp_unit_die=0x6ea90f0, pretend_language=language_minimal) at dwarf2/read.c:6954 #9 0x0000000000676ffd in process_psymtab_comp_unit (this_cu=0x23c0b30, per_objfile=0x1ad01b0, want_partial_unit=false, pretend_language=language_minimal) at dwarf2/read.c:7057 ... So in frame #9, a cutu_reader is created with dwarf2_cu A. Then a fixup takes us to the following CU @ 0x18aa33d6, in frame #5. And a similar fixup in frame #4 takes us back to CU @ 0x18a23e52. At that point, there's no information available that we're already trying to read that CU, and we end up creating another cutu_reader with dwarf2_cu B. It seems that there are two related problems: - creating two dwarf2_cu's is not optimal - the unoptimal case is not handled correctly This patch addresses the last problem, by moving the load_all_dies flag from dwarf2_per_cu_data to dwarf2_cu, such that it is paired with the partial_dies field, which ensures that the two can be kept in sync. Tested on x86_64-linux. gdb/ChangeLog: 2021-05-27 Tom de Vries <tdevries@suse.de> PR symtab/27898 * dwarf2/cu.c (dwarf2_cu::dwarf2_cu): Add load_all_dies init. * dwarf2/cu.h (dwarf2_cu): Add load_all_dies field. * dwarf2/read.c (load_partial_dies, find_partial_die): Update. * dwarf2/read.h (dwarf2_per_cu_data::dwarf2_per_cu_data): Remove load_all_dies init. (dwarf2_per_cu_data): Remove load_all_dies field.
This commit is contained in:
parent
3a706c17ee
commit
6dcd1193d9
@ -1,3 +1,13 @@
|
||||
2021-05-27 Tom de Vries <tdevries@suse.de>
|
||||
|
||||
PR symtab/27898
|
||||
* dwarf2/cu.c (dwarf2_cu::dwarf2_cu): Add load_all_dies init.
|
||||
* dwarf2/cu.h (dwarf2_cu): Add load_all_dies field.
|
||||
* dwarf2/read.c (load_partial_dies, find_partial_die): Update.
|
||||
* dwarf2/read.h (dwarf2_per_cu_data::dwarf2_per_cu_data): Remove
|
||||
load_all_dies init.
|
||||
(dwarf2_per_cu_data): Remove load_all_dies field.
|
||||
|
||||
2021-05-26 Simon Marchi <simon.marchi@efficios.com>
|
||||
|
||||
* regcache.c (reg_buffer::reg_buffer): Default-initialize
|
||||
|
@ -35,7 +35,8 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
|
||||
producer_is_icc (false),
|
||||
producer_is_icc_lt_14 (false),
|
||||
producer_is_codewarrior (false),
|
||||
processing_has_namespace_info (false)
|
||||
processing_has_namespace_info (false),
|
||||
load_all_dies (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -264,6 +264,12 @@ struct dwarf2_cu
|
||||
|
||||
bool processing_has_namespace_info : 1;
|
||||
|
||||
/* This flag will be set when reading partial DIEs if we need to load
|
||||
absolutely all DIEs for this compilation unit, instead of just the ones
|
||||
we think are interesting. It gets set if we look for a DIE in the
|
||||
hash table and don't find it. */
|
||||
bool load_all_dies : 1;
|
||||
|
||||
struct partial_die_info *find_partial_die (sect_offset sect_off);
|
||||
|
||||
/* If this CU was inherited by another CU (via specification,
|
||||
|
@ -18817,7 +18817,7 @@ load_partial_dies (const struct die_reader_specs *reader,
|
||||
last_die = NULL;
|
||||
|
||||
gdb_assert (cu->per_cu != NULL);
|
||||
if (cu->per_cu->load_all_dies)
|
||||
if (cu->load_all_dies)
|
||||
load_all = 1;
|
||||
|
||||
cu->partial_dies
|
||||
@ -19385,9 +19385,9 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
|
||||
/* If we didn't find it, and not all dies have been loaded,
|
||||
load them all and try again. */
|
||||
|
||||
if (pd == NULL && cu->per_cu->load_all_dies == 0)
|
||||
if (pd == NULL && cu->load_all_dies == 0)
|
||||
{
|
||||
cu->per_cu->load_all_dies = 1;
|
||||
cu->load_all_dies = 1;
|
||||
|
||||
/* This is nasty. When we reread the DIEs, somewhere up the call chain
|
||||
THIS_CU->cu may already be in use. So we can't just free it and
|
||||
|
@ -421,7 +421,6 @@ struct dwarf2_per_cu_data
|
||||
{
|
||||
dwarf2_per_cu_data ()
|
||||
: queued (false),
|
||||
load_all_dies (false),
|
||||
is_debug_types (false),
|
||||
is_dwz (false),
|
||||
reading_dwo_directly (false),
|
||||
@ -447,12 +446,6 @@ struct dwarf2_per_cu_data
|
||||
any of the current compilation units are processed. */
|
||||
unsigned int queued : 1;
|
||||
|
||||
/* This flag will be set when reading partial DIEs if we need to load
|
||||
absolutely all DIEs for this compilation unit, instead of just the ones
|
||||
we think are interesting. It gets set if we look for a DIE in the
|
||||
hash table and don't find it. */
|
||||
unsigned int load_all_dies : 1;
|
||||
|
||||
/* Non-zero if this CU is from .debug_types.
|
||||
Struct dwarf2_per_cu_data is contained in struct signatured_type iff
|
||||
this is non-zero. */
|
||||
|
Loading…
Reference in New Issue
Block a user