build as needed
[platform/upstream/binutils.git] / gdb / infrun.c
index 0b8dffe..5536350 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
+#include "infrun.h"
 #include <ctype.h>
 #include "symtab.h"
 #include "frame.h"
 #include "inferior.h"
-#include "exceptions.h"
 #include "breakpoint.h"
 #include "gdb_wait.h"
 #include "gdbcore.h"
@@ -45,7 +44,6 @@
 #include "main.h"
 #include "dictionary.h"
 #include "block.h"
-#include "gdb_assert.h"
 #include "mi/mi-common.h"
 #include "event-top.h"
 #include "record.h"
@@ -60,6 +58,8 @@
 #include "objfiles.h"
 #include "completer.h"
 #include "target-descriptions.h"
+#include "target-dcache.h"
+#include "terminal.h"
 
 /* Prototypes for local functions */
 
@@ -79,28 +79,17 @@ static int restore_selected_frame (void *);
 
 static int follow_fork (void);
 
+static int follow_fork_inferior (int follow_child, int detach_fork);
+
+static void follow_inferior_reset_breakpoints (void);
+
 static void set_schedlock_func (char *args, int from_tty,
                                struct cmd_list_element *c);
 
 static int currently_stepping (struct thread_info *tp);
 
-static int currently_stepping_or_nexting_callback (struct thread_info *tp,
-                                                  void *data);
-
 static void xdb_handle_command (char *args, int from_tty);
 
-static int prepare_to_proceed (int);
-
-static void print_exited_reason (int exitstatus);
-
-static void print_signal_exited_reason (enum gdb_signal siggnal);
-
-static void print_no_history_reason (void);
-
-static void print_signal_received_reason (enum gdb_signal siggnal);
-
-static void print_end_stepping_range_reason (void);
-
 void _initialize_infrun (void);
 
 void nullify_last_target_wait_ptid (void);
@@ -126,9 +115,9 @@ show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
 
 int sync_execution = 0;
 
-/* wait_for_inferior and normal_stop use this to notify the user
-   when the inferior stopped in a different thread than it had been
-   running in.  */
+/* proceed and normal_stop use this to notify the user when the
+   inferior stopped in a different thread than it had been running
+   in.  */
 
 static ptid_t previous_inferior_ptid;
 
@@ -246,7 +235,6 @@ set_observer_mode (char *args, int from_tty,
      going out we leave it that way.  */
   if (observer_mode)
     {
-      target_async_permitted = 1;
       pagination_enabled = 0;
       non_stop = non_stop_1 = 1;
     }
@@ -412,6 +400,241 @@ show_follow_fork_mode_string (struct ui_file *file, int from_tty,
 }
 \f
 
+/* Handle changes to the inferior list based on the type of fork,
+   which process is being followed, and whether the other process
+   should be detached.  On entry inferior_ptid must be the ptid of
+   the fork parent.  At return inferior_ptid is the ptid of the
+   followed inferior.  */
+
+static int
+follow_fork_inferior (int follow_child, int detach_fork)
+{
+  int has_vforked;
+  int parent_pid, child_pid;
+
+  has_vforked = (inferior_thread ()->pending_follow.kind
+                == TARGET_WAITKIND_VFORKED);
+  parent_pid = ptid_get_lwp (inferior_ptid);
+  if (parent_pid == 0)
+    parent_pid = ptid_get_pid (inferior_ptid);
+  child_pid
+    = ptid_get_pid (inferior_thread ()->pending_follow.value.related_pid);
+
+  if (has_vforked
+      && !non_stop /* Non-stop always resumes both branches.  */
+      && (!target_is_async_p () || sync_execution)
+      && !(follow_child || detach_fork || sched_multi))
+    {
+      /* The parent stays blocked inside the vfork syscall until the
+        child execs or exits.  If we don't let the child run, then
+        the parent stays blocked.  If we're telling the parent to run
+        in the foreground, the user will not be able to ctrl-c to get
+        back the terminal, effectively hanging the debug session.  */
+      fprintf_filtered (gdb_stderr, _("\
+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"));
+      /* FIXME output string > 80 columns.  */
+      return 1;
+    }
+
+  if (!follow_child)
+    {
+      /* Detach new forked process?  */
+      if (detach_fork)
+       {
+         struct cleanup *old_chain;
+
+         /* Before detaching from the child, remove all breakpoints
+            from it.  If we forked, then this has already been taken
+            care of by infrun.c.  If we vforked however, any
+            breakpoint inserted in the parent is visible in the
+            child, even those added while stopped in a vfork
+            catchpoint.  This will remove the breakpoints from the
+            parent also, but they'll be reinserted below.  */
+         if (has_vforked)
+           {
+             /* Keep breakpoints list in sync.  */
+             remove_breakpoints_pid (ptid_get_pid (inferior_ptid));
+           }
+
+         if (info_verbose || debug_infrun)
+           {
+             target_terminal_ours ();
+             fprintf_filtered (gdb_stdlog,
+                               "Detaching after fork from "
+                               "child process %d.\n",
+                               child_pid);
+           }
+       }
+      else
+       {
+         struct inferior *parent_inf, *child_inf;
+         struct cleanup *old_chain;
+
+         /* Add process to GDB's tables.  */
+         child_inf = add_inferior (child_pid);
+
+         parent_inf = current_inferior ();
+         child_inf->attach_flag = parent_inf->attach_flag;
+         copy_terminal_info (child_inf, parent_inf);
+         child_inf->gdbarch = parent_inf->gdbarch;
+         copy_inferior_target_desc_info (child_inf, parent_inf);
+
+         old_chain = save_inferior_ptid ();
+         save_current_program_space ();
+
+         inferior_ptid = ptid_build (child_pid, child_pid, 0);
+         add_thread (inferior_ptid);
+         child_inf->symfile_flags = SYMFILE_NO_READ;
+
+         /* If this is a vfork child, then the address-space is
+            shared with the parent.  */
+         if (has_vforked)
+           {
+             child_inf->pspace = parent_inf->pspace;
+             child_inf->aspace = parent_inf->aspace;
+
+             /* The parent will be frozen until the child is done
+                with the shared region.  Keep track of the
+                parent.  */
+             child_inf->vfork_parent = parent_inf;
+             child_inf->pending_detach = 0;
+             parent_inf->vfork_child = child_inf;
+             parent_inf->pending_detach = 0;
+           }
+         else
+           {
+             child_inf->aspace = new_address_space ();
+             child_inf->pspace = add_program_space (child_inf->aspace);
+             child_inf->removable = 1;
+             set_current_program_space (child_inf->pspace);
+             clone_program_space (child_inf->pspace, parent_inf->pspace);
+
+             /* Let the shared library layer (e.g., solib-svr4) learn
+                about this new process, relocate the cloned exec, pull
+                in shared libraries, and install the solib event
+                breakpoint.  If a "cloned-VM" event was propagated
+                better throughout the core, this wouldn't be
+                required.  */
+             solib_create_inferior_hook (0);
+           }
+
+         do_cleanups (old_chain);
+       }
+
+      if (has_vforked)
+       {
+         struct inferior *parent_inf;
+
+         parent_inf = current_inferior ();
+
+         /* If we detached from the child, then we have to be careful
+            to not insert breakpoints in the parent until the child
+            is done with the shared memory region.  However, if we're
+            staying attached to the child, then we can and should
+            insert breakpoints, so that we can debug it.  A
+            subsequent child exec or exit is enough to know when does
+            the child stops using the parent's address space.  */
+         parent_inf->waiting_for_vfork_done = detach_fork;
+         parent_inf->pspace->breakpoints_not_allowed = detach_fork;
+       }
+    }
+  else
+    {
+      /* Follow the child.  */
+      struct inferior *parent_inf, *child_inf;
+      struct program_space *parent_pspace;
+
+      if (info_verbose || debug_infrun)
+       {
+         target_terminal_ours ();
+         if (has_vforked)
+           fprintf_filtered (gdb_stdlog,
+                             _("Attaching after process %d "
+                               "vfork to child process %d.\n"),
+                             parent_pid, child_pid);
+         else
+           fprintf_filtered (gdb_stdlog,
+                             _("Attaching after process %d "
+                               "fork to child process %d.\n"),
+                             parent_pid, child_pid);
+       }
+
+      /* Add the new inferior first, so that the target_detach below
+        doesn't unpush the target.  */
+
+      child_inf = add_inferior (child_pid);
+
+      parent_inf = current_inferior ();
+      child_inf->attach_flag = parent_inf->attach_flag;
+      copy_terminal_info (child_inf, parent_inf);
+      child_inf->gdbarch = parent_inf->gdbarch;
+      copy_inferior_target_desc_info (child_inf, parent_inf);
+
+      parent_pspace = parent_inf->pspace;
+
+      /* If we're vforking, we want to hold on to the parent until the
+        child exits or execs.  At child exec or exit time we can
+        remove the old breakpoints from the parent and detach or
+        resume debugging it.  Otherwise, detach the parent now; we'll
+        want to reuse it's program/address spaces, but we can't set
+        them to the child before removing breakpoints from the
+        parent, otherwise, the breakpoints module could decide to
+        remove breakpoints from the wrong process (since they'd be
+        assigned to the same address space).  */
+
+      if (has_vforked)
+       {
+         gdb_assert (child_inf->vfork_parent == NULL);
+         gdb_assert (parent_inf->vfork_child == NULL);
+         child_inf->vfork_parent = parent_inf;
+         child_inf->pending_detach = 0;
+         parent_inf->vfork_child = child_inf;
+         parent_inf->pending_detach = detach_fork;
+         parent_inf->waiting_for_vfork_done = 0;
+       }
+      else if (detach_fork)
+       target_detach (NULL, 0);
+
+      /* Note that the detach above makes PARENT_INF dangling.  */
+
+      /* Add the child thread to the appropriate lists, and switch to
+        this new thread, before cloning the program space, and
+        informing the solib layer about this new process.  */
+
+      inferior_ptid = ptid_build (child_pid, child_pid, 0);
+      add_thread (inferior_ptid);
+
+      /* If this is a vfork child, then the address-space is shared
+        with the parent.  If we detached from the parent, then we can
+        reuse the parent's program/address spaces.  */
+      if (has_vforked || detach_fork)
+       {
+         child_inf->pspace = parent_pspace;
+         child_inf->aspace = child_inf->pspace->aspace;
+       }
+      else
+       {
+         child_inf->aspace = new_address_space ();
+         child_inf->pspace = add_program_space (child_inf->aspace);
+         child_inf->removable = 1;
+         child_inf->symfile_flags = SYMFILE_NO_READ;
+         set_current_program_space (child_inf->pspace);
+         clone_program_space (child_inf->pspace, parent_pspace);
+
+         /* Let the shared library layer (e.g., solib-svr4) learn
+            about this new process, relocate the cloned exec, pull in
+            shared libraries, and install the solib event breakpoint.
+            If a "cloned-VM" event was propagated better throughout
+            the core, this wouldn't be required.  */
+         solib_create_inferior_hook (0);
+       }
+    }
+
+  return target_follow_fork (follow_child, detach_fork);
+}
+
 /* Tell the target to follow the fork we're stopped at.  Returns true
    if the inferior should be resumed; false, if the target for some
    reason decided it's best not to resume.  */
@@ -432,6 +655,7 @@ follow_fork (void)
   CORE_ADDR step_range_start = 0;
   CORE_ADDR step_range_end = 0;
   struct frame_id step_frame_id = { 0 };
+  struct interp *command_interp = NULL;
 
   if (!non_stop)
     {
@@ -483,6 +707,7 @@ follow_fork (void)
            step_frame_id = tp->control.step_frame_id;
            exception_resume_breakpoint
              = clone_momentary_breakpoint (tp->control.exception_resume_breakpoint);
+           command_interp = tp->control.command_interp;
 
            /* For now, delete the parent's sr breakpoint, otherwise,
               parent/child sr breakpoints are considered duplicates,
@@ -494,14 +719,16 @@ follow_fork (void)
            tp->control.step_range_end = 0;
            tp->control.step_frame_id = null_frame_id;
            delete_exception_resume_breakpoint (tp);
+           tp->control.command_interp = NULL;
          }
 
        parent = inferior_ptid;
        child = tp->pending_follow.value.related_pid;
 
-       /* Tell the target to do whatever is necessary to follow
-          either parent or child.  */
-       if (target_follow_fork (follow_child, detach_fork))
+       /* Set up inferior(s) as specified by the caller, and tell the
+          target to do whatever is necessary to follow either parent
+          or child.  */
+       if (follow_fork_inferior (follow_child, detach_fork))
          {
            /* Target refused to follow, or there's some other reason
               we shouldn't resume.  */
@@ -538,6 +765,7 @@ follow_fork (void)
                    tp->control.step_frame_id = step_frame_id;
                    tp->control.exception_resume_breakpoint
                      = exception_resume_breakpoint;
+                   tp->control.command_interp = command_interp;
                  }
                else
                  {
@@ -572,14 +800,16 @@ follow_fork (void)
   return should_resume;
 }
 
-void
+static void
 follow_inferior_reset_breakpoints (void)
 {
   struct thread_info *tp = inferior_thread ();
 
   /* Was there a step_resume breakpoint?  (There was if the user
      did a "next" at the fork() call.)  If so, explicitly reset its
-     thread number.
+     thread number.  Cloned step_resume breakpoints are disabled on
+     creation, so enable it here now that it is associated with the
+     correct thread.
 
      step_resumes are a form of bp that are made to be per-thread.
      Since we created the step_resume bp when the parent process
@@ -589,10 +819,17 @@ follow_inferior_reset_breakpoints (void)
      it is for, or it'll be ignored when it triggers.  */
 
   if (tp->control.step_resume_breakpoint)
-    breakpoint_re_set_thread (tp->control.step_resume_breakpoint);
+    {
+      breakpoint_re_set_thread (tp->control.step_resume_breakpoint);
+      tp->control.step_resume_breakpoint->loc->enabled = 1;
+    }
 
+  /* Treat exception_resume breakpoints like step_resume breakpoints.  */
   if (tp->control.exception_resume_breakpoint)
-    breakpoint_re_set_thread (tp->control.exception_resume_breakpoint);
+    {
+      breakpoint_re_set_thread (tp->control.exception_resume_breakpoint);
+      tp->control.exception_resume_breakpoint->loc->enabled = 1;
+    }
 
   /* Reinsert all breakpoints in the child.  The user may have set
      breakpoints after catching the fork, in which case those
@@ -624,7 +861,7 @@ proceed_after_vfork_done (struct thread_info *thread,
                            target_pid_to_str (thread->ptid));
 
       switch_to_thread (thread->ptid);
-      clear_proceed_status ();
+      clear_proceed_status (0);
       proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
     }
 
@@ -971,19 +1208,76 @@ static ptid_t singlestep_ptid;
 /* PC when we started this single-step.  */
 static CORE_ADDR singlestep_pc;
 
-/* If another thread hit the singlestep breakpoint, we save the original
-   thread here so that we can resume single-stepping it later.  */
-static ptid_t saved_singlestep_ptid;
-static int stepping_past_singlestep_breakpoint;
+/* Info about an instruction that is being stepped over.  Invalid if
+   ASPACE is NULL.  */
+
+struct step_over_info
+{
+  /* The instruction's address space.  */
+  struct address_space *aspace;
+
+  /* The instruction's address.  */
+  CORE_ADDR address;
+};
+
+/* The step-over info of the location that is being stepped over.
+
+   Note that with async/breakpoint always-inserted mode, a user might
+   set a new breakpoint/watchpoint/etc. exactly while a breakpoint is
+   being stepped over.  As setting a new breakpoint inserts all
+   breakpoints, we need to make sure the breakpoint being stepped over
+   isn't inserted then.  We do that by only clearing the step-over
+   info when the step-over is actually finished (or aborted).
+
+   Presently GDB can only step over one breakpoint at any given time.
+   Given threads that can't run code in the same address space as the
+   breakpoint's can't really miss the breakpoint, GDB could be taught
+   to step-over at most one breakpoint per address space (so this info
+   could move to the address space object if/when GDB is extended).
+   The set of breakpoints being stepped over will normally be much
+   smaller than the set of all breakpoints, so a flag in the
+   breakpoint location structure would be wasteful.  A separate list
+   also saves complexity and run-time, as otherwise we'd have to go
+   through all breakpoint locations clearing their flag whenever we
+   start a new sequence.  Similar considerations weigh against storing
+   this info in the thread object.  Plus, not all step overs actually
+   have breakpoint locations -- e.g., stepping past a single-step
+   breakpoint, or stepping to complete a non-continuable
+   watchpoint.  */
+static struct step_over_info step_over_info;
+
+/* Record the address of the breakpoint/instruction we're currently
+   stepping over.  */
+
+static void
+set_step_over_info (struct address_space *aspace, CORE_ADDR address)
+{
+  step_over_info.aspace = aspace;
+  step_over_info.address = address;
+}
+
+/* Called when we're not longer stepping over a breakpoint / an
+   instruction, so all breakpoints are free to be (re)inserted.  */
+
+static void
+clear_step_over_info (void)
+{
+  step_over_info.aspace = NULL;
+  step_over_info.address = 0;
+}
+
+/* See infrun.h.  */
 
-/* If not equal to null_ptid, this means that after stepping over breakpoint
-   is finished, we need to switch to deferred_step_ptid, and step it.
+int
+stepping_past_instruction_at (struct address_space *aspace,
+                             CORE_ADDR address)
+{
+  return (step_over_info.aspace != NULL
+         && breakpoint_address_match (aspace, address,
+                                      step_over_info.aspace,
+                                      step_over_info.address));
+}
 
-   The use case is when one thread has hit a breakpoint, and then the user 
-   has switched to another thread and issued 'step'.  We need to step over
-   breakpoint in the thread which hit the breakpoint, but then continue
-   stepping the thread user has selected.  */
-static ptid_t deferred_step_ptid;
 \f
 /* Displaced stepping.  */
 
@@ -1239,7 +1533,7 @@ use_displaced_stepping (struct gdbarch *gdbarch)
   return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO && non_stop)
           || can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
          && gdbarch_displaced_step_copy_insn_p (gdbarch)
-         && !RECORD_IS_USED);
+         && find_record_target () == NULL);
 }
 
 /* Clean out any stray displaced stepping state.  */
