gdb/testsuite: don't use source tree as temporary HOME directory
[binutils-gdb.git] / gdb / infrun.c
index 71bf10f4c5eae5fc64fcbde41f98d20fd2e5766c..90bab8d984f5b1bd557e8cb58faf04c17f38a79e 100644 (file)
@@ -426,7 +426,7 @@ follow_fork_inferior (bool follow_child, bool detach_fork)
 Can not resume the parent process over vfork in the foreground while\n\
 holding the child stopped.  Try \"set detach-on-fork\" or \
 \"set schedule-multiple\".\n"));
-      return 1;
+      return true;
     }
 
   if (!follow_child)
@@ -477,7 +477,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
          set_current_inferior (child_inf);
          switch_to_no_thread ();
          child_inf->symfile_flags = SYMFILE_NO_READ;
-         push_target (parent_inf->process_target ());
+         child_inf->push_target (parent_inf->process_target ());
          thread_info *child_thr
            = add_thread_silent (child_inf->process_target (), child_ptid);
 
@@ -627,7 +627,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
           informing the solib layer about this new process.  */
 
        set_current_inferior (child_inf);
-       push_target (target);
+       child_inf->push_target (target);
       }
 
       thread_info *child_thr = add_thread_silent (target, child_ptid);
@@ -662,7 +662,9 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
       switch_to_thread (child_thr);
     }
 
-  return target_follow_fork (follow_child, detach_fork);
+  target_follow_fork (follow_child, detach_fork);
+
+  return false;
 }
 
 /* Tell the target to follow the fork we're stopped at.  Returns true
@@ -1183,7 +1185,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
 
       inferior *org_inferior = current_inferior ();
       switch_to_inferior_no_thread (inf);
-      push_target (org_inferior->process_target ());
+      inf->push_target (org_inferior->process_target ());
       thread_info *thr = add_thread (inf->process_target (), ptid);
       switch_to_thread (thr);
     }
@@ -1261,15 +1263,15 @@ struct step_over_info
      and address of the instruction the breakpoint is set at.  We'll
      skip inserting all breakpoints here.  Valid iff ASPACE is
      non-NULL.  */
-  const address_space *aspace;
-  CORE_ADDR address;
+  const address_space *aspace = nullptr;
+  CORE_ADDR address = 0;
 
   /* The instruction being stepped over triggers a nonsteppable
      watchpoint.  If true, we'll skip inserting watchpoints.  */
-  int nonsteppable_watchpoint_p;
+  int nonsteppable_watchpoint_p = 0;
 
   /* The thread's global number.  */
-  int thread;
+  int thread = -1;
 };
 
 /* The step-over info of the location that is being stepped over.
@@ -1777,7 +1779,7 @@ displaced_step_finish (thread_info *event_thread, enum gdb_signal signal)
   /* Fixup may need to read memory/registers.  Switch to the thread
      that we're fixing up.  Also, target_stopped_by_watchpoint checks
      the current thread, and displaced_step_restore performs ptid-dependent
-     memory accesses using current_inferior() and current_top_target().  */
+     memory accesses using current_inferior().  */
   switch_to_thread (event_thread);
 
   displaced_step_reset_cleanup cleanup (displaced);
@@ -2030,7 +2032,8 @@ set_schedlock_func (const char *args, int from_tty, struct cmd_list_element *c)
   if (!target_can_lock_scheduler ())
     {
       scheduler_mode = schedlock_off;
-      error (_("Target '%s' cannot support this command."), target_shortname);
+      error (_("Target '%s' cannot support this command."),
+            target_shortname ());
     }
 }
 
@@ -2172,8 +2175,6 @@ do_target_resume (ptid_t resume_ptid, bool step, enum gdb_signal sig)
 
   target_resume (resume_ptid, step, sig);
 
-  target_commit_resume ();
-
   if (target_can_async_p ())
     target_async (1);
 }
@@ -2760,28 +2761,220 @@ schedlock_applies (struct thread_info *tp)
                                            execution_direction)));
 }
 
