gdb/dwarf: disable per-BFD resource sharing for -readnow objfiles
authorSimon Marchi <simon.marchi@polymtl.ca>
Tue, 30 Mar 2021 17:37:11 +0000 (13:37 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Tue, 30 Mar 2021 17:37:11 +0000 (13:37 -0400)
commit8a91fbdf3b570460afdf0cac0d7f087b9d55f60c
tree221ffec33f1726400c34965b3ee4eaa6cfce0262
parentb953e70356feb6161a2c1c5b18dbebcdb7ea0c94
gdb/dwarf: disable per-BFD resource sharing for -readnow objfiles

New in v2:

  - Disable sharing only for -readnow objfiles, not all objfiles.

As described in PR 27541, we hit an internal error when loading a binary
the standard way and then loading it with the -readnow option:

    $ ./gdb -nx -q --data-directory=data-directory ~/a.out -ex "set confirm off" -ex "file -readnow ~/a.out"
    Reading symbols from /home/simark/a.out...
    Reading symbols from ~/a.out...
    /home/simark/src/binutils-gdb/gdb/dwarf2/read.c:8098: internal-error: void create_all_comp_units(dwarf2_per_objfile*): Assertion `per_objfile->per_bfd->all_comp_units.empty ()' failed.

This is a recurring problem that exposes a design issue in the DWARF
per-BFD sharing feature.  Things work well when loading a binary with
the same method (with/without index, with/without readnow) twice in a
row.  But they don't work so well when loading a binary with different
methods.  See this previous fix, for example:

    efb763a5ea35 ("gdb: check for partial symtab presence in dwarf2_initialize_objfile")

That one handled the case where the first load is normal (uses partial
symbols) and the second load uses an index.

The problem is that when loading an objfile with a method A, we create a
dwarf2_per_bfd and some dwarf2_per_cu_data and initialize them with the
data belonging to that method.  When loading another obfile sharing the
same BFD but with a different method B, it's not clear how to re-use the
dwarf2_per_bfd/dwarf2_per_cu_data previously created, because they
contain the data specific to method A.

I think the most sensible fix would be to not share a dwarf2_per_bfd
between two objfiles loaded with different methods.  That means that two
objfiles sharing the same BFD and loaded the same way would share a
dwarf2_per_bfd.  Two objfiles sharing the same BFD but loaded with
different methods would use two different dwarf2_per_bfd structures.

However, this isn't a trivial change.  So to fix the known issue quickly
(including in the gdb 10 branch), this patch just disables all
dwarf2_per_bfd sharing for objfiles using READNOW.

Generalize the gdb.base/index-cache-load-twice.exp test to test all
the possible combinations of loading a file with partial symtabs, index
and readnow.  Move it to gdb.dwarf2, since it really exercises features
of the DWARF reader.

gdb/ChangeLog:

PR gdb/27541
* dwarf2/read.c (dwarf2_has_info): Don't share dwarf2_per_bfd
with objfiles using READNOW.

gdb/testsuite/ChangeLog:

PR gdb/27541
* gdb.base/index-cache-load-twice.exp: Remove.
* gdb.base/index-cache-load-twice.c: Remove.
* gdb.dwarf2/per-bfd-sharing.exp: New.
* gdb.dwarf2/per-bfd-sharing.c: New.

Change-Id: I9ffcf1e136f3e75242f70e4e58e4ba1fd3083389
gdb/ChangeLog
gdb/dwarf2/read.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/index-cache-load-twice.c [deleted file]
gdb/testsuite/gdb.base/index-cache-load-twice.exp [deleted file]
gdb/testsuite/gdb.dwarf2/per-bfd-sharing.c [new file with mode: 0644]
gdb/testsuite/gdb.dwarf2/per-bfd-sharing.exp [new file with mode: 0644]