diff options
-rw-r--r-- | gdb/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/NEWS | 15 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 21 | ||||
-rw-r--r-- | gdb/exec.c | 53 | ||||
-rw-r--r-- | gdb/gdb_bfd.c | 23 | ||||
-rw-r--r-- | gdb/gdb_bfd.h | 6 |
7 files changed, 100 insertions, 36 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 643b4eb..f62557d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,17 @@ 2020-05-19 Pedro Alves <palves@redhat.com> + * NEWS (set exec-file-mismatch): Adjust entry. + * exec.c: Include "build-id.h". + (validate_exec_file): Try to match build IDs instead of filenames. + * gdb_bfd.c (struct gdb_bfd_open_closure): New. + (gdb_bfd_iovec_fileio_open): Adjust to use gdb_bfd_open_closure + and pass down 'warn_if_slow'. + (gdb_bfd_open): Add 'warn_if_slow' parameter. Use + gdb_bfd_open_closure to pass it down. + * gdb_bfd.h (gdb_bfd_open): Add 'warn_if_slow' parameter. + +2020-05-19 Pedro Alves <palves@redhat.com> + * gdb_bfd.c (gdb_bfd_iovec_fileio_open): Adjust. * target.c (target_fileio_open_1): Rename to target_fileio_open and make extern. Use bool. @@ -54,14 +54,13 @@ set exec-file-mismatch -- Set exec-file-mismatch handling (ask|warn|off). show exec-file-mismatch -- Show exec-file-mismatch handling (ask|warn|off). - Set or show the option 'exec-file-mismatch'. When GDB attaches to - a running process and can determine the name of the executable file - the process runs, this new option indicates whether to detect mismatch - between the name of the current executable file loaded by GDB - and the name of the executable file used to start the process. - If 'ask', the default, display a warning and ask the user - whether to load the process executable file; if 'warn', just display - a warning; if 'off', don't attempt to detect a mismatch. + Set or show the option 'exec-file-mismatch'. When GDB attaches to a + running process, this new option indicates whether to detect + a mismatch between the current executable file loaded by GDB and the + executable file used to start the process. If 'ask', the default, + display a warning and ask the user whether to load the process + executable file; if 'warn', just display a warning; if 'off', don't + attempt to detect a mismatch. tui new-layout NAME WINDOW WEIGHT [WINDOW WEIGHT]... Define a new TUI layout, specifying its name and the windows that diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 0cb4182..f19b897 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2020-05-19 Pedro Alves <palves@redhat.com> + + * gdb.texinfo (Attach): Update exec-file-mismatch description to + mention build IDs. + (Separate Debug Files): Add "build id" anchor. + 2020-05-15 Philippe Waroquiers <philippe.waroquiers@skynet.be> * gdb.texinfo (Help): Document the help and apropos changes. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 8f33012..6418162 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -2909,22 +2909,22 @@ the @code{file} command to load the program. @xref{Files, ,Commands to Specify Files}. @anchor{set exec-file-mismatch} -If the debugger can determine the name of the executable file running -in the process it is attaching to, and this file name does not match -the name of the current exec-file loaded by @value{GDBN}, the option -@code{exec-file-mismatch} specifies how to handle the mismatch. +If the debugger can determine that the executable file running in the +process it is attaching to does not match the current exec-file loaded +by @value{GDBN}, the option @code{exec-file-mismatch} specifies how to +handle the mismatch. @value{GDBN} tries to compare the files by +comparing their build IDs (@pxref{build ID}), if available. @table @code @kindex exec-file-mismatch @cindex set exec-file-mismatch @item set exec-file-mismatch @samp{ask|warn|off} -Whether to detect mismatch between the name of the current executable -file loaded by @value{GDBN} and the name of the executable file used to -start the process. If @samp{ask}, the default, display a warning -and ask the user whether to load the process executable file; if -@samp{warn}, just display a warning; if @samp{off}, don't attempt to -detect a mismatch. +Whether to detect mismatch between the current executable file loaded +by @value{GDBN} and the executable file used to start the process. If +@samp{ask}, the default, display a warning and ask the user whether to +load the process executable file; if @samp{warn}, just display a +warning; if @samp{off}, don't attempt to detect a mismatch. @cindex show exec-file-mismatch @item show exec-file-mismatch @@ -20874,6 +20874,7 @@ checksum for the debug file, which @value{GDBN} uses to validate that the executable and the debug file came from the same build. @item +@anchor{build ID} The executable contains a @dfn{build ID}, a unique bit string that is also present in the corresponding debug info file. (This is supported only on some operating systems, when using the ELF or PE file formats @@ -37,6 +37,7 @@ #include "gdb_bfd.h" #include "gcore.h" #include "source.h" +#include "build-id.h" #include <fcntl.h> #include "readline/tilde.h" @@ -247,20 +248,54 @@ validate_exec_file (int from_tty) struct inferior *inf = current_inferior (); /* Try to determine a filename from the process itself. */ const char *pid_exec_file = target_pid_to_exec_file (inf->pid); + bool build_id_mismatch = false; - /* If wee cannot validate the exec file, return. */ + /* If we cannot validate the exec file, return. */ if (current_exec_file == NULL || pid_exec_file == NULL) return; - std::string exec_file_target (pid_exec_file); + /* Try validating via build-id, if available. This is the most + reliable check. */ + const bfd_build_id *exec_file_build_id = build_id_bfd_get (exec_bfd); + if (exec_file_build_id != nullptr) + { + /* Prepend the target prefix, to force gdb_bfd_open to open the + file on the remote file system (if indeed remote). */ + std::string target_pid_exec_file + = std::string (TARGET_SYSROOT_PREFIX) + pid_exec_file; + + gdb_bfd_ref_ptr abfd (gdb_bfd_open (target_pid_exec_file.c_str (), + gnutarget, -1, false)); + if (abfd != nullptr) + { + const bfd_build_id *target_exec_file_build_id + = build_id_bfd_get (abfd.get ()); - /* In case the exec file is not local, exec_file_target has to point at - the target file system. */ - if (is_target_filename (current_exec_file) && !target_filesystem_is_local ()) - exec_file_target = TARGET_SYSROOT_PREFIX + exec_file_target; + if (target_exec_file_build_id != nullptr) + { + if (exec_file_build_id->size == target_exec_file_build_id->size + && memcmp (exec_file_build_id->data, + target_exec_file_build_id->data, + exec_file_build_id->size) == 0) + { + /* Match. */ + return; + } + else + build_id_mismatch = true; + } + } + } - if (exec_file_target != current_exec_file) + if (build_id_mismatch) { + std::string exec_file_target (pid_exec_file); + + /* In case the exec file is not local, exec_file_target has to point at + the target file system. */ + if (is_target_filename (current_exec_file) && !target_filesystem_is_local ()) + exec_file_target = TARGET_SYSROOT_PREFIX + exec_file_target; + warning (_("Mismatch between current exec-file %ps\n" "and automatically determined exec-file %ps\n" @@ -1215,8 +1250,8 @@ Set exec-file-mismatch handling (ask|warn|off)."), _("\ Show exec-file-mismatch handling (ask|warn|off)."), _("\ -Specifies how to handle a mismatch between the current exec-file name\n\ -loaded by GDB and the exec-file name automatically determined when attaching\n\ +Specifies how to handle a mismatch between the current exec-file\n\ +loaded by GDB and the exec-file automatically determined when attaching\n\ to a process:\n\n\ ask - warn the user and ask whether to load the determined exec-file.\n\ warn - warn the user, but do not change the exec-file.\n\ diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 61872a0..25e0178 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -271,22 +271,29 @@ fileio_errno_to_host (int errnum) return -1; } +/* bfd_openr_iovec OPEN_CLOSURE data for gdb_bfd_open. */ +struct gdb_bfd_open_closure +{ + inferior *inf; + bool warn_if_slow; +}; + /* Wrapper for target_fileio_open suitable for passing as the - OPEN_FUNC argument to gdb_bfd_openr_iovec. The supplied - OPEN_CLOSURE is unused. */ + OPEN_FUNC argument to gdb_bfd_openr_iovec. */ static void * -gdb_bfd_iovec_fileio_open (struct bfd *abfd, void *inferior) +gdb_bfd_iovec_fileio_open (struct bfd *abfd, void *open_closure) { const char *filename = bfd_get_filename (abfd); int fd, target_errno; int *stream; + gdb_bfd_open_closure *oclosure = (gdb_bfd_open_closure *) open_closure; gdb_assert (is_target_filename (filename)); - fd = target_fileio_open ((struct inferior *) inferior, + fd = target_fileio_open (oclosure->inf, filename + strlen (TARGET_SYSROOT_PREFIX), - FILEIO_O_RDONLY, 0, true, + FILEIO_O_RDONLY, 0, oclosure->warn_if_slow, &target_errno); if (fd == -1) { @@ -378,7 +385,8 @@ gdb_bfd_iovec_fileio_fstat (struct bfd *abfd, void *stream, /* See gdb_bfd.h. */ gdb_bfd_ref_ptr -gdb_bfd_open (const char *name, const char *target, int fd) +gdb_bfd_open (const char *name, const char *target, int fd, + bool warn_if_slow) { hashval_t hash; void **slot; @@ -392,9 +400,10 @@ gdb_bfd_open (const char *name, const char *target, int fd) { gdb_assert (fd == -1); + gdb_bfd_open_closure open_closure { current_inferior (), warn_if_slow }; return gdb_bfd_openr_iovec (name, target, gdb_bfd_iovec_fileio_open, - current_inferior (), + &open_closure, gdb_bfd_iovec_fileio_pread, gdb_bfd_iovec_fileio_close, gdb_bfd_iovec_fileio_fstat); diff --git a/gdb/gdb_bfd.h b/gdb/gdb_bfd.h index 532520e..a941b79 100644 --- a/gdb/gdb_bfd.h +++ b/gdb/gdb_bfd.h @@ -78,10 +78,12 @@ typedef gdb::ref_ptr<struct bfd, gdb_bfd_ref_policy> gdb_bfd_ref_ptr; If the BFD was not accessed using target fileio operations then the filename associated with the BFD and accessible with bfd_get_filename will not be exactly NAME but rather NAME with - TARGET_SYSROOT_PREFIX stripped. */ + TARGET_SYSROOT_PREFIX stripped. If WARN_IF_SLOW is true, print a + warning message if the file is being accessed over a link that may + be slow. */ gdb_bfd_ref_ptr gdb_bfd_open (const char *name, const char *target, - int fd = -1); + int fd = -1, bool warn_if_slow = true); /* Mark the CHILD BFD as being a member of PARENT. Also, increment the reference count of CHILD. Calling this function ensures that |