-/* Calls target_commit_resume on all targets.  */
+/* Set process_stratum_target::COMMIT_RESUMED_STATE in all target
+   stacks that have threads executing and don't have threads with
+   pending events.  */
 
 static void
-commit_resume_all_targets ()
+maybe_set_commit_resumed_all_targets ()
 {
   scoped_restore_current_thread restore_thread;
 
-  /* Map between process_target and a representative inferior.  This
-     is to avoid committing a resume in the same target more than
-     once.  Resumptions must be idempotent, so this is an
-     optimization.  */
-  std::unordered_map<process_stratum_target *, inferior *> conn_inf;
-
   for (inferior *inf : all_non_exited_inferiors ())
-    if (inf->has_execution ())
-      conn_inf[inf->process_target ()] = inf;
+    {
+      process_stratum_target *proc_target = inf->process_target ();
+
+      if (proc_target->commit_resumed_state)
+       {
+         /* We already set this in a previous iteration, via another
+            inferior sharing the process_stratum target.  */
+         continue;
+       }
+
+      /* If the target has no resumed threads, it would be useless to
+        ask it to commit the resumed threads.  */
+      if (!proc_target->threads_executing)
+       {
+         infrun_debug_printf ("not requesting commit-resumed for target "
+                              "%s, no resumed threads",
+                              proc_target->shortname ());
+         continue;
+       }
+
+      /* As an optimization, if a thread from this target has some
+        status to report, handle it before requiring the target to
+        commit its resumed threads: handling the status might lead to
+        resuming more threads.  */
+      bool has_thread_with_pending_status = false;
+      for (thread_info *thread : all_non_exited_threads (proc_target))
+       if (thread->resumed && thread->suspend.waitstatus_pending_p)
+         {
+           has_thread_with_pending_status = true;
+           break;
+         }
+
+      if (has_thread_with_pending_status)
+       {
+         infrun_debug_printf ("not requesting commit-resumed for target %s, a"
+                              " thread has a pending waitstatus",
+                              proc_target->shortname ());
+         continue;
+       }
+
+      switch_to_inferior_no_thread (inf);
+
+      if (target_has_pending_events ())
+       {
+         infrun_debug_printf ("not requesting commit-resumed for target %s, "
+                              "target has pending events",
+                              proc_target->shortname ());
+         continue;
+       }
+
+      infrun_debug_printf ("enabling commit-resumed for target %s",
+                          proc_target->shortname ());
+
+      proc_target->commit_resumed_state = true;
+    }
+}
+
+/* See infrun.h.  */
+
+void
+maybe_call_commit_resumed_all_targets ()
+{
+  scoped_restore_current_thread restore_thread;
 
-  for (const auto &ci : conn_inf)
+  for (inferior *inf : all_non_exited_inferiors ())
     {
-      inferior *inf = ci.second;
+      process_stratum_target *proc_target = inf->process_target ();
+
+      if (!proc_target->commit_resumed_state)
+       continue;
+
       switch_to_inferior_no_thread (inf);
-      target_commit_resume ();
+
+      infrun_debug_printf ("calling commit_resumed for target %s",
+                          proc_target->shortname());
+
+      target_commit_resumed ();
+    }
+}
+
+/* To track nesting of scoped_disable_commit_resumed objects, ensuring
+   that only the outermost one attempts to re-enable
+   commit-resumed.  */
+static bool enable_commit_resumed = true;
+
+/* See infrun.h.  */
+
+scoped_disable_commit_resumed::scoped_disable_commit_resumed
+  (const char *reason)
+  : m_reason (reason),
+    m_prev_enable_commit_resumed (enable_commit_resumed)
+{
+  infrun_debug_printf ("reason=%s", m_reason);
+
+  enable_commit_resumed = false;
+
+  for (inferior *inf : all_non_exited_inferiors ())
+    {
+      process_stratum_target *proc_target = inf->process_target ();
+
+      if (m_prev_enable_commit_resumed)
+       {
+         /* This is the outermost instance: force all
+            COMMIT_RESUMED_STATE to false.  */
+         proc_target->commit_resumed_state = false;
+       }
+      else
+       {
+         /* This is not the outermost instance, we expect
+            COMMIT_RESUMED_STATE to have been cleared by the
+            outermost instance.  */
+         gdb_assert (!proc_target->commit_resumed_state);
+       }
+    }
+}
+
+/* See infrun.h.  */
+
+void
+scoped_disable_commit_resumed::reset ()
+{
+  if (m_reset)
+    return;
+  m_reset = true;
+
+  infrun_debug_printf ("reason=%s", m_reason);
+
+  gdb_assert (!enable_commit_resumed);
+
+  enable_commit_resumed = m_prev_enable_commit_resumed;
+
+  if (m_prev_enable_commit_resumed)
+    {
+      /* This is the outermost instance, re-enable
+         COMMIT_RESUMED_STATE on the targets where it's possible.  */
+      maybe_set_commit_resumed_all_targets ();
+    }
+  else
+    {
+      /* This is not the outermost instance, we expect
+        COMMIT_RESUMED_STATE to still be false.  */
+      for (inferior *inf : all_non_exited_inferiors ())
+       {
+         process_stratum_target *proc_target = inf->process_target ();
+         gdb_assert (!proc_target->commit_resumed_state);
+       }
+    }
+}
+
+/* See infrun.h.  */
+
+scoped_disable_commit_resumed::~scoped_disable_commit_resumed ()
+{
+  reset ();
+}
+
+/* See infrun.h.  */
+
+void
+scoped_disable_commit_resumed::reset_and_commit ()
+{
+  reset ();
+  maybe_call_commit_resumed_all_targets ();
+}
+
+/* See infrun.h.  */
+
+scoped_enable_commit_resumed::scoped_enable_commit_resumed
+  (const char *reason)
+  : m_reason (reason),
+    m_prev_enable_commit_resumed (enable_commit_resumed)
+{
+  infrun_debug_printf ("reason=%s", m_reason);
+
+  if (!enable_commit_resumed)
+    {
+      enable_commit_resumed = true;
+
+      /* Re-enable COMMIT_RESUMED_STATE on the targets where it's
+        possible.  */
+      maybe_set_commit_resumed_all_targets ();
+
+      maybe_call_commit_resumed_all_targets ();
+    }
+}
+
+/* See infrun.h.  */
+
+scoped_enable_commit_resumed::~scoped_enable_commit_resumed ()
+{
+  infrun_debug_printf ("reason=%s", m_reason);
+
+  gdb_assert (enable_commit_resumed);
+
+  enable_commit_resumed = m_prev_enable_commit_resumed;
+
+  if (!enable_commit_resumed)
+    {
+      /* Force all COMMIT_RESUMED_STATE back to false.  */
+      for (inferior *inf : all_non_exited_inferiors ())
+       {
+         process_stratum_target *proc_target = inf->process_target ();
+         proc_target->commit_resumed_state = false;
+       }
     }
 }
 
