From 8e279fda0f725500c8f84a8b2ed56b0ee8d00ce0 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 10 Dec 2023 14:16:06 -0700 Subject: [PATCH] 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. --- gdb/dwarf2/aranges.c | 77 ++++++++++++++++++++++--------------------- gdb/dwarf2/aranges.h | 3 +- gdb/dwarf2/read-debug-names.c | 6 +++- gdb/dwarf2/read.c | 8 +++-- gdb/utils.h | 16 ++++++--- 5 files changed, 65 insertions(+), 45 deletions(-) diff --git a/gdb/dwarf2/aranges.c b/gdb/dwarf2/aranges.c index 06f49a4..b7d050b 100644 --- a/gdb/dwarf2/aranges.c +++ b/gdb/dwarf2/aranges.c @@ -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, diff --git a/gdb/dwarf2/aranges.h b/gdb/dwarf2/aranges.h index 43e1cbd..e3e9cde 100644 --- a/gdb/dwarf2/aranges.h +++ b/gdb/dwarf2/aranges.h @@ -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 */ diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index e912c2a..0877bf3 100644 --- a/gdb/dwarf2/read-debug-names.c +++ b/gdb/dwarf2/read-debug-names.c @@ -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. */ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index f1434bc..61d8700 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -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 ()); diff --git a/gdb/utils.h b/gdb/utils.h index f646b30..0acf11c 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -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 m_warnings; }; -- 2.7.4