summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-07-23 16:01:01 +0100
committerPedro Alves <palves@redhat.com>2015-08-06 14:30:07 +0100
commitf0ce0d3a331129309a46a6a9ac85fce35acae72b (patch)
tree670182cd3e8f7cb283d47a7f9afb00006ae88fdb
parentbf47e2482d3e88580ba5a22db48bc773fa8ced3f (diff)
downloadbinutils-gdb-f0ce0d3a331129309a46a6a9ac85fce35acae72b.tar.gz
gdbserver: move_out_of_jump_pad_callback misses switching current thread
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.
-rw-r--r--gdb/gdbserver/ChangeLog5
-rw-r--r--gdb/gdbserver/linux-low.c7
2 files changed, 12 insertions, 0 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 79904d9bc05..fe31f731750 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -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.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 2146a2c3e76..792c1782b0e 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -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