Bug 27541 - gdb crashes on "file -readnow"
Summary: gdb crashes on "file -readnow"
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: symtab (show other bugs)
Version: 10.1
: P2 normal
Target Milestone: 10.2
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-03-08 02:16 UTC by liangjs
Modified: 2021-11-24 13:41 UTC (History)
18 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2021-03-15 00:00:00


Attachments
an ELF binary with debug symbols (2.45 KB, application/x-sharedlib)
2021-03-08 05:25 UTC, liangjs
Details

Note You need to log in before you can comment on or make changes to this bug.
Description liangjs 2021-03-08 02:16:26 UTC
GDB crashes when you give it a binary on command line and then use "file -readnow" to load that binary again.

$ gdb -q -nx a
Reading symbols from a...
(gdb) file -readnow a
Load new symbol table from "a"? (y or n) y
Reading symbols from a...
../../gdb/dwarf2/read.c:8190: internal-error: void create_all_comp_units(dwarf2_per_objfile*): Assertion `per_objfile->per_bfd->all_comp_units.empty ()' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) y
Comment 1 Simon Marchi 2021-03-08 02:45:12 UTC
Can you share said binary / a reproducer?  It doesn't seem to occur with all binaries.
Comment 2 liangjs 2021-03-08 05:25:53 UTC
Created attachment 13293 [details]
an ELF binary with debug symbols

Actually it can be any binary with debug symbols.
Comment 3 Simon Marchi 2021-03-08 17:19:36 UTC
I tried with both master and gdb-10-branch, and I don't see a problem:

$ ./gdb -nx --data-directory=data-directory ~/Downloads/a -readnow
...
Reading symbols from /home/simark/Downloads/a...
Expanding full symbols from /home/simark/Downloads/a...
(gdb) 

What version of GDB are you testing with?
Comment 4 liangjs 2021-03-09 03:06:22 UTC
I'm using GDB 10.1 on Archlinux.

To make it crash, there are two steps to follow:
1. Give GDB a binary from bash command line, like `gdb -q -nx a`.
2. Inside GDB, load that binary again by `file -readnow a`.
Comment 5 Simon Marchi 2021-03-09 04:17:37 UTC
Ahh I see, I was using -readnow on the command line.  I clearly read your instructions in diagonal, sorry about that.  So I am able to reproduce it now, thanks.
Comment 6 Simon Marchi 2021-03-09 04:26:50 UTC
One liner to reproduce

  ./gdb -nx -q --data-directory=data-directory ~/a.out -ex "set confirm off" -ex "file -readnow ~/a.out"
Comment 7 Simon Marchi 2021-03-09 05:05:15 UTC
This is a GDB 9 -> 10 regression, introduced by commit

  Share DWARF partial symtabs
  17ee85fc2af74471e8c57502714a32bbeac5f1ae
Comment 8 Simon Marchi 2021-03-11 03:19:24 UTC
So this is tricky, I didn't consider the fact that readnow can be applied at the file command level.  I only considered the "global" -readnow flag, which applies readnow to all loaded binaries.

We therefore need to test all variations of "file" followed by "file -readnow" and "file -readnow" followed by "file", where the binary may or may not have an index (gdb index and debug names).
Comment 9 Sourceware Commits 2021-03-30 17:37:32 UTC
The master branch has been updated by Simon Marchi <simark@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8a91fbdf3b570460afdf0cac0d7f087b9d55f60c

commit 8a91fbdf3b570460afdf0cac0d7f087b9d55f60c
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Tue Mar 30 13:37:11 2021 -0400

    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
Comment 10 Sourceware Commits 2021-03-30 17:38:29 UTC
The gdb-10-branch branch has been updated by Simon Marchi <simark@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=314d069cd6f5e458023cefcf41459b82368b6e7e

commit 314d069cd6f5e458023cefcf41459b82368b6e7e
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Tue Mar 30 13:37:56 2021 -0400

    gdb/dwarf: disable per-BFD resource sharing for -readnow 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
Comment 11 Simon Marchi 2021-03-30 17:39:08 UTC
This is now hopefully fixed.
Comment 12 Ahmed Sayeed 2021-06-27 18:01:39 UTC Comment hidden (spam)
Comment 13 james rohan 2021-09-02 11:06:26 UTC Comment hidden (spam)
Comment 14 Kim Olsun 2021-09-05 07:34:46 UTC Comment hidden (spam)
Comment 15 james robin 2021-09-06 09:08:39 UTC Comment hidden (spam)
Comment 17 Mehmet gelisin 2021-09-10 19:38:07 UTC Comment hidden (spam)
Comment 18 Gulsen Engin 2021-10-09 11:00:27 UTC Comment hidden (spam)
Comment 19 svitvitraga 2021-10-09 17:44:17 UTC Comment hidden (spam)
Comment 20 Canerkin 2021-10-18 19:58:16 UTC Comment hidden (spam)
Comment 21 progonsaytu 2021-10-19 07:13:42 UTC Comment hidden (spam)
Comment 22 glassmtech 2021-10-24 10:01:40 UTC Comment hidden (spam)
Comment 23 tesaso8237@funboxcn.com 2021-11-13 19:34:42 UTC Comment hidden (spam)
Comment 24 gncbilgi 2021-11-19 06:37:50 UTC Comment hidden (spam)
Comment 25 gexed96894 2021-11-22 06:48:05 UTC Comment hidden (spam)
Comment 26 LeoRVM 2021-11-24 13:41:04 UTC Comment hidden (spam)