forked from Imagelibrary/binutils-gdb
Fix two regressions caused by CU / TU merging
PR symtab/28160 and PR symtab/27893 concern GDB crashes in the test
suite when using the "fission" target board. They are both caused by
the patches that merge the list of CUs with the list of TUs (and to a
lesser degree by the patches to share DWARF data across objfiles), and
the underlying issue is the same: it turns out that reading a DWO can
cause new type units to be created. This means that the list of
dwarf2_per_cu_data objects depends on precisely which CUs have been
expanded. However, because the type units can be created while
expanding a CU means that the vector of CUs can expand while it is
being iterated over -- a classic mistake. Also, because a TU can be
added later, it means the resize_symtabs approach is incorrect.
This patch fixes resize_symtabs by removing it, and having set_symtab
resize the vector on demand. It fixes the iteration problem by
introducing a safe (index-based) iterator and changing the relevant
spots to use it.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28160
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27893
(cherry picked from commit d58e54bd27)
This commit is contained in:
@@ -1639,6 +1639,73 @@ line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* An iterator for all_comp_units that is based on index. This
|
||||||
|
approach makes it possible to iterate over all_comp_units safely,
|
||||||
|
when some caller in the loop may add new units. */
|
||||||
|
|
||||||
|
class all_comp_units_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
all_comp_units_iterator (dwarf2_per_bfd *per_bfd, bool start)
|
||||||
|
: m_per_bfd (per_bfd),
|
||||||
|
m_index (start ? 0 : per_bfd->all_comp_units.size ())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
all_comp_units_iterator &operator++ ()
|
||||||
|
{
|
||||||
|
++m_index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwarf2_per_cu_data *operator* () const
|
||||||
|
{
|
||||||
|
return m_per_bfd->get_cu (m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator== (const all_comp_units_iterator &other) const
|
||||||
|
{
|
||||||
|
return m_index == other.m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator!= (const all_comp_units_iterator &other) const
|
||||||
|
{
|
||||||
|
return m_index != other.m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
dwarf2_per_bfd *m_per_bfd;
|
||||||
|
size_t m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A range adapter for the all_comp_units_iterator. */
|
||||||
|
class all_comp_units_range
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
all_comp_units_range (dwarf2_per_bfd *per_bfd)
|
||||||
|
: m_per_bfd (per_bfd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
all_comp_units_iterator begin ()
|
||||||
|
{
|
||||||
|
return all_comp_units_iterator (m_per_bfd, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
all_comp_units_iterator end ()
|
||||||
|
{
|
||||||
|
return all_comp_units_iterator (m_per_bfd, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
dwarf2_per_bfd *m_per_bfd;
|
||||||
|
};
|
||||||
|
|
||||||
/* See declaration. */
|
/* See declaration. */
|
||||||
|
|
||||||
dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
|
dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
|
||||||
@@ -1703,9 +1770,9 @@ private:
|
|||||||
bool
|
bool
|
||||||
dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
|
dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
|
||||||
{
|
{
|
||||||
gdb_assert (per_cu->index < this->m_symtabs.size ());
|
if (per_cu->index < this->m_symtabs.size ())
|
||||||
|
return this->m_symtabs[per_cu->index] != nullptr;
|
||||||
return this->m_symtabs[per_cu->index] != nullptr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See read.h. */
|
/* See read.h. */
|
||||||
@@ -1713,9 +1780,9 @@ dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
|
|||||||
compunit_symtab *
|
compunit_symtab *
|
||||||
dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
|
dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
|
||||||
{
|
{
|
||||||
gdb_assert (per_cu->index < this->m_symtabs.size ());
|
if (per_cu->index < this->m_symtabs.size ())
|
||||||
|
return this->m_symtabs[per_cu->index];
|
||||||
return this->m_symtabs[per_cu->index];
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See read.h. */
|
/* See read.h. */
|
||||||
@@ -1724,9 +1791,9 @@ void
|
|||||||
dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
|
dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
|
||||||
compunit_symtab *symtab)
|
compunit_symtab *symtab)
|
||||||
{
|
{
|
||||||
gdb_assert (per_cu->index < this->m_symtabs.size ());
|
if (per_cu->index >= this->m_symtabs.size ())
|
||||||
|
this->m_symtabs.resize (per_cu->index + 1);
|
||||||
gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
|
gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
|
||||||
|
|
||||||
this->m_symtabs[per_cu->index] = symtab;
|
this->m_symtabs[per_cu->index] = symtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4321,11 +4388,12 @@ dwarf2_gdb_index::expand_symtabs_matching
|
|||||||
|
|
||||||
if (symbol_matcher == NULL && lookup_name == NULL)
|
if (symbol_matcher == NULL && lookup_name == NULL)
|
||||||
{
|
{
|
||||||
for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
|
for (dwarf2_per_cu_data *per_cu
|
||||||
|
: all_comp_units_range (per_objfile->per_bfd))
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
if (!dw2_expand_symtabs_matching_one (per_cu.get (), per_objfile,
|
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
|
||||||
file_matcher,
|
file_matcher,
|
||||||
expansion_notify))
|
expansion_notify))
|
||||||
return false;
|
return false;
|
||||||
@@ -4437,14 +4505,14 @@ dwarf2_base_index_functions::map_symbol_filenames
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
|
for (dwarf2_per_cu_data *per_cu
|
||||||
|
: all_comp_units_range (per_objfile->per_bfd))
|
||||||
{
|
{
|
||||||
/* We only need to look at symtabs not already expanded. */
|
/* We only need to look at symtabs not already expanded. */
|
||||||
if (per_objfile->symtab_set_p (per_cu.get ()))
|
if (per_cu->is_debug_types || per_objfile->symtab_set_p (per_cu))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
|
quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
|
||||||
per_objfile);
|
|
||||||
if (file_data == nullptr
|
if (file_data == nullptr
|
||||||
|| qfn_cache.find (file_data) != qfn_cache.end ())
|
|| qfn_cache.find (file_data) != qfn_cache.end ())
|
||||||
continue;
|
continue;
|
||||||
@@ -5309,11 +5377,12 @@ dwarf2_debug_names_index::expand_symtabs_matching
|
|||||||
|
|
||||||
if (symbol_matcher == NULL && lookup_name == NULL)
|
if (symbol_matcher == NULL && lookup_name == NULL)
|
||||||
{
|
{
|
||||||
for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
|
for (dwarf2_per_cu_data *per_cu
|
||||||
|
: all_comp_units_range (per_objfile->per_bfd))
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
if (!dw2_expand_symtabs_matching_one (per_cu.get (), per_objfile,
|
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
|
||||||
file_matcher,
|
file_matcher,
|
||||||
expansion_notify))
|
expansion_notify))
|
||||||
return false;
|
return false;
|
||||||
@@ -5421,7 +5490,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
|
|||||||
if (per_bfd->using_index)
|
if (per_bfd->using_index)
|
||||||
{
|
{
|
||||||
dwarf_read_debug_printf ("using_index already set");
|
dwarf_read_debug_printf ("using_index already set");
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
objfile->qf.push_front (make_dwarf_gdb_index ());
|
objfile->qf.push_front (make_dwarf_gdb_index ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5430,7 +5498,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
|
|||||||
create_all_comp_units (per_objfile);
|
create_all_comp_units (per_objfile);
|
||||||
per_bfd->quick_file_names_table
|
per_bfd->quick_file_names_table
|
||||||
= create_quick_file_names_table (per_bfd->all_comp_units.size ());
|
= create_quick_file_names_table (per_bfd->all_comp_units.size ());
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
|
|
||||||
for (int i = 0; i < per_bfd->all_comp_units.size (); ++i)
|
for (int i = 0; i < per_bfd->all_comp_units.size (); ++i)
|
||||||
{
|
{
|
||||||
@@ -5452,7 +5519,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
|
|||||||
if (per_bfd->debug_names_table != nullptr)
|
if (per_bfd->debug_names_table != nullptr)
|
||||||
{
|
{
|
||||||
dwarf_read_debug_printf ("re-using shared debug names table");
|
dwarf_read_debug_printf ("re-using shared debug names table");
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
objfile->qf.push_front (make_dwarf_debug_names ());
|
objfile->qf.push_front (make_dwarf_debug_names ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5462,7 +5528,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
|
|||||||
if (per_bfd->index_table != nullptr)
|
if (per_bfd->index_table != nullptr)
|
||||||
{
|
{
|
||||||
dwarf_read_debug_printf ("re-using shared index table");
|
dwarf_read_debug_printf ("re-using shared index table");
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
objfile->qf.push_front (make_dwarf_gdb_index ());
|
objfile->qf.push_front (make_dwarf_gdb_index ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5482,7 +5547,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
|
|||||||
if (dwarf2_read_debug_names (per_objfile))
|
if (dwarf2_read_debug_names (per_objfile))
|
||||||
{
|
{
|
||||||
dwarf_read_debug_printf ("found debug names");
|
dwarf_read_debug_printf ("found debug names");
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
objfile->qf.push_front (make_dwarf_debug_names ());
|
objfile->qf.push_front (make_dwarf_debug_names ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5492,7 +5556,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
|
|||||||
get_gdb_index_contents_from_section<dwz_file>))
|
get_gdb_index_contents_from_section<dwz_file>))
|
||||||
{
|
{
|
||||||
dwarf_read_debug_printf ("found gdb index from file");
|
dwarf_read_debug_printf ("found gdb index from file");
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
objfile->qf.push_front (make_dwarf_gdb_index ());
|
objfile->qf.push_front (make_dwarf_gdb_index ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5504,7 +5567,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
|
|||||||
{
|
{
|
||||||
dwarf_read_debug_printf ("found gdb index from cache");
|
dwarf_read_debug_printf ("found gdb index from cache");
|
||||||
global_index_cache.hit ();
|
global_index_cache.hit ();
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
objfile->qf.push_front (make_dwarf_gdb_index ());
|
objfile->qf.push_front (make_dwarf_gdb_index ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5534,7 +5596,6 @@ dwarf2_build_psymtabs (struct objfile *objfile, psymbol_functions *psf)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
psf->set_partial_symtabs (per_bfd->partial_symtabs);
|
psf->set_partial_symtabs (per_bfd->partial_symtabs);
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5561,8 +5622,6 @@ dwarf2_build_psymtabs (struct objfile *objfile, psymbol_functions *psf)
|
|||||||
dwarf2_build_psymtabs_hard (per_objfile);
|
dwarf2_build_psymtabs_hard (per_objfile);
|
||||||
psymtabs.keep ();
|
psymtabs.keep ();
|
||||||
|
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
|
|
||||||
/* (maybe) store an index in the cache. */
|
/* (maybe) store an index in the cache. */
|
||||||
global_index_cache.store (per_objfile);
|
global_index_cache.store (per_objfile);
|
||||||
}
|
}
|
||||||
@@ -5904,8 +5963,6 @@ add_type_unit (dwarf2_per_objfile *per_objfile, ULONGEST sig, void **slot)
|
|||||||
= per_objfile->per_bfd->allocate_signatured_type (sig);
|
= per_objfile->per_bfd->allocate_signatured_type (sig);
|
||||||
signatured_type *sig_type = sig_type_holder.get ();
|
signatured_type *sig_type = sig_type_holder.get ();
|
||||||
|
|
||||||
per_objfile->resize_symtabs ();
|
|
||||||
|
|
||||||
per_objfile->per_bfd->all_comp_units.emplace_back
|
per_objfile->per_bfd->all_comp_units.emplace_back
|
||||||
(sig_type_holder.release ());
|
(sig_type_holder.release ());
|
||||||
if (per_objfile->per_bfd->using_index)
|
if (per_objfile->per_bfd->using_index)
|
||||||
|
|||||||
@@ -514,16 +514,6 @@ struct dwarf2_per_objfile
|
|||||||
const struct comp_unit_head *cu_header,
|
const struct comp_unit_head *cu_header,
|
||||||
unsigned int *bytes_read_ptr);
|
unsigned int *bytes_read_ptr);
|
||||||
|
|
||||||
/* Resize the M_SYMTABS vector to the needed size (the number of partial
|
|
||||||
symtabs allocated by the per-bfd). */
|
|
||||||
void resize_symtabs ()
|
|
||||||
{
|
|
||||||
/* The symtabs vector should only grow, not shrink. */
|
|
||||||
gdb_assert (per_bfd->all_comp_units.size () >= m_symtabs.size ());
|
|
||||||
|
|
||||||
m_symtabs.resize (per_bfd->all_comp_units.size ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true if the symtab corresponding to PER_CU has been set,
|
/* Return true if the symtab corresponding to PER_CU has been set,
|
||||||
false otherwise. */
|
false otherwise. */
|
||||||
bool symtab_set_p (const dwarf2_per_cu_data *per_cu) const;
|
bool symtab_set_p (const dwarf2_per_cu_data *per_cu) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user