@@ -1582,9 +1876,6 @@ infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
   if (ptid_equal (singlestep_ptid, old_ptid))
     singlestep_ptid = new_ptid;
 
-  if (ptid_equal (deferred_step_ptid, old_ptid))
-    deferred_step_ptid = new_ptid;
-
   for (displaced = displaced_step_inferior_states;
        displaced;
        displaced = displaced->next)
@@ -1668,15 +1959,6 @@ maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc)
   return hw_step;
 }
 
-/* Return a ptid representing the set of threads that we will proceed,
-   in the perspective of the user/frontend.  We may actually resume
-   fewer threads at first, e.g., if a thread is stopped at a
-   breakpoint that needs stepping-off, but that should not be visible
-   to the user/frontend, and neither should the frontend/user be
-   allowed to proceed any of the threads that happen to be stopped for
-   internal run control handling, if a previous command wanted them
-   resumed.  */
-
 ptid_t
 user_visible_resume_ptid (int step)
 {
@@ -1697,13 +1979,18 @@ user_visible_resume_ptid (int step)
       resume_ptid = inferior_ptid;
     }
   else if ((scheduler_mode == schedlock_on)
-          || (scheduler_mode == schedlock_step
-              && (step || singlestep_breakpoints_inserted_p)))
+          || (scheduler_mode == schedlock_step && step))
     {
       /* User-settable 'scheduler' mode requires solo thread resume.  */
       resume_ptid = inferior_ptid;
     }
 
+  /* We may actually resume fewer threads at first, e.g., if a thread
+     is stopped at a breakpoint that needs stepping-off, but that
+     should not be visible to the user/frontend, and neither should
+     the frontend/user be allowed to proceed any of the threads that
+     happen to be stopped for internal run control handling, if a
+     previous command wanted them resumed.  */
   return resume_ptid;
 }
 
@@ -1718,13 +2005,20 @@ user_visible_resume_ptid (int step)
 void
 resume (int step, enum gdb_signal sig)
 {
-  int should_resume = 1;
   struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   struct thread_info *tp = inferior_thread ();
   CORE_ADDR pc = regcache_read_pc (regcache);
   struct address_space *aspace = get_regcache_aspace (regcache);
+  ptid_t resume_ptid;
+  /* From here on, this represents the caller's step vs continue
+     request, while STEP represents what we'll actually request the
+     target to do.  STEP can decay from a step to a continue, if e.g.,
+     we need to implement single-stepping with breakpoints (software
+     single-step).  When deciding whether "set scheduler-locking step"
+     applies, it's the callers intention that counts.  */
+  const int entry_step = step;
 
   QUIT;
 
@@ -1799,11 +2093,14 @@ a command like `return' or `jump' to continue execution."));
        {
          /* Got placed in displaced stepping queue.  Will be resumed
             later when all the currently queued displaced stepping
-            requests finish.  The thread is not executing at this point,
-            and the call to set_executing will be made later.  But we
-            need to call set_running here, since from frontend point of view,
-            the thread is running.  */
-         set_running (inferior_ptid, 1);
+            requests finish.  The thread is not executing at this
+            point, and the call to set_executing will be made later.
+            But we need to call set_running here, since from the
+            user/frontend's point of view, threads were set running.
+            Unless we're calling an inferior function, as in that
+            case we pretend the inferior doesn't run at all.  */
+         if (!tp->control.in_infcall)
+           set_running (user_visible_resume_ptid (entry_step), 1);
          discard_cleanups (old_cleanups);
          return;
        }
@@ -1862,113 +2159,97 @@ a command like `return' or `jump' to continue execution."));
       remove_single_step_breakpoints ();
       singlestep_breakpoints_inserted_p = 0;
 
-      insert_breakpoints ();
+      clear_step_over_info ();
       tp->control.trap_expected = 0;
+
+      insert_breakpoints ();
     }
 