@@ -2809,7 +3002,7 @@ check_multi_target_resumption (process_stratum_target *resume_target)
         always-non-stop mode.  */
       inferior *first_not_non_stop = nullptr;
 
-      for (inferior *inf : all_non_exited_inferiors (resume_target))
+      for (inferior *inf : all_non_exited_inferiors ())
        {
          switch_to_inferior_no_thread (inf);
 
@@ -3005,7 +3198,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
   cur_thr->prev_pc = regcache_read_pc_protected (regcache);
 
   {
-    scoped_restore save_defer_tc = make_scoped_defer_target_commit_resume ();
+    scoped_disable_commit_resumed disable_commit_resumed ("proceeding");
 
     started = start_step_over ();
 
@@ -3073,9 +3266,9 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
        if (!ecs->wait_some_more)
          error (_("Command aborted."));
       }
-  }
 
-  commit_resume_all_targets ();
+    disable_commit_resumed.reset_and_commit ();
+  }
 
   finish_state.release ();
 
@@ -3566,6 +3759,7 @@ struct wait_one_event
 };
 
 static bool handle_one (const wait_one_event &event);
+static void restart_threads (struct thread_info *event_thread);
 
 /* Prepare and stabilize the inferior for detaching it.  E.g.,
    detaching while a thread is displaced stepping is a recipe for
@@ -3593,6 +3787,35 @@ prepare_for_detach (void)
        global_thread_step_over_chain_remove (tp);
     }
 
+  /* If we were already in the middle of an inline step-over, and the
+     thread stepping belongs to the inferior we're detaching, we need
+     to restart the threads of other inferiors.  */
+  if (step_over_info.thread != -1)
+    {
+      infrun_debug_printf ("inline step-over in-process while detaching");
+
+      thread_info *thr = find_thread_global_id (step_over_info.thread);
+      if (thr->inf == inf)
+       {
+         /* Since we removed threads of INF from the step-over chain,
+            we know this won't start a step-over for INF.  */
+         clear_step_over_info ();
+
+         if (target_is_non_stop_p ())
+           {
+             /* Start a new step-over in another thread if there's
+                one that needs it.  */
+             start_step_over ();
+
+             /* Restart all other threads (except the
+                previously-stepping thread, since that one is still
+                running).  */
+             if (!step_over_info_valid_p ())
+               restart_threads (thr);
+           }
+       }
+    }
+
   if (displaced_step_in_progress (inf))
     {
       infrun_debug_printf ("displaced-stepping in-process while detaching");
@@ -3847,8 +4070,16 @@ fetch_inferior_event ()
       = make_scoped_restore (&execution_direction,
                             target_execution_direction ());
 
+    /* Allow targets to pause their resumed threads while we handle
+       the event.  */
+    scoped_disable_commit_resumed disable_commit_resumed ("handling event");
+
     if (!do_target_wait (minus_one_ptid, ecs, TARGET_WNOHANG))
-      return;
+      {
+       infrun_debug_printf ("do_target_wait returned no event");
+       disable_commit_resumed.reset_and_commit ();
+       return;
+      }
 
     gdb_assert (ecs->ws.kind != TARGET_WAITKIND_IGNORE);
 
@@ -3939,6 +4170,8 @@ fetch_inferior_event ()
     /* No error, don't finish the thread states yet.  */
     finish_state.release ();
 
+    disable_commit_resumed.reset_and_commit ();
+
     /* This scope is used to ensure that readline callbacks are
        reinstalled here.  */
   }
