Ensure 'exec-file has changed' check has priority over 'exec-file-mismatch' check
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 23 May 2020 12:54:31 +0000 (14:54 +0200)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sun, 21 Jun 2020 10:48:18 +0000 (12:48 +0200)
Following the implementation of exec-file-mismatch based on build-id,
an attach to a process that runs a modified exec-file was triggering
the exec-file-mismatch handling, giving a warning such as:
  warning: Mismatch between current exec-file /bd/home/philippe/gdb/git/build_termours/gdb/testsuite/outputs/gdb.base/attach/attach
  and automatically determined exec-file /bd/home/philippe/gdb/git/build_termours/gdb/testsuite/outputs/gdb.base/attach/attach
  exec-file-mismatch handling is currently "ask"
as the build-ids differ when an exec-file is recompiled.

This patch ensures that the exec-file-mismatch check is done with an up to date
build-id.  With this, exec-file-mismatch check will only trigger when the
PID file really differs from the (build-id refreshed) current exec-file.
Note that the additional check does not (yet) reload the symbols if
the exec-file is changed: this reload will happen later if needed.

gdb/ChangeLog
2020-06-21  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

* exec.c (validate_exec_file): Ensure the build-id is up to
date by calling reopen_exec_file (that checks file timestamp
to decide to re-read the file).

gdb/testsuite/ChangeLog

2020-06-21  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

* gdb.base/attach.exp: Test priority of 'exec-file' changed
over 'exec-file-mismatch'.
* gdb.base/attach.c: Mark should_exit volatile.
* gdb.base/attach2.c: Likewise.  Add a comment explaining
why the sleep cannot be big.
* gdb.base/attach3.c: New file.

gdb/ChangeLog
gdb/exec.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/attach.c
gdb/testsuite/gdb.base/attach.exp
gdb/testsuite/gdb.base/attach2.c
gdb/testsuite/gdb.base/attach3.c [new file with mode: 0644]

index ff1fd7f405630a4fd7bf45c6ddbcd7a36ecdcc30..d03aae63ce8609f7ab6870dc1f4c0fdd0af001a0 100644 (file)
@@ -1,3 +1,9 @@
+2020-06-21  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
+
+       * exec.c (validate_exec_file): Ensure the build-id is up to
+       date by calling reopen_exec_file (that checks file timestamp
+       to decide to re-read the file).
+
 2020-06-18  Pedro Alves  <palves@redhat.com>
 
        PR gdb/25412
index ee13c5e027efc29eb07843b8c5474e60fd6a043d..fa770c6f02099bfe3d2d9a2190c7826d70a10027 100644 (file)
@@ -256,6 +256,14 @@ validate_exec_file (int from_tty)
 
   /* Try validating via build-id, if available.  This is the most
      reliable check.  */
+
+  /* In case current_exec_file was changed, reopen_exec_file ensures
+     an up to date build_id (will do nothing if the file timestamp
+     did not change).  If exec file changed, reopen_exec_file has
+     allocated another file name, so get_exec_file again.  */
+  reopen_exec_file ();
+  current_exec_file = get_exec_file (0);
+
   const bfd_build_id *exec_file_build_id = build_id_bfd_get (exec_bfd);
   if (exec_file_build_id != nullptr)
     {
index 713ec37cdf2bec90f45b7e0b01b77bb511014e05..5d64783df5dbfd0c5ac70ff88c1773d9ba05dee6 100644 (file)
@@ -1,3 +1,12 @@
+2020-06-21  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
+
+       * gdb.base/attach.exp: Test priority of 'exec-file' changed
+       over 'exec-file-mismatch'.
+       * gdb.base/attach.c: Mark should_exit volatile.
+       * gdb.base/attach2.c: Likewise.  Add a comment explaining
+       why the sleep cannot be big.
+       * gdb.base/attach3.c: New file.
+
 2020-06-20  Sandra Loosemore  <sandra@codesourcery.com>
 
        * gdb.mi/mi-sym-info.exp: Adjust filename patterns to make directory
index 2e87f9b7104aea4975b4b9d85c91dcbe0b037258..b3c5498401271b08ec7ba7afe210aad1df5aeaba 100644 (file)
@@ -8,7 +8,7 @@
 #include <unistd.h>
 
 int  bidule = 0;
-int  should_exit = 0;
+volatile int  should_exit = 0;
 
 int main ()
 {
index 32f72e2a9a2363afcf635a4cc936be5e6404e2fc..ab2d3185762b920330f3b444d1f483f1f3b8f862 100644 (file)
@@ -17,12 +17,13 @@ if {![can_spawn_for_attach]} {
     return 0
 }
 
-standard_testfile attach.c attach2.c
+standard_testfile attach.c attach2.c attach3.c
 set binfile2 ${binfile}2
+set binfile3 ${binfile}3
 set escapedbinfile  [string_to_regexp $binfile]
 
 #execute_anywhere "rm -f ${binfile} ${binfile2}"
-remote_exec build "rm -f ${binfile} ${binfile2}"
+remote_exec build "rm -f ${binfile} ${binfile2} ${binfile3}"
 # For debugging this test
 #
 #log_user 1
@@ -41,6 +42,13 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {d
     return -1
 }
 
+# Build the third file, used to check attach when the exec-file has changed.
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile3}" "${binfile3}" executable {debug}] != "" } {
+    untested "failed to compile attach exec-file changed test"
+    return -1
+}
+
 if [get_compiler_info] {
     return -1
 }