-  if (should_resume)
-    {
-      ptid_t resume_ptid;
+  /* If STEP is set, it's a request to use hardware stepping
+     facilities.  But in that case, we should never
+     use singlestep breakpoint.  */
+  gdb_assert (!(singlestep_breakpoints_inserted_p && step));
 
-      /* If STEP is set, it's a request to use hardware stepping
-        facilities.  But in that case, we should never
-        use singlestep breakpoint.  */
-      gdb_assert (!(singlestep_breakpoints_inserted_p && step));
+  /* Decide the set of threads to ask the target to resume.  Start
+     by assuming everything will be resumed, than narrow the set
+     by applying increasingly restricting conditions.  */
+  resume_ptid = user_visible_resume_ptid (entry_step);
 
-      /* Decide the set of threads to ask the target to resume.  Start
-        by assuming everything will be resumed, than narrow the set
-        by applying increasingly restricting conditions.  */
-      resume_ptid = user_visible_resume_ptid (step);
+  /* Even if RESUME_PTID is a wildcard, and we end up resuming less
+     (e.g., we might need to step over a breakpoint), from the
+     user/frontend's point of view, all threads in RESUME_PTID are now
+     running.  Unless we're calling an inferior function, as in that
+     case pretend we inferior doesn't run at all.  */
+  if (!tp->control.in_infcall)
+    set_running (resume_ptid, 1);
 
-      /* Maybe resume a single thread after all.  */
-      if (singlestep_breakpoints_inserted_p
-         && stepping_past_singlestep_breakpoint)
-       {
-         /* The situation here is as follows.  In thread T1 we wanted to
-            single-step.  Lacking hardware single-stepping we've
-            set breakpoint at the PC of the next instruction -- call it
-            P.  After resuming, we've hit that breakpoint in thread T2.
-            Now we've removed original breakpoint, inserted breakpoint
-            at P+1, and try to step to advance T2 past breakpoint.
-            We need to step only T2, as if T1 is allowed to freely run,
-            it can run past P, and if other threads are allowed to run,
-            they can hit breakpoint at P+1, and nested hits of single-step
-            breakpoints is not something we'd want -- that's complicated
-            to support, and has no value.  */
-         resume_ptid = inferior_ptid;
-       }
-      else if ((step || singlestep_breakpoints_inserted_p)
-              && tp->control.trap_expected)
-       {
-         /* We're allowing a thread to run past a breakpoint it has
-            hit, by single-stepping the thread with the breakpoint
-            removed.  In which case, we need to single-step only this
-            thread, and keep others stopped, as they can miss this
-            breakpoint if allowed to run.
-
-            The current code actually removes all breakpoints when
-            doing this, not just the one being stepped over, so if we
-            let other threads run, we can actually miss any
-            breakpoint, not just the one at PC.  */
-         resume_ptid = inferior_ptid;
-       }
+  /* Maybe resume a single thread after all.  */
+  if ((step || singlestep_breakpoints_inserted_p)
+      && tp->control.trap_expected)
+    {
+      /* We're allowing a thread to run past a breakpoint it has
+        hit, by single-stepping the thread with the breakpoint
+        removed.  In which case, we need to single-step only this
+        thread, and keep others stopped, as they can miss this
+        breakpoint if allowed to run.  */
+      resume_ptid = inferior_ptid;
+    }
 
-      if (gdbarch_cannot_step_breakpoint (gdbarch))
-       {
-         /* Most targets can step a breakpoint instruction, thus
-            executing it normally.  But if this one cannot, just
-            continue and we will hit it anyway.  */
-         if (step && breakpoint_inserted_here_p (aspace, pc))
-           step = 0;
-       }
+  if (gdbarch_cannot_step_breakpoint (gdbarch))
+    {
+      /* Most targets can step a breakpoint instruction, thus
+        executing it normally.  But if this one cannot, just
+        continue and we will hit it anyway.  */
+      if (step && breakpoint_inserted_here_p (aspace, pc))
+       step = 0;
+    }
 
-      if (debug_displaced
-          && use_displaced_stepping (gdbarch)
-          && tp->control.trap_expected)
-        {
-         struct regcache *resume_regcache = get_thread_regcache (resume_ptid);
-         struct gdbarch *resume_gdbarch = get_regcache_arch (resume_regcache);
-          CORE_ADDR actual_pc = regcache_read_pc (resume_regcache);
-          gdb_byte buf[4];
-
-          fprintf_unfiltered (gdb_stdlog, "displaced: run %s: ",
-                              paddress (resume_gdbarch, actual_pc));
-          read_memory (actual_pc, buf, sizeof (buf));
-          displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
-        }
-
-      if (tp->control.may_range_step)
-       {
-         /* If we're resuming a thread with the PC out of the step
-            range, then we're doing some nested/finer run control
-            operation, like stepping the thread out of the dynamic
-            linker or the displaced stepping scratch pad.  We
-            shouldn't have allowed a range step then.  */
-         gdb_assert (pc_in_thread_step_range (pc, tp));
-       }
+  if (debug_displaced
+      && use_displaced_stepping (gdbarch)
+      && tp->control.trap_expected)
+    {
+      struct regcache *resume_regcache = get_thread_regcache (resume_ptid);
+      struct gdbarch *resume_gdbarch = get_regcache_arch (resume_regcache);
+      CORE_ADDR actual_pc = regcache_read_pc (resume_regcache);
+      gdb_byte buf[4];
 
-      /* Install inferior's terminal modes.  */
-      target_terminal_inferior ();
-
-      /* Avoid confusing the next resume, if the next stop/resume
-        happens to apply to another thread.  */
-      tp->suspend.stop_signal = GDB_SIGNAL_0;
-
-      /* Advise target which signals may be handled silently.  If we have
-        removed breakpoints because we are stepping over one (which can
-        happen only if we are not using displaced stepping), we need to
-        receive all signals to avoid accidentally skipping a breakpoint
-        during execution of a signal handler.  */
-      if ((step || singlestep_breakpoints_inserted_p)
-         && tp->control.trap_expected
-         && !use_displaced_stepping (gdbarch))
-       target_pass_signals (0, NULL);
-      else
-       target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+      fprintf_unfiltered (gdb_stdlog, "displaced: run %s: ",
+                         paddress (resume_gdbarch, actual_pc));
+      read_memory (actual_pc, buf, sizeof (buf));
+      displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
+    }
 
-      target_resume (resume_ptid, step, sig);
+  if (tp->control.may_range_step)
+    {
+      /* If we're resuming a thread with the PC out of the step
+        range, then we're doing some nested/finer run control
+        operation, like stepping the thread out of the dynamic
+        linker or the displaced stepping scratch pad.  We
+        shouldn't have allowed a range step then.  */
+      gdb_assert (pc_in_thread_step_range (pc, tp));
     }
 
+  /* Install inferior's terminal modes.  */
+  target_terminal_inferior ();
+
+  /* Avoid confusing the next resume, if the next stop/resume
+     happens to apply to another thread.  */
+  tp->suspend.stop_signal = GDB_SIGNAL_0;
+
+  /* Advise target which signals may be handled silently.  If we have
+     removed breakpoints because we are stepping over one (which can
+     happen only if we are not using displaced stepping), we need to
+     receive all signals to avoid accidentally skipping a breakpoint
+     during execution of a signal handler.  */
+  if ((step || singlestep_breakpoints_inserted_p)
+      && tp->control.trap_expected
+      && !use_displaced_stepping (gdbarch))
+    target_pass_signals (0, NULL);
+  else
+    target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+
+  target_resume (resume_ptid, step, sig);
+
   discard_cleanups (old_cleanups);
 }
 \f
@@ -1985,6 +2266,11 @@ clear_proceed_status_thread (struct thread_info *tp)
                        "infrun: clear_proceed_status_thread (%s)\n",
                        target_pid_to_str (tp->ptid));
 
+  /* If this signal should not be seen by program, give it zero.
+     Used for debugging signals.  */
+  if (!signal_pass_state (tp->suspend.stop_signal))
+    tp->suspend.stop_signal = GDB_SIGNAL_0;
+
   tp->control.trap_expected = 0;
   tp->control.step_range_start = 0;
   tp->control.step_range_end = 0;
@@ -1998,30 +2284,30 @@ clear_proceed_status_thread (struct thread_info *tp)
 
   tp->control.proceed_to_finish = 0;
 
+  tp->control.command_interp = NULL;
+
   /* Discard any remaining commands or status from previous stop.  */
   bpstat_clear (&tp->control.stop_bpstat);
 }
 
-static int
-clear_proceed_status_callback (struct thread_info *tp, void *data)
-{
-  if (is_exited (tp->ptid))
-    return 0;
-
-  clear_proceed_status_thread (tp);
-  return 0;
-}
-
 void
-clear_proceed_status (void)
+clear_proceed_status (int step)
 {
   if (!non_stop)
     {
-      /* In all-stop mode, delete the per-thread status of all
-        threads, even if inferior_ptid is null_ptid, there may be
-        threads on the list.  E.g., we may be launching a new
-        process, while selecting the executable.  */
-      iterate_over_threads (clear_proceed_status_callback, NULL);
+      struct thread_info *tp;
+      ptid_t resume_ptid;
+
+      resume_ptid = user_visible_resume_ptid (step);
+
+      /* In all-stop mode, delete the per-thread status of all threads
+        we're about to resume, implicitly and explicitly.  */
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         if (!ptid_match (tp->ptid, resume_ptid))
+           continue;
+         clear_proceed_status_thread (tp);
+       }
     }
 
   if (!ptid_equal (inferior_ptid, null_ptid))
@@ -2041,6 +2327,8 @@ clear_proceed_status (void)
 
   stop_after_trap = 0;
 
+  clear_step_over_info ();
+
   observer_notify_about_to_proceed ();
 
   if (stop_registers)
@@ -2050,79 +2338,80 @@ clear_proceed_status (void)
     }
 }
 
-/* Check the current thread against the thread that reported the most recent
-   event.  If a step-over is required return TRUE and set the current thread
-   to the old thread.  Otherwise return FALSE.
-
-   This should be suitable for any targets that support threads.  */
+/* Returns true if TP is still stopped at a breakpoint that needs
+   stepping-over in order to make progress.  If the breakpoint is gone
+   meanwhile, we can skip the whole step-over dance.  */
 
 static int
-prepare_to_proceed (int step)
+thread_still_needs_step_over (struct thread_info *tp)
 {
-  ptid_t wait_ptid;
-  struct target_waitstatus wait_status;
-  int schedlock_enabled;
-
-  /* With non-stop mode on, threads are always handled individually.  */
-  gdb_assert (! non_stop);
+  if (tp->stepping_over_breakpoint)
+    {
+      struct regcache *regcache = get_thread_regcache (tp->ptid);
 
-  /* Get the last target status returned by target_wait().  */
-  get_last_target_status (&wait_ptid, &wait_status);
+      if (breakpoint_here_p (get_regcache_aspace (regcache),
+                            regcache_read_pc (regcache)))
+       return 1;
 
-  /* Make sure we were stopped at a breakpoint.  */
-  if (wait_status.kind != TARGET_WAITKIND_STOPPED
-      || (wait_status.value.sig != GDB_SIGNAL_TRAP
-         && wait_status.value.sig != GDB_SIGNAL_ILL
-         && wait_status.value.sig != GDB_SIGNAL_SEGV
-         && wait_status.value.sig != GDB_SIGNAL_EMT))
-    {
-      return 0;
+      tp->stepping_over_breakpoint = 0;
     }
 
-  schedlock_enabled = (scheduler_mode == schedlock_on
-                      || (scheduler_mode == schedlock_step
-                          && step));
+  return 0;
+}
 
-  /* Don't switch over to WAIT_PTID if scheduler locking is on.  */
-  if (schedlock_enabled)
-    return 0;
+/* Returns true if scheduler locking applies.  STEP indicates whether
+   we're about to do a step/next-like command to a thread.  */
 
-  /* Don't switch over if we're about to resume some other process
-     other than WAIT_PTID's, and schedule-multiple is off.  */
-  if (!sched_multi
-      && ptid_get_pid (wait_ptid) != ptid_get_pid (inferior_ptid))
-    return 0;
+static int
+schedlock_applies (int step)
+{
+  return (scheduler_mode == schedlock_on
+         || (scheduler_mode == schedlock_step
+             && step));
+}
 
-  /* Switched over from WAIT_PID.  */
-  if (!ptid_equal (wait_ptid, minus_one_ptid)
-      && !ptid_equal (inferior_ptid, wait_ptid))
-    {
-      struct regcache *regcache = get_thread_regcache (wait_ptid);
+/* Look a thread other than EXCEPT that has previously reported a
+   breakpoint event, and thus needs a step-over in order to make
+   progress.  Returns NULL is none is found.  STEP indicates whether
+   we're about to step the current thread, in order to decide whether
+   "set scheduler-locking step" applies.  */
 
-      if (breakpoint_here_p (get_regcache_aspace (regcache),
-                            regcache_read_pc (regcache)))
-       {
-         /* If stepping, remember current thread to switch back to.  */
-         if (step)
-           deferred_step_ptid = inferior_ptid;
+static struct thread_info *
+find_thread_needs_step_over (int step, struct thread_info *except)
+{
+  struct thread_info *tp, *current;
 
-         /* Switch back to WAIT_PID thread.  */
-         switch_to_thread (wait_ptid);
+  /* With non-stop mode on, threads are always handled individually.  */
+  gdb_assert (! non_stop);
 
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: prepare_to_proceed (step=%d), "
-                               "switched to [%s]\n",
-                               step, target_pid_to_str (inferior_ptid));
+  current = inferior_thread ();
 
-         /* We return 1 to indicate that there is a breakpoint here,
-            so we need to step over it before continuing to avoid
-            hitting it straight away.  */
-         return 1;
-       }
+  /* If scheduler locking applies, we can avoid iterating over all
+     threads.  */
+  if (schedlock_applies (step))
+    {
+      if (except != current
+         && thread_still_needs_step_over (current))
+       return current;
+
+      return NULL;
     }
 
-  return 0;
+  ALL_NON_EXITED_THREADS (tp)
+    {
+      /* Ignore the EXCEPT thread.  */
+      if (tp == except)
+       continue;
+      /* Ignore threads of processes we're not resuming.  */
+      if (!sched_multi
+         && ptid_get_pid (tp->ptid) != ptid_get_pid (inferior_ptid))
+       continue;
+
+      if (thread_still_needs_step_over (tp))
+       return tp;
+    }
+
+  return NULL;
 }
 
 /* Basic routine for continuing the program in various fashions.
@@ -2145,8 +2434,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
   struct thread_info *tp;
   CORE_ADDR pc;
   struct address_space *aspace;
-  /* GDB may force the inferior to step due to various reasons.  */
-  int force_step = 0;
 
   /* If we're stopped at a fork/vfork, follow the branch set by the
      "set follow-fork-mode" command; otherwise, we'll just proceed
@@ -2167,12 +2454,16 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
   gdbarch = get_regcache_arch (regcache);
   aspace = get_regcache_aspace (regcache);
   pc = regcache_read_pc (regcache);
+  tp = inferior_thread ();
 
   if (step > 0)
     step_start_function = find_pc_function (pc);
   if (step < 0)
     stop_after_trap = 1;
 
+  /* Fill in with reasonable starting values.  */
+  init_thread_stepping_state (tp);
+
   if (addr == (CORE_ADDR) -1)
     {
       if (pc == stop_pc && breakpoint_here_p (aspace, pc)
@@ -2185,20 +2476,30 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
           Note, we don't do this in reverse, because we won't
           actually be executing the breakpoint insn anyway.
           We'll be (un-)executing the previous instruction.  */
-
-       force_step = 1;
+       tp->stepping_over_breakpoint = 1;
       else if (gdbarch_single_step_through_delay_p (gdbarch)
               && gdbarch_single_step_through_delay (gdbarch,
                                                     get_current_frame ()))
        /* We stepped onto an instruction that needs to be stepped
           again before re-inserting the breakpoint, do so.  */
-       force_step = 1;
+       tp->stepping_over_breakpoint = 1;
     }
   else
     {
       regcache_write_pc (regcache, addr);
     }
 
+  if (siggnal != GDB_SIGNAL_DEFAULT)
+    tp->suspend.stop_signal = siggnal;
+
+  /* Record the interpreter that issued the execution command that
+     caused this thread to resume.  If the top level interpreter is
+     MI/async, and the execution command was a CLI command
+     (next/step/etc.), we'll want to print stop event output to the MI
+     console channel (the stepped-to line, etc.), as if the user
+     entered the execution command on a real GDB console.  */
+  inferior_thread ()->control.command_interp = command_interp ();
+
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
                        "infrun: proceed (addr=%s, signal=%s, step=%d)\n",
@@ -2211,6 +2512,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
     ;
   else
     {
+      struct thread_info *step_over;
+
       /* In a multi-threaded task we may select another thread and
         then continue or step.
 
@@ -2219,66 +2522,41 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
         execution (i.e. it will report a breakpoint hit incorrectly).
         So we must step over it first.
 
-        prepare_to_proceed checks the current thread against the
-        thread that reported the most recent event.  If a step-over
-        is required it returns TRUE and sets the current thread to
-        the old thread.  */
-      if (prepare_to_proceed (step))
-       force_step = 1;
-    }
-
-  /* prepare_to_proceed may change the current thread.  */
-  tp = inferior_thread ();
-
-  if (force_step)
-    {
-      tp->control.trap_expected = 1;
-      /* If displaced stepping is enabled, we can step over the
-        breakpoint without hitting it, so leave all breakpoints
-        inserted.  Otherwise we need to disable all breakpoints, step
-        one instruction, and then re-add them when that step is
-        finished.  */
-      if (!use_displaced_stepping (gdbarch))
-       remove_breakpoints ();
+        Look for a thread other than the current (TP) that reported a
+        breakpoint hit and hasn't been resumed yet since.  */
+      step_over = find_thread_needs_step_over (step, tp);
+      if (step_over != NULL)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: need to step-over [%s] first\n",
+                               target_pid_to_str (step_over->ptid));
+
+         /* Store the prev_pc for the stepping thread too, needed by
+            switch_back_to_stepping thread.  */
+         tp->prev_pc = regcache_read_pc (get_current_regcache ());
+         switch_to_thread (step_over->ptid);
+         tp = step_over;
+       }
     }
 