@@ -4470,12 +4703,11 @@ save_waitstatus (struct thread_info *tp, const target_waitstatus *ws)
   tp->suspend.waitstatus = *ws;
   tp->suspend.waitstatus_pending_p = 1;
 
-  struct regcache *regcache = get_thread_regcache (tp);
-  const address_space *aspace = regcache->aspace ();
-
   if (ws->kind == TARGET_WAITKIND_STOPPED
       && ws->value.sig == GDB_SIGNAL_TRAP)
     {
+      struct regcache *regcache = get_thread_regcache (tp);
+      const address_space *aspace = regcache->aspace ();
       CORE_ADDR pc = regcache_read_pc (regcache);
 
       adjust_pc_after_break (tp, &tp->suspend.waitstatus);
@@ -4993,8 +5225,6 @@ handle_inferior_event (struct execution_control_state *ecs)
      end.  */
   scoped_value_mark free_values;
 
-  enum stop_kind stop_soon;
-
   infrun_debug_printf ("%s", target_waitstatus_to_string (&ecs->ws).c_str ());
 
   if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
@@ -5088,80 +5318,82 @@ handle_inferior_event (struct execution_control_state *ecs)
   switch (ecs->ws.kind)
     {
     case TARGET_WAITKIND_LOADED:
-      context_switch (ecs);
-      /* Ignore gracefully during startup of the inferior, as it might
-        be the shell which has just loaded some objects, otherwise
-        add the symbols for the newly loaded objects.  Also ignore at
-        the beginning of an attach or remote session; we will query
-        the full list of libraries once the connection is
-        established.  */
-
-      stop_soon = get_inferior_stop_soon (ecs);
-      if (stop_soon == NO_STOP_QUIETLY)
-       {
-         struct regcache *regcache;
-
-         regcache = get_thread_regcache (ecs->event_thread);
+      {
+       context_switch (ecs);
+       /* Ignore gracefully during startup of the inferior, as it might
+          be the shell which has just loaded some objects, otherwise
+          add the symbols for the newly loaded objects.  Also ignore at
+          the beginning of an attach or remote session; we will query
+          the full list of libraries once the connection is
+          established.  */
+
+       stop_kind stop_soon = get_inferior_stop_soon (ecs);
+       if (stop_soon == NO_STOP_QUIETLY)
+         {
+           struct regcache *regcache;
 
-         handle_solib_event ();
+           regcache = get_thread_regcache (ecs->event_thread);
 
-         ecs->event_thread->control.stop_bpstat
-           = bpstat_stop_status (regcache->aspace (),
-                                 ecs->event_thread->suspend.stop_pc,
-                                 ecs->event_thread, &ecs->ws);
+           handle_solib_event ();
 
-         if (handle_stop_requested (ecs))
-           return;
+           ecs->event_thread->control.stop_bpstat
+             = bpstat_stop_status (regcache->aspace (),
+                                   ecs->event_thread->suspend.stop_pc,
+                                   ecs->event_thread, &ecs->ws);
 
-         if (bpstat_causes_stop (ecs->event_thread->control.stop_bpstat))
-           {
-             /* A catchpoint triggered.  */
-             process_event_stop_test (ecs);
+           if (handle_stop_requested (ecs))
              return;
-           }
 
-         /* If requested, stop when the dynamic linker notifies
-            gdb of events.  This allows the user to get control
-            and place breakpoints in initializer routines for
-            dynamically loaded objects (among other things).  */
-         ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
-         if (stop_on_solib_events)
-           {
-             /* Make sure we print "Stopped due to solib-event" in
-                normal_stop.  */
-             stop_print_frame = true;
+           if (bpstat_causes_stop (ecs->event_thread->control.stop_bpstat))
+             {
+               /* A catchpoint triggered.  */
+               process_event_stop_test (ecs);
+               return;
+             }
 
-             stop_waiting (ecs);
-             return;
-           }
-       }
+           /* If requested, stop when the dynamic linker notifies
+              gdb of events.  This allows the user to get control
+              and place breakpoints in initializer routines for
+              dynamically loaded objects (among other things).  */
+           ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+           if (stop_on_solib_events)
+             {
+               /* Make sure we print "Stopped due to solib-event" in
+                  normal_stop.  */
+               stop_print_frame = true;
 
-      /* If we are skipping through a shell, or through shared library
-        loading that we aren't interested in, resume the program.  If
-        we're running the program normally, also resume.  */
-      if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY)
-       {
-         /* Loading of shared libraries might have changed breakpoint
-            addresses.  Make sure new breakpoints are inserted.  */
-         if (stop_soon == NO_STOP_QUIETLY)
-           insert_breakpoints ();
-         resume (GDB_SIGNAL_0);
-         prepare_to_wait (ecs);
-         return;
-       }
+               stop_waiting (ecs);
+               return;
+             }
+         }
 
-      /* But stop if we're attaching or setting up a remote
-        connection.  */
-      if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
-         || stop_soon == STOP_QUIETLY_REMOTE)
-       {
-         infrun_debug_printf ("quietly stopped");
-         stop_waiting (ecs);
-         return;
-       }
+       /* If we are skipping through a shell, or through shared library
+          loading that we aren't interested in, resume the program.  If
+          we're running the program normally, also resume.  */
+       if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY)
+         {
+           /* Loading of shared libraries might have changed breakpoint
+              addresses.  Make sure new breakpoints are inserted.  */
+           if (stop_soon == NO_STOP_QUIETLY)
+             insert_breakpoints ();
+           resume (GDB_SIGNAL_0);
+           prepare_to_wait (ecs);
+           return;
+         }
 
