Factor out after-stop event handling code from stop_all_threads
authorPedro Alves <pedro@palves.net>
Sun, 13 Dec 2020 01:35:05 +0000 (01:35 +0000)
committerPedro Alves <pedro@palves.net>
Wed, 3 Feb 2021 01:15:00 +0000 (01:15 +0000)
This moves the code handling an event out of wait_one to a separate
function, to be used in another context in a following patch.

gdb/ChangeLog:

* infrun.c (handle_one): New function, factored out from ...
(stop_all_threads): ... here.

gdb/ChangeLog
gdb/infrun.c

index f11092d840c304a6a0d11485b77c64fdeb0214ae..920df3ec3125277e46c7d9315c5c255aaffbf150 100644 (file)
@@ -1,3 +1,8 @@
+2021-02-03  Pedro Alves  <pedro@palves.net>
+
+       * infrun.c (handle_one): New function, factored out from ...
+       (stop_all_threads): ... here.
+
 2021-02-03  Pedro Alves  <pedro@palves.net>
 
        * remote.c (remote_notif_stop_ack): Don't error out on
index 405b907856ae96ce740523eac0aeb044cd28fb0c..51d60f4962959b9d30f81a4e1da0afba9ed25507 100644 (file)
@@ -4560,6 +4560,156 @@ mark_non_executing_threads (process_stratum_target *target,
   set_resumed (target, mark_ptid, false);
 }
 