-  /* We can insert breakpoints if we're not trying to step over one,
-     or if we are stepping over one but we're using displaced stepping
-     to do so.  */
-  if (! tp->control.trap_expected || use_displaced_stepping (gdbarch))
-    insert_breakpoints ();
-
-  if (!non_stop)
+  /* If we need to step over a breakpoint, and we're not using
+     displaced stepping to do so, insert all breakpoints (watchpoints,
+     etc.) but the one we're stepping over, step one instruction, and
+     then re-insert the breakpoint when that step is finished.  */
+  if (tp->stepping_over_breakpoint && !use_displaced_stepping (gdbarch))
     {
-      /* Pass the last stop signal to the thread we're resuming,
-        irrespective of whether the current thread is the thread that
-        got the last event or not.  This was historically GDB's
-        behaviour before keeping a stop_signal per thread.  */
+      struct regcache *regcache = get_current_regcache ();
 
-      struct thread_info *last_thread;
-      ptid_t last_ptid;
-      struct target_waitstatus last_status;
-
-      get_last_target_status (&last_ptid, &last_status);
-      if (!ptid_equal (inferior_ptid, last_ptid)
-         && !ptid_equal (last_ptid, null_ptid)
-         && !ptid_equal (last_ptid, minus_one_ptid))
-       {
-         last_thread = find_thread_ptid (last_ptid);
-         if (last_thread)
-           {
-             tp->suspend.stop_signal = last_thread->suspend.stop_signal;
-             last_thread->suspend.stop_signal = GDB_SIGNAL_0;
-           }
-       }
+      set_step_over_info (get_regcache_aspace (regcache),
+                         regcache_read_pc (regcache));
     }
+  else
+    clear_step_over_info ();
 
-  if (siggnal != GDB_SIGNAL_DEFAULT)
-    tp->suspend.stop_signal = siggnal;
-  /* If this signal should not be seen by program,
-     give it zero.  Used for debugging signals.  */
-  else if (!signal_program[tp->suspend.stop_signal])
-    tp->suspend.stop_signal = GDB_SIGNAL_0;
+  insert_breakpoints ();
+
+  tp->control.trap_expected = tp->stepping_over_breakpoint;
 
   annotate_starting ();
 
@@ -2287,7 +2565,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
   gdb_flush (gdb_stdout);
 
   /* Refresh prev_pc value just prior to resuming.  This used to be
-     done in stop_stepping, however, setting prev_pc there did not handle
+     done in stop_waiting, however, setting prev_pc there did not handle
      scenarios such as inferior function calls or returning from
      a function via the return command.  In those cases, the prev_pc
      value was not set properly for subsequent commands.  The prev_pc value 
@@ -2311,14 +2589,11 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
      correctly when the inferior is stopped.  */
   tp->prev_pc = regcache_read_pc (get_current_regcache ());
 
-  /* Fill in with reasonable starting values.  */
-  init_thread_stepping_state (tp);
-
   /* Reset to normal state.  */
   init_infwait_state ();
 
   /* Resume inferior.  */
-  resume (force_step || step || bpstat_should_step (),
+  resume (tp->control.trap_expected || step || bpstat_should_step (),
          tp->suspend.stop_signal);
 
   /* Wait for it to stop (if not standalone)
@@ -2376,10 +2651,7 @@ init_wait_for_inferior (void)
 
   breakpoint_init_inferior (inf_starting);
 
-  clear_proceed_status ();
-
-  stepping_past_singlestep_breakpoint = 0;
-  deferred_step_ptid = null_ptid;
+  clear_proceed_status (0);
 
   target_last_wait_ptid = minus_one_ptid;
 
@@ -2388,6 +2660,9 @@ init_wait_for_inferior (void)
 
   /* Discard any skipped inlined frames.  */
   clear_inline_frame_state (minus_one_ptid);
+
+  singlestep_ptid = null_ptid;
+  singlestep_pc = 0;
 }
 
 \f
@@ -2398,7 +2673,6 @@ init_wait_for_inferior (void)
 enum infwait_states
 {
   infwait_normal_state,
-  infwait_thread_hop_state,
   infwait_step_watch_state,
   infwait_nonstep_watch_state
 };
@@ -2429,6 +2703,12 @@ struct execution_control_state
      infwait_nonstep_watch_state state, and the thread reported an
      event.  */
   int stepped_after_stopped_by_watchpoint;
+
+  /* True if the event thread hit the single-step breakpoint of
+     another thread.  Thus the event doesn't cause a stop, the thread
+     needs to be single-stepped past the single-step breakpoint before
+     we can switch back to the original stepping thread.  */
+  int hit_singlestep_breakpoint;
 };
 
 static void handle_inferior_event (struct execution_control_state *ecs);
@@ -2441,7 +2721,8 @@ static void handle_signal_stop (struct execution_control_state *ecs);
 static void check_exception_resume (struct execution_control_state *,
                                    struct frame_info *);
 
-static void stop_stepping (struct execution_control_state *ecs);
+static void end_stepping_range (struct execution_control_state *ecs);
+static void stop_waiting (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 void process_event_stop_test (struct execution_control_state *ecs);
@@ -2475,6 +2756,13 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
 
       old_chain = make_cleanup_restore_current_thread ();
 
+      overlay_cache_invalid = 1;
+      /* Flush target cache before starting to handle each event.
+        Target was running and cache could be stale.  This is just a
+        heuristic.  Running threads may modify target memory, but we
+        don't get any event.  */
+      target_dcache_invalidate ();
+
       /* Go through handle_inferior_event/normal_stop, so we always
         have consistent output as if the stop event had been
         reported.  */
@@ -2677,6 +2965,11 @@ prepare_for_detach (void)
       memset (ecs, 0, sizeof (*ecs));
 
       overlay_cache_invalid = 1;
+      /* Flush target cache before starting to handle each event.
+        Target was running and cache could be stale.  This is just a
+        heuristic.  Running threads may modify target memory, but we
+        don't get any event.  */
+      target_dcache_invalidate ();
 
       if (deprecated_target_wait_hook)
        ecs->ptid = deprecated_target_wait_hook (pid_ptid, &ecs->ws, 0);
@@ -2740,6 +3033,12 @@ wait_for_inferior (void)
 
       overlay_cache_invalid = 1;
 
+      /* Flush target cache before starting to handle each event.
+        Target was running and cache could be stale.  This is just a
+        heuristic.  Running threads may modify target memory, but we
+        don't get any event.  */
+      target_dcache_invalidate ();
+
       if (deprecated_target_wait_hook)
        ecs->ptid = deprecated_target_wait_hook (waiton_ptid, &ecs->ws, 0);
       else
@@ -2805,6 +3104,11 @@ fetch_inferior_event (void *client_data)
     make_cleanup_restore_current_thread ();
 
   overlay_cache_invalid = 1;
+  /* Flush target cache before starting to handle each event.  Target
+     was running and cache could be stale.  This is just a heuristic.
+     Running threads may modify target memory, but we don't get any
+     event.  */
+  target_dcache_invalidate ();
 
   make_cleanup_restore_integer (&execution_direction);
   execution_direction = target_execution_direction ();
@@ -2867,7 +3171,7 @@ fetch_inferior_event (void *client_data)
      restore the prompt (a synchronous execution command has finished,
      and we're ready for input).  */
   if (interpreter_async && was_sync && !sync_execution)
-    display_gdb_prompt (0);
+    observer_notify_sync_execution_done ();
 
   if (cmd_done
       && !was_sync
@@ -2899,6 +3203,15 @@ init_thread_stepping_state (struct thread_info *tss)
   tss->step_after_step_resume_breakpoint = 0;
 }
 
+/* Set the cached copy of the last ptid/waitstatus.  */
+
+static void
+set_last_target_status (ptid_t ptid, struct target_waitstatus status)
+{
+  target_last_wait_ptid = ptid;
+  target_last_waitstatus = status;
+}
+
 /* Return the cached copy of the last pid/waitstatus returned by
    target_wait()/deprecated_target_wait_hook().  The data is actually
    cached by handle_inferior_event(), which gets called immediately
@@ -2939,7 +3252,7 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   struct regcache *regcache;
   struct gdbarch *gdbarch;
   struct address_space *aspace;
-  CORE_ADDR breakpoint_pc;
+  CORE_ADDR breakpoint_pc, decr_pc;
 
   /* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP.  If
      we aren't, just return.
@@ -3001,15 +3314,16 @@ adjust_pc_after_break (struct execution_control_state *ecs)
      we have nothing to do.  */
   regcache = get_thread_regcache (ecs->ptid);
   gdbarch = get_regcache_arch (regcache);
-  if (gdbarch_decr_pc_after_break (gdbarch) == 0)
+
+  decr_pc = target_decr_pc_after_break (gdbarch);
+  if (decr_pc == 0)
     return;
 
   aspace = get_regcache_aspace (regcache);
 
   /* Find the location where (if we've hit a breakpoint) the
      breakpoint would be.  */
-  breakpoint_pc = regcache_read_pc (regcache)
-                 - gdbarch_decr_pc_after_break (gdbarch);
+  breakpoint_pc = regcache_read_pc (regcache) - decr_pc;
 
   /* Check whether there actually is a software breakpoint inserted at
      that location.
@@ -3024,7 +3338,7 @@ adjust_pc_after_break (struct execution_control_state *ecs)
     {
       struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
 
-      if (RECORD_IS_USED)
+      if (record_full_is_used ())
        record_full_gdb_operation_disable_set ();
 
       /* When using hardware single-step, a SIGTRAP is reported for both
@@ -3134,6 +3448,10 @@ fill_in_stop_func (struct gdbarch *gdbarch,
       ecs->stop_func_start
        += gdbarch_deprecated_function_start_offset (gdbarch);
 
+      if (gdbarch_skip_entrypoint_p (gdbarch))
+       ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch,
+                                                       ecs->stop_func_start);
+
       ecs->stop_func_filled_in = 1;
     }
 }
@@ -3156,7 +3474,7 @@ get_inferior_stop_soon (ptid_t ptid)
 
    The alternatives are:
 
-   1) stop_stepping and return; to really stop and return to the
+   1) stop_waiting and return; to really stop and return to the
    debugger.
 
    2) keep_going and return; to wait for the next event (set
@@ -3201,8 +3519,7 @@ handle_inferior_event (struct execution_control_state *ecs)
     }
 
   /* Cache the last pid/waitstatus.  */
-  target_last_wait_ptid = ecs->ptid;
-  target_last_waitstatus = ecs->ws;
+  set_last_target_status (ecs->ptid, ecs->ws);
 
   /* Always clear state belonging to the previous time we stopped.  */
   stop_stack_dummy = STOP_NONE;
@@ -3215,7 +3532,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
 
       stop_print_frame = 0;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
     }
 
@@ -3281,11 +3598,6 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   switch (infwait_state)
     {
-    case infwait_thread_hop_state:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: infwait_thread_hop_state\n");
-      break;
-
     case infwait_normal_state:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: infwait_normal_state\n");
@@ -3363,7 +3675,7 @@ handle_inferior_event (struct execution_control_state *ecs)
                 normal_stop.  */
              stop_print_frame = 1;
 
-             stop_stepping (ecs);
+             stop_waiting (ecs);
              return;
            }
        }
