Add deferred_warnings parameter to read_addrmap_from_aranges

When DWARF reading is done in the background,
read_addrmap_from_aranges will be called from a worker thread.
Because warnings can't be emitted from these threads, this patch adds
a new deferred_warnings parameter to the function, letting the caller
control exactly how the warnings are emitted.
This commit is contained in:
Tom Tromey 2023-12-10 14:16:06 -07:00
parent 54b815ddb4
commit 8e279fda0f
5 changed files with 65 additions and 45 deletions

View file

@ -26,7 +26,8 @@
bool
read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
dwarf2_section_info *section,
addrmap *mutable_map)
addrmap *mutable_map,
deferred_warnings *warn)
{
/* Caller must ensure that the section has already been read. */
gdb_assert (section->readin);
@ -76,13 +77,13 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
const uint8_t offset_size = dwarf5_is_dwarf64 ? 8 : 4;
if (addr + entry_length > section->buffer + section->size)
{
warning (_("Section .debug_aranges in %s entry at offset %s "
"length %s exceeds section length %s, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer),
plongest (bytes_read + entry_length),
pulongest (section->size));
warn->warn (_("Section .debug_aranges in %s entry at offset %s "
"length %s exceeds section length %s, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer),
plongest (bytes_read + entry_length),
pulongest (section->size));
return false;
}
@ -91,10 +92,11 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
addr += 2;
if (version != 2)
{
warning (_("Section .debug_aranges in %s entry at offset %s "
"has unsupported version %d, ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer), version);
warn->warn
(_("Section .debug_aranges in %s entry at offset %s "
"has unsupported version %d, ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer), version);
return false;
}
@ -105,22 +107,22 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
= debug_info_offset_to_per_cu.find (sect_offset (debug_info_offset));
if (per_cu_it == debug_info_offset_to_per_cu.cend ())
{
warning (_("Section .debug_aranges in %s entry at offset %s "
"debug_info_offset %s does not exists, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer),
pulongest (debug_info_offset));
warn->warn (_("Section .debug_aranges in %s entry at offset %s "
"debug_info_offset %s does not exists, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer),
pulongest (debug_info_offset));
return false;
}
const auto insertpair
= debug_info_offset_seen.insert (sect_offset (debug_info_offset));
if (!insertpair.second)
{
warning (_("Section .debug_aranges in %s has duplicate "
"debug_info_offset %s, ignoring .debug_aranges."),
objfile_name (objfile),
sect_offset_str (sect_offset (debug_info_offset)));
warn->warn (_("Section .debug_aranges in %s has duplicate "
"debug_info_offset %s, ignoring .debug_aranges."),
objfile_name (objfile),
sect_offset_str (sect_offset (debug_info_offset)));
return false;
}
dwarf2_per_cu_data *const per_cu = per_cu_it->second;
@ -128,22 +130,23 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
const uint8_t address_size = *addr++;
if (address_size < 1 || address_size > 8)
{
warning (_("Section .debug_aranges in %s entry at offset %s "
"address_size %u is invalid, ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer), address_size);
warn->warn
(_("Section .debug_aranges in %s entry at offset %s "
"address_size %u is invalid, ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer), address_size);
return false;
}
const uint8_t segment_selector_size = *addr++;
if (segment_selector_size != 0)
{
warning (_("Section .debug_aranges in %s entry at offset %s "
"segment_selector_size %u is not supported, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer),
segment_selector_size);
warn->warn (_("Section .debug_aranges in %s entry at offset %s "
"segment_selector_size %u is not supported, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer),
segment_selector_size);
return false;
}
@ -160,11 +163,11 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
{
if (addr + 2 * address_size > entry_end)
{
warning (_("Section .debug_aranges in %s entry at offset %s "
"address list is not properly terminated, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer));
warn->warn (_("Section .debug_aranges in %s entry at offset %s "
"address list is not properly terminated, "
"ignoring .debug_aranges."),
objfile_name (objfile),
plongest (entry_addr - section->buffer));
return false;
}
ULONGEST start = extract_unsigned_integer (addr, address_size,

View file

@ -30,6 +30,7 @@ class addrmap;
extern bool read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
dwarf2_section_info *section,
addrmap *mutable_map);
addrmap *mutable_map,
deferred_warnings *warn);
#endif /* GDB_DWARF2_ARANGES_H */

View file

@ -153,12 +153,16 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
addrmap_mutable mutable_map;
deferred_warnings warnings;
section->read (per_objfile->objfile);
if (read_addrmap_from_aranges (per_objfile, section, &mutable_map))
if (read_addrmap_from_aranges (per_objfile, section, &mutable_map,
&warnings))
per_bfd->index_addrmap
= new (&per_bfd->obstack) addrmap_fixed (&per_bfd->obstack,
&mutable_map);
warnings.emit ();
}
/* DWARF-5 debug_names reader. */

View file

@ -4926,8 +4926,12 @@ dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
per_bfd->quick_file_names_table
= create_quick_file_names_table (per_bfd->all_units.size ());
if (!per_bfd->debug_aranges.empty ())
read_addrmap_from_aranges (per_objfile, &per_bfd->debug_aranges,
index_storage.get_addrmap ());
{
deferred_warnings warn;
read_addrmap_from_aranges (per_objfile, &per_bfd->debug_aranges,
index_storage.get_addrmap (), &warn);
warn.emit ();
}
{
using iter_type = decltype (per_bfd->all_units.begin ());

View file

@ -395,13 +395,16 @@ assign_return_if_changed (T &lval, const T &val)
struct deferred_warnings
{
deferred_warnings ()
: m_can_style (gdb_stderr->can_emit_style_escape ())
{
}
/* Add a warning to the list of deferred warnings. */
void warn (const char *format, ...) ATTRIBUTE_PRINTF(2,3)
{
/* Generate the warning text into a string_file. We allow the text to
be styled only if gdb_stderr allows styling -- warnings are sent to
gdb_stderr. */
string_file msg (gdb_stderr->can_emit_style_escape ());
/* Generate the warning text into a string_file. */
string_file msg (m_can_style);
va_list args;
va_start (args, format);
@ -421,6 +424,11 @@ struct deferred_warnings
private:
/* True if gdb_stderr supports styling at the moment this object is
constructed. This is done just once so that objects of this type
can be used off the main thread. */
bool m_can_style;
/* The list of all deferred warnings. */
std::vector<string_file> m_warnings;
};