infrun.c:handle_inferior_event: Put all ecs->random_signal tests together.
authorPedro Alves <palves@redhat.com>
Mon, 28 Oct 2013 16:39:05 +0000 (16:39 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 28 Oct 2013 16:45:02 +0000 (16:45 +0000)
I recently added a new ecs->random_signal test after the "switch back to
stepped thread" code, and before the stepping tests.  Looking at
making process_event_stop_test a proper function, I realized it'd be
better to keep ecs->random_signal related code together.  To do that,
I needed to factor out the "switch back to stepped thread" code to a new
function, and call it in both the "random signal" and "not random
signal" paths.

gdb/
2013-10-28  Pedro Alves  <palves@redhat.com>

* infrun.c (switch_back_to_stepped_thread): New function, factored
out from handle_inferior_event.
(handle_inferior_event): Adjust to call
switch_back_to_stepped_thread.  Call it also at the tail of the
random signal handling, and return, instead of also handling
random signals just before the stepping tests.

gdb/ChangeLog
gdb/infrun.c

index 1a0328b..baf9a11 100644 (file)
@@ -1,5 +1,14 @@
 2013-10-28  Pedro Alves  <palves@redhat.com>
 
+       * infrun.c (switch_back_to_stepped_thread): New function, factored
+       out from handle_inferior_event.
+       (handle_inferior_event): Adjust to call
+       switch_back_to_stepped_thread.  Call it also at the tail of the
+       random signal handling, and return, instead of also handling
+       random signals just before the stepping tests.
+
+2013-10-28  Pedro Alves  <palves@redhat.com>
+
        * infrun.c (clear_stop_func): Delete.
        (handle_inferior_event): Don't call clear_stop_func and don't
        clear 'ecs->random_signal'.
index 8b1b668..0da90ec 100644 (file)
@@ -2439,6 +2439,7 @@ static void check_exception_resume (struct execution_control_state *,
 static void stop_stepping (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
 static void keep_going (struct execution_control_state *ecs);
+static int switch_back_to_stepped_thread (struct execution_control_state *ecs);
 
 /* Callback for iterate over threads.  If the thread is stopped, but
    the user/frontend doesn't know about that yet, go through
@@ -4398,6 +4399,16 @@ process_event_stop_test:
         (leaving the inferior at the step-resume-breakpoint without
         actually executing it).  Either way continue until the
         breakpoint is really hit.  */
+
+      if (!switch_back_to_stepped_thread (ecs))
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: random signal, keep going\n");
+
+         keep_going (ecs);
+       }
+      return;
     }
   else
     {
@@ -4628,84 +4639,8 @@ process_event_stop_test:
 
   /* In all-stop mode, if we're currently stepping but have stopped in
      some other thread, we need to switch back to the stepped thread.  */
-  if (!non_stop)
-    {
-      struct thread_info *tp;
-
-      tp = iterate_over_threads (currently_stepping_or_nexting_callback,
-                                ecs->event_thread);
-      if (tp)
-       {
-         /* However, if the current thread is blocked on some internal
-            breakpoint, and we simply need to step over that breakpoint
-            to get it going again, do that first.  */
-         if ((ecs->event_thread->control.trap_expected
-              && ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_TRAP)
-             || ecs->event_thread->stepping_over_breakpoint)
-           {
-             keep_going (ecs);
-             return;
-           }
-
-         /* 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);
-             keep_going (ecs);
-             return;
-           }
-
-         /* Otherwise, we no longer expect a trap in the current thread.
-            Clear the trap_expected flag before switching back -- this is
-            what keep_going would do as well, if we called it.  */
-         ecs->event_thread->control.trap_expected = 0;
-
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: switching back to stepped thread\n");
-
-         ecs->event_thread = tp;
-         ecs->ptid = tp->ptid;
-         context_switch (ecs->ptid);
-         keep_going (ecs);
-         return;
-       }
-    }
-
-  if (ecs->random_signal)
-    {
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                            "infrun: random signal, keep going\n");
-
-      /* Signal not stepping related.  */
-      keep_going (ecs);
-      return;
-    }
+  if (switch_back_to_stepped_thread (ecs))
+    return;
 
   if (ecs->event_thread->control.step_resume_breakpoint)
     {
@@ -5286,6 +5221,84 @@ process_event_stop_test:
   keep_going (ecs);
 }
 
+/* In all-stop mode, if we're currently stepping but have stopped in
+   some other thread, we may need to switch back to the stepped
+   thread.  Returns true we set the inferior running, false if we left
+   it stopped (and the event needs further processing).  */
+
+static int
+switch_back_to_stepped_thread (struct execution_control_state *ecs)
+{
+  if (!non_stop)
+    {
+      struct thread_info *tp;
+
+      tp = iterate_over_threads (currently_stepping_or_nexting_callback,
+                                ecs->event_thread);
+      if (tp)
+       {
+         /* However, if the current thread is blocked on some internal
+            breakpoint, and we simply need to step over that breakpoint
+            to get it going again, do that first.  */
+         if ((ecs->event_thread->control.trap_expected
+              && ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_TRAP)
+             || ecs->event_thread->stepping_over_breakpoint)
+           {
+             keep_going (ecs);
+             return 1;
+           }
+
+         /* 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);
+             keep_going (ecs);
+             return 1;
+           }
+
+         /* Otherwise, we no longer expect a trap in the current thread.
+            Clear the trap_expected flag before switching back -- this is
+            what keep_going would do as well, if we called it.  */
+         ecs->event_thread->control.trap_expected = 0;
+
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: switching back to stepped thread\n");
+
+         ecs->event_thread = tp;
+         ecs->ptid = tp->ptid;
+         context_switch (ecs->ptid);
+         keep_going (ecs);
+         return 1;
+       }
+    }
+  return 0;
+}
+
 /* Is thread TP in the middle of single-stepping?  */
 
 static int