@@ -3375,8 +3687,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        {
          /* Loading of shared libraries might have changed breakpoint
             addresses.  Make sure new breakpoints are inserted.  */
-         if (stop_soon == NO_STOP_QUIETLY
-             && !breakpoints_always_inserted_mode ())
+         if (stop_soon == NO_STOP_QUIETLY)
            insert_breakpoints ();
          resume (0, GDB_SIGNAL_0);
          prepare_to_wait (ecs);
@@ -3390,7 +3701,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        {
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
-         stop_stepping (ecs);
+         stop_waiting (ecs);
          return;
        }
 
@@ -3438,7 +3749,10 @@ handle_inferior_event (struct execution_control_state *ecs)
          current_inferior ()->has_exit_code = 1;
          current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
 
-         print_exited_reason (ecs->ws.value.integer);
+         /* Support the --return-child-result option.  */
+         return_child_result_value = ecs->ws.value.integer;
+
+         observer_notify_exited (ecs->ws.value.integer);
        }
       else
        {
@@ -3467,7 +3781,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 Cannot fill $_exitsignal with the correct signal number.\n"));
            }
 
-         print_signal_exited_reason (ecs->ws.value.sig);
+         observer_notify_signal_exited (ecs->ws.value.sig);
        }
 
       gdb_flush (gdb_stdout);
@@ -3475,7 +3789,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       singlestep_breakpoints_inserted_p = 0;
       cancel_single_step_breakpoints ();
       stop_print_frame = 0;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
 
       /* The following are the only cases in which we keep going;
@@ -3627,7 +3941,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          if (should_resume)
            keep_going (ecs);
          else
-           stop_stepping (ecs);
+           stop_waiting (ecs);
          return;
        }
       process_event_stop_test (ecs);
@@ -3735,8 +4049,8 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          singlestep_breakpoints_inserted_p = 0;
        }
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
-      print_no_history_reason ();
-      stop_stepping (ecs);
+      observer_notify_no_history ();
+      stop_waiting (ecs);
       return;
     }
 }
@@ -3752,22 +4066,20 @@ handle_signal_stop (struct execution_control_state *ecs)
   enum stop_kind stop_soon;
   int random_signal;
 
-  if (ecs->ws.kind == TARGET_WAITKIND_STOPPED)
-    {
-      /* Do we need to clean up the state of a thread that has
-        completed a displaced single-step?  (Doing so usually affects
-        the PC, so do it here, before we set stop_pc.)  */
-      displaced_step_fixup (ecs->ptid,
-                           ecs->event_thread->suspend.stop_signal);
+  gdb_assert (ecs->ws.kind == TARGET_WAITKIND_STOPPED);
 
-      /* If we either finished a single-step or hit a breakpoint, but
-        the user wanted this thread to be stopped, pretend we got a
-        SIG0 (generic unsignaled stop).  */
+  /* Do we need to clean up the state of a thread that has
+     completed a displaced single-step?  (Doing so usually affects
+     the PC, so do it here, before we set stop_pc.)  */
+  displaced_step_fixup (ecs->ptid,
+                       ecs->event_thread->suspend.stop_signal);
 
-      if (ecs->event_thread->stop_requested
-         && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
-       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
-    }
+  /* If we either finished a single-step or hit a breakpoint, but
+     the user wanted this thread to be stopped, pretend we got a
+     SIG0 (generic unsignaled stop).  */
+  if (ecs->event_thread->stop_requested
+      && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
+    ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
 
   stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
@@ -3809,7 +4121,7 @@ handle_signal_stop (struct execution_control_state *ecs)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
       stop_print_frame = 1;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
     }
 
@@ -3821,7 +4133,7 @@ handle_signal_stop (struct execution_control_state *ecs)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
       stop_print_frame = 0;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
     }
 
@@ -3851,226 +4163,11 @@ handle_signal_stop (struct execution_control_state *ecs)
          || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0))
     {
       stop_print_frame = 1;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
       return;
     }
 
-  if (stepping_past_singlestep_breakpoint)
-    {
-      gdb_assert (singlestep_breakpoints_inserted_p);
-      gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid));
-      gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid));
-
-      stepping_past_singlestep_breakpoint = 0;
-
-      /* We've either finished single-stepping past the single-step
-         breakpoint, or stopped for some other reason.  It would be nice if
-         we could tell, but we can't reliably.  */
-      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
-       {
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: stepping_past_"
-                               "singlestep_breakpoint\n");
-         /* Pull the single step breakpoints out of the target.  */
-         if (!ptid_equal (ecs->ptid, inferior_ptid))
-           context_switch (ecs->ptid);
-         remove_single_step_breakpoints ();
-         singlestep_breakpoints_inserted_p = 0;
-
-         ecs->event_thread->control.trap_expected = 0;
-
-         context_switch (saved_singlestep_ptid);
-         if (deprecated_context_hook)
-           deprecated_context_hook (pid_to_thread_id (saved_singlestep_ptid));
-
-         resume (1, GDB_SIGNAL_0);
-         prepare_to_wait (ecs);
-         return;
-       }
-    }
-
-  if (!ptid_equal (deferred_step_ptid, null_ptid))
-    {
-      /* In non-stop mode, there's never a deferred_step_ptid set.  */
-      gdb_assert (!non_stop);
-
-      /* If we stopped for some other reason than single-stepping, ignore
-        the fact that we were supposed to switch back.  */
-      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
-       {
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: handling deferred step\n");
-
-         /* Pull the single step breakpoints out of the target.  */
-         if (singlestep_breakpoints_inserted_p)
-           {
-             if (!ptid_equal (ecs->ptid, inferior_ptid))
-               context_switch (ecs->ptid);
-             remove_single_step_breakpoints ();
-             singlestep_breakpoints_inserted_p = 0;
-           }
-
-         ecs->event_thread->control.trap_expected = 0;
-
-         context_switch (deferred_step_ptid);
-         deferred_step_ptid = null_ptid;
-         /* Suppress spurious "Switching to ..." message.  */
-         previous_inferior_ptid = inferior_ptid;
-
-         resume (1, GDB_SIGNAL_0);
-         prepare_to_wait (ecs);
-         return;
-       }
-
-      deferred_step_ptid = null_ptid;
-    }
-
-  /* See if a thread hit a thread-specific breakpoint that was meant for
-     another thread.  If so, then step that thread past the breakpoint,
-     and continue it.  */
-
-  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
-    {
-      int thread_hop_needed = 0;
-      struct address_space *aspace = 
-       get_regcache_aspace (get_thread_regcache (ecs->ptid));
-
-      /* Check if a regular breakpoint has been hit before checking
-         for a potential single step breakpoint.  Otherwise, GDB will
-         not see this breakpoint hit when stepping onto breakpoints.  */
-      if (regular_breakpoint_inserted_here_p (aspace, stop_pc))
-       {
-         if (!breakpoint_thread_match (aspace, stop_pc, ecs->ptid))
-           thread_hop_needed = 1;
-       }
-      else if (singlestep_breakpoints_inserted_p)
-       {
-         /* We have not context switched yet, so this should be true
-            no matter which thread hit the singlestep breakpoint.  */
-         gdb_assert (ptid_equal (inferior_ptid, singlestep_ptid));
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: software single step "
-                               "trap for %s\n",
-                               target_pid_to_str (ecs->ptid));
-
-         /* The call to in_thread_list is necessary because PTIDs sometimes
-            change when we go from single-threaded to multi-threaded.  If
-            the singlestep_ptid is still in the list, assume that it is
-            really different from ecs->ptid.  */
-         if (!ptid_equal (singlestep_ptid, ecs->ptid)
-             && in_thread_list (singlestep_ptid))
-           {
-             /* If the PC of the thread we were trying to single-step
-                has changed, discard this event (which we were going
-                to ignore anyway), and pretend we saw that thread
-                trap.  This prevents us continuously moving the
-                single-step breakpoint forward, one instruction at a
-                time.  If the PC has changed, then the thread we were
-                trying to single-step has trapped or been signalled,
-                but the event has not been reported to GDB yet.
-
-                There might be some cases where this loses signal
-                information, if a signal has arrived at exactly the
-                same time that the PC changed, but this is the best
-                we can do with the information available.  Perhaps we
-                should arrange to report all events for all threads
-                when they stop, or to re-poll the remote looking for
-                this particular thread (i.e. temporarily enable
-                schedlock).  */
-
-            CORE_ADDR new_singlestep_pc
-              = regcache_read_pc (get_thread_regcache (singlestep_ptid));
-
-            if (new_singlestep_pc != singlestep_pc)
-              {
-                enum gdb_signal stop_signal;
-
-                if (debug_infrun)
-                  fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread,"
-                                      " but expected thread advanced also\n");
-
-                /* The current context still belongs to
-                   singlestep_ptid.  Don't swap here, since that's
-                   the context we want to use.  Just fudge our
-                   state and continue.  */
-                 stop_signal = ecs->event_thread->suspend.stop_signal;
-                 ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
-                 ecs->ptid = singlestep_ptid;
-                 ecs->event_thread = find_thread_ptid (ecs->ptid);
-                 ecs->event_thread->suspend.stop_signal = stop_signal;
-                 stop_pc = new_singlestep_pc;
-               }
-             else
-              {
-                if (debug_infrun)
-                  fprintf_unfiltered (gdb_stdlog,
-                                      "infrun: unexpected thread\n");
-
-                thread_hop_needed = 1;
-                stepping_past_singlestep_breakpoint = 1;
-                saved_singlestep_ptid = singlestep_ptid;
-              }
-           }
-       }
-
-      if (thread_hop_needed)
-       {
-         struct regcache *thread_regcache;
-         int remove_status = 0;
-
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: thread_hop_needed\n");
-
-         /* Switch context before touching inferior memory, the
-            previous thread may have exited.  */
-         if (!ptid_equal (inferior_ptid, ecs->ptid))
-           context_switch (ecs->ptid);
-
-         /* Saw a breakpoint, but it was hit by the wrong thread.
-            Just continue.  */
-
-         if (singlestep_breakpoints_inserted_p)
-           {
-             /* Pull the single step breakpoints out of the target.  */
-             remove_single_step_breakpoints ();
-             singlestep_breakpoints_inserted_p = 0;
-           }
-
-         /* If the arch can displace step, don't remove the
-            breakpoints.  */
-         thread_regcache = get_thread_regcache (ecs->ptid);
-         if (!use_displaced_stepping (get_regcache_arch (thread_regcache)))
-           remove_status = remove_breakpoints ();
-
-         /* Did we fail to remove breakpoints?  If so, try
-            to set the PC past the bp.  (There's at least
-            one situation in which we can fail to remove
-            the bp's: On HP-UX's that use ttrace, we can't
-            change the address space of a vforking child
-            process until the child exits (well, okay, not
-            then either :-) or execs.  */
-         if (remove_status != 0)
-           error (_("Cannot step over breakpoint hit in wrong thread"));
-         else
-           {                   /* Single step */
-             if (!non_stop)
-               {
-                 /* Only need to require the next event from this
-                    thread in all-stop mode.  */
-                 waiton_ptid = ecs->ptid;
-                 infwait_state = infwait_thread_hop_state;
-               }
-
-             ecs->event_thread->stepping_over_breakpoint = 1;
-             keep_going (ecs);
-             return;
-           }
-       }
-    }
-
   /* See if something interesting happened to the non-current thread.  If
      so, then switch to that thread.  */
   if (!ptid_equal (ecs->ptid, inferior_ptid))
