diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/corelow.c | 38 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/corefile3.c | 118 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/corefile3.exp | 71 |
3 files changed, 223 insertions, 4 deletions
diff --git a/gdb/corelow.c b/gdb/corelow.c index fc0df25..4518781 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -540,11 +540,41 @@ core_target::build_file_mappings () /* If ABFD was opened, but the wrong format, close it now. */ abfd = nullptr; + /* When true, this indicates that the mapped contents of this + file are available within the core file. When false, some of + the mapped contents are not available. If the contents are + entirely available within the core file, then we don't need to + warn the user if GDB cannot find the file. */ + bool content_is_in_core_file_p = true; + /* Record all regions for this file as unavailable. */ for (const mapped_file::region ®ion : file_data.regions) - m_core_unavailable_mappings.emplace_back (region.start, - region.end - - region.start); + { + /* Check to see if the region is available within the core + file. */ + bool found_region_in_core_file = false; + for (const target_section &ts : m_core_section_table) + { + if (ts.addr <= region.start && ts.endaddr >= region.end + && (ts.the_bfd_section->flags & SEC_HAS_CONTENTS) != 0) + { + found_region_in_core_file = true; + break; + } + } + + /* This region is not available within the core file. + Without the file available to read from it is not possible + for GDB to read this mapping within the inferior. Warn + the user about this case. */ + if (!found_region_in_core_file) + content_is_in_core_file_p = false; + + /* Record the unavailable region. */ + m_core_unavailable_mappings.emplace_back (region.start, + region.end + - region.start); + } /* And give the user an appropriate warning. */ if (build_id_mismatch) @@ -564,7 +594,7 @@ core_target::build_file_mappings () styled_string (file_name_style.style (), expanded_fname.get ())); } - else + else if (!content_is_in_core_file_p) { if (expanded_fname == nullptr || filename == expanded_fname.get ()) diff --git a/gdb/testsuite/gdb.base/corefile3.c b/gdb/testsuite/gdb.base/corefile3.c new file mode 100644 index 0000000..16030dd --- /dev/null +++ b/gdb/testsuite/gdb.base/corefile3.c @@ -0,0 +1,118 @@ +/* Copyright 1992-2025 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* This file is based on coremaker.c. */ + +#include <stdio.h> +#include <sys/types.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <assert.h> +#include <sys/ipc.h> +#include <sys/shm.h> + +#define MAPSIZE (8 * 1024) + +/* Global pointers so it's easier to access them from GDB. */ + +char *rw_mapping = NULL; +char *malloc_buffer = NULL; +char *anon_mapping = NULL; +char *shm_mapping = NULL; + +/* Create mappings within this process. */ + +void +mmapdata () +{ + /* Allocate and initialize a buffer that will be used to write the file + that is later mapped in. */ + + malloc_buffer = (char *) malloc (MAPSIZE); + for (int j = 0; j < MAPSIZE; ++j) + malloc_buffer[j] = j; + + /* Write the file to map in. */ + + int fd = open ("coremmap.data", O_CREAT | O_RDWR, 0666); + assert (fd != -1); + write (fd, malloc_buffer, MAPSIZE); + + /* Now map the file into our address space as RW_MAPPING. */ + + rw_mapping + = (char *) mmap (0, MAPSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + assert (rw_mapping != (char *) MAP_FAILED); + + /* Verify that the original data and the mapped data are identical. If + not, we'd rather fail now than when trying to access the mapped data + from the core file. */ + + for (int j = 0; j < MAPSIZE; ++j) + assert (malloc_buffer[j] == rw_mapping[j]); + + /* Touch RW_MAPPING so the kernel writes it out into 'core'. */ + rw_mapping[0] = malloc_buffer[0]; + + /* Create yet another region which is allocated, but not written to. */ + anon_mapping = mmap (NULL, MAPSIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + assert (anon_mapping != MAP_FAILED); + + /* Create a shared memory mapping. */ + int sid = shmget (IPC_PRIVATE, MAPSIZE, IPC_CREAT | IPC_EXCL | 0777); + assert (sid != -1); + shm_mapping = (char *) shmat (sid, NULL, 0); + int res = shmctl (sid, IPC_RMID, NULL); + assert (res == 0); + assert (shm_mapping != MAP_FAILED); +} + +void +func2 () +{ +#ifdef SA_FULLDUMP + /* Force a corefile that includes the data section for AIX. */ + { + struct sigaction sa; + + sigaction (SIGABRT, (struct sigaction *)0, &sa); + sa.sa_flags |= SA_FULLDUMP; + sigaction (SIGABRT, &sa, (struct sigaction *)0); + } +#endif + + abort (); +} + +void +func1 () +{ + func2 (); +} + +int +main (void) +{ + mmapdata (); + func1 (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/corefile3.exp b/gdb/testsuite/gdb.base/corefile3.exp new file mode 100644 index 0000000..57b2300 --- /dev/null +++ b/gdb/testsuite/gdb.base/corefile3.exp @@ -0,0 +1,71 @@ +# Copyright 2025 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Create a core file with some mapped file regions, but ensure that +# the the kernel should write the regions into the core file (e.g. r/w +# file backed mapping). +# +# We then delete the file that backed the mapping and load the core +# file into GDB. +# +# GDB shouldn't warn about the file being missing. It doesn't matter; +# the file contents can all be found in the core file itself. + +require isnative +require {!is_remote host} + +standard_testfile + +if {[build_executable $testfile.exp $testfile $srcfile] == -1} { + return +} + +set corefile [core_find $binfile {}] +if {$corefile == ""} { + return +} + +# Move the coremap.data file out of the way, so it cannot be found +# when we later load the core file into GDB. This file was generated +# by the inferior as it was running. +set data_filename \ + [standard_output_file coredir.[getpid]/coremmap.data] +set backup_filename \ + [standard_output_file coredir.[getpid]/coremmap.data.backup] +remote_exec host "mv ${data_filename} ${backup_filename}" + +clean_restart $binfile + +# Load the core file. The 'coremap.data' file cannot be found by GDB, +# but all the mappings for that file are r/w and should be present in +# the core file, so we shouldn't get any warnings from GDB about it. +set warnings_seen 0 +gdb_test_multiple "core-file $corefile" "core-file command" { + -re "^warning: Can't open file \[^\r\n\]+ during file-backed mapping note processing\r\n" { + incr warnings_seen + exp_continue + } + -re "^$gdb_prompt $" { + gdb_assert { $warnings_seen == 0 } $gdb_test_name + } + -re "^\[^\r\n\]*\r\n" { + exp_continue + } +} + +# Check the mappings are all readable. +foreach label { rw_mapping malloc_buffer anon_mapping shm_mapping } { + gdb_test "x/1wd $label" "^$hex:\\s+$decimal" +} |