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.129.124]) by sourceware.org (Postfix) with ESMTPS id AD4CC3858414 for ; Tue, 23 May 2023 20:56:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AD4CC3858414 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=1684875377; 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: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tRb42e4lJ/V+7anP4Uo8s1faEG+qwKpsy/LGEZ+QN/4=; b=FxNNge8DF9WTqdXQF0DTLCB8wHm8BXyXOKG84TNRsiyuzZ3yzG7ZOonwIV1rdEnkI3vPI7 Cipd+GF4EIA0RJ+sSV3rK9LVeAdWObc/NU3LMQst0wHKd30N1FSJ1S+vSGZ/MPw+gnWOcN QhrAtI4VCvhCXwfqrp386SXURjmIImg= Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-9-zOkZ1sNvN7Cn3BYff4m-og-1; Tue, 23 May 2023 16:56:16 -0400 X-MC-Unique: zOkZ1sNvN7Cn3BYff4m-og-1 Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-5308f5d8ac9so43019a12.0 for ; Tue, 23 May 2023 13:56:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684875375; x=1687467375; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tRb42e4lJ/V+7anP4Uo8s1faEG+qwKpsy/LGEZ+QN/4=; b=hJzmI+ldstwEQriN+BhOJJqGRVw/uEjH4qcIPbDFSCXbifTVu5xwLHbM4WhUv5ptmM NE9+KpV+cxrePROZNk4PcmyHfQSORi6G8c/E5pUN6r80BfSNxj1fDuV21IOtkc7UNzLJ xtvphAhwOXxzkmJiTAw8FNRhDgI703RUe3Mw9O+kqqKr+ZltFH8OyrgW7iGqWDFFAhB5 5YuMMyzgoBHdhM33bmgG3N3IYwMg2YR9s9LAT/42dQammaLpOl3d1OF5EPDQP16yHcnD smB2c6chNiQdcCu6ggnFH7lQAHGZ3yqznDMAbp85dUBkl/CqD2Ls5J4nx5ZbGVpNj8fV rgDg== X-Gm-Message-State: AC+VfDxhtz3Tb84UZzI6e+/y8KVMxg4pey3D/mLNDVEINjpREqMId0+s Q8SFfqQyQ6fFoAgHqXXlyOMOyxg9dSZ2nNGEoigKBllwNaxoe0ZiQm9J1ofIVlVTRxlWXkzVokM piLfhrUmP8ZmrlL9ZGbMDfdwxU0iWqIE1Rh70f9hdckYF X-Received: by 2002:a17:902:db0a:b0:1a6:b496:4053 with SMTP id m10-20020a170902db0a00b001a6b4964053mr17012024plx.59.1684875374272; Tue, 23 May 2023 13:56:14 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6dpDbH2R3hWlAB5UAv5l7XT6M32ipMHHuLU/s9cgqkpalxDsNl9MI5gW3DHpvh6ws5Jfmcq5GqhwR5ZWTi3UM= X-Received: by 2002:a17:902:db0a:b0:1a6:b496:4053 with SMTP id m10-20020a170902db0a00b001a6b4964053mr17011995plx.59.1684875373360; Tue, 23 May 2023 13:56:13 -0700 (PDT) MIME-Version: 1.0 References: <20230424163941.413711-1-amerey@redhat.com> <20230503042556.1613600-1-amerey@redhat.com> In-Reply-To: From: Aaron Merey Date: Tue, 23 May 2023 16:56:02 -0400 Message-ID: Subject: Re: [PING*3][PATCH 5/7 v2.2] gdb/debuginfod: Support on-demand debuginfo downloading To: gdb-patches@sourceware.org Cc: Andrew Burgess , Tom Tromey X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-11.4 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_H2,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: Ping Thanks, Aaron On Tue, May 16, 2023 at 10:50=E2=80=AFAM Aaron Merey wr= ote: > > Ping > > Thanks, > Aaron > > On Tue, May 9, 2023 at 9:49=E2=80=AFAM Aaron Merey wr= ote: > > > > Ping > > > > Thanks, > > Aaron > > > > On Wed, May 3, 2023 at 12:26=E2=80=AFAM Aaron Merey = wrote: > > > > > > For v2.1 see > > > https://sourceware.org/pipermail/gdb-patches/2023-April/199076.html > > > > > > Andrew pointed out [1] that if GDB is built with '-D_GLIBCXX_DEBUG=3D= 1' > > > and '-D_GLIBCXX_DEBUG_PEDANTIC=3D1', changes in this patch cause C++ > > > debug to trigger an abort due to a begin iterator being decremented. > > > This was due to the design of the reverse objfile list iterator I > > > introduced in v2.1. > > > > > > I'm resending this patch with the issue fixed. The reverse objfile > > > list iterator has been modified so that no begin iterator can be > > > decremented. > > > > > > Aaron > > > > > > [1] https://sourceware.org/pipermail/gdb-patches/2023-May/199287.html > > > > > > --- > > > gdb/dwarf2/frame.c | 13 ++ > > > gdb/dwarf2/frame.h | 4 + > > > gdb/dwarf2/index-cache.c | 33 +++++ > > > gdb/dwarf2/index-cache.h | 13 ++ > > > gdb/dwarf2/public.h | 7 ++ > > > gdb/dwarf2/read-gdb-index.c | 156 ++++++++++++++++++++--= - > > > gdb/dwarf2/read.c | 150 +++++++++++++++++++++- > > > gdb/dwarf2/read.h | 10 ++ > > > gdb/dwarf2/section.c | 3 +- > > > gdb/elfread.c | 2 +- > > > gdb/objfile-flags.h | 4 + > > > gdb/objfiles.c | 1 + > > > gdb/objfiles.h | 22 +++- > > > gdb/progspace.c | 8 +- > > > gdb/progspace.h | 159 +++++++++++++++++++---= -- > > > gdb/symfile-debug.c | 136 ++++++++++---------- > > > gdb/symfile.c | 7 +- > > > gdb/testsuite/gdb.python/py-objfile.exp | 2 +- > > > 19 files changed, 599 insertions(+), 132 deletions(-) > > > > > > diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c > > > index a561aaf3100..3613f8252a7 100644 > > > --- a/gdb/dwarf2/frame.c > > > +++ b/gdb/dwarf2/frame.c > > > @@ -1609,6 +1609,19 @@ set_comp_unit (struct objfile *objfile, struct= comp_unit *unit) > > > return dwarf2_frame_bfd_data.set (abfd, unit); > > > } > > > > > > +/* See frame.h. */ > > > + > > > +void > > > +dwarf2_clear_frame_data (struct objfile *objfile) > > > +{ > > > + bfd *abfd =3D objfile->obfd.get (); > > > + > > > + if (gdb_bfd_requires_relocations (abfd)) > > > + dwarf2_frame_objfile_data.clear (objfile); > > > + else > > > + dwarf2_frame_bfd_data.clear (abfd); > > > +} > > > + > > > /* Find the FDE for *PC. Return a pointer to the FDE, and store the > > > initial location associated with it into *PC. */ > > > > > > diff --git a/gdb/dwarf2/frame.h b/gdb/dwarf2/frame.h > > > index 5643e557513..2391e313e7c 100644 > > > --- a/gdb/dwarf2/frame.h > > > +++ b/gdb/dwarf2/frame.h > > > @@ -238,6 +238,10 @@ void dwarf2_append_unwinders (struct gdbarch *gd= barch); > > > extern const struct frame_base * > > > dwarf2_frame_base_sniffer (frame_info_ptr this_frame); > > > > > > +/* Delete OBJFILEs comp_unit. */ > > > + > > > +extern void dwarf2_clear_frame_data (struct objfile * objfile); > > > + > > > /* Compute the DWARF CFA for a frame. */ > > > > > > CORE_ADDR dwarf2_frame_cfa (frame_info_ptr this_frame); > > > diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c > > > index 79ab706ee9d..bbafcd321b2 100644 > > > --- a/gdb/dwarf2/index-cache.c > > > +++ b/gdb/dwarf2/index-cache.c > > > @@ -216,6 +216,33 @@ index_cache::lookup_gdb_index (const bfd_build_i= d *build_id, > > > return {}; > > > } > > > > > > +/* See index-cache.h. */ > > > + > > > +gdb::array_view > > > +index_cache::lookup_gdb_index_debuginfod (const char *index_path, > > > + std::unique_ptr *resource) > > > +{ > > > + try > > > + { > > > + /* Try to map that file. */ > > > + index_cache_resource_mmap *mmap_resource > > > + =3D new index_cache_resource_mmap (index_path); > > > + > > > + /* Hand the resource to the caller. */ > > > + resource->reset (mmap_resource); > > > + > > > + return gdb::array_view > > > + ((const gdb_byte *) mmap_resource->mapping.get (), > > > + mmap_resource->mapping.size ()); > > > + } > > > + catch (const gdb_exception_error &except) > > > + { > > > + warning (_("Unable to read %s: %s"), index_path, except.what (= )); > > > + } > > > + > > > + return {}; > > > +} > > > + > > > #else /* !HAVE_SYS_MMAN_H */ > > > > > > /* See dwarf-index-cache.h. This is a no-op on unsupported systems.= */ > > > @@ -227,6 +254,12 @@ index_cache::lookup_gdb_index (const bfd_build_i= d *build_id, > > > return {}; > > > } > > > > > > +gdb::array_view > > > +index_cache::lookup_gdb_index_debuginfod (const char *index_path, > > > + std::unique_ptr *resource) > > > +{ > > > + return {}; > > > +} > > > #endif > > > > > > /* See dwarf-index-cache.h. */ > > > diff --git a/gdb/dwarf2/index-cache.h b/gdb/dwarf2/index-cache.h > > > index 1efff17049f..e400afd5123 100644 > > > --- a/gdb/dwarf2/index-cache.h > > > +++ b/gdb/dwarf2/index-cache.h > > > @@ -67,6 +67,19 @@ class index_cache > > > lookup_gdb_index (const bfd_build_id *build_id, > > > std::unique_ptr *resource); > > > > > > + /* Look for an index file located at INDEX_PATH in the debuginfod = cache. > > > + Unlike lookup_gdb_index, this function does not exit early if t= he > > > + index cache has not been enabled. > > > + > > > + If found, return the contents as an array_view and store the un= derlying > > > + resources (allocated memory, mapped file, etc) in RESOURCE. Th= e returned > > > + array_view is valid as long as RESOURCE is not destroyed. > > > + > > > + If no matching index file is found, return an empty array view.= */ > > > + gdb::array_view > > > + lookup_gdb_index_debuginfod (const char *index_path, > > > + std::unique_ptr = *resource); > > > + > > > /* Return the number of cache hits. */ > > > unsigned int n_hits () const > > > { return m_n_hits; } > > > diff --git a/gdb/dwarf2/public.h b/gdb/dwarf2/public.h > > > index 0e74857eb1a..4a44cdbc223 100644 > > > --- a/gdb/dwarf2/public.h > > > +++ b/gdb/dwarf2/public.h > > > @@ -40,4 +40,11 @@ extern void dwarf2_initialize_objfile (struct objf= ile *objfile); > > > > > > extern void dwarf2_build_frame_info (struct objfile *); > > > > > > +/* Query debuginfod for the .gdb_index associated with OBJFILE. If > > > + successful, create an objfile to hold the .gdb_index information > > > + and act as a placeholder until the full debuginfo needs to be > > > + downloaded. */ > > > + > > > +extern bool dwarf2_has_separate_index (struct objfile *); > > > + > > > #endif /* DWARF2_PUBLIC_H */ > > > diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.= c > > > index 1006386cb2d..d3516e92361 100644 > > > --- a/gdb/dwarf2/read-gdb-index.c > > > +++ b/gdb/dwarf2/read-gdb-index.c > > > @@ -136,6 +136,7 @@ struct dwarf2_gdb_index : public dwarf2_base_inde= x_functions > > > gdb.dwarf2/gdb-index.exp testcase. */ > > > void dump (struct objfile *objfile) override; > > > > > > + /* Calls do_expand_matching_symbols and downloads debuginfo if nec= essary. */ > > > void expand_matching_symbols > > > (struct objfile *, > > > const lookup_name_info &lookup_name, > > > @@ -143,6 +144,14 @@ struct dwarf2_gdb_index : public dwarf2_base_ind= ex_functions > > > int global, > > > symbol_compare_ftype *ordered_compare) override; > > > > > > + void do_expand_matching_symbols > > > + (struct objfile *, > > > + const lookup_name_info &lookup_name, > > > + domain_enum domain, > > > + int global, > > > + symbol_compare_ftype *ordered_compare); > > > + > > > + /* Calls do_expand_symtabs_matching and downloads debuginfo if nec= essary. */ > > > bool expand_symtabs_matching > > > (struct objfile *objfile, > > > gdb::function_view file_matc= her, > > > @@ -152,8 +161,59 @@ struct dwarf2_gdb_index : public dwarf2_base_ind= ex_functions > > > block_search_flags search_flags, > > > domain_enum domain, > > > enum search_domain kind) override; > > > + > > > + bool do_expand_symtabs_matching > > > + (struct objfile *objfile, > > > + gdb::function_view file_matc= her, > > > + const lookup_name_info *lookup_name, > > > + gdb::function_view symbol_= matcher, > > > + gdb::function_view expansion_n= otify, > > > + block_search_flags search_flags, > > > + domain_enum domain, > > > + enum search_domain kind); > > > + > > > + /* Calls dwarf2_base_index_functions::expand_all_symtabs and downl= oads > > > + debuginfo if necessary. */ > > > + void expand_all_symtabs (struct objfile *objfile) override; > > > + > > > + /* Calls dwarf2_base_index_functions::find_last_source_symtab and = downloads > > > + debuginfo if necessary. */ > > > + struct symtab *find_last_source_symtab (struct objfile *objfile) o= verride; > > > }; > > > > > > +void > > > +dwarf2_gdb_index::expand_all_symtabs (struct objfile *objfile) > > > +{ > > > + try > > > + { > > > + dwarf2_base_index_functions::expand_all_symtabs (objfile); > > > + } > > > + catch (gdb_exception e) > > > + { > > > + if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) =3D=3D 0) > > > + exception_print (gdb_stderr, e); > > > + else > > > + read_full_dwarf_from_debuginfod (objfile, this); > > > + } > > > +} > > > + > > > +struct symtab * > > > +dwarf2_gdb_index::find_last_source_symtab (struct objfile *objfile) > > > +{ > > > + try > > > + { > > > + return dwarf2_base_index_functions::find_last_source_symtab (o= bjfile); > > > + } > > > + catch (gdb_exception e) > > > + { > > > + if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) =3D=3D 0) > > > + exception_print (gdb_stderr, e); > > > + else > > > + read_full_dwarf_from_debuginfod (objfile, this); > > > + return nullptr; > > > + } > > > +} > > > + > > > /* This dumps minimal information about the index. > > > It is called via "mt print objfiles". > > > One use is to verify .gdb_index has been loaded by the > > > @@ -315,7 +375,7 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator = *iter, > > > } > > > > > > void > > > -dwarf2_gdb_index::expand_matching_symbols > > > +dwarf2_gdb_index::do_expand_matching_symbols > > > (struct objfile *objfile, > > > const lookup_name_info &name, domain_enum domain, > > > int global, > > > @@ -353,6 +413,29 @@ dwarf2_gdb_index::expand_matching_symbols > > > }, per_objfile); > > > } > > > > > > +void > > > +dwarf2_gdb_index::expand_matching_symbols > > > + (struct objfile *objfile, > > > + const lookup_name_info &lookup_name, > > > + domain_enum domain, > > > + int global, > > > + symbol_compare_ftype *ordered_compare) > > > +{ > > > + try > > > + { > > > + do_expand_matching_symbols (objfile, lookup_name, domain, > > > + global, ordered_compare); > > > + } > > > + catch (gdb_exception e) > > > + { > > > + if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) =3D=3D 0) > > > + exception_print (gdb_stderr, e); > > > + else > > > + read_full_dwarf_from_debuginfod (objfile, this); > > > + return; > > > + } > > > +} > > > + > > > /* Helper for dw2_expand_matching symtabs. Called on each symbol > > > matched, to expand corresponding CUs that were marked. IDX is th= e > > > index of the symbol name that matched. */ > > > @@ -455,7 +538,7 @@ dw2_expand_marked_cus > > > } > > > > > > bool > > > -dwarf2_gdb_index::expand_symtabs_matching > > > +dwarf2_gdb_index::do_expand_symtabs_matching > > > (struct objfile *objfile, > > > gdb::function_view file_matc= her, > > > const lookup_name_info *lookup_name, > > > @@ -504,6 +587,39 @@ dwarf2_gdb_index::expand_symtabs_matching > > > return result; > > > } > > > > > > +bool > > > +dwarf2_gdb_index::expand_symtabs_matching > > > + (struct objfile *objfile, > > > + gdb::function_view file_matc= her, > > > + const lookup_name_info *lookup_name, > > > + gdb::function_view symbol_= matcher, > > > + gdb::function_view expansion_n= otify, > > > + block_search_flags search_flags, > > > + domain_enum domain, > > > + enum search_domain kind) > > > +{ > > > + if (objfile->flags & OBJF_READNEVER) > > > + return false; > > > + > > > + try > > > + { > > > + return do_expand_symtabs_matching (objfile, file_matcher, look= up_name, > > > + symbol_matcher, expansion_no= tify, > > > + search_flags, domain, kind); > > > + } > > > + catch (gdb_exception e) > > > + { > > > + if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) =3D=3D 0) > > > + { > > > + exception_print (gdb_stderr, e); > > > + return false; > > > + } > > > + > > > + read_full_dwarf_from_debuginfod (objfile, this); > > > + return true; > > > + } > > > +} > > > + > > > quick_symbol_functions_up > > > mapped_gdb_index::make_quick_functions () const > > > { > > > @@ -797,28 +913,32 @@ dwarf2_read_gdb_index > > > > > > /* If there is a .dwz file, read it so we can get its CU list as > > > well. */ > > > - dwz =3D dwarf2_get_dwz_file (per_bfd); > > > - if (dwz !=3D NULL) > > > + if (get_gdb_index_contents_dwz !=3D nullptr) > > > { > > > mapped_gdb_index dwz_map; > > > const gdb_byte *dwz_types_ignore; > > > offset_type dwz_types_elements_ignore; > > > + dwz =3D dwarf2_get_dwz_file (per_bfd); > > > > > > - gdb::array_view dwz_index_content > > > - =3D get_gdb_index_contents_dwz (objfile, dwz); > > > - > > > - if (dwz_index_content.empty ()) > > > - return 0; > > > - > > > - if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bf= d.get ()), > > > - 1, dwz_index_content, &dwz_map= , > > > - &dwz_list, &dwz_list_elements, > > > - &dwz_types_ignore, > > > - &dwz_types_elements_ignore)) > > > + if (dwz !=3D nullptr) > > > { > > > - warning (_("could not read '.gdb_index' section from %s; sk= ipping"), > > > - bfd_get_filename (dwz->dwz_bfd.get ())); > > > - return 0; > > > + gdb::array_view dwz_index_content > > > + =3D get_gdb_index_contents_dwz (objfile, dwz); > > > + > > > + if (dwz_index_content.empty ()) > > > + return 0; > > > + > > > + if (!read_gdb_index_from_buffer (bfd_get_filename > > > + (dwz->dwz_bfd.get ()), > > > + 1, dwz_index_content, &dwz= _map, > > > + &dwz_list, &dwz_list_eleme= nts, > > > + &dwz_types_ignore, > > > + &dwz_types_elements_ignore= )) > > > + { > > > + warning (_("could not read '.gdb_index' section from %s= ; skipping"), > > > + bfd_get_filename (dwz->dwz_bfd.get ())); > > > + return 0; > > > + } > > > } > > > } > > > > > > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c > > > index 29a95cb8b2f..185a999ccee 100644 > > > --- a/gdb/dwarf2/read.c > > > +++ b/gdb/dwarf2/read.c > > > @@ -34,6 +34,7 @@ > > > #include "dwarf2/attribute.h" > > > #include "dwarf2/comp-unit-head.h" > > > #include "dwarf2/cu.h" > > > +#include "dwarf2/frame.h" > > > #include "dwarf2/index-cache.h" > > > #include "dwarf2/index-common.h" > > > #include "dwarf2/leb.h" > > > @@ -95,6 +96,8 @@ > > > #include "split-name.h" > > > #include "gdbsupport/parallel-for.h" > > > #include "gdbsupport/thread-pool.h" > > > +#include "inferior.h" > > > +#include "debuginfod-support.h" > > > > > > /* When =3D=3D 1, print basic high level tracing messages. > > > When > 1, be more verbose. > > > @@ -3163,7 +3166,7 @@ dwarf2_base_index_functions::find_per_cu (dwarf= 2_per_bfd *per_bfd, > > > } > > > > > > struct compunit_symtab * > > > -dwarf2_base_index_functions::find_pc_sect_compunit_symtab > > > +dwarf2_base_index_functions::do_find_pc_sect_compunit_symtab > > > (struct objfile *objfile, > > > struct bound_minimal_symbol msymbol, > > > CORE_ADDR pc, > > > @@ -3194,6 +3197,32 @@ dwarf2_base_index_functions::find_pc_sect_comp= unit_symtab > > > return result; > > > } > > > > > > +struct compunit_symtab * > > > +dwarf2_base_index_functions::find_pc_sect_compunit_symtab > > > + (struct objfile *objfile, > > > + struct bound_minimal_symbol msymbol, > > > + CORE_ADDR pc, > > > + struct obj_section *section, > > > + int warn_if_readin) > > > +{ > > > + if (objfile->flags & OBJF_READNEVER) > > > + return nullptr; > > > + > > > + try > > > + { > > > + return do_find_pc_sect_compunit_symtab (objfile, msymbol, pc, > > > + section, warn_if_readin= ); > > > + } > > > + catch (gdb_exception e) > > > + { > > > + if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) =3D=3D 0) > > > + exception_print (gdb_stderr, e); > > > + else > > > + read_full_dwarf_from_debuginfod (objfile, this); > > > + return nullptr; > > > + } > > > +} > > > + > > > void > > > dwarf2_base_index_functions::map_symbol_filenames > > > (struct objfile *objfile, > > > @@ -3350,6 +3379,29 @@ get_gdb_index_contents_from_cache_dwz (objfile= *obj, dwz_file *dwz) > > > return global_index_cache.lookup_gdb_index (build_id, &dwz->index_= cache_res); > > > } > > > > > > +/* Query debuginfod for the .gdb_index matching OBJFILE's build-id. = Return the > > > + contents if successful. */ > > > + > > > +static gdb::array_view > > > +get_gdb_index_contents_from_debuginfod (objfile *objfile, dwarf2_per= _bfd *per_bfd) > > > +{ > > > + const bfd_build_id *build_id =3D build_id_bfd_get (objfile->obfd.g= et ()); > > > + if (build_id =3D=3D nullptr) > > > + return {}; > > > + > > > + gdb::unique_xmalloc_ptr index_path; > > > + scoped_fd fd =3D debuginfod_section_query (build_id->data, build_i= d->size, > > > + bfd_get_filename > > > + (objfile->obfd.get ()), > > > + ".gdb_index", > > > + &index_path); > > > + if (fd.get () < 0) > > > + return {}; > > > + > > > + return global_index_cache.lookup_gdb_index_debuginfod > > > + (index_path.get (), &per_bfd->index_cache_res); > > > +} > > > + > > > static quick_symbol_functions_up make_cooked_index_funcs (); > > > > > > /* See dwarf2/public.h. */ > > > @@ -3415,10 +3467,106 @@ dwarf2_initialize_objfile (struct objfile *o= bjfile) > > > return; > > > } > > > > > > + if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) > > > + && dwarf2_read_gdb_index (per_objfile, > > > + get_gdb_index_contents_from_debuginfo= d, > > > + nullptr)) > > > + { > > > + dwarf_read_debug_printf ("found .gdb_index from debuginfod"); > > > + objfile->qf.push_front (per_bfd->index_table->make_quick_funct= ions ()); > > > + return; > > > + } > > > + > > > global_index_cache.miss (); > > > objfile->qf.push_front (make_cooked_index_funcs ()); > > > } > > > > > > +/* See read.h. */ > > > + > > > +void > > > +read_full_dwarf_from_debuginfod (struct objfile *objfile, > > > + dwarf2_base_index_functions *fncs) > > > +{ > > > + gdb_assert (objfile->flags & OBJF_DOWNLOAD_DEFERRED); > > > + > > > + const struct bfd_build_id *build_id =3D build_id_bfd_get (objfile-= >obfd.get ()); > > > + const char *filename; > > > + gdb_bfd_ref_ptr debug_bfd; > > > + gdb::unique_xmalloc_ptr symfile_path; > > > + scoped_fd fd; > > > + > > > + if (build_id =3D=3D nullptr) > > > + goto unset; > > > + > > > + filename =3D bfd_get_filename (objfile->obfd.get ()); > > > + fd =3D debuginfod_debuginfo_query (build_id->data, build_id->size, > > > + filename, &symfile_path); > > > + if (fd.get () < 0) > > > + goto unset; > > > + > > > + /* Separate debuginfo successfully retrieved from server. */ > > > + debug_bfd =3D symfile_bfd_open (symfile_path.get ()); > > > + if (debug_bfd =3D=3D nullptr > > > + || !build_id_verify (debug_bfd.get (), build_id->size, build_i= d->data)) > > > + { > > > + warning (_("File \"%s\" from debuginfod cannot be opened as bf= d"), > > > + filename); > > > + goto unset; > > > + } > > > + > > > + /* This may also trigger a dwz download. */ > > > + symbol_file_add_separate (debug_bfd, symfile_path.get (), > > > + current_inferior ()->symfile_flags, objfi= le); > > > + > > > + /* Clear frame data so it can be recalculated using DWARF. */ > > > + dwarf2_clear_frame_data (objfile); > > > + > > > +unset: > > > + objfile->flags &=3D ~OBJF_DOWNLOAD_DEFERRED; > > > + > > > + /* Avoid reading this objfile's index from now on. If available t= he > > > + separate debug objfile's index will be used instead, since it a= ctually > > > + contains the symbols and CUs referenced in the index. */ > > > + objfile->remove_partial_symbol (fncs); > > > +} > > > + > > > +/* See public.h. */ > > > + > > > +bool > > > +dwarf2_has_separate_index (struct objfile *objfile) > > > +{ > > > + if (objfile->flags & OBJF_DOWNLOAD_DEFERRED) > > > + return true; > > > + if (objfile->flags & OBJF_MAINLINE) > > > + return false; > > > + if (!IS_DIR_SEPARATOR (*objfile_filename (objfile))) > > > + return false; > > > + > > > + gdb::unique_xmalloc_ptr index_path; > > > + const bfd_build_id *build_id =3D build_id_bfd_get (objfile->obfd.g= et ()); > > > + > > > + if (build_id =3D=3D nullptr) > > > + return false; > > > + > > > + scoped_fd fd =3D debuginfod_section_query (build_id->data, > > > + build_id->size, > > > + bfd_get_filename > > > + (objfile->obfd.get ()), > > > + ".gdb_index", > > > + &index_path); > > > + > > > + if (fd.get () < 0) > > > + return false; > > > + > > > + /* We found a separate .gdb_index file so a separate debuginfo fil= e > > > + should exist, but we don't want to download it until necessary. > > > + Attach the index to this objfile and defer the debuginfo downlo= ad > > > + until gdb needs to expand symtabs referenced by the index. */ > > > + objfile->flags |=3D OBJF_DOWNLOAD_DEFERRED; > > > + dwarf2_initialize_objfile (objfile); > > > + return true; > > > +} > > > + > > > > > > > > > /* Build a partial symbol table. */ > > > diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h > > > index 37023a20709..e3131693b81 100644 > > > --- a/gdb/dwarf2/read.h > > > +++ b/gdb/dwarf2/read.h > > > @@ -866,6 +866,10 @@ struct dwarf2_base_index_functions : public quic= k_symbol_functions > > > CORE_ADDR pc, struct obj_section *section, int warn_if_readin) > > > override final; > > > > > > + struct compunit_symtab *do_find_pc_sect_compunit_symtab > > > + (struct objfile *objfile, struct bound_minimal_symbol msymbol, > > > + CORE_ADDR pc, struct obj_section *section, int warn_if_readin); > > > + > > > struct compunit_symtab *find_compunit_symtab_by_address > > > (struct objfile *objfile, CORE_ADDR address) override > > > { > > > @@ -942,4 +946,10 @@ extern bool read_addrmap_from_aranges (dwarf2_pe= r_objfile *per_objfile, > > > dwarf2_section_info *section, > > > addrmap *mutable_map); > > > > > > +/* If OBJFILE contains information from a separately downloaded .gdb= _index, > > > + attempt to download the full debuginfo. */ > > > + > > > +extern void read_full_dwarf_from_debuginfod (struct objfile *, > > > + dwarf2_base_index_functi= ons *); > > > + > > > #endif /* DWARF2READ_H */ > > > diff --git a/gdb/dwarf2/section.c b/gdb/dwarf2/section.c > > > index c9ef41893ee..8cb09e3381a 100644 > > > --- a/gdb/dwarf2/section.c > > > +++ b/gdb/dwarf2/section.c > > > @@ -54,7 +54,8 @@ dwarf2_section_info::get_bfd_owner () const > > > section =3D get_containing_section (); > > > gdb_assert (!section->is_virtual); > > > } > > > - gdb_assert (section->s.section !=3D nullptr); > > > + if (section->s.section =3D=3D nullptr) > > > + error (_("Can't find owner of DWARF section.")); > > > return section->s.section->owner; > > > } > > > > > > diff --git a/gdb/elfread.c b/gdb/elfread.c > > > index 0305bf21894..01eccfaac36 100644 > > > --- a/gdb/elfread.c > > > +++ b/gdb/elfread.c > > > @@ -1239,7 +1239,7 @@ elf_symfile_read_dwarf2 (struct objfile *objfil= e, > > > symbol_file_add_separate (debug_bfd, debugfile.c_str (), > > > symfile_flags, objfile); > > > } > > > - else > > > + else if (!dwarf2_has_separate_index (objfile)) > > > { > > > has_dwarf2 =3D false; > > > const struct bfd_build_id *build_id > > > diff --git a/gdb/objfile-flags.h b/gdb/objfile-flags.h > > > index 9dee2ee51a0..fb3f741c899 100644 > > > --- a/gdb/objfile-flags.h > > > +++ b/gdb/objfile-flags.h > > > @@ -60,6 +60,10 @@ enum objfile_flag : unsigned > > > /* User requested that we do not read this objfile's symbolic > > > information. */ > > > OBJF_READNEVER =3D 1 << 6, > > > + > > > + /* A separate .gdb_index has been downloaded for this objfile. > > > + Debuginfo for this objfile can be downloaded when required. = */ > > > + OBJF_DOWNLOAD_DEFERRED =3D 1 << 7, > > > }; > > > > > > DEF_ENUM_FLAGS_TYPE (enum objfile_flag, objfile_flags); > > > diff --git a/gdb/objfiles.c b/gdb/objfiles.c > > > index 9caebfefd59..7f32037caa5 100644 > > > --- a/gdb/objfiles.c > > > +++ b/gdb/objfiles.c > > > @@ -52,6 +52,7 @@ > > > #include "gdb_bfd.h" > > > #include "btrace.h" > > > #include "gdbsupport/pathstuff.h" > > > +#include "symfile.h" > > > > > > #include > > > #include > > > diff --git a/gdb/objfiles.h b/gdb/objfiles.h > > > index 342aa09ac6a..d00c2b21933 100644 > > > --- a/gdb/objfiles.h > > > +++ b/gdb/objfiles.h > > > @@ -587,6 +587,17 @@ struct objfile > > > /* See quick_symbol_functions. */ > > > void require_partial_symbols (bool verbose); > > > > > > + /* Remove TARGET from this objfile's collection of quick_symbol_fu= nctions. */ > > > + void remove_partial_symbol (quick_symbol_functions *target) > > > + { > > > + for (quick_symbol_functions_up &qf_up : qf) > > > + if (qf_up.get () =3D=3D target) > > > + { > > > + qf.remove (qf_up); > > > + return; > > > + } > > > + } > > > + > > > /* Return the relocation offset applied to SECTION. */ > > > CORE_ADDR section_offset (bfd_section *section) const > > > { > > > @@ -611,13 +622,20 @@ struct objfile > > > > > > private: > > > > > > + using qf_list =3D std::forward_list; > > > + using unwrapping_qf_range =3D iterator_range>; > > > + using qf_safe_range =3D basic_safe_range; > > > + > > > /* Ensure that partial symbols have been read and return the "quic= k" (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 =3D=3D nullptr) > > > + if (after =3D=3D nullptr) > > > objfiles_list.push_back (std::move (objfile)); > > > else > > > { > > > auto iter =3D std::find_if (objfiles_list.begin (), objfiles_l= ist.end (), > > > [=3D] (const std::unique_ptr<::objfil= e> &objf) > > > { > > > - return objf.get () =3D=3D before; > > > + return objf.get () =3D=3D after; > > > }); > > > gdb_assert (iter !=3D 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..933474ca8af 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 dere= ferences > > > + the returned object. This is useful for iterating over a list of= shared > > > + pointers and returning raw pointers -- which helped avoid touchin= g a lot > > > + of code when changing how objfiles are managed. */ > > > + > > > +template > > > +class unwrapping_iterator > > > +{ > > > +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_categor= y; > > > + 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!=3D (const unwrapping_iterator &other) const > > > + { > > > + return m_iter !=3D 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 iterati= ng > > > - over a list of shared pointers and returning raw pointers -- whic= h > > > - helped avoid touching a lot of code when changing how objfiles ar= e > > > - managed. */ > > > +/* An reverse iterator that wraps an iterator over objfile_list, and > > > + dereferences the returned object. This is useful for reverse ite= rating > > > + over a list of shared pointers and returning raw pointers -- whic= h helped > > > + avoid touching a lot of code when changing how objfiles are manag= ed. */ > > > > > > -class unwrapping_objfile_iterator > > > +class unwrapping_reverse_objfile_iterator > > > { > > > 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 iterato= r_category; > > > typedef typename objfile_list::iterator::difference_type differenc= e_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 !=3D m_begin) > > > + --m_iter; > > > + else > > > + { > > > + /* We can't decrement M_ITER since it is the begin iterator o= f the > > > + objfile list. Set M_ITER to the list's end iterator to in= dicate > > > + this is now one-past-the-end. */ > > > + m_iter =3D m_end; > > > + > > > + /* Overwrite M_BEGIN to avoid possibly copying an invalid ite= rator. */ > > > + m_begin =3D m_end; > > > + } > > > + > > > return *this; > > > } > > > > > > - bool operator!=3D (const unwrapping_objfile_iterator &other) const > > > + bool operator!=3D (const unwrapping_reverse_objfile_iterator &othe= r) const > > > { > > > return m_iter !=3D other.m_iter; > > > } > > > > > > + /* Return an unwrapping reverse iterator starting at the last elem= ent of > > > + OBJF_LIST. */ > > > + static unwrapping_reverse_objfile_iterator begin (objfile_list &ob= jf_list) > > > + { > > > + auto begin =3D objf_list.begin (); > > > + auto end =3D objf_list.end (); > > > + auto rev_begin =3D objf_list.end (); > > > + > > > + /* Start REV_BEGIN on the last objfile in OBJF_LIST. */ > > > + if (begin !=3D end) > > > + --rev_begin; > > > + > > > + return unwrapping_reverse_objfile_iterator (rev_begin, begin, en= d); > > > + } > > > + > > > + /* 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: > > > + /* This begin and end methods should be used to create these objec= ts. */ > > > + 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 seq= uence. 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 =3D iterator_range; > > > +/* A range that returns unwrapping_iterators. */ > > > + > > > +using unwrapping_objfile_range > > > + =3D 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.be= gin ()), > > > + unwrapping_iterator (objfiles_list.en= d ())); > > > } > > > > > > - using objfiles_safe_range =3D basic_safe_range; > > > + using objfiles_reverse_range =3D iterator_range; > > > + using objfiles_safe_reverse_range =3D basic_safe_range; > > > > > > /* An iterable object that can be used to iterate over all objfile= s. > > > 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 prevent= s > > > + 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 =3D 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 =3D 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 =3D iter->find_last_source_symtab (this); > > > + retval =3D qf->find_last_source_symtab (this); > > > if (retval !=3D 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 =3D 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 =3D=3D 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 =3D=3D 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 cha= r *func_name) > > > lookup_name_info base_lookup (func_name, symbol_name_match_type::F= ULL); > > > lookup_name_info lookup_name =3D 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 ch= ar *fullname) > > > return filename_cmp (basenames ? basename : fullname, filename) = =3D=3D 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_n= ame, > > > - symbol_matcher, expansion_not= ify, > > > - search_flags, domain, kind)) > > > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > > > + if (!qf->expand_symtabs_matching (this, file_matcher, lookup_nam= e, > > > + symbol_matcher, expansion_notif= y, > > > + search_flags, domain, kind)) > > > return false; > > > return true; > > > } > > > @@ -454,10 +454,10 @@ objfile::find_pc_sect_compunit_symtab (struct b= ound_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 =3D iter->find_pc_sect_compunit_symtab (this, msymbol, = pc, section, > > > - warn_if_readin); > > > + retval =3D qf->find_pc_sect_compunit_symtab (this, msymbol, pc= , section, > > > + warn_if_readin); > > > if (retval !=3D 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_AD= DR address) > > > hex_string (address)); > > > > > > struct compunit_symtab *result =3D NULL; > > > - for (const auto &iter : qf_require_partial_symbols ()) > > > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > > > { > > > - result =3D iter->find_compunit_symtab_by_address (this, addres= s); > > > + result =3D qf->find_compunit_symtab_by_address (this, address)= ; > > > if (result !=3D nullptr) > > > break; > > > } > > > @@ -521,10 +521,10 @@ objfile::lookup_global_symbol_language (const c= har *name, > > > enum language result =3D language_unknown; > > > *symbol_found_p =3D false; > > > > > > - for (const auto &iter : qf_require_partial_symbols ()) > > > + for (quick_symbol_functions *qf : qf_require_partial_symbols ()) > > > { > > > - result =3D iter->lookup_global_symbol_language (this, name, do= main, > > > - symbol_found_p); > > > + result =3D qf->lookup_global_symbol_language (this, name, doma= in, > > > + symbol_found_p); > > > if (*symbol_found_p) > > > break; > > > } > > > diff --git a/gdb/symfile.c b/gdb/symfile.c > > > index 8ae2177b159..9c943c4d5be 100644 > > > --- a/gdb/symfile.c > > > +++ b/gdb/symfile.c > > > @@ -992,6 +992,10 @@ syms_from_objfile (struct objfile *objfile, > > > static void > > > finish_new_objfile (struct objfile *objfile, symfile_add_flags add_f= lags) > > > { > > > + struct objfile *parent =3D objfile->separate_debug_objfile_backlin= k; > > > + bool was_deferred > > > + =3D (parent !=3D nullptr) && (parent->flags & OBJF_DOWNLOAD_DEFE= RRED); > > > + > > > /* If this is the main symbol file we have to clean up all users o= f the > > > old main symbol file. Otherwise it is sufficient to fixup all = the > > > breakpoints that may have been redefined by this symbol file. = */ > > > @@ -1002,7 +1006,8 @@ finish_new_objfile (struct objfile *objfile, sy= mfile_add_flags add_flags) > > > > > > clear_symtab_users (add_flags); > > > } > > > - else if ((add_flags & SYMFILE_DEFER_BP_RESET) =3D=3D 0) > > > + else if ((add_flags & SYMFILE_DEFER_BP_RESET) =3D=3D 0 > > > + && !was_deferred) > > > { > > > breakpoint_re_set (); > > > } > > > 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" "=3D {} $hex
" \ > > > gdb_py_test_silent_cmd "python objfile.add_separate_debug_file(\"${b= infile}\")" \ > > > "Add separate debug file file" 1 > > > > > > -gdb_py_test_silent_cmd "python sep_objfile =3D gdb.objfiles()\[0\]" = \ > > > +gdb_py_test_silent_cmd "python sep_objfile =3D gdb.objfiles()\[1\]" = \ > > > "Get separate debug info objfile" 1 > > > > > > gdb_test "python print (sep_objfile.owner.filename)" "${testfile}2" = \ > > > -- > > > 2.39.2 > > >