mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-04-12 14:33:06 +08:00
gdb: silence some 'Can't open file' warnings from core file loading
But PR gdb/20126 highlights a case where GDB emits a large number of warnings like: warning: Can't open file /anon_hugepage (deleted) during file-backed mapping note processing warning: Can't open file /dev/shm/PostgreSQL.1150234652 during file-backed mapping note processing warning: Can't open file /dev/shm/PostgreSQL.535700290 during file-backed mapping note processing warning: Can't open file /SYSV604b7d00 (deleted) during file-backed mapping note processing ... etc ... when opening a core file. This commit aims to avoid at least some of these warnings. What we know is that, for at least some of these cases, (e.g. the '(deleted)' mappings), the content of the mapping will have been written into the core file itself. As such, the fact that the file isn't available ('/SYSV604b7d00' at least is a shared memory mapping), isn't really relevant, GDB can still provide access to the mapping, by reading the content from the core file itself. What I propose is that, when processing the file backed mappings, if all of the mappings for a file are covered by segments within the core file itself, then there is no need to warn the user that the file can't be opened again. The debug experience should be unchanged, as GDB would have read from the in-core mapping anyway. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30126
This commit is contained in:
parent
7fa205d2fe
commit
33d5188ab1
@ -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 ())
|
||||
|
118
gdb/testsuite/gdb.base/corefile3.c
Normal file
118
gdb/testsuite/gdb.base/corefile3.c
Normal file
@ -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;
|
||||
}
|
71
gdb/testsuite/gdb.base/corefile3.exp
Normal file
71
gdb/testsuite/gdb.base/corefile3.exp
Normal file
@ -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"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user