gdbserver: When attaching, add process before lwps
authorAlan Hayward <alan.hayward@arm.com>
Thu, 7 Feb 2019 14:36:34 +0000 (14:36 +0000)
committerAlan Hayward <alan.hayward@arm.com>
Thu, 7 Feb 2019 14:37:45 +0000 (14:37 +0000)
The recent BP/WP changes for AArch64 swapping the order in add_lwp()
so that the process was added before the lwp. This was due to the lwp
creation requiring the process data.

This also needs changing in linux_attach().

Also add additional checks to make sure cannot attach to the same
process twice. Add test case for this - do this by splitting
attach.exp into distinct pass and error case sections.

Fixes gdb.server/ext-attach.exp on Aarch64.

gdb/gdbserver/ChangeLog:

* linux-low.c (linux_attach): Add process before lwp.
* server.c (attach_inferior): Check if already attached.

gdb/testsuite/ChangeLog:

* gdb.base/attach.exp: Add double attach test.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/attach.exp

index 17593cb8c24de78e8abb72bdfc84bc3d2439e534..e9fe5ab03f01cf1167fec8988b1b687b03552aa9 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-07  Alan Hayward  <alan.hayward@arm.com>
+
+       * linux-low.c (linux_attach): Add process before lwp.
+       * server.c (attach_inferior): Check if already attached.
+
 2019-02-07  Tom Tromey  <tom@tromey.com>
 
        * x86-tdesc.h: Rename include guard.
index 44016d2310534cf96c7da0509266ca43aeb70bf9..8c5a51f23c6cef7618845bc4cf10b927e940df47 100644 (file)
@@ -1188,18 +1188,19 @@ linux_attach (unsigned long pid)
   ptid_t ptid = ptid_t (pid, pid, 0);
   int err;
 
+  proc = linux_add_process (pid, 1);
+
   /* Attach to PID.  We will check for other threads
      soon.  */
   err = linux_attach_lwp (ptid);
   if (err != 0)
     {
-      std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
+      remove_process (proc);
 
+      std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
       error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
     }
 
-  proc = linux_add_process (pid, 1);
-
   /* Don't ignore the initial SIGSTOP if we just attached to this
      process.  It will be collected by wait shortly.  */
   initial_thread = find_thread_ptid (ptid_t (pid, pid, 0));
index f9bfdd730715064724e0119f33ca9fcbe21d6c29..e960c10d40266f71df3b70307691bdde59c9852e 100644 (file)
@@ -295,6 +295,9 @@ attach_inferior (int pid)
   /* myattach should return -1 if attaching is unsupported,
      0 if it succeeded, and call error() otherwise.  */
 
+  if (find_process_pid (pid) != nullptr)
+    error ("Already attached to process %d\n", pid);
+
   if (myattach (pid) != 0)
     return -1;
 
index d4ab609612fac33275194112dc7e68cc5aa5075a..1369b5a6b37d573d80c9415dbfc483c3c3792bbe 100644 (file)
@@ -1,3 +1,7 @@
+2019-02-07  Alan Hayward  <alan.hayward@arm.com>
+
+       * gdb.base/attach.exp: Add double attach test.
+
 2019-02-07  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * lib/gdb.exp (default_gdb_start): Don't match pagination
index 2343354dda2d66abeb0832ae3d52172faef36d78..ec6e45766bcad6eda9eddb8e8724d2126a5168ae 100644 (file)
@@ -45,7 +45,10 @@ if [get_compiler_info] {
     return -1
 }
 
