diff options
author | Andrew Burgess <aburgess@redhat.com> | 2025-03-11 14:12:45 +0000 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2025-05-06 13:45:57 +0100 |
commit | 1e21c846c275fc6e387ca903a129096be2a53d0b (patch) | |
tree | ed462dd446e3a8faaee544a88f73a9b2bc44311b /gdb | |
parent | 18e05d3a711b3b86ace033fe6544407fe8d12555 (diff) | |
download | binutils-master.zip binutils-master.tar.gz binutils-master.tar.bz2 |
It is possible, when creating a shared memory segment (i.e. with
shmget), that the id of the segment will be zero.
When looking at the segment in /proc/PID/smaps, the inode field of the
entry holds the shared memory segment id.
And so, it can be the case that an entry (in the smaps file) will have
an inode of zero.
When GDB generates a core file, with the generate-core-file (or its
gcore alias) command, the shared memory segment should be written into
the core file.
Fedora GDB has, since 2008, carried a patch that tests this case.
There is no fix for GDB associated with the test, and unfortunately,
the motivation for the test has been lost to the mists of time. This
likely means that a fix was merged upstream without a suitable test,
but I've not been able to find and relevant commit. The test seems to
be checking that the shared memory segment with id zero, is being
written to the core file.
While looking at this test and trying to work out if it should be
posted upstream, I saw that GDB does appear to write the shared memory
segment into the core file (as expected), which is good. However, GDB
still isn't getting this case exactly right.
In gcore_memory_sections (gcore.c) we call back into linux-tdep.c (via
the gdbarch_find_memory_regions call) to correctly write the shared
memory segment into the core file, however, in
linux_make_mappings_corefile_notes, when we use
linux_find_memory_regions_full to create the NT_FILE note, we call
back into linux_make_mappings_callback for each mapping, and in here
we reject any mapping with a zero inode.
The result of this, is that, for a shared memory segment with a
non-zero id, after loading the core file, the shared memory segment
will appear in the 'proc info mappings' output. But, for a shared
memory segment with a zero id, the segment will not appear in the
'proc info mappings' output.
I propose fixing this by not checking the inode in
linux_make_mappings_callback. The inode check was in place since the
code was originally added in commit 451b7c33cb3c9ec6272c36870 (in
2012).
The test for this bug, based on the original Fedora patch, can be
found on the mailing list here:
https://inbox.sourceware.org/gdb-patches/0d389b435cbb0924335adbc9eba6cf30b4a2c4ee.1741776651.git.aburgess@redhat.com
I have not committed this test into the tree though because the test
was just too unreliable. User space doesn't have any control over the
shared memory id, so all we can do is spam out requests for new shared
memory segments and hope that we eventually get the zero id.
Obviously, this can fail; the zero id might already be in use by some
long running process, or the kernel, for whatever reason, might choose
to never allocate the zero id. The test I posted (see above thread)
did work more than 50% of the time, but it was far closer to a 50%
success rate than 100%, and I really don't like introducing unreliable
tests.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/linux-tdep.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index bbffb3d..a03f931 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1712,7 +1712,7 @@ linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size, = (struct linux_make_mappings_data *) data; gdb_byte buf[sizeof (ULONGEST)]; - if (*filename == '\0' || inode == 0) + if (*filename == '\0') return 0; ++map_data->file_count; |