gdb: Don't fault for 'maint print psymbols' when using an index

Cherrypick of upstream 3dd9bb462012df685d6d41300dacedae1c81e28a.
Original commit message:

    I found that these tests:

      make check-gdb RUNTESTFLAGS="--target_board=cc-with-gdb-index gdb.base/maint.exp"
      make check-gdb RUNTESTFLAGS="--target_board=cc-with-debug-names gdb.base/maint.exp"

    were causing GDB to segfault.  It turns out that this test runs this
    command:

      maint print psymbols -pc main /path/to/some/file

    which tries to lookup the partial_symtab for 'main'.  The problem is
    that there is no partial_symtab for 'main' as we are using the
    .gdb_index or .debug_names instead of partial_symtabs.

    What happens is that maintenance_print_symbols calls
    find_pc_sect_psymtab, which looks for the partial_symtab in the
    objfile's objfile->partial_symtabs->psymtabs_addrmap.

    This is a problem because when we are using the indexes
    psymtabs_addrmap is reused to hold things other than partial_symtabs,
    this can be seen in dwarf2read.c in create_addrmap_from_index and
    create_addrmap_from_aranges.  If we then lookup in psymtabs_addrmap we
    end up returning a pointer to something that isn't really a
    partial_symtab, after which everything goes wrong.

    Initially I simply added a check at the start of find_pc_sect_psymtab
    that the objfile had some partial_symtabs, like:

      if (objfile->partial_symtabs->psymtabs == NULL)
        return NULL;

    Figuring that if there were no partial_symtabs at all then this
    function should always return NULL, however, this caused a failure in
    the test gdb.python/py-event.exp which I didn't dig into too deeply,
    but seems to be that in this tests there are initially no psymtabs,
    but the second part of find_pc_sect_psymtab does manage to read some
    in from somewhere, with the check I added the test fails as we
    returned NULL here and this caused GDB to load in the full symtabs
    earlier than was expected.

    Instead I chose to guard only the access to psymtabs_addrmap with a
    check that the function has some psymtabs.  This allows my original
    tests to pass, and the py-event.exp test to pass too.

    Now, a good argument can be made that we simply should never call
    find_pc_sect_psymtab on an objfile that is using indexes instead of
    partial_symtabs.  I did consider this approach, we could easily add an
    assert into find_pc_sect_psymtab that if we find a partial_symtab in
    psymtabs_addrmap then the psymtabs pointer must be non-null.  The
    responsibility would then be on the user of find_pc_sect_psymtab to
    ensure that the objfile being checked is suitable.  In the end I
    didn't take this approach as the check in find_pc_sect_psymtab is
    cheap and this ensures that any future miss-uses of the function will
    not cause problems.

    I also extended the comment on psymtabs_addrmap to indicate that it
    holds more than just partial_symtabs as this was not at all clear from
    the original comment, and caused me some confusion when I was
    initially debugging this problem.

    gdb/ChangeLog:

            * psymtab.c (find_pc_sect_psymtab): Move baseaddr local into more
            inner scope, add check that the objfile has psymtabs before
            checking psymtabs_addrmap.
            * psymtab.h (psymtab_storage) <psymtabs_addrmap>: Extend comment.

Bug: http://b/144102122
Test: gdbclient.py -p `adb shell pgrep dialer`
Change-Id: I0ad68ac5dd29d86d5b1df06cca5fe02206afcfdb
2 files changed
tree: 8bf356a97efd8f717a43fed6e9406c750d1d0248
  1. gdb-7.11/
  2. gdb-8.0.1/
  3. gdb-8.2/
  4. gdb-8.3/