+/* Handle one event after stopping threads.  If the eventing thread
+   reports back any interesting event, we leave it pending.  If the
+   eventing thread was in the middle of a displaced step, we
+   cancel/finish it.  Returns true if there are no resumed threads
+   left in the target (thus there's no point in waiting further),
+   false otherwise.  */
+
+static bool
+handle_one (const wait_one_event &event)
+{
+  infrun_debug_printf
+    ("%s %s", target_waitstatus_to_string (&event.ws).c_str (),
+     target_pid_to_str (event.ptid).c_str ());
+
+  if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED)
+    {
+      /* All resumed threads exited.  */
+      return true;
+    }
+  else if (event.ws.kind == TARGET_WAITKIND_THREAD_EXITED
+          || event.ws.kind == TARGET_WAITKIND_EXITED
+          || event.ws.kind == TARGET_WAITKIND_SIGNALLED)
+    {
+      /* One thread/process exited/signalled.  */
+
+      thread_info *t = nullptr;
+
+      /* The target may have reported just a pid.  If so, try
+        the first non-exited thread.  */
+      if (event.ptid.is_pid ())
+       {
+         int pid  = event.ptid.pid ();
+         inferior *inf = find_inferior_pid (event.target, pid);
+         for (thread_info *tp : inf->non_exited_threads ())
+           {
+             t = tp;
+             break;
+           }
+
+         /* If there is no available thread, the event would
+            have to be appended to a per-inferior event list,
+            which does not exist (and if it did, we'd have
+            to adjust run control command to be able to
+            resume such an inferior).  We assert here instead
+            of going into an infinite loop.  */
+         gdb_assert (t != nullptr);
+
+         infrun_debug_printf
+           ("using %s", target_pid_to_str (t->ptid).c_str ());
+       }
+      else
+       {
+         t = find_thread_ptid (event.target, event.ptid);
+         /* Check if this is the first time we see this thread.
+            Don't bother adding if it individually exited.  */
+         if (t == nullptr
+             && event.ws.kind != TARGET_WAITKIND_THREAD_EXITED)
+           t = add_thread (event.target, event.ptid);
+       }
+
+      if (t != nullptr)
+       {
+         /* Set the threads as non-executing to avoid
+            another stop attempt on them.  */
+         switch_to_thread_no_regs (t);
+         mark_non_executing_threads (event.target, event.ptid,
+                                     event.ws);
+         save_waitstatus (t, &event.ws);
+         t->stop_requested = false;
+       }
+    }
+  else
+    {
+      thread_info *t = find_thread_ptid (event.target, event.ptid);
+      if (t == NULL)
+       t = add_thread (event.target, event.ptid);
+
+      t->stop_requested = 0;
+      t->executing = 0;
+      t->resumed = false;
+      t->control.may_range_step = 0;
+
+      /* This may be the first time we see the inferior report
+        a stop.  */
+      inferior *inf = find_inferior_ptid (event.target, event.ptid);
+      if (inf->needs_setup)
+       {
+         switch_to_thread_no_regs (t);
+         setup_inferior (0);
+       }
+
+      if (event.ws.kind == TARGET_WAITKIND_STOPPED
+         && event.ws.value.sig == GDB_SIGNAL_0)
+       {
+         /* We caught the event that we intended to catch, so
+            there's no event pending.  */
+         t->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
+         t->suspend.waitstatus_pending_p = 0;
+
+         if (displaced_step_finish (t, GDB_SIGNAL_0)
+             == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
+           {
+             /* Add it back to the step-over queue.  */
+             infrun_debug_printf
+               ("displaced-step of %s canceled",
+                target_pid_to_str (t->ptid).c_str ());
+
+             t->control.trap_expected = 0;
+             global_thread_step_over_chain_enqueue (t);
+           }
+       }
+      else
+       {
+         enum gdb_signal sig;
+         struct regcache *regcache;
+
+         infrun_debug_printf
+           ("target_wait %s, saving status for %d.%ld.%ld",
+            target_waitstatus_to_string (&event.ws).c_str (),
+            t->ptid.pid (), t->ptid.lwp (), t->ptid.tid ());
+
+         /* Record for later.  */
+         save_waitstatus (t, &event.ws);
+
+         sig = (event.ws.kind == TARGET_WAITKIND_STOPPED
+                ? event.ws.value.sig : GDB_SIGNAL_0);
+
+         if (displaced_step_finish (t, sig)
+             == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
+           {
+             /* Add it back to the step-over queue.  */
+             t->control.trap_expected = 0;
+             global_thread_step_over_chain_enqueue (t);
+           }
+
+         regcache = get_thread_regcache (t);
+         t->suspend.stop_pc = regcache_read_pc (regcache);
+
+         infrun_debug_printf ("saved stop_pc=%s for %s "
+                              "(currently_stepping=%d)",
+                              paddress (target_gdbarch (),
+                                        t->suspend.stop_pc),
+                              target_pid_to_str (t->ptid).c_str (),
+                              currently_stepping (t));
+       }
+    }
+
+  return false;
+}
+
 /* See infrun.h.  */
 
 void
@@ -4673,144 +4823,8 @@ stop_all_threads (void)
          for (int i = 0; i < waits_needed; i++)
            {
              wait_one_event event = wait_one ();
-
-             infrun_debug_printf
-               ("%s %s", target_waitstatus_to_string (&event.ws).c_str (),
-                target_pid_to_str (event.ptid).c_str ());
-
-             if (event.ws.kind == TARGET_WAITKIND_NO_RESUMED)
-               {
-                 /* All resumed threads exited.  */
-                 break;
-               }
-             else if (event.ws.kind == TARGET_WAITKIND_THREAD_EXITED
-                      || event.ws.kind == TARGET_WAITKIND_EXITED
-                      || event.ws.kind == TARGET_WAITKIND_SIGNALLED)
-               {
-                 /* One thread/process exited/signalled.  */
-
-                 thread_info *t = nullptr;
-
-                 /* The target may have reported just a pid.  If so, try
-                    the first non-exited thread.  */
-                 if (event.ptid.is_pid ())
-                   {
-                     int pid  = event.ptid.pid ();
-                     inferior *inf = find_inferior_pid (event.target, pid);
-                     for (thread_info *tp : inf->non_exited_threads ())
-                       {
-                         t = tp;
-                         break;
-                       }
-
-                     /* If there is no available thread, the event would
-                        have to be appended to a per-inferior event list,
-                        which does not exist (and if it did, we'd have
-                        to adjust run control command to be able to
-                        resume such an inferior).  We assert here instead
-                        of going into an infinite loop.  */
-                     gdb_assert (t != nullptr);
-
-                     infrun_debug_printf
-                       ("using %s", target_pid_to_str (t->ptid).c_str ());
-                   }
-                 else
-                   {
-                     t = find_thread_ptid (event.target, event.ptid);
-                     /* Check if this is the first time we see this thread.
-                        Don't bother adding if it individually exited.  */
-                     if (t == nullptr
-                         && event.ws.kind != TARGET_WAITKIND_THREAD_EXITED)
-                       t = add_thread (event.target, event.ptid);
-                   }
-
-                 if (t != nullptr)
-                   {
-                     /* Set the threads as non-executing to avoid
-                        another stop attempt on them.  */
-                     switch_to_thread_no_regs (t);
-                     mark_non_executing_threads (event.target, event.ptid,
-                                                 event.ws);
-                     save_waitstatus (t, &event.ws);
-                     t->stop_requested = false;
-                   }
-               }
-             else
-               {
-                 thread_info *t = find_thread_ptid (event.target, event.ptid);
-                 if (t == NULL)
-                   t = add_thread (event.target, event.ptid);
-
-                 t->stop_requested = 0;
-                 t->executing = 0;
-                 t->resumed = false;
-                 t->control.may_range_step = 0;
-
-                 /* This may be the first time we see the inferior report
-                    a stop.  */
-                 inferior *inf = find_inferior_ptid (event.target, event.ptid);
-                 if (inf->needs_setup)
-                   {
-                     switch_to_thread_no_regs (t);
-                     setup_inferior (0);
-                   }
-
-                 if (event.ws.kind == TARGET_WAITKIND_STOPPED
-                     && event.ws.value.sig == GDB_SIGNAL_0)
-                   {
-                     /* We caught the event that we intended to catch, so
-                        there's no event pending.  */
-                     t->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
-                     t->suspend.waitstatus_pending_p = 0;
-
-                     if (displaced_step_finish (t, GDB_SIGNAL_0)
-                         == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
-                       {
-                         /* Add it back to the step-over queue.  */
-                         infrun_debug_printf
-                           ("displaced-step of %s canceled: adding back to "
-                            "the step-over queue",
-                             target_pid_to_str (t->ptid).c_str ());
-
-                         t->control.trap_expected = 0;
-                         global_thread_step_over_chain_enqueue (t);
-                       }
-                   }
-                 else
-                   {
-                     enum gdb_signal sig;
-                     struct regcache *regcache;
-
-                     infrun_debug_printf
-                       ("target_wait %s, saving status for %d.%ld.%ld",
-                        target_waitstatus_to_string (&event.ws).c_str (),
-                        t->ptid.pid (), t->ptid.lwp (), t->ptid.tid ());
-
-                     /* Record for later.  */
-                     save_waitstatus (t, &event.ws);
-
-                     sig = (event.ws.kind == TARGET_WAITKIND_STOPPED
-                            ? event.ws.value.sig : GDB_SIGNAL_0);
-
-                     if (displaced_step_finish (t, sig)
-                         == DISPLACED_STEP_FINISH_STATUS_NOT_EXECUTED)
-                       {
-                         /* Add it back to the step-over queue.  */
-                         t->control.trap_expected = 0;
-                         global_thread_step_over_chain_enqueue (t);
-                       }
-
-                     regcache = get_thread_regcache (t);
-                     t->suspend.stop_pc = regcache_read_pc (regcache);
-
-                     infrun_debug_printf ("saved stop_pc=%s for %s "
-                                          "(currently_stepping=%d)",
-                                          paddress (target_gdbarch (),
-                                                    t->suspend.stop_pc),
-                                          target_pid_to_str (t->ptid).c_str (),
-                                          currently_stepping (t));
-                   }
-               }
+             if (handle_one (event))
+               break;
            }
        }
     }