Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 13/23] Factor out code to re-resume stepped thread
Date: Tue, 07 Apr 2015 12:59:00 -0000	[thread overview]
Message-ID: <1428410990-28560-14-git-send-email-palves@redhat.com> (raw)
In-Reply-To: <1428410990-28560-1-git-send-email-palves@redhat.com>

Just a code refactor, no funcionality change intended.

gdb/ChangeLog:
2015-04-07  Pedro Alves  <palves@redhat.com>

	* infrun.c (keep_going_stepped_thread): New function, factored out
	from ...
	(switch_back_to_stepped_thread): ... here.
---
 gdb/infrun.c | 198 ++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 106 insertions(+), 92 deletions(-)

diff --git a/gdb/infrun.c b/gdb/infrun.c
index 87bbe03..f24e8d7 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1879,6 +1879,7 @@ reset_ecs (struct execution_control_state *ecs, struct thread_info *tp)
 
 static void keep_going_pass (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
+static int keep_going_stepped_thread (struct thread_info *tp);
 static int thread_still_needs_step_over (struct thread_info *tp);
 
 /* Are there any pending step-over requests for INF?  If so, run one
@@ -5753,110 +5754,123 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
 
       if (stepping_thread != NULL)
 	{
-	  struct frame_info *frame;
-	  struct gdbarch *gdbarch;
-
-	  tp = stepping_thread;
-
-	  /* If the stepping thread exited, then don't try to switch
-	     back and resume it, which could fail in several different
-	     ways depending on the target.  Instead, just keep going.
-
-	     We can find a stepping dead thread in the thread list in
-	     two cases:
-
-	     - The target supports thread exit events, and when the
-	     target tries to delete the thread from the thread list,
-	     inferior_ptid pointed at the exiting thread.  In such
-	     case, calling delete_thread does not really remove the
-	     thread from the list; instead, the thread is left listed,
-	     with 'exited' state.
-
-	     - The target's debug interface does not support thread
-	     exit events, and so we have no idea whatsoever if the
-	     previously stepping thread is still alive.  For that
-	     reason, we need to synchronously query the target
-	     now.  */
-	  if (is_exited (tp->ptid)
-	      || !target_thread_alive (tp->ptid))
-	    {
-	      if (debug_infrun)
-		fprintf_unfiltered (gdb_stdlog,
-				    "infrun: not switching back to "
-				    "stepped thread, it has vanished\n");
-
-	      delete_thread (tp->ptid);
-	      return 0;
-	    }
-
 	  if (debug_infrun)
 	    fprintf_unfiltered (gdb_stdlog,
 				"infrun: switching back to stepped thread\n");
 
-	  reset_ecs (ecs, tp);
-	  switch_to_thread (tp->ptid);
+	  if (keep_going_stepped_thread (stepping_thread))
+	    {
+	      prepare_to_wait (ecs);
+	      return 1;
+	    }
+	}
+    }
 
-	  stop_pc = regcache_read_pc (get_thread_regcache (tp->ptid));
-	  frame = get_current_frame ();
-	  gdbarch = get_frame_arch (frame);
+  return 0;
+}
 
