]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/dwarf: use all_units_range in dwarf2_base_index_functions::expand_all_symtabs
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 13 Mar 2025 02:56:33 +0000 (22:56 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Thu, 13 Mar 2025 03:19:12 +0000 (23:19 -0400)
Commit 292041562289 ("gdb/dwarf: use ranged for loop in some spots")
broke some tests notably gdb.base/maint.exp with the fission board.

    $ ./gdb -nx -q --data-directory=data-directory testsuite/outputs/gdb.base/maint/maint -ex start -ex "maint expand-sym" -batch
    ...
    Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdc48, envp=0x7fffffffdc58) at /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/break.c:43
    43          if (argc == 12345) {  /* an unlikely value < 2^16, in case uninited */ /* set breakpoint 6 here */
    /usr/include/c++/14.2.1/debug/safe_iterator.h:392:
    In function:
        gnu_debug::_Safe_iterator<_Iterator, _Sequence, _Category>&
        gnu_debug::_Safe_iterator<_Iterator, _Sequence, _Category>::operator++()
        [with _Iterator = gnu_cxx::
        normal_iterator<std::unique_ptr<dwarf2_per_cu, dwarf2_per_cu_deleter>*,
        std::vector<std::unique_ptr<dwarf2_per_cu, dwarf2_per_cu_deleter>,
        std::allocator<std::unique_ptr<dwarf2_per_cu, dwarf2_per_cu_deleter> > >
        >; _Sequence = std::debug::vector<std::unique_ptr<dwarf2_per_cu,
        dwarf2_per_cu_deleter> >; _Category = std::forward_iterator_tag]

    Error: attempt to increment a singular iterator.

Note that this is caught because I build with -D_GLIBCXX_DEBUG=1.
Otherwise, it might crash more randomly, or just not crash at all (but
still be buggy).

While iterating on the all_units vector, some type units get added
there:

    #0  add_type_unit (per_bfd=0x51b000044b80, section=0x50e0000c2280, sect_off=0, length=74, sig=4367013491293299229) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:2576
    #1  0x00005555618a3a40 in lookup_dwo_signatured_type (cu=0x51700009b580, sig=4367013491293299229) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:2664
    #2  0x00005555618ee176 in queue_and_load_dwo_tu (dwo_unit=0x521000120e00, cu=0x51700009b580) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:8329
    #3  0x00005555618eeafe in queue_and_load_all_dwo_tus (cu=0x51700009b580) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:8366
    #4  0x00005555618966a6 in dw2_do_instantiate_symtab (per_cu=0x50f0000043c0, per_objfile=0x516000065a80, skip_partial=true) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:1695
    #5  0x00005555618968d4 in dw2_instantiate_symtab (per_cu=0x50f0000043c0, per_objfile=0x516000065a80, skip_partial=true) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:1719
    #6  0x000055556189ac3f in dwarf2_base_index_functions::expand_all_symtabs (this=0x502000024390, objfile=0x516000065780) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/read.c:1977

This invalidates the iterator in
dwarf2_base_index_functions::expand_all_symtabs, which is caught by the
libstdc++ debug mode.

I'm not entirely sure that it is correct to append type units from dwo
files to the all_units vector like this.  The
dwarf2_find_containing_comp_unit function expects a precise ordering of
the elements of the all_units vector, to be able to do a binary search.
Appending a type unit at the end at this point certainly doesn't respect
that ordering.

For now I'd just like to undo the regression.  Do that by using
all_units_range in the ranged for loop.  I will keep in mind to
investigate whether this insertion of type units in all_units after the
fact really makes sense or not.

Change-Id: Iec131e59281cf2dbd12d3f3d163b59018fdc54da

gdb/dwarf2/read.c

index d53c1e95b39d33cd6957ab856ac5fa37f70b83a0..455567ecb0d8550ac1cca23b3954ceaababe30a3 100644 (file)
@@ -1967,14 +1967,14 @@ dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
 {
   dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
 
-  for (const dwarf2_per_cu_up &per_cu : per_objfile->per_bfd->all_units)
+  for (dwarf2_per_cu *per_cu : all_units_range (per_objfile->per_bfd))
     {
       /* We don't want to directly expand a partial CU, because if we
         read it with the wrong language, then assertion failures can
         be triggered later on.  See PR symtab/23010.  So, tell
         dw2_instantiate_symtab to skip partial CUs -- any important
         partial CU will be read via DW_TAG_imported_unit anyway.  */
-      dw2_instantiate_symtab (per_cu.get (), per_objfile, true);
+      dw2_instantiate_symtab (per_cu, per_objfile, true);
     }
 }