-      internal_error (__FILE__, __LINE__,
-                     _("unhandled stop_soon: %d"), (int) stop_soon);
+       /* But stop if we're attaching or setting up a remote
+          connection.  */
+       if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
+           || stop_soon == STOP_QUIETLY_REMOTE)
+         {
+           infrun_debug_printf ("quietly stopped");
+           stop_waiting (ecs);
+           return;
+         }
+
+       internal_error (__FILE__, __LINE__,
+                       _("unhandled stop_soon: %d"), (int) stop_soon);
+      }
 
     case TARGET_WAITKIND_SPURIOUS:
       if (handle_stop_requested (ecs))
@@ -5528,6 +5760,13 @@ restart_threads (struct thread_info *event_thread)
 
   for (thread_info *tp : all_non_exited_threads ())
     {
+      if (tp->inf->detaching)
+       {
+         infrun_debug_printf ("restart threads: [%s] inferior detaching",
+                              target_pid_to_str (tp->ptid).c_str ());
+         continue;
+       }
+
       switch_to_thread_no_regs (tp);
 
       if (tp == event_thread)
@@ -5775,7 +6014,8 @@ handle_signal_stop (struct execution_control_state *ecs)
 
          infrun_debug_printf ("stopped by watchpoint");
 
-         if (target_stopped_data_address (current_top_target (), &addr))
+         if (target_stopped_data_address (current_inferior ()->top_target (),
+                                          &addr))
            infrun_debug_printf ("stopped data address=%s",
                                 paddress (reg_gdbarch, addr));
          else
@@ -7073,6 +7313,9 @@ process_event_stop_test (struct execution_control_state *ecs)
   keep_going (ecs);
 }
 