@@ -4088,9 +4185,36 @@ handle_signal_stop (struct execution_control_state *ecs)
   frame = get_current_frame ();
   gdbarch = get_frame_arch (frame);
 
+  /* Pull the single step breakpoints out of the target.  */
   if (singlestep_breakpoints_inserted_p)
     {
-      /* Pull the single step breakpoints out of the target.  */
+      /* However, before doing so, if this single-step breakpoint was
+        actually for another thread, set this thread up for moving
+        past it.  */
+      if (!ptid_equal (ecs->ptid, singlestep_ptid)
+         && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
+       {
+         struct regcache *regcache;
+         struct address_space *aspace;
+         CORE_ADDR pc;
+
+         regcache = get_thread_regcache (ecs->ptid);
+         aspace = get_regcache_aspace (regcache);
+         pc = regcache_read_pc (regcache);
+         if (single_step_breakpoint_inserted_here_p (aspace, pc))
+           {
+             if (debug_infrun)
+               {
+                 fprintf_unfiltered (gdb_stdlog,
+                                     "infrun: [%s] hit step over single-step"
+                                     " breakpoint of [%s]\n",
+                                     target_pid_to_str (ecs->ptid),
+                                     target_pid_to_str (singlestep_ptid));
+               }
+             ecs->hit_singlestep_breakpoint = 1;
+           }
+       }
+
       remove_single_step_breakpoints ();
       singlestep_breakpoints_inserted_p = 0;
     }
@@ -4118,7 +4242,7 @@ handle_signal_stop (struct execution_control_state *ecs)
          watchpoint expression.  We do this by single-stepping the
         target.
 
-        It may not be necessary to disable the watchpoint to stop over
+        It may not be necessary to disable the watchpoint to step over
         it.  For example, the PA can (with some kernel cooperation)
         single step over a watchpoint without disabling the watchpoint.
 
@@ -4285,6 +4409,12 @@ handle_signal_stop (struct execution_control_state *ecs)
     random_signal = !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
                      && currently_stepping (ecs->event_thread));
 
+  /* Perhaps the thread hit a single-step breakpoint of _another_
+     thread.  Single-step breakpoints are transparent to the
+     breakpoints module.  */
+  if (random_signal)
+    random_signal = !ecs->hit_singlestep_breakpoint;
+
   /* No?  Perhaps we got a moribund watchpoint.  */
   if (random_signal)
     random_signal = !stopped_by_watchpoint;
@@ -4295,7 +4425,6 @@ handle_signal_stop (struct execution_control_state *ecs)
   if (random_signal)
     {
       /* Signal not for debugging purposes.  */
-      int printed = 0;
       struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
       enum gdb_signal stop_signal = ecs->event_thread->suspend.stop_signal;
 
@@ -4305,13 +4434,6 @@ handle_signal_stop (struct execution_control_state *ecs)
 
       stopped_by_random_signal = 1;
 
-      if (signal_print[ecs->event_thread->suspend.stop_signal])
-       {
-         printed = 1;
-         target_terminal_ours_for_output ();
-         print_signal_received_reason
-                                    (ecs->event_thread->suspend.stop_signal);
-       }
       /* Always stop on signals if we're either just gaining control
         of the program, or the user explicitly requested this thread
         to remain stopped.  */
@@ -4320,13 +4442,20 @@ handle_signal_stop (struct execution_control_state *ecs)
          || (!inf->detaching
              && signal_stop_state (ecs->event_thread->suspend.stop_signal)))
        {
-         stop_stepping (ecs);
+         stop_waiting (ecs);
          return;
        }
-      /* If not going to stop, give terminal back
-         if we took it away.  */
-      else if (printed)
-       target_terminal_inferior ();
+
+      /* Notify observers the signal has "handle print" set.  Note we
+        returned early above if stopping; normal_stop handles the
+        printing in that case.  */
+      if (signal_print[ecs->event_thread->suspend.stop_signal])
+       {
+         /* The signal table tells us to print about this signal.  */
+         target_terminal_ours_for_output ();
+         observer_notify_signal_received (ecs->event_thread->suspend.stop_signal);
+         target_terminal_inferior ();
+       }
 
       /* Clear the signal if it should not be passed.  */
       if (signal_program[ecs->event_thread->suspend.stop_signal] == 0)
@@ -4355,7 +4484,11 @@ handle_signal_stop (struct execution_control_state *ecs)
          ecs->event_thread->step_after_step_resume_breakpoint = 1;
          /* Reset trap_expected to ensure breakpoints are re-inserted.  */
          ecs->event_thread->control.trap_expected = 0;
-         keep_going (ecs);
+
+         /* If we were nexting/stepping some other thread, switch to
+            it, so that we don't continue it, losing control.  */
+         if (!switch_back_to_stepped_thread (ecs))
+           keep_going (ecs);
          return;
        }
 
@@ -4516,7 +4649,7 @@ process_event_stop_test (struct execution_control_state *ecs)
 
        if (what.is_longjmp)
          {
-           check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
+           check_longjmp_breakpoint_for_call_dummy (ecs->event_thread);
 
            if (!frame_id_p (ecs->event_thread->initiating_frame))
              {
@@ -4549,9 +4682,7 @@ process_event_stop_test (struct execution_control_state *ecs)
           exists.  */
        delete_step_resume_breakpoint (ecs->event_thread);
 
-       ecs->event_thread->control.stop_step = 1;
-       print_end_stepping_range_reason ();
-       stop_stepping (ecs);
+       end_stepping_range (ecs);
       }
       return;
 
@@ -4601,10 +4732,12 @@ process_event_stop_test (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
       stop_print_frame = 1;
 
-      /* We are about to nuke the step_resume_breakpointt via the
-        cleanup chain, so no need to worry about it here.  */
+      /* Assume the thread stopped for a breapoint.  We'll still check
+        whether a/the breakpoint is there when the thread is next
+        resumed.  */
+      ecs->event_thread->stepping_over_breakpoint = 1;
 
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
 
     case BPSTAT_WHAT_STOP_SILENT:
@@ -4612,10 +4745,11 @@ process_event_stop_test (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
       stop_print_frame = 0;
 
-      /* We are about to nuke the step_resume_breakpoin via the
-        cleanup chain, so no need to worry about it here.  */
-
-      stop_stepping (ecs);
+      /* Assume the thread stopped for a breapoint.  We'll still check
+        whether a/the breakpoint is there when the thread is next
+        resumed.  */
+      ecs->event_thread->stepping_over_breakpoint = 1;
+      stop_waiting (ecs);
       return;
 
     case BPSTAT_WHAT_HP_STEP_RESUME:
@@ -4710,11 +4844,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (stop_pc == ecs->event_thread->control.step_range_start
          && stop_pc != ecs->stop_func_start
          && execution_direction == EXEC_REVERSE)
-       {
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
-       }
+       end_stepping_range (ecs);
       else
        keep_going (ecs);
 
@@ -4865,9 +4995,7 @@ process_event_stop_test (struct execution_control_state *ecs)
             thought it was a subroutine call but it was not.  Stop as
             well.  FENN */
          /* And this works the same backward as frontward.  MVS */
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
+         end_stepping_range (ecs);
          return;
        }
 
@@ -4981,9 +5109,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
          && step_stop_if_no_debug)
        {
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
+         end_stepping_range (ecs);
          return;
        }
 
@@ -5077,9 +5203,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          /* If we have no line number and the step-stop-if-no-debug
             is set, we stop the step so that the user has a chance to
             switch in assembly mode.  */
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
+         end_stepping_range (ecs);
          return;
        }
       else
@@ -5098,9 +5222,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          one instruction.  */
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: stepi/nexti\n");
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
       return;
     }
 
@@ -5112,9 +5234,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          or can this happen as a result of a return or longjmp?).  */
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: no line number info\n");
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
       return;
     }
 
@@ -5145,9 +5265,7 @@ process_event_stop_test (struct execution_control_state *ecs)
              && call_sal.symtab == ecs->event_thread->current_symtab)
            step_into_inline_frame (ecs->ptid);
 
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
+         end_stepping_range (ecs);
          return;
        }
       else
@@ -5159,11 +5277,7 @@ process_event_stop_test (struct execution_control_state *ecs)
              && call_sal.symtab == ecs->event_thread->current_symtab)
            keep_going (ecs);
          else
-           {
-             ecs->event_thread->control.stop_step = 1;
-             print_end_stepping_range_reason ();
-             stop_stepping (ecs);
-           }
+           end_stepping_range (ecs);
          return;
        }
     }
@@ -5186,11 +5300,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
        keep_going (ecs);
       else
-       {
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
-       }
+       end_stepping_range (ecs);
       return;
     }
 
@@ -5205,9 +5315,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog,
                             "infrun: stepped to a different line\n");
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
       return;
     }
 
