This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 05/17] btrace: split record_btrace_step_thread


The code for BTHR_STEP and BTHR_CONT is fairly similar.  Extract the common
parts into a new function record_btrace_single_step_forward.  The function
returns TARGET_WAITKIND_SPURIOUS to indicate that the single-step completed
without triggering a trap.

Same for BTHR_RSTEP and BTHR_RCONT.

2015-09-11  Markus Metzger <markus.t.metzger@intel.com>

gdb/
	* record-btrace.c (btrace_step_spurious)
	(record_btrace_single_step_forward)
	(record_btrace_single_step_backward): New.
	(record_btrace_step_thread): Call record_btrace_single_step_forward
	and record_btrace_single_step_backward.
---
 gdb/record-btrace.c | 187 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 105 insertions(+), 82 deletions(-)

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 77494ba..fdf7afb 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1971,6 +1971,18 @@ btrace_step_stopped_on_request (void)
   return status;
 }
 
+/* Return a target_waitstatus indicating a spurious stop.  */
+
+static struct target_waitstatus
+btrace_step_spurious (void)
+{
+  struct target_waitstatus status;
+
+  status.kind = TARGET_WAITKIND_SPURIOUS;
+
+  return status;
+}
+
 /* Clear the record histories.  */
 
 static void
@@ -2011,20 +2023,86 @@ record_btrace_replay_at_breakpoint (struct thread_info *tp)
 					     &btinfo->stop_reason);
 }
 
-/* Step a single thread.  */
+/* Step one instruction in forward direction.  */
 
 static struct target_waitstatus