+static bool restart_stepped_thread (process_stratum_target *resume_target,
+                                   ptid_t resume_ptid);
+
 /* 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
@@ -7083,8 +7326,6 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
 {
   if (!target_is_non_stop_p ())
     {
-      struct thread_info *stepping_thread;
-
       /* If any thread is blocked on some internal breakpoint, and we
         simply need to step over that breakpoint to get it going
         again, do that first.  */
@@ -7147,78 +7388,136 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
       if (!signal_program[ecs->event_thread->suspend.stop_signal])
        ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
 
-      /* Do all pending step-overs before actually proceeding with
-        step/next/etc.  */
-      if (start_step_over ())
+      if (restart_stepped_thread (ecs->target, ecs->ptid))
        {
          prepare_to_wait (ecs);
          return true;
        }
 
-      /* Look for the stepping/nexting thread.  */
-      stepping_thread = NULL;
+      switch_to_thread (ecs->event_thread);
+    }
 
-      for (thread_info *tp : all_non_exited_threads ())
-       {
-         switch_to_thread_no_regs (tp);
+  return false;
+}
 
-         /* Ignore threads of processes the caller is not
-            resuming.  */
-         if (!sched_multi
-             && (tp->inf->process_target () != ecs->target
-                 || tp->inf->pid != ecs->ptid.pid ()))
-           continue;
+/* Look for the thread that was stepping, and resume it.
+   RESUME_TARGET / RESUME_PTID indicate the set of threads the caller
+   is resuming.  Return true if a thread was started, false
+   otherwise.  */
 
