From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id A326A3858C66 for ; Mon, 31 Jul 2023 10:11:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A326A3858C66 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1690798285; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=6ExIDx+U9zj5TSFISKYlBhg9OdgfN4oiojFkMRvrER0=; b=VD9T6C0+JilXBzNYWjA4GVZ2qIokpXKBYDgDB1iUU4CCW3FXumZ+fHv8lRsdERnc5jJdnO rZ1xTafbDzw46Kh19Is47gYezfxuABLG28lIPrbCVj9yWrOkBLg7L2PxQPKh2VyTLP/yWi j3M5G2nLw80XHuzpMBIm77fGL4p2SCQ= Received: from mail-ej1-f71.google.com (mail-ej1-f71.google.com [209.85.218.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-518-0RjuPfJbM66nzp2kWTQYEQ-1; Mon, 31 Jul 2023 06:11:23 -0400 X-MC-Unique: 0RjuPfJbM66nzp2kWTQYEQ-1 Received: by mail-ej1-f71.google.com with SMTP id a640c23a62f3a-99bfe3dd009so255294366b.0 for ; Mon, 31 Jul 2023 03:11:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690798282; x=1691403082; h=mime-version:message-id:date:references:in-reply-to:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6ExIDx+U9zj5TSFISKYlBhg9OdgfN4oiojFkMRvrER0=; b=SvcRLomuxlC5mYwdh3nMj9JiQzIl3VeQQroUqywLiXo4Jv0dOqD11KBOOU1emqNlEI YJASCSHNK6E5GM3Sab7REcc0riufk/GZ52qSHGmK+rhfdD+UNlv6wPXHpnN4aqDfWIFk k+oLrYkXuIXE1TtsXJuJfauUTXlbSlRJaNADbbn4sIpKjQgvAu4yi6wIvd51s3CZaGHW OF63R9g4PNAe+IJS4U5/1YMkd/tW1gXHB/pMQhHv487DzbPKVzC3q4fjHxeJHiJGErK1 kTjMdhhdGj9mXRx0fJw1XUr40gUbPUeG9poymitCzBGav6P8KbdTLDs3uEVGoiTTc1us f7lA== X-Gm-Message-State: ABy/qLbHncSZK70nJkR8KufpntfF0zwfd+7t6e2L1h7VadT8bzc22jLP 2nm+SkPAGlSwTE/BLvedmDkSuuyzPf3dK+QdQLnWLwgL7AeLAXYe9oOMfTPwCWCO2XcOFOLUxgn PvaxTVnTG9VWH0xgZiUQD92CrARLb6w== X-Received: by 2002:a17:906:4e:b0:99b:50ea:2f96 with SMTP id 14-20020a170906004e00b0099b50ea2f96mr7353404ejg.12.1690798282085; Mon, 31 Jul 2023 03:11:22 -0700 (PDT) X-Google-Smtp-Source: APBJJlGwd/gqQidiqGGfOZIdWs9RyTanRSUtIcRufCHIoveEGSyGgVm3irXeRWEsEfWHsEkZ8BNB6Q== X-Received: by 2002:a17:906:4e:b0:99b:50ea:2f96 with SMTP id 14-20020a170906004e00b0099b50ea2f96mr7353385ejg.12.1690798281605; Mon, 31 Jul 2023 03:11:21 -0700 (PDT) Received: from localhost ([31.111.84.232]) by smtp.gmail.com with ESMTPSA id br15-20020a170906d14f00b0098e42bef736sm5975404ejb.176.2023.07.31.03.11.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jul 2023 03:11:21 -0700 (PDT) From: Andrew Burgess To: Aaron Merey , gdb-patches@sourceware.org Cc: Aaron Merey Subject: Re: [PATCH 4/6] gdb/progspace: Add reverse safe iterator and template for unwrapping iterator In-Reply-To: <20230601014347.3367489-5-amerey@redhat.com> References: <20230601014347.3367489-1-amerey@redhat.com> <20230601014347.3367489-5-amerey@redhat.com> Date: Mon, 31 Jul 2023 11:11:19 +0100 Message-ID: <87wmyge6go.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Aaron Merey writes: > To facilitate the deletion of objfiles, progspace objects use a safe > iterator that holds a reference to the next objfile in the progspace's > objfile_list. This allows objfiles to be deleted in a loop without > invalidating the loop's iterator. progspace also uses an unwrapping > iterator over std::unique_ptr that automatically deferences > the unique_ptr. > > This patch changes the objfile safe iterator to be a reverse safe > iterator. It changes the unwrapping iterator into a template. It > also modifies objfile_list insertion so that separate debug objfiles > are placed into the list after the parent objfile, instead of before. > > These changes are intended to prepare gdb for on-demand debuginfo > downloading and the downloading of .gdb_index sections. > > With on-demand downloading enabled, gdb might download a debuginfo > file during symtab expansion. In this case an objfile could be added > to an objfiles_list during iteration over the list (for example, in > iterate_over_symtabs). We want these loops to also iterate over newly > downloaded objfiles. So objfiles need to be inserted into objfiles_list > after their parent since it is during the search of the parent > objfile for some symbol or filename that the separate debug objfile > might be downloaded. > > The unwrapping iterator is changed into a template in order to > use it with objfile qf_require_partial_symbols, which is now also > uses with a safe iterator. This is because after a separate debug > objfile is downloaded on-demand, we want to remove any .gdb_index > quick_symbol_functions from the parent objfile during iteration over > the parent's quick_symbol_functions. The newly downloaded separate > debug objfile contains the index and all of the related symbols > so the .gdb_index should not be associated with the parent objfile > any longer. This doesn't really explain why we need to use the unwrapping iterator though, couldn't we just use basic_safe_range instead? This would remove the need for some of the updates in symfile-debug.c. > > Finally a safe reverse iterator is now used during progspace objfile > deletion in order to prevent iterator invalidation during the loop > in which objfiles are deleted. This could happen during forward > iteration over objfiles_list when a separate debug objfile immediately > follows it's parent objfile in the list (which is now possible since > objfiles are inserted into the list after their parent). Deletion > of the parent would cause deletion of the separate debug objfile, > which would invalidate the safe forward iterator's reference to the > next objfile in the list. A safe reverse iterator deletes separate > debug objfiles before their parent, so the iterator's reference to > the next objfile always stays valid. > > A small change was also made to a testcase in py-objfile.exp to > account for the new placement of separate debug objfiles in > objfiles_list. > --- > gdb/objfiles.h | 22 +++- > gdb/progspace.c | 8 +- > gdb/progspace.h | 159 +++++++++++++++++++----- > gdb/symfile-debug.c | 136 ++++++++++---------- > gdb/testsuite/gdb.python/py-objfile.exp | 2 +- > 5 files changed, 218 insertions(+), 109 deletions(-) > > diff --git a/gdb/objfiles.h b/gdb/objfiles.h > index 189856f0a51..bb7b0a4579d 100644 > --- a/gdb/objfiles.h > +++ b/gdb/objfiles.h > @@ -613,6 +613,17 @@ struct objfile > /* See quick_symbol_functions. */ > void require_partial_symbols (bool verbose); > > + /* Remove TARGET from this objfile's collection of quick_symbol_functions. */ > + void remove_partial_symbol (quick_symbol_functions *target) > + { > + for (quick_symbol_functions_up &qf_up : qf) > + if (qf_up.get () == target) > + { > + qf.remove (qf_up); > + return; > + } I think the more C++ way of writing this would be: qf.remove_if ([&] (const quick_symbol_functions_up &qf_up) { return qf_up.get () == target; }); The remove function already walks the whole of `qf` to remove every item matching qf_up, so the early return isn't actually saving anything. > + } > + > /* Return the relocation offset applied to SECTION. */ > CORE_ADDR section_offset (bfd_section *section) const > { > @@ -699,13 +710,20 @@ struct objfile > > private: > > + using qf_list = std::forward_list; > + using unwrapping_qf_range = iterator_range>; > + using qf_safe_range = basic_safe_range; > + > /* Ensure that partial symbols have been read and return the "quick" (aka > partial) symbol functions for this symbol reader. */ > - const std::forward_list & > + qf_safe_range > qf_require_partial_symbols () > { > this->require_partial_symbols (true); > - return qf; > + return qf_safe_range > + (unwrapping_qf_range > + (unwrapping_iterator (qf.begin ()), > + unwrapping_iterator (qf.end ()))); > } > > public: > diff --git a/gdb/progspace.c b/gdb/progspace.c > index 32bdfebcf7c..1ed75eef2f9 100644 > --- a/gdb/progspace.c > +++ b/gdb/progspace.c > @@ -139,19 +139,19 @@ program_space::free_all_objfiles () > > void > program_space::add_objfile (std::unique_ptr &&objfile, > - struct objfile *before) > + struct objfile *after) > { > - if (before == nullptr) > + if (after == nullptr) > objfiles_list.push_back (std::move (objfile)); > else > { > auto iter = std::find_if (objfiles_list.begin (), objfiles_list.end (), > [=] (const std::unique_ptr<::objfile> &objf) > { > - return objf.get () == before; > + return objf.get () == after; > }); > gdb_assert (iter != objfiles_list.end ()); > - objfiles_list.insert (iter, std::move (objfile)); > + objfiles_list.insert (++iter, std::move (objfile)); > } > } > > diff --git a/gdb/progspace.h b/gdb/progspace.h > index 85215f0e2f1..6e33e48c88e 100644 > --- a/gdb/progspace.h > +++ b/gdb/progspace.h > @@ -40,56 +40,141 @@ struct address_space; > struct program_space; > struct so_list; > > +/* An iterator that wraps an iterator over std::unique_ptr, and dereferences > + the returned object. This is useful for iterating over a list of shared > + pointers and returning raw pointers -- which helped avoid touching a lot > + of code when changing how objfiles are managed. */ > + > +template > +class unwrapping_iterator If my comment above about qf using basic_safe_range is correct, then this change might not be needed. > +{ > +public: > + typedef unwrapping_iterator self_type; > + typedef typename UniquePtrIter::value_type::pointer value_type; > + typedef typename UniquePtrIter::reference reference; > + typedef typename UniquePtrIter::pointer pointer; > + typedef typename UniquePtrIter::iterator_category iterator_category; > + typedef typename UniquePtrIter::difference_type difference_type; > + > + unwrapping_iterator (UniquePtrIter iter) > + : m_iter (std::move (iter)) > + { > + } > + > + value_type operator* () const > + { > + return m_iter->get (); > + } > + > + unwrapping_iterator operator++ () > + { > + ++m_iter; > + return *this; > + } > + > + bool operator!= (const unwrapping_iterator &other) const > + { > + return m_iter != other.m_iter; > + } > + > +private: > + /* The underlying iterator. */ > + UniquePtrIter m_iter; > +}; > + > typedef std::list> objfile_list; > > -/* An iterator that wraps an iterator over std::unique_ptr, > - and dereferences the returned object. This is useful for iterating > - over a list of shared pointers and returning raw pointers -- which > - helped avoid touching a lot of code when changing how objfiles are > - managed. */ > +/* An reverse iterator that wraps an iterator over objfile_list, and > + dereferences the returned object. This is useful for reverse iterating > + over a list of shared pointers and returning raw pointers -- which helped > + avoid touching a lot of code when changing how objfiles are managed. */ > > -class unwrapping_objfile_iterator > +class unwrapping_reverse_objfile_iterator I see what you did here, but I wonder if this is the right approach. Rather than using basic_safe_range, maybe we should instead create basic_safe_reverse_range, which would imply creating a basic_safe_reverse_iterator. The basic_safe_reverse_range would take a "normal" forward range, but walk over it backwards. I also think it would be super useful to have some comments about why we can't just use the standard reverse iterators here, my initial thought was that this should be possible, and it was only once I tried it out that I discovered what the problems were -- I guess you already ran into those issues, but neither the commit message, nor any comments really explain why _this_ implementation. Additionally, I question the need to use an unwrapping iterator here. The comment (clearly copy & paste) says "which helped avoid touching a lot of code when changing how objfiles are managed.", however, for this reverse case, as far as I can tell, there's only two users, so, I'd be tempted to say we should just update those two users to make use of iterators... ... but both the users of progspace::objfiles_safe() actually just do: for (objfile *objf : current_program_space->objfiles_safe ()) { if (predicate (objf)) objf->unlink (); } So I wonder if a better solution would be to offer: void progspace::unlink_objfiles_if (gdb::function_view predicate); which would mean that the callers can focus on the logic of _what_ to unlink, while progspace.c can focus on the mechanism of _how_ to unlink? Thanks, Andrew > { > public: > - > - typedef unwrapping_objfile_iterator self_type; > + typedef unwrapping_reverse_objfile_iterator self_type; > typedef typename ::objfile *value_type; > typedef typename ::objfile &reference; > typedef typename ::objfile **pointer; > typedef typename objfile_list::iterator::iterator_category iterator_category; > typedef typename objfile_list::iterator::difference_type difference_type; > > - unwrapping_objfile_iterator (objfile_list::iterator iter) > - : m_iter (std::move (iter)) > - { > - } > - > - objfile *operator* () const > + value_type operator* () const > { > return m_iter->get (); > } > > - unwrapping_objfile_iterator operator++ () > + unwrapping_reverse_objfile_iterator operator++ () > { > - ++m_iter; > + if (m_iter != m_begin) > + --m_iter; > + else > + { > + /* We can't decrement M_ITER since it is the begin iterator of the > + objfile list. Set M_ITER to the list's end iterator to indicate > + this is now one-past-the-end. */ > + m_iter = m_end; > + > + /* Overwrite M_BEGIN to avoid possibly copying an invalid iterator. */ > + m_begin = m_end; > + } > + > return *this; > } > > - bool operator!= (const unwrapping_objfile_iterator &other) const > + bool operator!= (const unwrapping_reverse_objfile_iterator &other) const > { > return m_iter != other.m_iter; > } > > + /* Return an unwrapping reverse iterator starting at the last element of > + OBJF_LIST. */ > + static unwrapping_reverse_objfile_iterator begin (objfile_list &objf_list) > + { > + auto begin = objf_list.begin (); > + auto end = objf_list.end (); > + auto rev_begin = objf_list.end (); > + > + /* Start REV_BEGIN on the last objfile in OBJF_LIST. */ > + if (begin != end) > + --rev_begin; > + > + return unwrapping_reverse_objfile_iterator (rev_begin, begin, end); > + } > + > + /* Return a one-past-the-end unwrapping reverse iterator. */ > + static unwrapping_reverse_objfile_iterator end (objfile_list &objf_list) > + { > + return unwrapping_reverse_objfile_iterator (objf_list.end (), > + objf_list.end (), > + objf_list.end ()); > + } > + > private: > + /* begin and end methods should be used to create these objects. */ > + unwrapping_reverse_objfile_iterator (objfile_list::iterator iter, > + objfile_list::iterator begin, > + objfile_list::iterator end) > + : m_iter (std::move (iter)), m_begin (std::move (begin)), > + m_end (std::move (end)) > + { > + } > > - /* The underlying iterator. */ > - objfile_list::iterator m_iter; > -}; > + /* The underlying iterator. */ > + objfile_list::iterator m_iter; > > + /* The underlying iterator pointing to the first objfile in the sequence. Used > + to track when to stop decrementing M_ITER. */ > + objfile_list::iterator m_begin; > > -/* A range that returns unwrapping_objfile_iterators. */ > + /* The underlying iterator's one-past-the-end. */ > + objfile_list::iterator m_end; > +}; > > -using unwrapping_objfile_range = iterator_range; > +/* A range that returns unwrapping_iterators. */ > + > +using unwrapping_objfile_range > + = iterator_range>; > > /* A program space represents a symbolic view of an address space. > Roughly speaking, it holds all the data associated with a > @@ -209,11 +294,12 @@ struct program_space > objfiles_range objfiles () > { > return objfiles_range > - (unwrapping_objfile_iterator (objfiles_list.begin ()), > - unwrapping_objfile_iterator (objfiles_list.end ())); > + (unwrapping_iterator (objfiles_list.begin ()), > + unwrapping_iterator (objfiles_list.end ())); > } > > - using objfiles_safe_range = basic_safe_range; > + using objfiles_reverse_range = iterator_range; > + using objfiles_safe_reverse_range = basic_safe_range; > > /* An iterable object that can be used to iterate over all objfiles. > The basic use is in a foreach, like: > @@ -221,20 +307,25 @@ struct program_space > for (objfile *objf : pspace->objfiles_safe ()) { ... } > > This variant uses a basic_safe_iterator so that objfiles can be > - deleted during iteration. */ > - objfiles_safe_range objfiles_safe () > + deleted during iteration. > + > + The use of a reverse iterator helps ensure that separate debug > + objfiles are deleted before their parent objfile. This prevents > + the invalidation of an iterator due to the deletion of a parent > + objfile. */ > + objfiles_safe_reverse_range objfiles_safe () > { > - return objfiles_safe_range > - (objfiles_range > - (unwrapping_objfile_iterator (objfiles_list.begin ()), > - unwrapping_objfile_iterator (objfiles_list.end ()))); > + return objfiles_safe_reverse_range > + (objfiles_reverse_range > + (unwrapping_reverse_objfile_iterator::begin (objfiles_list), > + unwrapping_reverse_objfile_iterator::end (objfiles_list))); > } > > - /* Add OBJFILE to the list of objfiles, putting it just before > - BEFORE. If BEFORE is nullptr, it will go at the end of the > + /* Add OBJFILE to the list of objfiles, putting it just after > + AFTER. If AFTER is nullptr, it will go at the end of the > list. */ > void add_objfile (std::unique_ptr &&objfile, > - struct objfile *before); > + struct objfile *after); > > /* Remove OBJFILE from the list of objfiles. */ > void remove_objfile (struct objfile *objfile); > diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c > index 9db5c47a8ce..784b81b5ca6 100644 > --- a/gdb/symfile-debug.c > +++ b/gdb/symfile-debug.c > @@ -109,9 +109,9 @@ objfile::has_unexpanded_symtabs () > objfile_debug_name (this)); > > bool result = false; > - for (const auto &iter : qf_require_partial_symbols ()) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > { > - if (iter->has_unexpanded_symtabs (this)) > + if (qf->has_unexpanded_symtabs (this)) > { > result = true; > break; > @@ -134,9 +134,9 @@ 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_require_partial_symbols ()) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > { > - retval = iter->find_last_source_symtab (this); > + retval = qf->find_last_source_symtab (this); > if (retval != nullptr) > break; > } > @@ -167,8 +167,8 @@ objfile::forget_cached_source_info () > } > } > > - for (const auto &iter : qf_require_partial_symbols ()) > - iter->forget_cached_source_info (this); > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + qf->forget_cached_source_info (this); > } > > bool > @@ -214,17 +214,17 @@ objfile::map_symtabs_matching_filename > return result; > }; > > - for (const auto &iter : qf_require_partial_symbols ()) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > { > - if (!iter->expand_symtabs_matching (this, > - match_one_filename, > - nullptr, > - nullptr, > - on_expansion, > - (SEARCH_GLOBAL_BLOCK > - | SEARCH_STATIC_BLOCK), > - UNDEF_DOMAIN, > - ALL_DOMAIN)) > + if (!qf->expand_symtabs_matching (this, > + match_one_filename, > + nullptr, > + nullptr, > + on_expansion, > + (SEARCH_GLOBAL_BLOCK > + | SEARCH_STATIC_BLOCK), > + UNDEF_DOMAIN, > + ALL_DOMAIN)) > { > retval = false; > break; > @@ -283,18 +283,18 @@ objfile::lookup_symbol (block_enum kind, const char *name, domain_enum domain) > return true; > }; > > - for (const auto &iter : qf_require_partial_symbols ()) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > { > - if (!iter->expand_symtabs_matching (this, > - nullptr, > - &lookup_name, > - nullptr, > - search_one_symtab, > - kind == GLOBAL_BLOCK > - ? SEARCH_GLOBAL_BLOCK > - : SEARCH_STATIC_BLOCK, > - domain, > - ALL_DOMAIN)) > + if (!qf->expand_symtabs_matching (this, > + nullptr, > + &lookup_name, > + nullptr, > + search_one_symtab, > + kind == GLOBAL_BLOCK > + ? SEARCH_GLOBAL_BLOCK > + : SEARCH_STATIC_BLOCK, > + domain, > + ALL_DOMAIN)) > break; > } > > @@ -314,8 +314,8 @@ 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_require_partial_symbols ()) > - iter->print_stats (this, print_bcache); > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + qf->print_stats (this, print_bcache); > } > > void > @@ -340,16 +340,16 @@ objfile::expand_symtabs_for_function (const char *func_name) > lookup_name_info base_lookup (func_name, symbol_name_match_type::FULL); > lookup_name_info lookup_name = base_lookup.make_ignore_params (); > > - for (const auto &iter : qf_require_partial_symbols ()) > - iter->expand_symtabs_matching (this, > - nullptr, > - &lookup_name, > - nullptr, > - nullptr, > - (SEARCH_GLOBAL_BLOCK > - | SEARCH_STATIC_BLOCK), > - VAR_DOMAIN, > - ALL_DOMAIN); > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + qf->expand_symtabs_matching (this, > + nullptr, > + &lookup_name, > + nullptr, > + nullptr, > + (SEARCH_GLOBAL_BLOCK > + | SEARCH_STATIC_BLOCK), > + VAR_DOMAIN, > + ALL_DOMAIN); > } > > void > @@ -359,8 +359,8 @@ objfile::expand_all_symtabs () > gdb_printf (gdb_stdlog, "qf->expand_all_symtabs (%s)\n", > objfile_debug_name (this)); > > - for (const auto &iter : qf_require_partial_symbols ()) > - iter->expand_all_symtabs (this); > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + qf->expand_all_symtabs (this); > } > > void > @@ -377,16 +377,16 @@ objfile::expand_symtabs_with_fullname (const char *fullname) > return filename_cmp (basenames ? basename : fullname, filename) == 0; > }; > > - for (const auto &iter : qf_require_partial_symbols ()) > - iter->expand_symtabs_matching (this, > - file_matcher, > - nullptr, > - nullptr, > - nullptr, > - (SEARCH_GLOBAL_BLOCK > - | SEARCH_STATIC_BLOCK), > - UNDEF_DOMAIN, > - ALL_DOMAIN); > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + qf->expand_symtabs_matching (this, > + file_matcher, > + nullptr, > + nullptr, > + nullptr, > + (SEARCH_GLOBAL_BLOCK > + | SEARCH_STATIC_BLOCK), > + UNDEF_DOMAIN, > + ALL_DOMAIN); > } > > void > @@ -402,9 +402,9 @@ objfile::expand_matching_symbols > domain_name (domain), global, > host_address_to_string (ordered_compare)); > > - for (const auto &iter : qf_require_partial_symbols ()) > - iter->expand_matching_symbols (this, name, domain, global, > - ordered_compare); > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + qf->expand_matching_symbols (this, name, domain, global, > + ordered_compare); > } > > bool > @@ -429,10 +429,10 @@ objfile::expand_symtabs_matching > host_address_to_string (&expansion_notify), > search_domain_name (kind)); > > - for (const auto &iter : qf_require_partial_symbols ()) > - if (!iter->expand_symtabs_matching (this, file_matcher, lookup_name, > - symbol_matcher, expansion_notify, > - search_flags, domain, kind)) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + if (!qf->expand_symtabs_matching (this, file_matcher, lookup_name, > + symbol_matcher, expansion_notify, > + search_flags, domain, kind)) > return false; > return true; > } > @@ -454,10 +454,10 @@ objfile::find_pc_sect_compunit_symtab (struct bound_minimal_symbol msymbol, > host_address_to_string (section), > warn_if_readin); > > - for (const auto &iter : qf_require_partial_symbols ()) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > { > - retval = iter->find_pc_sect_compunit_symtab (this, msymbol, pc, section, > - warn_if_readin); > + retval = qf->find_pc_sect_compunit_symtab (this, msymbol, pc, section, > + warn_if_readin); > if (retval != nullptr) > break; > } > @@ -482,8 +482,8 @@ objfile::map_symbol_filenames (gdb::function_view fun, > objfile_debug_name (this), > need_fullname); > > - for (const auto &iter : qf_require_partial_symbols ()) > - iter->map_symbol_filenames (this, fun, need_fullname); > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > + qf->map_symbol_filenames (this, fun, need_fullname); > } > > struct compunit_symtab * > @@ -496,9 +496,9 @@ objfile::find_compunit_symtab_by_address (CORE_ADDR address) > hex_string (address)); > > struct compunit_symtab *result = NULL; > - for (const auto &iter : qf_require_partial_symbols ()) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > { > - result = iter->find_compunit_symtab_by_address (this, address); > + result = qf->find_compunit_symtab_by_address (this, address); > if (result != nullptr) > break; > } > @@ -521,10 +521,10 @@ objfile::lookup_global_symbol_language (const char *name, > enum language result = language_unknown; > *symbol_found_p = false; > > - for (const auto &iter : qf_require_partial_symbols ()) > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > { > - result = iter->lookup_global_symbol_language (this, name, domain, > - symbol_found_p); > + result = qf->lookup_global_symbol_language (this, name, domain, > + symbol_found_p); > if (*symbol_found_p) > break; > } > diff --git a/gdb/testsuite/gdb.python/py-objfile.exp b/gdb/testsuite/gdb.python/py-objfile.exp > index 61b9942de79..0bf49976b73 100644 > --- a/gdb/testsuite/gdb.python/py-objfile.exp > +++ b/gdb/testsuite/gdb.python/py-objfile.exp > @@ -135,7 +135,7 @@ gdb_test "p main" "= {} $hex
" \ > gdb_py_test_silent_cmd "python objfile.add_separate_debug_file(\"${binfile}\")" \ > "Add separate debug file file" 1 > > -gdb_py_test_silent_cmd "python sep_objfile = gdb.objfiles()\[0\]" \ > +gdb_py_test_silent_cmd "python sep_objfile = gdb.objfiles()\[1\]" \ > "Get separate debug info objfile" 1 > > gdb_test "python print (sep_objfile.owner.filename)" "${testfile}2" \ > -- > 2.40.1