[16/23] Fix reconnecting to a gdbserver already debugging multiple processes, II

Message ID 20190906232807.6191-17-palves@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves Sept. 6, 2019, 11:28 p.m. UTC
  Another bug exposed by gdb.server/extended-remote-restart.exp in the
multi-target work is that remote_target::start_remote can leave
inferior_ptid and current_inferior() out of sync:

 (top-gdb) p current_inferior_->pid
 $1 = 29541
 (top-gdb) p inferior_ptid
 $2 = {m_pid = 29540, m_lwp = 29540, m_tid = 0}

This is caused by writing to inferior_ptid directly instead of using
switch_to_thread.  Also, "inferior_list->thread_list->ptid" assumes
that we want the first thread of the first inferior, but that inferior
may not have threads, or with multi-target, that target may be
connected to some other target.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* remote.c (remote_target::start_remote): Don't set inferior_ptid
	directly.  Instead find the first thread in the thread list and
	use switch_to_thread.
---
 gdb/remote.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
  

Patch

diff --git a/gdb/remote.c b/gdb/remote.c
index 16ef9dbdfd..ef6eb99999 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4709,8 +4709,8 @@  remote_target::start_remote (int from_tty, int extended_p)
 	     says should be current.  If we're reconnecting to a
 	     multi-threaded program, this will ideally be the thread
 	     that last reported an event before GDB disconnected.  */
-	  inferior_ptid = get_current_thread (wait_status);
-	  if (inferior_ptid == null_ptid)
+	  ptid_t curr_thread = get_current_thread (wait_status);
+	  if (curr_thread == null_ptid)
 	    {
 	      /* Odd... The target was able to list threads, but not
 		 tell us which thread was current (no "thread"
@@ -4722,8 +4722,14 @@  remote_target::start_remote (int from_tty, int extended_p)
 		                    "warning: couldn't determine remote "
 				    "current thread; picking first in list.\n");
 
-	      inferior_ptid = inferior_list->thread_list->ptid;
+	      for (thread_info *tp : all_non_exited_threads ())
+		{
+		  switch_to_thread (tp);
+		  break;
+		}
 	    }
+	  else
+	    switch_to_thread (find_thread_ptid (curr_thread));
 	}
 
       /* init_wait_for_inferior should be called before get_offsets in order