btrace: split record_btrace_step_thread
authorMarkus Metzger <markus.t.metzger@intel.com>
Mon, 24 Aug 2015 12:49:43 +0000 (14:49 +0200)
committerMarkus Metzger <markus.t.metzger@intel.com>
Fri, 18 Sep 2015 12:21:31 +0000 (14:21 +0200)
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.

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/ChangeLog
gdb/record-btrace.c

index e56028aea30066a4f5224994c79de953850acd9a..6b5de6cd9ff696c25d5eea8a40b1a2c2429931db 100644 (file)
@@ -1,3 +1,11 @@
+2015-09-18  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * 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.
+
 2015-09-18  Markus Metzger  <markus.t.metzger@intel.com>
 
        * record-btrace.c (record_btrace_replay_at_breakpoint): New.
index 77494baa54f73a4ec24a27b329a1520809cb4f08..fdf7afba8bba863bbba238810fffb295f489786a 100644 (file)
@@ -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),