@@ -5239,22 +5347,144 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
   if (!non_stop)
     {
       struct thread_info *tp;
+      struct thread_info *stepping_thread;
+      struct thread_info *step_over;
+
+      /* 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.  */
+
+      /* However, if we see an event for the stepping thread, then we
+        know all other threads have been moved past their breakpoints
+        already.  Let the caller check whether the step is finished,
+        etc., before deciding to move it past a breakpoint.  */
+      if (ecs->event_thread->control.step_range_end != 0)
+       return 0;
+
+      /* Check if the current thread is blocked on an incomplete
+        step-over, interrupted by a random signal.  */
+      if (ecs->event_thread->control.trap_expected
+         && ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_TRAP)
+       {
+         if (debug_infrun)
+           {
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: need to finish step-over of [%s]\n",
+                                 target_pid_to_str (ecs->event_thread->ptid));
+           }
+         keep_going (ecs);
+         return 1;
+       }
+
+      /* Check if the current thread is blocked by a single-step
+        breakpoint of another thread.  */
+      if (ecs->hit_singlestep_breakpoint)
+       {
+        if (debug_infrun)
+          {
+            fprintf_unfiltered (gdb_stdlog,
+                                "infrun: need to step [%s] over single-step "
+                                "breakpoint\n",
+                                target_pid_to_str (ecs->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 does as well, if we call it.  */
+      ecs->event_thread->control.trap_expected = 0;
+
+      /* Likewise, clear the signal if it should not be passed.  */
+      if (!signal_program[ecs->event_thread->suspend.stop_signal])
+       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+
+      /* If scheduler locking applies even if not stepping, there's no
+        need to walk over threads.  Above we've checked whether the
+        current thread is stepping.  If some other thread not the
+        event thread is stepping, then it must be that scheduler
+        locking is not in effect.  */
+      if (schedlock_applies (0))
+       return 0;
+
+      /* Look for the stepping/nexting thread, and check if any other
+        thread other than the stepping thread needs to start a
+        step-over.  Do all step-overs before actually proceeding with
+        step/next/etc.  */
+      stepping_thread = NULL;
+      step_over = NULL;
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         /* Ignore threads of processes we're not resuming.  */
+         if (!sched_multi
+             && ptid_get_pid (tp->ptid) != ptid_get_pid (inferior_ptid))
+           continue;
+
+         /* 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.  */
+         gdb_assert (!tp->control.trap_expected);
 
-      tp = iterate_over_threads (currently_stepping_or_nexting_callback,
-                                ecs->event_thread);
-      if (tp)
+         /* Did we find the stepping thread?  */
+         if (tp->control.step_range_end)
+           {
+             /* Yep.  There should only one though.  */
+             gdb_assert (stepping_thread == NULL);
+
+             /* The event thread is handled at the top, before we
+                enter this loop.  */
+             gdb_assert (tp != ecs->event_thread);
+
+             /* 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 (1));
+
+             stepping_thread = tp;
+           }
+         else if (thread_still_needs_step_over (tp))
+           {
+             step_over = tp;
+
+             /* At the top we've returned early if the event thread
+                is stepping.  If some other thread not the event
+                thread is stepping, then scheduler locking can't be
+                in effect, and we can resume this thread.  No need to
+                keep looking for the stepping thread then.  */
+             break;
+           }
+       }
+
+      if (step_over != NULL)
        {
-         /* 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)
+         tp = step_over;
+         if (debug_infrun)
            {
-             keep_going (ecs);
-             return 1;
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: need to step-over [%s]\n",
+                                 target_pid_to_str (tp->ptid));
            }
 
+         /* Only the stepping thread should have this set.  */
+         gdb_assert (tp->control.step_range_end == 0);
+
+         ecs->ptid = tp->ptid;
+         ecs->event_thread = tp;
+         switch_to_thread (ecs->ptid);
+         keep_going (ecs);
+         return 1;
+       }
+
+      if (stepping_thread != NULL)
+       {
+         struct frame_info *frame;
+         struct gdbarch *gdbarch;
+
+         tp = stepping_thread;
+
          /* 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.
@@ -5287,11 +5517,6 @@ switch_back_to_stepped_thread (struct execution_control_state *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");
@@ -5299,7 +5524,52 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
          ecs->event_thread = tp;
          ecs->ptid = tp->ptid;
          context_switch (ecs->ptid);
-         keep_going (ecs);
+
+         stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
+         frame = get_current_frame ();
+         gdbarch = get_frame_arch (frame);
+
+         /* If the PC of the thread we were trying to single-step has
+            changed, then that thread has trapped or been signaled,
+            but the event has not been reported to GDB yet.  Re-poll
+            the target looking for this particular thread's event
+            (i.e. temporarily enable schedlock) by:
+
+              - setting a break at the current PC
+              - resuming that particular thread, only (by setting
+                trap expected)
+
+            This prevents us continuously moving the single-step
+            breakpoint forward, one instruction at a time,
+            overstepping.  */
+
+         if (gdbarch_software_single_step_p (gdbarch)
+             && stop_pc != tp->prev_pc)
+           {
+             if (debug_infrun)
+               fprintf_unfiltered (gdb_stdlog,
+                                   "infrun: expected thread advanced also\n");
+
+             insert_single_step_breakpoint (get_frame_arch (frame),
+                                            get_frame_address_space (frame),
+                                            stop_pc);
+             singlestep_breakpoints_inserted_p = 1;
+             ecs->event_thread->control.trap_expected = 1;
+             singlestep_ptid = inferior_ptid;
+             singlestep_pc = stop_pc;
+
+             resume (0, GDB_SIGNAL_0);
+             prepare_to_wait (ecs);
+           }
+         else
+           {
+             if (debug_infrun)
+               fprintf_unfiltered (gdb_stdlog,
+                                   "infrun: expected thread still "
+                                   "hasn't advanced\n");
+             keep_going (ecs);
+           }
+
          return 1;
        }
     }
@@ -5317,19 +5587,6 @@ currently_stepping (struct thread_info *tp)
          || bpstat_should_step ());
 }
 
-/* Returns true if any thread *but* the one passed in "data" is in the
-   middle of stepping or of handling a "next".  */
-
-static int
-currently_stepping_or_nexting_callback (struct thread_info *tp, void *data)
-{
-  if (tp == data)
-    return 0;
-
-  return (tp->control.step_range_end
-         || tp->control.trap_expected);
-}
-
 /* Inferior has stepped into a subroutine call with source code that
    we should not step over.  Do step to the first line of code in
    it.  */