-	  /* If the PC of the thread we were trying to single-step has
-	     changed, then that thread has trapped or been signaled,
-	     but the event has not been reported to GDB yet.  Re-poll
-	     the target looking for this particular thread's event
-	     (i.e. temporarily enable schedlock) by:
+/* Set a previously stepped thread back to stepping.  Returns true on
+   success, false if the resume is not possible (e.g., the thread
+   vanished).  */
+
+static int
+keep_going_stepped_thread (struct thread_info *tp)
+{
+  struct frame_info *frame;
+  struct gdbarch *gdbarch;
+  struct execution_control_state ecss;
+  struct execution_control_state *ecs = &ecss;
 
-	       - setting a break at the current PC
-	       - resuming that particular thread, only (by setting
-		 trap expected)
+  /* If the stepping thread exited, then don't try to switch back and
+     resume it, which could fail in several different ways depending
+     on the target.  Instead, just keep going.
 
-	     This prevents us continuously moving the single-step
-	     breakpoint forward, one instruction at a time,
-	     overstepping.  */
+     We can find a stepping dead thread in the thread list in two
+     cases:
 
-	  if (stop_pc != tp->prev_pc)
-	    {
-	      ptid_t resume_ptid;
+     - The target supports thread exit events, and when the target
+       tries to delete the thread from the thread list, inferior_ptid
+       pointed at the exiting thread.  In such case, calling
+       delete_thread does not really remove the thread from the list;
+       instead, the thread is left listed, with 'exited' state.
 
-	      if (debug_infrun)
-		fprintf_unfiltered (gdb_stdlog,
-				    "infrun: expected thread advanced also "
-				    "(%s -> %s)\n",
-				    paddress (target_gdbarch (), tp->prev_pc),
-				    paddress (target_gdbarch (), stop_pc));
-
-	      /* Clear the info of the previous step-over, as it's no
-		 longer valid (if the thread was trying to step over a
-		 breakpoint, it has already succeeded).  It's what
-		 keep_going would do too, if we called it.  Do this
-		 before trying to insert the sss breakpoint, otherwise
-		 if we were previously trying to step over this exact
-		 address in another thread, the breakpoint is
-		 skipped.  */
-	      clear_step_over_info ();
-	      tp->control.trap_expected = 0;
-
-	      insert_single_step_breakpoint (get_frame_arch (frame),
-					     get_frame_address_space (frame),
-					     stop_pc);
-
-	      resume_ptid = user_visible_resume_ptid (tp->control.stepping_command);
-	      do_target_resume (resume_ptid, 0, GDB_SIGNAL_0);
-	      prepare_to_wait (ecs);
-	    }
-	  else
-	    {
-	      if (debug_infrun)
-		fprintf_unfiltered (gdb_stdlog,
-				    "infrun: expected thread still "
-				    "hasn't advanced\n");
-	      keep_going_pass (ecs);
-	    }
+       - The target's debug interface does not support thread exit
+         events, and so we have no idea whatsoever if the previously
+         stepping thread is still alive.  For that reason, we need to
+         synchronously query the target now.  */
 
-	  return 1;
-	}
+  if (is_exited (tp->ptid)
+      || !target_thread_alive (tp->ptid))
+    {
+      if (debug_infrun)
+	fprintf_unfiltered (gdb_stdlog,
+			    "infrun: not resuming previously  "
+			    "stepped thread, it has vanished\n");
+
+      delete_thread (tp->ptid);
+      return 0;
     }
-  return 0;
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+			"infrun: resuming previously stepped thread\n");
+
+  reset_ecs (ecs, tp);
+  switch_to_thread (tp->ptid);
+
+  stop_pc = regcache_read_pc (get_thread_regcache (tp->ptid));
+  frame = get_current_frame ();
+  gdbarch = get_frame_arch (frame);
+
+  /* If the PC of the thread we were trying to single-step has
+     changed, then that thread has trapped or been signaled, but the
+     event has not been reported to GDB yet.  Re-poll the target
+     looking for this particular thread's event (i.e. temporarily
+     enable schedlock) by:
+
+     - setting a break at the current PC
+     - resuming that particular thread, only (by setting trap
+     expected)
+
+     This prevents us continuously moving the single-step breakpoint
+     forward, one instruction at a time, overstepping.  */
+
+  if (stop_pc != tp->prev_pc)
+    {
+      ptid_t resume_ptid;
+
+      if (debug_infrun)
+	fprintf_unfiltered (gdb_stdlog,
+			    "infrun: expected thread advanced also (%s -> %s)\n",
+			    paddress (target_gdbarch (), tp->prev_pc),
+			    paddress (target_gdbarch (), stop_pc));
+
+      /* Clear the info of the previous step-over, as it's no longer
+	 valid (if the thread was trying to step over a breakpoint, it
+	 has already succeeded).  It's what keep_going would do too,
+	 if we called it.  Do this before trying to insert the sss
+	 breakpoint, otherwise if we were previously trying to step
+	 over this exact address in another thread, the breakpoint is
+	 skipped.  */
+      clear_step_over_info ();
+      tp->control.trap_expected = 0;
+
+      insert_single_step_breakpoint (get_frame_arch (frame),
+				     get_frame_address_space (frame),
+				     stop_pc);
+
+      resume_ptid = user_visible_resume_ptid (tp->control.stepping_command);
+      do_target_resume (resume_ptid, 0, GDB_SIGNAL_0);
+    }
+  else
+    {
+      if (debug_infrun)
+	fprintf_unfiltered (gdb_stdlog,
+			    "infrun: expected thread still hasn't advanced\n");
+
+      keep_going_pass (ecs);
+    }
+  return 1;
 }
 
 /* Is thread TP in the middle of single-stepping?  */
