98c59b5 Make exec-file-mismatch compare build IDs

Authored and Committed by palves 3 years ago
    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.
        
file modified
+12 -0
file modified
+7 -8
file modified
+6 -0
file modified
+11 -10
file modified
+44 -9
file modified
+16 -7
file modified
+4 -2