-record_btrace_step_thread (struct thread_info *tp)
+record_btrace_single_step_forward (struct thread_info *tp)
 {
   struct btrace_insn_iterator *replay, end;
   struct btrace_thread_info *btinfo;
-  enum btrace_thread_flag flags;
-  unsigned int steps;
 
+  btinfo = &tp->btrace;
+  replay = btinfo->replay;
+
+  /* We're done if we're not replaying.  */
+  if (replay == NULL)
+    return btrace_step_no_history ();
+
+  /* Skip gaps during replay.  */
+  do
+    {
+      unsigned int steps;
+
+      steps = btrace_insn_next (replay, 1);
+      if (steps == 0)
+	{
+	  record_btrace_stop_replaying (tp);
+	  return btrace_step_no_history ();
+	}
+    }
+  while (btrace_insn_get (replay) == NULL);
+
+  /* Determine the end of the instruction trace.  */
+  btrace_insn_end (&end, btinfo);
+
+  /* We stop replaying if we reached the end of the trace.  */
+  if (btrace_insn_cmp (replay, &end) == 0)
+    record_btrace_stop_replaying (tp);
+
+  return btrace_step_spurious ();
+}
+
+/* Step one instruction in backward direction.  */
+
+static struct target_waitstatus
+record_btrace_single_step_backward (struct thread_info *tp)
+{
+  struct btrace_insn_iterator *replay;
+  struct btrace_thread_info *btinfo;
 
   btinfo = &tp->btrace;
   replay = btinfo->replay;
 
+  /* Start replaying if we're not already doing so.  */
+  if (replay == NULL)
+    replay = record_btrace_start_replaying (tp);
+
+  /* If we can't step any further, we reached the end of the history.
+     Skip gaps during replay.  */
+  do
+    {
+      unsigned int steps;
+
+      steps = btrace_insn_prev (replay, 1);
+      if (steps == 0)
+	return btrace_step_no_history ();
+    }
+  while (btrace_insn_get (replay) == NULL);
+
+  return btrace_step_spurious ();
+}
+
+/* Step a single thread.  */
+
+static struct target_waitstatus
+record_btrace_step_thread (struct thread_info *tp)
+{
+  struct btrace_thread_info *btinfo;
+  struct target_waitstatus status;
+  enum btrace_thread_flag flags;
+
+  btinfo = &tp->btrace;
+
   flags = btinfo->flags & (BTHR_MOVE | BTHR_STOP);
   btinfo->flags &= ~(BTHR_MOVE | BTHR_STOP);
 
@@ -2045,110 +2123,55 @@ record_btrace_step_thread (struct thread_info *tp)
       return btrace_step_stopped_on_request ();
 
     case BTHR_STEP:
-      /* We're done if we're not replaying.  */
-      if (replay == NULL)
-	return btrace_step_no_history ();
-
-      /* Skip gaps during replay.  */
-      do
-	{
-	  steps = btrace_insn_next (replay, 1);
-	  if (steps == 0)
-	    {
-	      record_btrace_stop_replaying (tp);
-	      return btrace_step_no_history ();
-	    }
-	}
-      while (btrace_insn_get (replay) == NULL);
-
-      /* Determine the end of the instruction trace.  */
-      btrace_insn_end (&end, btinfo);
-
-      /* We stop replaying if we reached the end of the trace.  */
-      if (btrace_insn_cmp (replay, &end) == 0)
-	record_btrace_stop_replaying (tp);
+      status = record_btrace_single_step_forward (tp);
+      if (status.kind != TARGET_WAITKIND_SPURIOUS)
+	return status;
 
       return btrace_step_stopped ();
 
     case BTHR_RSTEP:
-      /* Start replaying if we're not already doing so.  */
-      if (replay == NULL)
-	replay = record_btrace_start_replaying (tp);
-
-      /* If we can't step any further, we reached the end of the history.
-	 Skip gaps during replay.  */
-      do
-	{
-	  steps = btrace_insn_prev (replay, 1);
-	  if (steps == 0)
-	    return btrace_step_no_history ();
-
-	}
-      while (btrace_insn_get (replay) == NULL);
+      status = record_btrace_single_step_backward (tp);
+      if (status.kind != TARGET_WAITKIND_SPURIOUS)
+	return status;
 
       return btrace_step_stopped ();
 
     case BTHR_CONT:
-      /* We're done if we're not replaying.  */
-      if (replay == NULL)
-	return btrace_step_no_history ();
-
-      /* Determine the end of the instruction trace.  */
-      btrace_insn_end (&end, btinfo);
-
       for (;;)
 	{
-	  const struct btrace_insn *insn;
+	  status = record_btrace_single_step_forward (tp);
+	  if (status.kind != TARGET_WAITKIND_SPURIOUS)
+	    return status;
 
-	  /* Skip gaps during replay.  */
-	  do
+	  if (btinfo->replay != NULL)
 	    {
-	      steps = btrace_insn_next (replay, 1);
-	      if (steps == 0)
-		{
-		  record_btrace_stop_replaying (tp);
-		  return btrace_step_no_history ();
-		}
+	      const struct btrace_insn *insn;
 
-	      insn = btrace_insn_get (replay);
-	    }
-	  while (insn == NULL);
+	      insn = btrace_insn_get (btinfo->replay);
+	      gdb_assert (insn != NULL);
 
-	  /* We stop replaying if we reached the end of the trace.  */
-	  if (btrace_insn_cmp (replay, &end) == 0)
-	    {
-	      record_btrace_stop_replaying (tp);
-	      return btrace_step_no_history ();
+	      DEBUG ("stepping %d (%s) ... %s", tp->num,
+		     target_pid_to_str (tp->ptid),
+		     core_addr_to_string_nz (insn->pc));
 	    }
 
-	  DEBUG ("stepping %d (%s) ... %s", tp->num,
-		 target_pid_to_str (tp->ptid),
-		 core_addr_to_string_nz (insn->pc));
-
 	  if (record_btrace_replay_at_breakpoint (tp))
 	    return btrace_step_stopped ();
 	}
 
     case BTHR_RCONT:
-      /* Start replaying if we're not already doing so.  */
-      if (replay == NULL)
-	replay = record_btrace_start_replaying (tp);
-
       for (;;)
 	{
 	  const struct btrace_insn *insn;
 
-	  /* If we can't step any further, we reached the end of the history.
-	     Skip gaps during replay.  */
-	  do
-	    {
-	      steps = btrace_insn_prev (replay, 1);
-	      if (steps == 0)
-		return btrace_step_no_history ();
+	  status = record_btrace_single_step_backward (tp);
+	  if (status.kind != TARGET_WAITKIND_SPURIOUS)
+	    return status;
 
-	      insn = btrace_insn_get (replay);
-	    }
-	  while (insn == NULL);
+	  gdb_assert (btinfo->replay != NULL);
+
+	  insn = btrace_insn_get (btinfo->replay);
+	  gdb_assert (insn != NULL);
 
 	  DEBUG ("reverse-stepping %d (%s) ... %s", tp->num,
 		 target_pid_to_str (tp->ptid),
-- 
1.8.3.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]