gdb/linux: handle missing NT_FILE note when opening core files
This patch originated from this mailing list discussion:
https://inbox.sourceware.org/gdb-patches/b9b5bf03c59b58e02ca27b522338c6103d5ae49f.camel@gnu.org
The user has some core files which lack an NT_FILE note. They
wondered why GDB was still unable to find the shared libraries based
on their build-id.
The reason right now is that GDB only records the build-id information
for mappings based on the entries in the NT_FILE note. With the
entries in this note we build several lookup tables; a filename to
build-id table, a soname (extracted from the file if it is a shared
library) to build-id table, and an address range to build-id table.
When a shared library is being loaded we perform a lookup using two
pieces of information; the shared library's filename, and an address
that we know is within the shared library. If either of these give a
build-id, then we can use that build-id to ensure GDB loads the
shared library that matches the core file.
If the NT_FILE note is missing then none of the lookup tables are
created, and so the shared library build-id lookup fails, meaning that
all GDB can do is look for the shared library by name on the local
file system. This often results in the wrong library version being
loaded, or the library not being found at all.
However, Linux core files also have the segment table. This table
gives address ranges. The segment table doesn't tell us what file was
mapped in, or the offset within the file that was mapped in. But if
we go back to the three lookup tables, we can use the segment table to
build the address to build-id lookup table, and that would be enough
to allow GDB to find the build-id for a shared library in most cases.
So, here's what this patch does: linux_read_core_file_mappings (in
linux-tdep.c) is updated to first parse the NT_FILE note as it
currently does. But after this we also walk the segment table (BFD
actually converts these into sections with the LOAD flag set), and if
a segment has a build-id, and doesn't correspond to an entry found in
the NT_FILE note, we create an anonymous mapping. An anonymous
mapping is just like a mapping from the NT_FILE note, but without a
filename and file offset. This mapping is passed through the callback
just like the traditional, non-anonymous, mappings.
Then in corelow.c various functions are updated in order to handle
anonymous mappings.
Back in linux-tdep.c, function linux_core_info_proc_mappings gets a
small update to handle anonymous mappings.
The corefile-buildid.exp test is updated to remove the NT_FILE notes
and rerun the tests. This should make no difference as all this test
is checking is that GDB is able to find and load the shared libraries
and executable based on their build-ids; this is something we can do
fine now without the NT_FILE note.
I have also had to update the Python core file API documentation after
this commit. Previously we claimed that CorefileMappedFile.filename
would never be empty, but this is now possible. Luckily, this API has
not yet been in a released version of GDB, so this minor tweak isn't
going to break any existing user code. I did consider having
CorefileMappedFile.filename be a non-empty string or None, but I
couldn't see much value in this, so I just documented that the string
could be empty, and what this means.
The py-corefile.exp test needed a minor update to filter out anonymous
mappings (those without a filename), this matches the behaviour of the
builtin 'info proc mappings' command.
Reviewed-By: Keith Seitz <keiths@redhat.com>
6 files changed