@@ -515,6 +523,7 @@ proc_with_prefix do_attach_exec_mismatch_handling_tests {} {
     global gdb_prompt
     global binfile
     global binfile2
+    global binfile3
 
     clean_restart $binfile
 
@@ -577,10 +586,51 @@ proc_with_prefix do_attach_exec_mismatch_handling_tests {} {
     # Detach the process.
     gdb_test "detach" "Detaching from program: .* detached\\\]" "$test detach attach"
 
+    # Test that the 'exec-file' changed is checked before exec-file-mismatch.
+    set test "mismatch exec-file changed has priority"
+    gdb_test_no_output "set exec-file-mismatch ask"
+    gdb_test_multiple "attach $testpid" "$test attach1 again, initial exec-file" {
+       -re "Attaching to program.*exec-file-mismatch handling is currently \"ask\".*Load new symbol table from .*attach\".*\(y or n\)" {
+           gdb_test "y" "Reading symbols from .*attach.*" $gdb_test_name
+       }
+    }
+    
+
+    gdb_test "detach" "Detaching from program: .* detached\\\]" "$test detach attach initial exec-file"
+
+    # Change the exec-file and attach to a new process using the changed file.
+    remote_exec build "mv ${binfile} ${binfile}.initial"
+    remote_exec build "mv ${binfile3} ${binfile}"
+    # Ensure GDB detects ${binfile} has changed when checking timestamp.
+    sleep 1
+    remote_exec build "touch ${binfile}"
+    set test_spawn_id3 [spawn_wait_for_attach $binfile]
+    set testpid3 [spawn_id_get_pid $test_spawn_id3]
+
+    gdb_test "attach $testpid3" "Attaching to program.*attach' has changed; re-reading symbols.*" \
+       "$test attach1 again, after changing exec-file"
+    gdb_test "detach" "Detaching from program: .* detached\\\]" "$test detach after attach changed exec-file"
+
+    # Now, test the situation when current exec-file has changed
+    # and we attach to a pid using another file.
+    # Ensure GDB detects ${binfile} has changed when checking timestamp.
+    sleep 1
+    remote_exec build "touch ${binfile}"
+
+    gdb_test_multiple "attach $testpid2" "$test attach2" {
+       -re "Attaching to program.*exec-file-mismatch handling is currently \"ask\".*Load new symbol table from .*attach2\".*\(y or n\)" {
+           gdb_test "y" "Reading symbols from .*attach2.*" $gdb_test_name
+       }
+    }
+
+    # Restore initial build situation.
+    remote_exec build "mv ${binfile} ${binfile3}"
+    remote_exec build "mv ${binfile}.initial ${binfile}"
 
     # Don't leave a process around
     kill_wait_spawned_process $test_spawn_id
     kill_wait_spawned_process $test_spawn_id2
+    kill_wait_spawned_process $test_spawn_id3
 }
 
 do_attach_tests
index 44d37258fbc8d78647d7290bcb21bbb7e2a3cd00..d070d933b08b20149ce5499508146a05399a67b8 100644 (file)
@@ -9,12 +9,14 @@
 #include <unistd.h>
 
 float  bidule = 0.0;
-int  should_exit = 0;
+volatile int  should_exit = 0;
 
 int main ()
 {
   int  local_i = 0;
 
+  /* Cannot sleep a very long time, as attach.exp assumes the
+     process will exit before the standard GDB timeout.  */
   sleep( 10 ); /* System call causes register fetch to fail */
                /* This is a known HPUX "feature"            */
   while (! should_exit)
diff --git a/gdb/testsuite/gdb.base/attach3.c b/gdb/testsuite/gdb.base/attach3.c
new file mode 100644 (file)
index 0000000..09a6d88
--- /dev/null
@@ -0,0 +1,25 @@
+/* This program is intended to be started outside of gdb, and then
+   attached to by gdb.  Thus, it simply spins in a loop.  The loop
+   is exited when & if the variable 'should_exit' is non-zero.  (It
+   is initialized to zero in this program, so the loop will never
+   exit unless/until gdb sets the variable to non-zero.)
+   */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+double  bidule = 0.0;
+volatile int  should_exit = 0;
+
+int main ()
+{
+  int  local_i = 0;
+
+  sleep( 60 ); /* System call causes register fetch to fail */
+               /* This is a known HPUX "feature"            */
+  while (! should_exit)
+    {
+      local_i++;
+    }
+  return (0);
+}