-         /* When stepping over a breakpoint, we lock all threads
-            except the one that needs to move past the breakpoint.
-            If a non-event thread has this set, the "incomplete
-            step-over" check above should have caught it earlier.  */
-         if (tp->control.trap_expected)
-           {
-             internal_error (__FILE__, __LINE__,
-                             "[%s] has inconsistent state: "
-                             "trap_expected=%d\n",
-                             target_pid_to_str (tp->ptid).c_str (),
-                             tp->control.trap_expected);
-           }
+static bool
+restart_stepped_thread (process_stratum_target *resume_target,
+                       ptid_t resume_ptid)
+{
+  /* Do all pending step-overs before actually proceeding with
+     step/next/etc.  */
+  if (start_step_over ())
+    return true;
 
-         /* Did we find the stepping thread?  */
-         if (tp->control.step_range_end)
-           {
-             /* Yep.  There should only one though.  */
-             gdb_assert (stepping_thread == NULL);
+  for (thread_info *tp : all_threads_safe ())
+    {
+      if (tp->state == THREAD_EXITED)
+       continue;
+
+      if (tp->suspend.waitstatus_pending_p)
+       continue;
 
-             /* The event thread is handled at the top, before we
-                enter this loop.  */
-             gdb_assert (tp != ecs->event_thread);
+      /* Ignore threads of processes the caller is not
+        resuming.  */
+      if (!sched_multi
+         && (tp->inf->process_target () != resume_target
+             || tp->inf->pid != resume_ptid.pid ()))
+       continue;
 
-             /* If some thread other than the event thread is
-                stepping, then scheduler locking can't be in effect,
-                otherwise we wouldn't have resumed the current event
-                thread in the first place.  */
-             gdb_assert (!schedlock_applies (tp));
+      if (tp->control.trap_expected)
+       {
+         infrun_debug_printf ("switching back to stepped thread (step-over)");
 
-             stepping_thread = tp;
-           }
+         if (keep_going_stepped_thread (tp))
+           return true;
        }
+    }
 
-      if (stepping_thread != NULL)
+  for (thread_info *tp : all_threads_safe ())
+    {
+      if (tp->state == THREAD_EXITED)
+       continue;
+
+      if (tp->suspend.waitstatus_pending_p)
+       continue;
+
+      /* Ignore threads of processes the caller is not
+        resuming.  */
+      if (!sched_multi
+         && (tp->inf->process_target () != resume_target
+             || tp->inf->pid != resume_ptid.pid ()))
+       continue;
+
+      /* Did we find the stepping thread?  */
+      if (tp->control.step_range_end)
        {
-         infrun_debug_printf ("switching back to stepped thread");
+         infrun_debug_printf ("switching back to stepped thread (stepping)");
 
-         if (keep_going_stepped_thread (stepping_thread))
-           {
-             prepare_to_wait (ecs);
-             return true;
-           }
+         if (keep_going_stepped_thread (tp))
+           return true;
        }
-
-      switch_to_thread (ecs->event_thread);
     }
 
   return false;
 }
 
+/* See infrun.h.  */
+
+void
+restart_after_all_stop_detach (process_stratum_target *proc_target)
+{
+  /* Note we don't check target_is_non_stop_p() here, because the
+     current inferior may no longer have a process_stratum target
+     pushed, as we just detached.  */
+
+  /* See if we have a THREAD_RUNNING thread that need to be
+     re-resumed.  If we have any thread that is already executing,
+     then we don't need to resume the target -- it is already been
+     resumed.  With the remote target (in all-stop), it's even
+     impossible to issue another resumption if the target is already
+     resumed, until the target reports a stop.  */
+  for (thread_info *thr : all_threads (proc_target))
+    {
+      if (thr->state != THREAD_RUNNING)
+       continue;
+
+      /* If we have any thread that is already executing, then we
+        don't need to resume the target -- it is already been
+        resumed.  */
+      if (thr->executing)
+       return;
+
+      /* If we have a pending event to process, skip resuming the
+        target and go straight to processing it.  */
+      if (thr->resumed && thr->suspend.waitstatus_pending_p)
+       return;
+    }
+
+  /* Alright, we need to re-resume the target.  If a thread was
+     stepping, we need to restart it stepping.  */
+  if (restart_stepped_thread (proc_target, minus_one_ptid))
+    return;
+
+  /* Otherwise, find the first THREAD_RUNNING thread and resume
+     it.  */
+  for (thread_info *thr : all_threads (proc_target))
+    {
+      if (thr->state != THREAD_RUNNING)
+       continue;
+
+      execution_control_state ecs;
+      reset_ecs (&ecs, thr);
+      switch_to_thread (thr);
+      keep_going (&ecs);
+      return;
+    }
+}
+
 /* Set a previously stepped thread back to stepping.  Returns true on
    success, false if the resume is not possible (e.g., the thread
    vanished).  */
