gdbserver: move_out_of_jump_pad_callback misses switching current thread
authorPedro Alves <palves@redhat.com>
Thu, 23 Jul 2015 15:01:01 +0000 (16:01 +0100)
committerPedro Alves <palves@redhat.com>
Thu, 6 Aug 2015 13:30:07 +0000 (14:30 +0100)
While hacking on the fix for PR threads/18600 (Threads left stopped
after fork+thread spawn), I once saw its test (fork-plus-threads.exp)
FAIL against gdbserver because move_out_of_jump_pad_callback has a
gdb_breakpoint_here call, and the caller isn't making sure the current
thread points to the right thread.  In the case I saw, the current
thread pointed to the wrong process, so gdb_breakpoint_here returned
the wrong answer.  Unfortunately I didn't save logs.  Still, seems
obvious enough and it should fix a potential occasional racy FAIL.

Tested on x86_64 Fedora 20.

gdb/gdbserver/ChangeLog:
2015-08-06  Pedro Alves  <palves@redhat.com>

* linux-low.c (move_out_of_jump_pad_callback): Temporarily switch
the current thread.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c

index 79904d9..fe31f73 100644 (file)
@@ -1,5 +1,10 @@
 2015-08-06  Pedro Alves  <palves@redhat.com>
 
+       * linux-low.c (move_out_of_jump_pad_callback): Temporarily switch
+       the current thread.
+
+2015-08-06  Pedro Alves  <palves@redhat.com>
+
        * linux-low.c (linux_write_memory): Rewrite debug output to avoid
        reading beyond the passed in buffer length.
 
index 2146a2c..792c178 100644 (file)
@@ -3664,6 +3664,7 @@ static void
 move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
 {
   struct thread_info *thread = (struct thread_info *) entry;
+  struct thread_info *saved_thread;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int *wstat;
 
@@ -3675,6 +3676,10 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
     }
   gdb_assert (lwp->stopped);
 
+  /* For gdb_breakpoint_here.  */
+  saved_thread = current_thread;
+  current_thread = thread;
+
   wstat = lwp->status_pending_p ? &lwp->status_pending : NULL;
 
   /* Allow debugging the jump pad, gdb_collect, etc.  */
@@ -3702,6 +3707,8 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
     }
   else
     lwp_suspended_inc (lwp);
+
+  current_thread = saved_thread;
 }
 
 static int