public inbox for gdb-testers@sourceware.org
help / color / mirror / Atom feed
From: gdb-buildbot@sergiodj.net
To: gdb-testers@sourceware.org
Subject: [binutils-gdb] switch inferior/thread before calling target methods
Date: Sat, 11 Jan 2020 04:36:00 -0000	[thread overview]
Message-ID: <f3f8ece4b1c77c925d1f1566df0bf632790a4d24@gdb-build> (raw)

*** TEST RESULTS FOR COMMIT f3f8ece4b1c77c925d1f1566df0bf632790a4d24 ***

commit f3f8ece4b1c77c925d1f1566df0bf632790a4d24
Author:     Pedro Alves <palves@redhat.com>
AuthorDate: Fri Jan 10 20:05:48 2020 +0000
Commit:     Pedro Alves <palves@redhat.com>
CommitDate: Fri Jan 10 20:05:48 2020 +0000

    switch inferior/thread before calling target methods
    
    Once each inferior has its own target stack, we'll need to make sure
    that the right inferior is selected before we call into target
    methods.
    
    It kind of sounds worse than it is in practice.  Not that many places
    need to be concerned.
    
    In thread.c, we add a new switch_to_thread_if_alive function that
    centralizes the switching before calls to target_thread_alive.  Other
    cases are handled with explicit switching.
    
    gdb/ChangeLog:
    2020-01-10  Pedro Alves  <palves@redhat.com>
    
            * gdbthread.h (scoped_restore_current_thread)
            <dont_restore, restore, m_dont_restore>: Declare.
            * thread.c (thread_alive): Add assertion.  Return bool.
            (switch_to_thread_if_alive): New.
            (prune_threads): Switch inferior/thread.
            (print_thread_info_1): Switch thread before calling target methods.
            (scoped_restore_current_thread::restore): New, factored out from
            ...
            (scoped_restore_current_thread::~scoped_restore_current_thread):
            ... this.
            (scoped_restore_current_thread::scoped_restore_current_thread):
            Add assertion.
            (thread_apply_all_command, thread_select): Use
            switch_to_thread_if_alive.
            * infrun.c (proceed, restart_threads, handle_signal_stop)
            (switch_back_to_stepped_thread): Switch current thread before
            calling target methods.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 50c56c95c6..a733f0dfa0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,23 @@
+2020-01-10  Pedro Alves  <palves@redhat.com>
+
+	* gdbthread.h (scoped_restore_current_thread)
+	<dont_restore, restore, m_dont_restore>: Declare.
+	* thread.c (thread_alive): Add assertion.  Return bool.
+	(switch_to_thread_if_alive): New.
+	(prune_threads): Switch inferior/thread.
+	(print_thread_info_1): Switch thread before calling target methods.
+	(scoped_restore_current_thread::restore): New, factored out from
+	...
+	(scoped_restore_current_thread::~scoped_restore_current_thread):
+	... this.
+	(scoped_restore_current_thread::scoped_restore_current_thread):
+	Add assertion.
+	(thread_apply_all_command, thread_select): Use
+	switch_to_thread_if_alive.
+	* infrun.c (proceed, restart_threads, handle_signal_stop)
+	(switch_back_to_stepped_thread): Switch current thread before
+	calling target methods.
+
 2020-01-10  Pedro Alves <palves@redhat.com>
 
 	* inferior.c (switch_to_inferior_no_thread): New function,
diff --git a/gdb/infrun.c b/gdb/infrun.c
index d876634f19..2fa5cd89b4 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2940,6 +2940,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
     {
       for (thread_info *tp : all_non_exited_threads (resume_ptid))
 	{
+	  switch_to_thread_no_regs (tp);
+
 	  /* Ignore the current thread here.  It's handled
 	     afterwards.  */
 	  if (tp == cur_thr)
@@ -2957,6 +2959,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 
 	  thread_step_over_chain_enqueue (tp);
 	}
+
+      switch_to_thread (cur_thr);
     }
 
   /* Enqueue the current thread last, so that we move all other
@@ -2993,6 +2997,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 	   Start all other threads that are implicitly resumed too.  */
       for (thread_info *tp : all_non_exited_threads (resume_ptid))
         {
+	  switch_to_thread_no_regs (tp);
+
 	  if (tp->resumed)
 	    {
 	      if (debug_infrun)
@@ -4377,6 +4383,7 @@ stop_all_threads (void)
 					    "infrun:   %s executing, "
 					    "need stop\n",
 					    target_pid_to_str (t->ptid).c_str ());
+		      switch_to_thread_no_regs (t);
 		      target_stop (t->ptid);
 		      t->stop_requested = 1;
 		    }