@@ -8738,7 +9037,8 @@ siginfo_value_read (struct value *v)
   validate_registers_access ();
 
   transferred =
-    target_read (current_top_target (), TARGET_OBJECT_SIGNAL_INFO,
+    target_read (current_inferior ()->top_target (),
+                TARGET_OBJECT_SIGNAL_INFO,
                 NULL,
                 value_contents_all_raw (v),
                 value_offset (v),
@@ -8760,7 +9060,7 @@ siginfo_value_write (struct value *v, struct value *fromval)
      vice versa.  */
   validate_registers_access ();
 
-  transferred = target_write (current_top_target (),
+  transferred = target_write (current_inferior ()->top_target (),
                              TARGET_OBJECT_SIGNAL_INFO,
                              NULL,
                              value_contents_all_raw (fromval),
@@ -8824,7 +9124,8 @@ public:
 
        siginfo_data.reset ((gdb_byte *) xmalloc (len));
 
-       if (target_read (current_top_target (), TARGET_OBJECT_SIGNAL_INFO, NULL,
+       if (target_read (current_inferior ()->top_target (),
+                        TARGET_OBJECT_SIGNAL_INFO, NULL,
                         siginfo_data.get (), 0, len) != len)
          {
            /* Errors ignored.  */
@@ -8859,7 +9160,8 @@ public:
        struct type *type = gdbarch_get_siginfo_type (gdbarch);
 
        /* Errors ignored.  */
-       target_write (current_top_target (), TARGET_OBJECT_SIGNAL_INFO, NULL,
+       target_write (current_inferior ()->top_target (),
+                     TARGET_OBJECT_SIGNAL_INFO, NULL,
                      m_siginfo_data.get (), 0, TYPE_LENGTH (type));
       }
 
@@ -9116,6 +9418,7 @@ static const struct internalvar_funcs siginfo_funcs =
 static void
 infrun_async_inferior_event_handler (gdb_client_data data)
 {
+  clear_async_event_handler (infrun_async_inferior_event_token);
   inferior_event_handler (INF_REG_EVENT);
 }
 
@@ -9455,11 +9758,13 @@ enabled by default on some platforms."),
   inferior_ptid = null_ptid;
   target_last_wait_ptid = minus_one_ptid;
 
-  gdb::observers::thread_ptid_changed.attach (infrun_thread_ptid_changed);
-  gdb::observers::thread_stop_requested.attach (infrun_thread_stop_requested);
-  gdb::observers::thread_exit.attach (infrun_thread_thread_exit);
-  gdb::observers::inferior_exit.attach (infrun_inferior_exit);
-  gdb::observers::inferior_execd.attach (infrun_inferior_execd);
+  gdb::observers::thread_ptid_changed.attach (infrun_thread_ptid_changed,
+                                             "infrun");
+  gdb::observers::thread_stop_requested.attach (infrun_thread_stop_requested,
+                                               "infrun");
+  gdb::observers::thread_exit.attach (infrun_thread_thread_exit, "infrun");
+  gdb::observers::inferior_exit.attach (infrun_inferior_exit, "infrun");
+  gdb::observers::inferior_execd.attach (infrun_inferior_execd, "infrun");
 
   /* Explicitly create without lookup, since that tries to create a
      value with a void typed value, and when we get here, gdbarch