@@ -5386,9 +5643,7 @@ handle_step_into_function (struct gdbarch *gdbarch,
   if (ecs->stop_func_start == stop_pc)
     {
       /* We are already there: stop now.  */
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
       return;
     }
   else
@@ -5435,9 +5690,7 @@ handle_step_into_function_backward (struct gdbarch *gdbarch,
   if (stop_func_sal.pc == stop_pc)
     {
       /* We're there already.  Just stop stepping now.  */
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
     }
   else
     {
@@ -5577,7 +5830,7 @@ insert_longjmp_resume_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 static void
 insert_exception_resume_breakpoint (struct thread_info *tp,
-                                   struct block *b,
+                                   const struct block *b,
                                    struct frame_info *frame,
                                    struct symbol *sym)
 {
@@ -5620,7 +5873,7 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
 
 static void
 insert_exception_resume_from_probe (struct thread_info *tp,
-                                   const struct probe *probe,
+                                   const struct bound_probe *probe,
                                    struct frame_info *frame)
 {
   struct value *arg_value;
@@ -5654,7 +5907,7 @@ check_exception_resume (struct execution_control_state *ecs,
                        struct frame_info *frame)
 {
   volatile struct gdb_exception e;
-  const struct probe *probe;
+  struct bound_probe probe;
   struct symbol *func;
 
   /* First see if this exception unwinding breakpoint was set via a
@@ -5662,9 +5915,9 @@ check_exception_resume (struct execution_control_state *ecs,
      CFA and the HANDLER.  We ignore the CFA, extract the handler, and
      set a breakpoint there.  */
   probe = find_probe_by_pc (get_frame_pc (frame));
-  if (probe)
+  if (probe.probe)
     {
-      insert_exception_resume_from_probe (ecs->event_thread, probe, frame);
+      insert_exception_resume_from_probe (ecs->event_thread, &probe, frame);
       return;
     }
 
@@ -5674,7 +5927,7 @@ check_exception_resume (struct execution_control_state *ecs,
 
   TRY_CATCH (e, RETURN_MASK_ERROR)
     {
-      struct block *b;
+      const struct block *b;
       struct block_iterator iter;
       struct symbol *sym;
       int argno = 0;
@@ -5712,10 +5965,12 @@ check_exception_resume (struct execution_control_state *ecs,
 }
 
 static void
-stop_stepping (struct execution_control_state *ecs)
+stop_waiting (struct execution_control_state *ecs)
 {
   if (debug_infrun)
-    fprintf_unfiltered (gdb_stdlog, "infrun: stop_stepping\n");
+    fprintf_unfiltered (gdb_stdlog, "infrun: stop_waiting\n");
+
+  clear_step_over_info ();
 
   /* Let callers know we don't want to wait for the inferior anymore.  */
   ecs->wait_some_more = 0;
@@ -5749,6 +6004,9 @@ keep_going (struct execution_control_state *ecs)
     }
   else
     {
+      volatile struct gdb_exception e;
+      struct regcache *regcache = get_current_regcache ();
+
       /* Either the trap was not expected, but we are continuing
         anyway (if we got a signal, the user asked it be passed to
         the child)
@@ -5762,37 +6020,36 @@ keep_going (struct execution_control_state *ecs)
         already inserted breakpoints.  Therefore, we don't
         care if breakpoints were already inserted, or not.  */
 
-      if (ecs->event_thread->stepping_over_breakpoint)
+      /* If we need to step over a breakpoint, and we're not using
+        displaced stepping to do so, insert all breakpoints
+        (watchpoints, etc.) but the one we're stepping over, step one
+        instruction, and then re-insert the breakpoint when that step
+        is finished.  */
+      if ((ecs->hit_singlestep_breakpoint
+          || thread_still_needs_step_over (ecs->event_thread))
+         && !use_displaced_stepping (get_regcache_arch (regcache)))
        {
-         struct regcache *thread_regcache = get_thread_regcache (ecs->ptid);
-
-         if (!use_displaced_stepping (get_regcache_arch (thread_regcache)))
-           {
-             /* Since we can't do a displaced step, we have to remove
-                the breakpoint while we step it.  To keep things
-                simple, we remove them all.  */
-             remove_breakpoints ();
-           }
+         set_step_over_info (get_regcache_aspace (regcache),
+                             regcache_read_pc (regcache));
        }
       else
-       {
-         volatile struct gdb_exception e;
+       clear_step_over_info ();
 
-         /* Stop stepping if inserting breakpoints fails.  */
-         TRY_CATCH (e, RETURN_MASK_ERROR)
-           {
-             insert_breakpoints ();
-           }
-         if (e.reason < 0)
-           {
-             exception_print (gdb_stderr, e);
-             stop_stepping (ecs);
-             return;
-           }
+      /* Stop stepping if inserting breakpoints fails.  */
+      TRY_CATCH (e, RETURN_MASK_ERROR)
+       {
+         insert_breakpoints ();
+       }
+      if (e.reason < 0)
+       {
+         exception_print (gdb_stderr, e);
+         stop_waiting (ecs);
+         return;
        }
 
       ecs->event_thread->control.trap_expected
-       = ecs->event_thread->stepping_over_breakpoint;
+       = (ecs->event_thread->stepping_over_breakpoint
+          || ecs->hit_singlestep_breakpoint);
 
       /* Do not deliver GDB_SIGNAL_TRAP (except when the user
         explicitly specifies that such a signal should be delivered
@@ -5832,35 +6089,42 @@ prepare_to_wait (struct execution_control_state *ecs)
   ecs->wait_some_more = 1;
 }
 
+/* We are done with the step range of a step/next/si/ni command.
+   Called once for each n of a "step n" operation.  */
+
+static void
+end_stepping_range (struct execution_control_state *ecs)
+{
+  ecs->event_thread->control.stop_step = 1;
+  stop_waiting (ecs);
+}
+
 /* Several print_*_reason functions to print why the inferior has stopped.
    We always print something when the inferior exits, or receives a signal.
    The rest of the cases are dealt with later on in normal_stop and
    print_it_typical.  Ideally there should be a call to one of these
    print_*_reason functions functions from handle_inferior_event each time
-   stop_stepping is called.  */
+   stop_waiting is called.
 
-/* Print why the inferior has stopped.  
-   We are done with a step/next/si/ni command, print why the inferior has
-   stopped.  For now print nothing.  Print a message only if not in the middle
-   of doing a "step n" operation for n > 1.  */
+   Note that we don't call these directly, instead we delegate that to
+   the interpreters, through observers.  Interpreters then call these
+   with whatever uiout is right.  */
 
-static void
-print_end_stepping_range_reason (void)
+void
+print_end_stepping_range_reason (struct ui_out *uiout)
 {
-  if ((!inferior_thread ()->step_multi
-       || !inferior_thread ()->control.stop_step)
-      && ui_out_is_mi_like_p (current_uiout))
-    ui_out_field_string (current_uiout, "reason",
-                         async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
-}
+  /* For CLI-like interpreters, print nothing.  */
 
-/* The inferior was terminated by a signal, print why it stopped.  */
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason",
+                          async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
+    }
+}
 
-static void
-print_signal_exited_reason (enum gdb_signal siggnal)
+void
+print_signal_exited_reason (struct ui_out *uiout, enum gdb_signal siggnal)
 {
-  struct ui_out *uiout = current_uiout;
-
   annotate_signalled ();
   if (ui_out_is_mi_like_p (uiout))
     ui_out_field_string
@@ -5879,14 +6143,11 @@ print_signal_exited_reason (enum gdb_signal siggnal)
   ui_out_text (uiout, "The program no longer exists.\n");
 }
 
-/* The inferior program is finished, print why it stopped.  */
-
-static void
-print_exited_reason (int exitstatus)
+void
+print_exited_reason (struct ui_out *uiout, int exitstatus)
 {
   struct inferior *inf = current_inferior ();
   const char *pidstr = target_pid_to_str (pid_to_ptid (inf->pid));
-  struct ui_out *uiout = current_uiout;
 
   annotate_exited (exitstatus);
   if (exitstatus)
@@ -5913,18 +6174,11 @@ print_exited_reason (int exitstatus)
       ui_out_text (uiout, pidstr);
       ui_out_text (uiout, ") exited normally]\n");
     }
-  /* Support the --return-child-result option.  */
-  return_child_result_value = exitstatus;
 }
 
-/* Signal received, print why the inferior has stopped.  The signal table
-   tells us to print about it.  */
-
-static void
-print_signal_received_reason (enum gdb_signal siggnal)
+void
+print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
 {
-  struct ui_out *uiout = current_uiout;
-
   annotate_signal ();
 
   if (siggnal == GDB_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
@@ -5956,13 +6210,72 @@ print_signal_received_reason (enum gdb_signal siggnal)
   ui_out_text (uiout, ".\n");
 }
 
-/* Reverse execution: target ran out of history info, print why the inferior
-   has stopped.  */
+void
+print_no_history_reason (struct ui_out *uiout)
+{
+  ui_out_text (uiout, "\nNo more reverse-execution history.\n");
+}
 
-static void
-print_no_history_reason (void)
+/* Print current location without a level number, if we have changed
+   functions or hit a breakpoint.  Print source line if we have one.
+   bpstat_print contains the logic deciding in detail what to print,
+   based on the event(s) that just occurred.  */
+
+void
+print_stop_event (struct target_waitstatus *ws)
 {
-  ui_out_text (current_uiout, "\nNo more reverse-execution history.\n");
+  int bpstat_ret;
+  int source_flag;
+  int do_frame_printing = 1;
+  struct thread_info *tp = inferior_thread ();
+
+  bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws->kind);
+  switch (bpstat_ret)
+    {
+    case PRINT_UNKNOWN:
+      /* FIXME: cagney/2002-12-01: Given that a frame ID does (or
+        should) carry around the function and does (or should) use
+        that when doing a frame comparison.  */
+      if (tp->control.stop_step
+         && frame_id_eq (tp->control.step_frame_id,
+                         get_frame_id (get_current_frame ()))
+         && step_start_function == find_pc_function (stop_pc))
+       {
+         /* Finished step, just print source line.  */
+         source_flag = SRC_LINE;
+       }
+      else
+       {
+         /* Print location and source line.  */
+         source_flag = SRC_AND_LOC;
+       }
+      break;
+    case PRINT_SRC_AND_LOC:
+      /* Print location and source line.  */
+      source_flag = SRC_AND_LOC;
+      break;
+    case PRINT_SRC_ONLY:
+      source_flag = SRC_LINE;
+      break;
+    case PRINT_NOTHING:
+      /* Something bogus.  */
+      source_flag = SRC_LINE;
+      do_frame_printing = 0;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, _("Unknown value."));
+    }
+
+  /* The behavior of this routine with respect to the source
+     flag is:
+     SRC_LINE: Print only source line
+     LOCATION: Print only location
+     SRC_AND_LOC: Print location and source line.  */
+  if (do_frame_printing)
+    print_stack_frame (get_selected_frame (NULL), 0, source_flag, 1);
+
+  /* Display the auto-display expressions.  */
+  do_displays ();
 }
 
 /* Here to return control to GDB when the inferior stops for real.
@@ -5993,10 +6306,18 @@ normal_stop (void)
           && last.kind != TARGET_WAITKIND_NO_RESUMED)
     make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
 
-  /* In non-stop mode, we don't want GDB to switch threads behind the
-     user's back, to avoid races where the user is typing a command to
-     apply to thread x, but GDB switches to thread y before the user
-     finishes entering the command.  */
+  /* As we're presenting a stop, and potentially removing breakpoints,
+     update the thread list so we can tell whether there are threads
+     running on the target.  With target remote, for example, we can
+     only learn about new threads when we explicitly update the thread
+     list.  Do this before notifying the interpreters about signal
+     stops, end of stepping ranges, etc., so that the "new thread"
+     output is emitted before e.g., "Program received signal FOO",
+     instead of after.  */
+  update_thread_list ();
+
+  if (last.kind == TARGET_WAITKIND_STOPPED && stopped_by_random_signal)
+    observer_notify_signal_received (inferior_thread ()->suspend.stop_signal);
 
   /* As with the notification of thread events, we want to delay
      notifying the user that we've switched thread context until
@@ -6004,7 +6325,16 @@ normal_stop (void)
 
      There's no point in saying anything if the inferior has exited.
      Note that SIGNALLED here means "exited with a signal", not
-     "received a signal".  */
+     "received a signal".
+
+     Also skip saying anything in non-stop mode.  In that mode, as we
+     don't want GDB to switch threads behind the user's back, to avoid
+     races where the user is typing a command to apply to thread x,
+     but GDB switches to thread y before the user finishes entering
+     the command, fetch_inferior_event installs a cleanup to restore
+     the current thread back to the thread the user had selected right
+     after this event is handled, so we're not really switching, only
+     informing of a stop.  */
   if (!non_stop
       && !ptid_equal (previous_inferior_ptid, inferior_ptid)
       && target_has_execution
@@ -6027,7 +6357,8 @@ normal_stop (void)
       printf_filtered (_("No unwaited-for children left.\n"));
     }
 
-  if (!breakpoints_always_inserted_mode () && target_has_execution)
+  /* Note: this depends on the update_thread_list call above.  */
+  if (!breakpoints_should_be_inserted_now () && target_has_execution)
     {
       if (remove_breakpoints ())
        {
@@ -6044,14 +6375,19 @@ normal_stop (void)
   if (stopped_by_random_signal)
     disable_current_display ();
 
-  /* Don't print a message if in the middle of doing a "step n"
-     operation for n > 1 */
+  /* Notify observers if we finished a "step"-like command, etc.  */
   if (target_has_execution
       && last.kind != TARGET_WAITKIND_SIGNALLED
       && last.kind != TARGET_WAITKIND_EXITED
-      && inferior_thread ()->step_multi
       && inferior_thread ()->control.stop_step)
-    goto done;
+    {
+      /* But not if in the middle of doing a "step n" operation for
+        n > 1 */
+      if (inferior_thread ()->step_multi)
+       goto done;
+
+      observer_notify_end_stepping_range ();
+    }
 
   target_terminal_ours ();
   async_enable_stdin ();
@@ -6060,10 +6396,20 @@ normal_stop (void)
      display the frame below, but the current SAL will be incorrect
      during a user hook-stop function.  */
   if (has_stack_frames () && !stop_stack_dummy)
-    set_current_sal_from_frame (get_current_frame (), 1);
-
-  /* Let the user/frontend see the threads as stopped.  */
-  do_cleanups (old_chain);
+    set_current_sal_from_frame (get_current_frame ());
+
+  /* Let the user/frontend see the threads as stopped, but do nothing
+     if the thread was running an infcall.  We may be e.g., evaluating
+     a breakpoint condition.  In that case, the thread had state
+     THREAD_RUNNING before the infcall, and shall remain set to
+     running, all without informing the user/frontend about state
+     transition changes.  If this is actually a call command, then the
+     thread was originally already stopped, so there's no state to
+     finish either.  */
+  if (target_has_execution && inferior_thread ()->control.in_infcall)
+    discard_cleanups (old_chain);
+  else
+    do_cleanups (old_chain);
 
   /* Look up the hook_stop and run it (CLI internally handles problem
      of stop_command's pre-hook not existing).  */
@@ -6087,65 +6433,11 @@ normal_stop (void)
     {
       select_frame (get_current_frame ());
 
-      /* Print current location without a level number, if
-         we have changed functions or hit a breakpoint.
-         Print source line if we have one.
-         bpstat_print() contains the logic deciding in detail
-         what to print, based on the event(s) that just occurred.  */
-
       /* If --batch-silent is enabled then there's no need to print the current
         source location, and to try risks causing an error message about
         missing source files.  */
       if (stop_print_frame && !batch_silent)
-       {
-         int bpstat_ret;
-         int source_flag;
-         int do_frame_printing = 1;
-         struct thread_info *tp = inferior_thread ();
-
-         bpstat_ret = bpstat_print (tp->control.stop_bpstat, last.kind);
-         switch (bpstat_ret)
-           {
-           case PRINT_UNKNOWN:
-             /* FIXME: cagney/2002-12-01: Given that a frame ID does
-                (or should) carry around the function and does (or
-                should) use that when doing a frame comparison.  */
-             if (tp->control.stop_step
-                 && frame_id_eq (tp->control.step_frame_id,
-                                 get_frame_id (get_current_frame ()))
-                 && step_start_function == find_pc_function (stop_pc))
-               source_flag = SRC_LINE;         /* Finished step, just
-                                                  print source line.  */
-             else
-               source_flag = SRC_AND_LOC;      /* Print location and
-                                                  source line.  */
-             break;
-           case PRINT_SRC_AND_LOC:
-             source_flag = SRC_AND_LOC;        /* Print location and
-                                                  source line.  */
-             break;
-           case PRINT_SRC_ONLY:
-             source_flag = SRC_LINE;
-             break;
-           case PRINT_NOTHING:
-             source_flag = SRC_LINE;   /* something bogus */
-             do_frame_printing = 0;
-             break;
-           default:
-             internal_error (__FILE__, __LINE__, _("Unknown value."));
-           }
-
-         /* The behavior of this routine with respect to the source
-            flag is:
-            SRC_LINE: Print only source line
-            LOCATION: Print only location
-            SRC_AND_LOC: Print location and source line.  */
-         if (do_frame_printing)
-           print_stack_frame (get_selected_frame (NULL), 0, source_flag, 1);
-
-         /* Display the auto-display expressions.  */
-         do_displays ();
-       }
+       print_stop_event (&last);
     }
 
   /* Save the function value return registers, if we care.
@@ -6827,7 +7119,7 @@ save_infcall_suspend_state (void)
        }
     }
 
-  inf_state = XZALLOC (struct infcall_suspend_state);
+  inf_state = XCNEW (struct infcall_suspend_state);
 
   if (siginfo_data)
     {
@@ -7059,20 +7351,6 @@ discard_infcall_control_state (struct infcall_control_state *inf_status)
   xfree (inf_status);
 }
 \f
-int
-ptid_match (ptid_t ptid, ptid_t filter)
-{
-  if (ptid_equal (filter, minus_one_ptid))
-    return 1;
-  if (ptid_is_pid (filter)
-      && ptid_get_pid (ptid) == ptid_get_pid (filter))
-    return 1;
-  else if (ptid_equal (ptid, filter))
-    return 1;
-
-  return 0;
-}
-
 /* restore_inferior_ptid() will be used by the cleanup machinery
    to restore the inferior_ptid value saved in a call to
    save_inferior_ptid().  */
@@ -7100,7 +7378,7 @@ save_inferior_ptid (void)
   return make_cleanup (restore_inferior_ptid, saved_ptid_ptr);
 }
 
-/* See inferior.h.  */
+/* See infrun.h.  */
 
 void
 clear_exit_convenience_vars (void)
@@ -7291,7 +7569,7 @@ leave it stopped or free to run as needed."),
   signal_catch = (unsigned char *)
     xmalloc (sizeof (signal_catch[0]) * numsigs);
   signal_pass = (unsigned char *)
-    xmalloc (sizeof (signal_program[0]) * numsigs);
+    xmalloc (sizeof (signal_pass[0]) * numsigs);
   for (i = 0; i < numsigs; i++)
     {
       signal_stop[i] = 1;