aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2025-03-11 14:12:45 +0000
committerAndrew Burgess <aburgess@redhat.com>2025-05-06 13:45:57 +0100
commit1e21c846c275fc6e387ca903a129096be2a53d0b (patch)
treeed462dd446e3a8faaee544a88f73a9b2bc44311b /gdb
parent18e05d3a711b3b86ace033fe6544407fe8d12555 (diff)
downloadbinutils-master.zip
binutils-master.tar.gz
binutils-master.tar.bz2
gdb: support zero inode in generate-core-file commandHEADmaster
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.c2
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;