aboutsummaryrefslogtreecommitdiff
path: root/gdb/exec.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2020-05-19 18:36:24 +0100
committerPedro Alves <palves@redhat.com>2020-05-19 18:37:15 +0100
commit98c59b527b1472b87a9ee4959c4bfae85061bc1d (patch)
tree3f6aba282331272a9f85a58f7b95b698440e1b4e /gdb/exec.c
parent4111f652f955028e8219fad2d60af1fd22aa29ee (diff)
downloadgdb-98c59b527b1472b87a9ee4959c4bfae85061bc1d.zip
gdb-98c59b527b1472b87a9ee4959c4bfae85061bc1d.tar.gz
gdb-98c59b527b1472b87a9ee4959c4bfae85061bc1d.tar.bz2
Make exec-file-mismatch compare build IDs
The patch makes GDB do exec-file-mismatch validation by comparing build IDs instead of the current method of comparing filenames. Currently, the exec-file-mismatch feature simply compares filenames to decide whether the exec file loaded in gdb and the exec file the target reports is running match. This causes false positives when remote debugging, because it'll often be the case that the paths in the host and the target won't match. And of course misses the case of the files having the same name but being actually different files (e.g., different builds). This also broke many testcases when running against gdbserver, causing tests to be skipped like (here native-extended-gdbserver): (gdb) run Starting program: /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/argv0-symlink/argv0-symlink-filelink warning: Mismatch between current exec-file /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/argv0-symlink/argv0-symlink-filelink and automatically determined exec-file /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/argv0-symlink/argv0-symlink exec-file-mismatch handling is currently "ask" Load new symbol table from "/home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/argv0-symlink/argv0-symlink"? (y or n) UNTESTED: gdb.base/argv0-symlink.exp: could not run to main or to fail like (here native-gdbserver): (gdb) spawn /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/../../gdbserver/gdbserver --once localhost:2346 /home/pedro/gdb/binutils-gdb/build/gdb/te stsuite/outputs/gdb.btrace/buffer-size/skip_btrace_tests-19968.x Process /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.btrace/buffer-size/skip_btrace_tests-19968.x created; pid = 20040 Listening on port 2346 target remote localhost:2346 Remote debugging using localhost:2346 warning: Mismatch between current exec-file /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/temp/19968/skip_btrace_tests-19968.x and automatically determined exec-file /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.btrace/buffer-size/skip_btrace_tests-19968.x exec-file-mismatch handling is currently "ask" Load new symbol table from "/home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.btrace/buffer-size/skip_btrace_tests-19968.x"? (y or n) Quit (gdb) UNSUPPORTED: gdb.btrace/buffer-size.exp: target does not support record-btrace The former case is about GDB not realizing the two files are the same, because one of the them is a symlink to the other. The latter case is about GDB realizing that one file is a copy of the other. Over the years, the toolchain has settled on build ID matching being the canonical method to match core dumps to executables, and executables with no debug info to their debug info. This patch makes us use build IDs to match the running image of a binary with its version loaded in gdb, which may or may not have debug info. This is very much like the core dump/executable matching. The change to gdb_bfd_open is necessary to get rid of the "transfers from remote targets can be slow" warning when we open the remote file to read its build ID: (gdb) r Starting program: /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/break/break Reading /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/argv0-symlink/argv0-symlink from remote target... warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: Mismatch between current exec-file /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/break/break and automatically determined exec-file /home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/argv0-symlink/argv0-symlink exec-file-mismatch handling is currently "ask" Load new symbol table from "/home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.base/argv0-symlink/argv0-symlink"? (y or n) While trying this out, I was worried that bfd would read a lot of stuff from the binary in order to extract the build ID, making it potentially slow, but turns out we don't read all that much. Maybe a couple hundred bytes, and most of it seemingly is the read-ahead cache. So I'm not worried about that. Otherwise I'd consider whether a new qXfer:buildid:read would be better. But I'm happy that we seemingly don't need to worry about it. gdb/ChangeLog: 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. gdb/doc/ChangeLog: 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.
Diffstat (limited to 'gdb/exec.c')
-rw-r--r--gdb/exec.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/gdb/exec.c b/gdb/exec.c
index a2added..932270a 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -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\