-proc do_attach_tests {} {
+# This is a test of the error cases for gdb's ability to attach to a
+# running process.
+
+proc_with_prefix do_attach_failure_tests {} {
     global gdb_prompt
     global binfile
     global escapedbinfile
@@ -54,7 +57,9 @@ proc do_attach_tests {} {
     global subdir
     global timeout
     global decimal
-    
+
+    clean_restart $binfile
+
     # Figure out a regular expression that will match the sysroot,
     # noting that the default sysroot is "target:", and also noting
     # that GDB will strip "target:" from the start of filenames when
@@ -154,6 +159,75 @@ proc do_attach_tests {} {
        }
     }
     
+    # Verify that we can't double attach to the process.
+
+    set test "first attach"
+    gdb_test_multiple "attach $testpid" "$test" {
+       -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $" {
+           pass "$test"
+       }
+       -re "Attaching to program.*`?$escapedbinfile\.exe'?, process $testpid.*\[Switching to thread $testpid\..*\].*$gdb_prompt $" {
+           # Response expected on Cygwin.
+           pass "$test"
+       }
+    }
+
+    gdb_test "add-inferior" "Added inferior 2.*" "add empty inferior 2"
+    gdb_test "inferior 2" "Switching to inferior 2.*" "switch to inferior 2"
+
+    set test "fail to attach again"
+    gdb_test_multiple "attach $testpid" "$test" {
+       -re "Attaching to process $testpid.*warning: process .* is already traced by process .*$gdb_prompt $" {
+           pass "$test"
+       }
+       -re "Attaching to process .* failed.*$gdb_prompt $" {
+           # Response expected when using gdbserver.
+           pass "$test"
+       }
+    }
+
+    gdb_test "inferior 1" "Switching to inferior 1.*" "switch to inferior 1"
+    set test "exit after attach failures"
+    gdb_test "kill" \
+       "" \
+       "$test" \
+       "Kill the program being debugged.*y or n. $" \
+       "y"
+
+    # Another "don't leave a process around"
+    kill_wait_spawned_process $test_spawn_id
+}
+
+# This is a test of gdb's ability to attach to a running process.
+
+proc_with_prefix do_attach_tests {} {
+    global gdb_prompt
+    global binfile
+    global escapedbinfile
+    global srcfile
+    global testfile
+    global subdir
+    global timeout
+    global decimal
+
+    clean_restart $binfile
+
+    # Figure out a regular expression that will match the sysroot,
+    # noting that the default sysroot is "target:", and also noting
+    # that GDB will strip "target:" from the start of filenames when
+    # operating on the local filesystem.  However the default sysroot
+    # can be set via configure option --with-sysroot, which can be "/".
+    # If $binfile is a absolute path, so pattern
+    # "$sysroot$escapedbinfile" below is wrong.  Use [^\r\n]* to make
+    # $sysroot simple.
+    set sysroot "\[^\r\n\]*"
+
+    # Start the program running and then wait for a bit, to be sure
+    # that it can be attached to.
+
+    set test_spawn_id [spawn_wait_for_attach $binfile]
+    set testpid [spawn_id_get_pid $test_spawn_id]
+
     # Verify that we can attach to the process by first giving its
     # executable name via the file command, and using attach with the
     # process ID.
@@ -313,10 +387,14 @@ proc do_attach_tests {} {
     kill_wait_spawned_process $test_spawn_id
 }
 
-proc do_call_attach_tests {} {
+# Test attaching when the target is inside a system call.
+
+proc_with_prefix do_call_attach_tests {} {
     global gdb_prompt
     global binfile2
-    
+
+    clean_restart
+
     set test_spawn_id [spawn_wait_for_attach $binfile2]
     set testpid [spawn_id_get_pid $test_spawn_id]
 
@@ -358,7 +436,7 @@ proc do_call_attach_tests {} {
     kill_wait_spawned_process $test_spawn_id
 }
 
-proc do_command_attach_tests {} {
+proc_with_prefix do_command_attach_tests {} {
     global gdb_prompt
     global binfile
     global verbose
@@ -435,23 +513,8 @@ proc test_command_line_attach_run {} {
     }
 }
 
-# Start with a fresh gdb
-
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_load ${binfile}
-
-# This is a test of gdb's ability to attach to a running process.
-
 do_attach_tests
-
-# Test attaching when the target is inside a system call
-
-gdb_exit
-gdb_start
-
-gdb_reinitialize_dir $srcdir/$subdir
+do_attach_failure_tests
 do_call_attach_tests
 
 # Test "gdb --pid"