@@ -5221,6 +5228,8 @@ restart_threads (struct thread_info *event_thread)
 
   for (thread_info *tp : all_non_exited_threads ())
     {
+      switch_to_thread_no_regs (tp);
+
       if (tp == event_thread)
 	{
 	  if (debug_infrun)
@@ -5479,9 +5488,8 @@ handle_signal_stop (struct execution_control_state *ecs)
     {
       struct regcache *regcache = get_thread_regcache (ecs->event_thread);
       struct gdbarch *reg_gdbarch = regcache->arch ();
-      scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
-      inferior_ptid = ecs->ptid;
+      switch_to_thread (ecs->event_thread);
 
       fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
 			  paddress (reg_gdbarch,
@@ -6924,6 +6932,8 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
 
       for (thread_info *tp : all_non_exited_threads ())
         {
+	  switch_to_thread_no_regs (tp);
+
 	  /* Ignore threads of processes the caller is not
 	     resuming.  */
 	  if (!sched_multi
@@ -6975,6 +6985,8 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
 	      return 1;
 	    }
 	}
+
+      switch_to_thread (ecs->event_thread);
     }
 
   return 0;
diff --git a/gdb/thread.c b/gdb/thread.c
index 630899c8cb..17a79e22c6 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -62,8 +62,6 @@ static int highest_thread_num;
    spawned new threads we haven't heard of yet.  */
 static int threads_executing;
 
-static int thread_alive (struct thread_info *);
-
 /* RAII type used to increase / decrease the refcount of each thread
    in a given list of threads.  */
 
@@ -679,14 +677,38 @@ any_live_thread_of_inferior (inferior *inf)
 }
 
 /* Return true if TP is an active thread.  */
-static int
-thread_alive (struct thread_info *tp)
+static bool
+thread_alive (thread_info *tp)
 {
   if (tp->state == THREAD_EXITED)
-    return 0;
-  if (!target_thread_alive (tp->ptid))
-    return 0;
-  return 1;
+    return false;
+
+  /* Ensure we're looking at the right target stack.  */
+  gdb_assert (tp->inf == current_inferior ());
+
+  return target_thread_alive (tp->ptid);
+}
+
+/* Switch to thread TP if it is alive.  Returns true if successfully
+   switched, false otherwise.  */
+
+static bool
+switch_to_thread_if_alive (thread_info *thr)
+{
+  scoped_restore_current_thread restore_thread;
+
+  /* Switch inferior first, so that we're looking at the right target
+     stack.  */
+  switch_to_inferior_no_thread (thr->inf);
+
+  if (thread_alive (thr))
+    {
+      switch_to_thread (thr);
+      restore_thread.dont_restore ();
+      return true;
+    }
+
+  return false;
 }
 
 /* See gdbthreads.h.  */
@@ -694,9 +716,15 @@ thread_alive (struct thread_info *tp)
 void
 prune_threads (void)
 {
+  scoped_restore_current_thread restore_thread;
+
   for (thread_info *tp : all_threads_safe ())
-    if (!thread_alive (tp))
-      delete_thread (tp);
+    {
+      switch_to_inferior_no_thread (tp->inf);
+
+      if (!thread_alive (tp))
+	delete_thread (tp);
+    }
 }
 
 /* See gdbthreads.h.  */
@@ -1037,6 +1065,9 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
     gdb::optional<ui_out_emit_list> list_emitter;
     gdb::optional<ui_out_emit_table> table_emitter;
 
+    /* We'll be switching threads temporarily below.  */
+    scoped_restore_current_thread restore_thread;
+
     if (uiout->is_mi_like_p ())
       list_emitter.emplace (uiout, "threads");
     else
@@ -1054,6 +1085,10 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
 
 	    if (!uiout->is_mi_like_p ())
 	      {
+		/* Switch inferiors so we're looking at the right
+		   target stack.  */
+		switch_to_inferior_no_thread (tp->inf);
+
 		target_id_col_width
 		  = std::max (target_id_col_width,
 			      thread_target_id_str (tp).size ());
@@ -1085,9 +1120,6 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
 	uiout->table_body ();
       }
 
-    /* We'll be switching threads temporarily.  */
-    scoped_restore_current_thread restore_thread;
-
     for (inferior *inf : all_inferiors ())
       for (thread_info *tp : inf->threads ())
 	{
@@ -1116,6 +1148,9 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
 	  if (show_global_ids || uiout->is_mi_like_p ())
 	    uiout->field_signed ("id", tp->global_num);
 
+	  /* Switch to the thread (and inferior / target).  */
+	  switch_to_thread (tp);
+
 	  /* For the CLI, we stuff everything into the target-id field.
 	     This is a gross hack to make the output come out looking
 	     correct.  The underlying problem here is that ui-out has no
@@ -1147,9 +1182,8 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads,
 	    uiout->text ("(running)\n");
 	  else
 	    {
-	      /* The switch below puts us at the top of the stack (leaf
+	      /* The switch above put us at the top of the stack (leaf
 		 frame).  */
-	      switch_to_thread (tp);
 	      print_stack_frame (get_selected_frame (NULL),
 				 /* For MI output, print frame level.  */
 				 uiout->is_mi_like_p (),
@@ -1662,7 +1696,7 @@ thread_apply_all_command (const char *cmd, int from_tty)
       scoped_restore_current_thread restore_thread;
 
       for (thread_info *thr : thr_list_cpy)
-	if (thread_alive (thr))
+	if (switch_to_thread_if_alive (thr))
 	  thr_try_catch_cmd (thr, cmd, from_tty, flags);
     }
 }
@@ -1819,7 +1853,7 @@ thread_apply_command (const char *tidlist, int from_tty)
 	  continue;
 	}
 
-      if (!thread_alive (tp))
+      if (!switch_to_thread_if_alive (tp))
 	{
 	  warning (_("Thread %s has terminated."), print_thread_id (tp));
 	  continue;
@@ -1987,11 +2021,9 @@ show_print_thread_events (struct ui_file *file, int from_tty,
 void
 thread_select (const char *tidstr, thread_info *tp)
 {
-  if (!thread_alive (tp))
+  if (!switch_to_thread_if_alive (tp))
     error (_("Thread ID %s has terminated."), tidstr);
 
-  switch_to_thread (tp);
-
   annotate_thread_changed ();
 
   /* Since the current thread may have changed, see if there is any


             reply	other threads:[~2020-01-11  4:36 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-11  4:36 gdb-buildbot [this message]
2020-01-11  4:36 ` Failures on Ubuntu-Aarch64-m64, branch master gdb-buildbot
2020-01-11  5:06 ` Failures on Ubuntu-Aarch64-native-gdbserver-m64, " gdb-buildbot
2020-01-12 15:35 ` Failures on Fedora-x86_64-cc-with-index, " gdb-buildbot
2020-01-12 15:47 ` Failures on Fedora-x86_64-m64, " gdb-buildbot
2020-01-12 15:49 ` Failures on Fedora-x86_64-native-extended-gdbserver-m32, " gdb-buildbot
2020-01-12 16:18 ` Failures on Fedora-x86_64-native-gdbserver-m32, " gdb-buildbot
2020-01-12 16:26 ` Failures on Fedora-x86_64-native-extended-gdbserver-m64, " gdb-buildbot
2020-01-12 16:26 ` Failures on Fedora-x86_64-native-gdbserver-m64, " gdb-buildbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f3f8ece4b1c77c925d1f1566df0bf632790a4d24@gdb-build \
    --to=gdb-buildbot@sergiodj.net \
    --cc=gdb-testers@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).