-- 
1.9.3


  parent reply	other threads:[~2015-04-07 12:59 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-07 12:49 [PATCH v2 00/23] All-stop on top of non-stop Pedro Alves
2015-04-07 12:50 ` [PATCH v2 11/23] Use keep_going in proceed and start_step_over too Pedro Alves
2015-04-07 12:50 ` [PATCH v2 12/23] Misc switch_back_to_stepped_thread cleanups Pedro Alves
2015-04-07 12:50 ` [PATCH v2 04/23] Change adjust_pc_after_break's prototype Pedro Alves
2015-04-07 12:50 ` [PATCH v2 09/23] Make gdb.threads/step-over-trips-on-watchpoint.exp effective on !x86 Pedro Alves
2015-04-07 12:50 ` [PATCH v2 20/23] PPC64: symbol-file + exec-file results in broken displaced stepping Pedro Alves
2015-04-07 12:50 ` [PATCH v2 21/23] PPC64: Fix gdb.arch/ppc64-atomic-inst.exp with " Pedro Alves
2015-04-07 12:50 ` [PATCH v2 16/23] Fix signal-while-stepping-over-bp-other-thread.exp on targets always in non-stop Pedro Alves
2015-04-07 12:50 ` [PATCH v2 23/23] native Linux: enable always non-stop by default Pedro Alves
2015-04-07 12:50 ` [PATCH v2 03/23] PR13858 - Can't do displaced stepping with no symbols Pedro Alves
2015-04-09 12:46   ` Pedro Alves
2015-04-07 12:50 ` [PATCH v2 19/23] Disable displaced stepping if trying it fails Pedro Alves
2015-04-07 12:50 ` [PATCH v2 22/23] S/390: displaced stepping and PC-relative RIL-b/RIL-c instructions Pedro Alves
2015-04-07 12:50 ` [PATCH v2 01/23] Fix gdb.base/sigstep.exp with displaced stepping on software single-step targets Pedro Alves
2015-04-10  9:56   ` Pedro Alves
2015-04-07 12:50 ` [PATCH v2 05/23] remote.c/all-stop: Implement TARGET_WAITKIND_NO_RESUMED and TARGET_WNOHANG Pedro Alves
2015-04-07 12:50 ` [PATCH v2 02/23] Fix and test "checkpoint" in non-stop mode Pedro Alves
2015-04-07 12:50 ` [PATCH v2 10/23] PPC64: Fix step-over-trips-on-watchpoint.exp with displaced stepping on Pedro Alves
2015-04-07 12:50 ` [PATCH v2 15/23] Implement all-stop on top of a target running non-stop mode Pedro Alves
2015-04-07 13:36   ` Eli Zaretskii
2015-04-08  9:34   ` Yao Qi
2015-04-08  9:53     ` Pedro Alves
2015-04-08 11:08       ` Pedro Alves
2015-04-08 19:35         ` Pedro Alves
2015-04-08 19:41           ` Pedro Alves
2015-04-07 12:55 ` [PATCH v2 17/23] Fix interrupt-noterm.exp on targets always in non-stop Pedro Alves
2015-04-07 12:57 ` [PATCH v2 08/23] Test step-over-{lands-on-breakpoint|trips-on-watchpoint}.exp with displaced stepping Pedro Alves
2015-04-10 14:54   ` Pedro Alves
2015-04-07 12:59 ` [PATCH v2 14/23] Teach non-stop to do in-line step-overs (stop all, step, restart) Pedro Alves
2015-04-07 12:59 ` [PATCH v2 07/23] Embed the pending step-over chain in thread_info objects Pedro Alves
2015-04-07 12:59 ` Pedro Alves [this message]
2015-04-07 13:30 ` [PATCH v2 18/23] Fix step-over-{trips-on-watchpoint|lands-on-breakpoint}.exp race Pedro Alves
2015-04-07 13:30 ` [PATCH v2 06/23] Make thread_still_needs_step_over consider stepping_over_watchpoint too Pedro Alves
2015-04-08  9:28   ` Yao Qi
2015-04-13 10:47     ` Pedro Alves
2015-04-08  9:45 ` [PATCH v2 00/23] All-stop on top of non-stop Yao Qi
2015-04-08 10:17   ` Pedro Alves
2015-04-08 10:30     ` Pedro Alves
2015-04-10  8:41     ` Yao Qi
2015-04-10  8:50       ` Pedro Alves
2015-04-10  8:22 ` Yao Qi
2015-04-10  8:34   ` Pedro Alves
2015-04-10  9:26     ` Yao Qi
2015-04-13 15:28       ` Pedro Alves
2015-04-13 16:16         ` Yao Qi
2015-04-13 16:23           ` Pedro Alves
2015-04-13 16:23           ` Pedro Alves

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=1428410990-28560-14-git-send-email-palves@redhat.com \
    --to=palves@redhat.com \
    --cc=gdb-patches@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