From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Aaron Merey <amerey@redhat.com>
Subject: [RFC 2/3] gdb: use basic_safe_range to iterate over objfile::qf
Date: Fri, 14 Aug 2026 16:06:07 +0100 [thread overview]
Message-ID: <4337714baed7b5b73e4b2168fc0e61d395e95322.1786715843.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1786715843.git.aburgess@redhat.com>
From: Aaron Merey <amerey@redhat.com>
Change objfile's quick_symbol_function iteration to use a safe
iterator which allows for a quick_symbol_function to be deleted while
iterating over the list.
The next patch adds deferred debug information downloading. To make
this work GDB needs to be able to delete a quick_symbol_function from
an objfile's list while iterating over the quick_symbol_function
list. Such deletion requires that we use a deletion safe iterator.
Make objfile::qf private and rename to objfile::m_qf. Add member
function objfile::add_qf and objfile::clear_qf for manipulating the
quick_symbol_function list now that it is private.
A new member function objfile::qf returns a basic_safe_range object
suitably templated to allow iteration over objfile::m_qf.
All the other changes are straight forward updates to handle the
objfile API changes.
---
gdb/ctfread.c | 4 ++--
gdb/dwarf2/read.c | 4 ++--
gdb/jit.c | 4 ++--
gdb/objfiles.h | 33 ++++++++++++++++++++++++++++++---
gdb/symfile-debug.c | 32 ++++++++++++++++----------------
gdb/symfile.c | 4 ++--
6 files changed, 54 insertions(+), 27 deletions(-)
diff --git a/gdb/ctfread.c b/gdb/ctfread.c
index 5f8c54a34df..c5d623a9b11 100644
--- a/gdb/ctfread.c
+++ b/gdb/ctfread.c
@@ -1324,8 +1324,8 @@ elfctf_build_symtabs (objfile *objfile)
styled_string (file_name_style.style (), bfd_get_filename (abfd)),
ctf_errmsg (err));
- objfile->qf.emplace_front (std::make_unique<expanded_symbols_functions>
- (std::move (iter_data.compunit_symtabs)));
+ objfile->add_qf (std::make_unique<expanded_symbols_functions>
+ (std::move (iter_data.compunit_symtabs)));
}
#else
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 114c608fde3..3557d88833a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2139,7 +2139,7 @@ dwarf2_initialize_objfile (struct objfile *objfile,
dwarf_read_debug_printf ("readnow requested");
create_all_units (per_objfile);
- objfile->qf.emplace_front (new readnow_functions);
+ objfile->add_qf (std::make_unique<readnow_functions> ());
}
/* Was a GDB index already read when we processed an objfile sharing
PER_BFD? */
@@ -2169,7 +2169,7 @@ dwarf2_initialize_objfile (struct objfile *objfile,
{
if (dwarf_synchronous)
per_bfd->index_table->wait_completely ();
- objfile->qf.push_front (per_bfd->index_table->make_quick_functions ());
+ objfile->add_qf (per_bfd->index_table->make_quick_functions ());
}
return true;
diff --git a/gdb/jit.c b/gdb/jit.c
index c0aeb41e5aa..73e16e0a704 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -683,8 +683,8 @@ jit_object_close_impl (struct gdb_symbol_callbacks *cb,
for (gdb_symtab &symtab : obj->symtabs)
compunit_symtabs.emplace_back (finalize_symtab (&symtab, objfile));
- objfile->qf.emplace_front (std::make_unique<expanded_symbols_functions>
- (std::move (compunit_symtabs)));
+ objfile->add_qf (std::make_unique<expanded_symbols_functions>
+ (std::move (compunit_symtabs)));
add_objfile_entry (objfile, priv_data->entry_addr,
priv_data->entry.symfile_addr,
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 406ab36b39d..12e77d51b74 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -344,6 +344,12 @@ class separate_debug_iterator
using separate_debug_range = iterator_range<separate_debug_iterator>;
+/* See objfile::qf_safe. */
+
+using qf_list = std::forward_list<quick_symbol_functions_up>;
+using qf_range = iterator_range<qf_list::iterator>;
+using qf_safe_range = basic_safe_range<qf_range>;
+
/* Sections in an objfile. The section offsets are stored in the
OBJFILE. */
@@ -743,9 +749,22 @@ struct objfile : intrusive_list_node<objfile>
const struct sym_fns *sf = nullptr;
- /* The "quick" (aka partial) symbol functions for this symbol
- reader. */
- std::forward_list<quick_symbol_functions_up> qf;
+ /* Returns an iterable object that allows for safe deletion during
+ iteration. See gdbsupport/safe-iterator.h. */
+ qf_safe_range qf ()
+ {
+ return qf_safe_range (qf_range (m_qf.begin (), m_qf.end ()));
+ }
+
+ void add_qf (quick_symbol_functions_up qf)
+ {
+ m_qf.push_front (std::move (qf));
+ }
+
+ void clear_qf ()
+ {
+ m_qf.clear ();
+ }
/* Per objfile data-pointers required by other GDB modules. */
@@ -861,6 +880,14 @@ struct objfile : intrusive_list_node<objfile>
mechanism as ELF should set this flag too. This flag is used in
conjunction with the minimal_symbol::maybe_copied method. */
bool object_format_has_copy_relocs = false;
+
+private:
+ /* The "quick" (aka partial) symbol functions for this symbol
+ reader. Many quick_symbol_functions methods may result
+ in the deletion of a quick_symbol_functions from this
+ qf_list. It is recommended that qf_safe be used to iterate
+ over the qf_list. */
+ qf_list m_qf;
};
/* A deleter for objfile. */
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 2432a709ddf..e009821f78c 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -83,7 +83,7 @@ objfile::has_partial_symbols ()
them, then that is an indication that they are in fact available. Without
this function the symbols may have been already read in but they also may
not be present in this objfile. */
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
{
retval = iter->has_symbols (this);
if (retval)
@@ -106,7 +106,7 @@ objfile::has_unexpanded_symtabs ()
objfile_debug_name (this));
bool result = false;
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
{
if (iter->has_unexpanded_symtabs (this))
{
@@ -131,7 +131,7 @@ objfile::find_last_source_symtab ()
gdb_printf (gdb_stdlog, "qf->find_last_source_symtab (%s)\n",
objfile_debug_name (this));
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
{
retval = iter->find_last_source_symtab (this);
if (retval != nullptr)
@@ -155,7 +155,7 @@ objfile::forget_cached_source_info ()
for (compunit_symtab &cu : compunits ())
cu.forget_cached_source_info ();
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
iter->forget_cached_source_info (this);
}
@@ -273,7 +273,7 @@ objfile::find_symtab_matching_filename (const char *name,
: iteration_status::stop);
};
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
if (iter->search (this, match_one_filename, nullptr, nullptr,
compunit_callback,
SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
@@ -325,7 +325,7 @@ objfile::lookup_symbol (block_enum kind, const lookup_name_info &name,
return iteration_status::keep_going;
};
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
{
if (iter->search (this, nullptr, &name, nullptr, search_one_symtab,
kind == GLOBAL_BLOCK
@@ -352,7 +352,7 @@ objfile::print_stats (bool print_bcache)
gdb_printf (gdb_stdlog, "qf->print_stats (%s, %d)\n",
objfile_debug_name (this), print_bcache);
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
iter->print_stats (this, print_bcache);
}
@@ -363,7 +363,7 @@ objfile::dump ()
gdb_printf (gdb_stdlog, "qf->dump (%s)\n",
objfile_debug_name (this));
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
iter->dump (this);
}
@@ -374,7 +374,7 @@ objfile::expand_all_symtabs ()
gdb_printf (gdb_stdlog, "qf->expand_all_symtabs (%s)\n",
objfile_debug_name (this));
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
iter->expand_all_symtabs (this);
}
@@ -392,7 +392,7 @@ objfile::expand_symtabs_with_fullname (const char *fullname)
return filename_cmp (basenames ? basename : fullname, filename) == 0;
};
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
iter->search (this, file_matcher, nullptr, nullptr, nullptr,
SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
SEARCH_ALL_DOMAINS);
@@ -419,7 +419,7 @@ objfile::search (search_symtabs_file_matcher file_matcher,
host_address_to_string (&compunit_callback),
domain_name (domain).c_str ());
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
if (iter->search (this, file_matcher, lookup_name, symbol_matcher,
compunit_callback, search_flags, domain, lang_matcher)
== iteration_status::stop)
@@ -445,7 +445,7 @@ objfile::find_pc_sect_compunit_symtab (bound_minimal_symbol msymbol,
host_address_to_string (section),
warn_if_readin);
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
{
retval = iter->find_pc_sect_compunit_symtab (this, msymbol, pc, section,
warn_if_readin);
@@ -472,7 +472,7 @@ objfile::map_symbol_filenames (symbol_filename_listener fun, bool need_fullname)
objfile_debug_name (this),
need_fullname);
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
iter->map_symbol_filenames (this, fun, need_fullname);
}
@@ -484,7 +484,7 @@ objfile::compute_main_name ()
"qf->compute_main_name (%s)\n",
objfile_debug_name (this));
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
iter->compute_main_name (this);
}
@@ -498,7 +498,7 @@ objfile::find_symbol_by_address (CORE_ADDR address)
hex_string (address));
struct symbol *result = NULL;
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
{
result = iter->find_symbol_by_address (this, address);
if (result != nullptr)
@@ -523,7 +523,7 @@ objfile::lookup_global_symbol_language (const char *name,
enum language result = language_unknown;
*symbol_found_p = false;
- for (const auto &iter : qf)
+ for (const auto &iter : qf ())
{
result = iter->lookup_global_symbol_language (this, name, domain,
symbol_found_p);
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 017f7a49d8d..ce37d764485 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -881,7 +881,7 @@ syms_from_objfile_1 (struct objfile *objfile,
scoped_objfile_unlinker objfile_holder (objfile);
objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd.get ()));
- objfile->qf.clear ();
+ objfile->clear_qf ();
if (objfile->sf == NULL)
{
@@ -2603,7 +2603,7 @@ reread_symbols (int from_tty)
based on whether .gdb_index is present, and we need it to
start over. PR symtab/15885 */
objfile_set_sym_fns (&objfile, find_sym_fns (objfile.obfd.get ()));
- objfile.qf.clear ();
+ objfile.clear_qf ();
build_objfile_section_table (&objfile);
--
2.25.4
next prev parent reply other threads:[~2026-08-14 15:07 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 15:06 [RFC 0/3] Deferred, or on-demand, debuginfod downloading Andrew Burgess
2026-08-14 15:06 ` [RFC 1/3] gdb: limited support for frame cache flushing while building stack Andrew Burgess
2026-08-14 15:06 ` Andrew Burgess [this message]
2026-08-14 15:06 ` [RFC 3/3] gdb/debuginfod: support on-demand debuginfo downloading Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4337714baed7b5b73e4b2168fc0e61d395e95322.1786715843.git.aburgess@redhat.com \
--to=aburgess@redhat.com \
--cc=amerey@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox