Replace the sync_execution global with a new enum prompt_state tristate
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 51a032b8ae5aba39ab7ba6c8ad5edca138c0244a..25313b476a9f20df7b36daa1b4efcfe0f8130e55 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-2016 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"
 #include "objfiles.h"
 #include "completer.h"
 #include "target-descriptions.h"
+#include "target-dcache.h"
+#include "terminal.h"
+#include "solist.h"
+#include "event-loop.h"
+#include "thread-fsm.h"
+#include "common/enum-flags.h"
 
 /* Prototypes for local functions */
 
@@ -79,37 +83,63 @@ 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);
+void _initialize_infrun (void);
 
-static void xdb_handle_command (char *args, int from_tty);
+void nullify_last_target_wait_ptid (void);
 
-static int prepare_to_proceed (int);
+static void insert_hp_step_resume_breakpoint_at_frame (struct frame_info *);
 
-static void print_exited_reason (int exitstatus);
+static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
 
-static void print_signal_exited_reason (enum gdb_signal siggnal);
+static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
 
-static void print_no_history_reason (void);
+static int maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc);
 
-static void print_signal_received_reason (enum gdb_signal siggnal);
+/* Asynchronous signal handler registered as event loop source for
+   when we have pending events ready to be passed to the core.  */
+static struct async_event_handler *infrun_async_inferior_event_token;
 
-static void print_end_stepping_range_reason (void);
+/* Stores whether infrun_async was previously enabled or disabled.
+   Starts off as -1, indicating "never enabled/disabled".  */
+static int infrun_is_async = -1;
 
-void _initialize_infrun (void);
+/* See infrun.h.  */
 
-void nullify_last_target_wait_ptid (void);
+void
+infrun_async (int enable)
+{
+  if (infrun_is_async != enable)
+    {
+      infrun_is_async = enable;
 
-static void insert_hp_step_resume_breakpoint_at_frame (struct frame_info *);
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: infrun_async(%d)\n",
+                           enable);
 
-static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
+      if (enable)
+       mark_async_event_handler (infrun_async_inferior_event_token);
+      else
+       clear_async_event_handler (infrun_async_inferior_event_token);
+    }
+}
 
-static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
+/* See infrun.h.  */
+
+void
+mark_infrun_async_event_handler (void)
+{
+  mark_async_event_handler (infrun_async_inferior_event_token);
+}
 
 /* When set, stop the 'step' command if we enter a function which has
    no line number information.  The normal behavior is that we step
@@ -122,18 +152,18 @@ show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Mode of the step operation is %s.\n"), value);
 }
 
-/* In asynchronous mode, but simulating synchronous execution.  */
-
-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;
 
-/* Default behavior is to detach newly forked processes (legacy).  */
-int detach_fork = 1;
+/* If set (default for legacy reasons), when following a fork, GDB
+   will detach from one of the fork branches, child or parent.
+   Exactly which branch is detached depends on 'set follow-fork-mode'
+   setting.  */
+
+static int detach_fork = 1;
 
 int debug_displaced = 0;
 static void
@@ -181,64 +211,37 @@ set_disable_randomization (char *args, int from_tty,
             "this platform."));
 }
 
+/* User interface for non-stop mode.  */
+
+int non_stop = 0;
+static int non_stop_1 = 0;
+
+static void
+set_non_stop (char *args, int from_tty,
+             struct cmd_list_element *c)
+{
+  if (target_has_execution)
+    {
+      non_stop_1 = non_stop;
+      error (_("Cannot change this setting while the inferior is running."));
+    }
+
+  non_stop = non_stop_1;
+}
 
-/* If the program uses ELF-style shared libraries, then calls to
-   functions in shared libraries go through stubs, which live in a
-   table called the PLT (Procedure Linkage Table).  The first time the
-   function is called, the stub sends control to the dynamic linker,
-   which looks up the function's real address, patches the stub so
-   that future calls will go directly to the function, and then passes
-   control to the function.
-
-   If we are stepping at the source level, we don't want to see any of
-   this --- we just want to skip over the stub and the dynamic linker.
-   The simple approach is to single-step until control leaves the
-   dynamic linker.
-
-   However, on some systems (e.g., Red Hat's 5.2 distribution) the
-   dynamic linker calls functions in the shared C library, so you
-   can't tell from the PC alone whether the dynamic linker is still
-   running.  In this case, we use a step-resume breakpoint to get us
-   past the dynamic linker, as if we were using "next" to step over a
-   function call.
-
-   in_solib_dynsym_resolve_code() says whether we're in the dynamic
-   linker code or not.  Normally, this means we single-step.  However,
-   if SKIP_SOLIB_RESOLVER then returns non-zero, then its value is an
-   address where we can place a step-resume breakpoint to get past the
-   linker's symbol resolution function.
-
-   in_solib_dynsym_resolve_code() can generally be implemented in a
-   pretty portable way, by comparing the PC against the address ranges
-   of the dynamic linker's sections.
-
-   SKIP_SOLIB_RESOLVER is generally going to be system-specific, since
-   it depends on internal details of the dynamic linker.  It's usually
-   not too hard to figure out where to put a breakpoint, but it
-   certainly isn't portable.  SKIP_SOLIB_RESOLVER should do plenty of
-   sanity checking.  If it can't figure things out, returning zero and
-   getting the (possibly confusing) stepping behavior is better than
-   signalling an error, which will obscure the change in the
-   inferior's state.  */
-
-/* This function returns TRUE if pc is the address of an instruction
-   that lies within the dynamic linker (such as the event hook, or the
-   dld itself).
-
-   This function must be used only when a dynamic linker event has
-   been caught, and the inferior is being stepped out of the hook, or
-   undefined results are guaranteed.  */
-
-#ifndef SOLIB_IN_DYNAMIC_LINKER
-#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0
-#endif
+static void
+show_non_stop (struct ui_file *file, int from_tty,
+              struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file,
+                   _("Controlling the inferior in non-stop mode is %s.\n"),
+                   value);
+}
 
 /* "Observer mode" is somewhat like a more extreme version of
    non-stop, in which all GDB operations that might affect the
    target's execution have been disabled.  */
 
-static int non_stop_1 = 0;
-
 int observer_mode = 0;
 static int observer_mode_1 = 0;
 
@@ -246,8 +249,6 @@ static void
 set_observer_mode (char *args, int from_tty,
                   struct cmd_list_element *c)
 {
-  extern int pagination_enabled;
-
   if (target_has_execution)
     {
       observer_mode_1 = observer_mode;
@@ -271,7 +272,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;
     }
@@ -363,10 +363,6 @@ update_signals_program_target (void)
 
 static struct cmd_list_element *stop_command;
 
-/* Function inferior was in as of last step command.  */
-
-static struct symbol *step_start_function;
-
 /* Nonzero if we want to give control to the user when we're notified
    of shared library events by the dynamic linker.  */
 int stop_on_solib_events;
@@ -388,18 +384,6 @@ show_stop_on_solib_events (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* Nonzero means expecting a trace trap
-   and should stop the inferior and return silently when it happens.  */
-
-int stop_after_trap;
-
-/* Save register contents here when executing a "finish" command or are
-   about to pop a stack dummy frame, if-and-only-if proceed_to_finish is set.
-   Thus this contains the return value from the called function (assuming
-   values are returned in a register).  */
-
-struct regcache *stop_registers;
-
 /* Nonzero after stop if current stack frame should be printed.  */
 
 static int stop_print_frame;
@@ -414,8 +398,6 @@ static void context_switch (ptid_t ptid);
 
 void init_thread_stepping_state (struct thread_info *tss);
 
-static void init_infwait_state (void);
-
 static const char follow_fork_mode_child[] = "child";
 static const char follow_fork_mode_parent[] = "parent";
 
@@ -437,6 +419,248 @@ 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;
+  ptid_t parent_ptid, child_ptid;
+
+  has_vforked = (inferior_thread ()->pending_follow.kind
+                == TARGET_WAITKIND_VFORKED);
+  parent_ptid = inferior_ptid;
+  child_ptid = inferior_thread ()->pending_follow.value.related_pid;
+
+  if (has_vforked
+      && !non_stop /* Non-stop always resumes both branches.  */
+      && current_ui->prompt_state == PROMPT_BLOCKED
+      && !(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)
+       {
+         /* 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)
+           {
+             /* Ensure that we have a process ptid.  */
+             ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
+
+             target_terminal_ours_for_output ();
+             fprintf_filtered (gdb_stdlog,
+                               _("Detaching after %s from child %s.\n"),
+                               has_vforked ? "vfork" : "fork",
+                               target_pid_to_str (process_ptid));
+           }
+       }
+      else
+       {
+         struct inferior *parent_inf, *child_inf;
+         struct cleanup *old_chain;
+
+         /* Add process to GDB's tables.  */
+         child_inf = add_inferior (ptid_get_pid (child_ptid));
+
+         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 = child_ptid;
+         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_for_output ();
+         fprintf_filtered (gdb_stdlog,
+                           _("Attaching after %s %s to child %s.\n"),
+                           target_pid_to_str (parent_ptid),
+                           has_vforked ? "vfork" : "fork",
+                           target_pid_to_str (child_ptid));
+       }
+
+      /* Add the new inferior first, so that the target_detach below
+        doesn't unpush the target.  */
+
+      child_inf = add_inferior (ptid_get_pid (child_ptid));
+
+      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)
+       {
+         if (info_verbose || debug_infrun)
+           {
+             /* Ensure that we have a process ptid.  */
+             ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
+
+             target_terminal_ours_for_output ();
+             fprintf_filtered (gdb_stdlog,
+                               _("Detaching after fork from "
+                                 "child %s.\n"),
+                               target_pid_to_str (process_ptid));
+           }
+
+         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 = child_ptid;
+      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.  */
@@ -457,6 +681,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)
     {
@@ -508,6 +733,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,
@@ -519,14 +745,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))
+       /* 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.  */
@@ -563,6 +791,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
                  {
@@ -573,7 +802,7 @@ follow_fork (void)
                       issued is most likely not applicable to the
                       child, so just warn, and refuse to resume.  */
                    warning (_("Not resuming: switched threads "
-                              "before following fork child.\n"));
+                              "before following fork child."));
                  }
 
                /* Reset breakpoints in the child as appropriate.  */
@@ -597,14 +826,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
@@ -614,10 +845,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
@@ -649,8 +887,8 @@ proceed_after_vfork_done (struct thread_info *thread,
                            target_pid_to_str (thread->ptid));
 
       switch_to_thread (thread->ptid);
-      clear_proceed_status ();
-      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+      clear_proceed_status (0);
+      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
 
   return 0;
@@ -717,18 +955,22 @@ handle_vfork_child_exec_or_exit (int exec)
 
          if (debug_infrun || info_verbose)
            {
-             target_terminal_ours ();
+             target_terminal_ours_for_output ();
 
              if (exec)
-               fprintf_filtered (gdb_stdlog,
-                                 "Detaching vfork parent process "
-                                 "%d after child exec.\n",
-                                 inf->vfork_parent->pid);
+               {
+                 fprintf_filtered (gdb_stdlog,
+                                   _("Detaching vfork parent process "
+                                     "%d after child exec.\n"),
+                                   inf->vfork_parent->pid);
+               }
              else
-               fprintf_filtered (gdb_stdlog,
-                                 "Detaching vfork parent process "
-                                 "%d after child exit.\n",
-                                 inf->vfork_parent->pid);
+               {
+                 fprintf_filtered (gdb_stdlog,
+                                   _("Detaching vfork parent process "
+                                     "%d after child exit.\n"),
+                                   inf->vfork_parent->pid);
+               }
            }
 
          target_detach (NULL, 0);
@@ -838,10 +1080,12 @@ show_follow_exec_mode_string (struct ui_file *file, int from_tty,
 /* EXECD_PATHNAME is assumed to be non-NULL.  */
 
 static void
-follow_exec (ptid_t pid, char *execd_pathname)
+follow_exec (ptid_t ptid, char *execd_pathname)
 {
-  struct thread_info *th = inferior_thread ();
+  struct thread_info *th, *tmp;
   struct inferior *inf = current_inferior ();
+  int pid = ptid_get_pid (ptid);
+  ptid_t process_ptid;
 
   /* This is an exec event that we actually wish to pay attention to.
      Refresh our symbol table to the newly exec'd program, remove any
@@ -866,26 +1110,51 @@ follow_exec (ptid_t pid, char *execd_pathname)
 
   mark_breakpoints_out ();
 
-  update_breakpoints_after_exec ();
-
-  /* If there was one, it's gone now.  We cannot truly step-to-next
-     statement through an exec().  */
+  /* The target reports the exec event to the main thread, even if
+     some other thread does the exec, and even if the main thread was
+     stopped or already gone.  We may still have non-leader threads of
+     the process on our list.  E.g., on targets that don't have thread
+     exit events (like remote); or on native Linux in non-stop mode if
+     there were only two threads in the inferior and the non-leader
+     one is the one that execs (and nothing forces an update of the
+     thread list up to here).  When debugging remotely, it's best to
+     avoid extra traffic, when possible, so avoid syncing the thread
+     list with the target, and instead go ahead and delete all threads
+     of the process but one that reported the event.  Note this must
+     be done before calling update_breakpoints_after_exec, as
+     otherwise clearing the threads' resources would reference stale
+     thread breakpoints -- it may have been one of these threads that
+     stepped across the exec.  We could just clear their stepping
+     states, but as long as we're iterating, might as well delete
+     them.  Deleting them now rather than at the next user-visible
+     stop provides a nicer sequence of events for user and MI
+     notifications.  */
+  ALL_THREADS_SAFE (th, tmp)
+    if (ptid_get_pid (th->ptid) == pid && !ptid_equal (th->ptid, ptid))
+      delete_thread (th->ptid);
+
+  /* We also need to clear any left over stale state for the
+     leader/event thread.  E.g., if there was any step-resume
+     breakpoint or similar, it's gone now.  We cannot truly
+     step-to-next statement through an exec().  */
+  th = inferior_thread ();
   th->control.step_resume_breakpoint = NULL;
   th->control.exception_resume_breakpoint = NULL;
+  th->control.single_step_breakpoints = NULL;
   th->control.step_range_start = 0;
   th->control.step_range_end = 0;
 
-  /* The target reports the exec event to the main thread, even if
-     some other thread does the exec, and even if the main thread was
-     already stopped --- if debugging in non-stop mode, it's possible
-     the user had the main thread held stopped in the previous image
-     --- release it now.  This is the same behavior as step-over-exec
-     with scheduler-locking on in all-stop mode.  */
+  /* The user may have had the main thread held stopped in the
+     previous image (e.g., schedlock on, or non-stop).  Release
+     it now.  */
   th->stop_requested = 0;
 
+  update_breakpoints_after_exec ();
+
   /* What is this a.out's name?  */
+  process_ptid = pid_to_ptid (pid);
   printf_unfiltered (_("%s is executing new program: %s\n"),
-                    target_pid_to_str (inferior_ptid),
+                    target_pid_to_str (process_ptid),
                     execd_pathname);
 
   /* We've followed the inferior through an exec.  Therefore, the
@@ -895,15 +1164,13 @@ follow_exec (ptid_t pid, char *execd_pathname)
 
   breakpoint_init_inferior (inf_execd);
 
-  if (gdb_sysroot && *gdb_sysroot)
+  if (*gdb_sysroot != '\0')
     {
-      char *name = alloca (strlen (gdb_sysroot)
-                           + strlen (execd_pathname)
-                           + 1);
+      char *name = exec_file_find (execd_pathname, NULL);
 
-      strcpy (name, gdb_sysroot);
-      strcat (name, execd_pathname);
-      execd_pathname = name;
+      execd_pathname = (char *) alloca (strlen (name) + 1);
+      strcpy (execd_pathname, name);
+      xfree (name);
     }
 
   /* Reset the shared library package.  This ensures that we get a
@@ -916,20 +1183,21 @@ follow_exec (ptid_t pid, char *execd_pathname)
 
   if (follow_exec_mode_string == follow_exec_mode_new)
     {
-      struct program_space *pspace;
-
       /* The user wants to keep the old inferior and program spaces
         around.  Create a new fresh one, and switch to it.  */
 
-      inf = add_inferior (current_inferior ()->pid);
-      pspace = add_program_space (maybe_new_address_space ());
-      inf->pspace = pspace;
-      inf->aspace = pspace->aspace;
-
+      /* Do exit processing for the original inferior before adding
+        the new inferior so we don't have two active inferiors with
+        the same ptid, which can confuse find_inferior_ptid.  */
       exit_inferior_num_silent (current_inferior ()->num);
 
+      inf = add_inferior_with_spaces ();
+      inf->pid = pid;
+      target_follow_exec (inf, execd_pathname);
+
       set_current_inferior (inf);
-      set_current_program_space (pspace);
+      set_current_program_space (inf->pspace);
+      add_thread (ptid);
     }
   else
     {
@@ -985,30 +1253,141 @@ follow_exec (ptid_t pid, char *execd_pathname)
      matically get reset there in the new process.).  */
 }
 
-/* Non-zero if we just simulating a single-step.  This is needed
-   because we cannot remove the breakpoints in the inferior process
-   until after the `wait' in `wait_for_inferior'.  */
-static int singlestep_breakpoints_inserted_p = 0;
+/* The queue of threads that need to do a step-over operation to get
+   past e.g., a breakpoint.  What technique is used to step over the
+   breakpoint/watchpoint does not matter -- all threads end up in the
+   same queue, to maintain rough temporal order of execution, in order
+   to avoid starvation, otherwise, we could e.g., find ourselves
+   constantly stepping the same couple threads past their breakpoints
+   over and over, if the single-step finish fast enough.  */
+struct thread_info *step_over_queue_head;
+
+/* Bit flags indicating what the thread needs to step over.  */
+
+enum step_over_what_flag
+  {
+    /* Step over a breakpoint.  */
+    STEP_OVER_BREAKPOINT = 1,
+
+    /* Step past a non-continuable watchpoint, in order to let the
+       instruction execute so we can evaluate the watchpoint
+       expression.  */
+    STEP_OVER_WATCHPOINT = 2
+  };
+DEF_ENUM_FLAGS_TYPE (enum step_over_what_flag, step_over_what);
+
+/* Info about an instruction that is being stepped over.  */
+
+struct step_over_info
+{
+  /* If we're stepping past a breakpoint, this is the address space
+     and address of the instruction the breakpoint is set at.  We'll
+     skip inserting all breakpoints here.  Valid iff ASPACE is
+     non-NULL.  */
+  struct address_space *aspace;
+  CORE_ADDR address;
+
+  /* The instruction being stepped over triggers a nonsteppable
+     watchpoint.  If true, we'll skip inserting watchpoints.  */
+  int nonsteppable_watchpoint_p;
+
+  /* The thread's global number.  */
+  int thread;
+};
+
+/* 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,
+                   int nonsteppable_watchpoint_p,
+                   int thread)
+{
+  step_over_info.aspace = aspace;
+  step_over_info.address = address;
+  step_over_info.nonsteppable_watchpoint_p = nonsteppable_watchpoint_p;
+  step_over_info.thread = thread;
+}
+
+/* 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)
+{
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+                       "infrun: clear_step_over_info\n");
+  step_over_info.aspace = NULL;
+  step_over_info.address = 0;
+  step_over_info.nonsteppable_watchpoint_p = 0;
+  step_over_info.thread = -1;
+}
+
+/* See infrun.h.  */
+
+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));
+}
+
+/* See infrun.h.  */
 
-/* The thread we inserted single-step breakpoints for.  */
-static ptid_t singlestep_ptid;
+int
+thread_is_stepping_over_breakpoint (int thread)
+{
+  return (step_over_info.thread != -1
+         && thread == step_over_info.thread);
+}
+
+/* See infrun.h.  */
 
-/* PC when we started this single-step.  */
-static CORE_ADDR singlestep_pc;
+int
+stepping_past_nonsteppable_watchpoint (void)
+{
+  return step_over_info.nonsteppable_watchpoint_p;
+}
 
-/* 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;
+/* Returns true if step-over info is valid.  */
 
-/* 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.
+static int
+step_over_info_valid_p (void)
+{
+  return (step_over_info.aspace != NULL
+         || stepping_past_nonsteppable_watchpoint ());
+}
 
-   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.  */
 
@@ -1098,12 +1477,6 @@ static ptid_t deferred_step_ptid;
    displaced step operation on it.  See displaced_step_prepare and
    displaced_step_fixup for details.  */
 
-struct displaced_step_request
-{
-  ptid_t ptid;
-  struct displaced_step_request *next;
-};
-
 /* Per-inferior displaced stepping state.  */
 struct displaced_step_inferior_state
 {
@@ -1113,9 +1486,9 @@ struct displaced_step_inferior_state
   /* The process this displaced step state refers to.  */
   int pid;
 
-  /* A queue of pending displaced stepping requests.  One entry per
-     thread that needs to do a displaced step.  */
-  struct displaced_step_request *step_request_queue;
+  /* True if preparing a displaced step ever failed.  If so, we won't
+     try displaced stepping for this inferior again.  */
+  int failed_before;
 
   /* If this is not null_ptid, this is the thread carrying out a
      displaced single-step in process PID.  This thread's state will
@@ -1157,6 +1530,52 @@ get_displaced_stepping_state (int pid)
   return NULL;
 }
 
+/* Returns true if any inferior has a thread doing a displaced
+   step.  */
+
+static int
+displaced_step_in_progress_any_inferior (void)
+{
+  struct displaced_step_inferior_state *state;
+
+  for (state = displaced_step_inferior_states;
+       state != NULL;
+       state = state->next)
+    if (!ptid_equal (state->step_ptid, null_ptid))
+      return 1;
+
+  return 0;
+}
+
+/* Return true if thread represented by PTID is doing a displaced
+   step.  */
+
+static int
+displaced_step_in_progress_thread (ptid_t ptid)
+{
+  struct displaced_step_inferior_state *displaced;
+
+  gdb_assert (!ptid_equal (ptid, null_ptid));
+
+  displaced = get_displaced_stepping_state (ptid_get_pid (ptid));
+
+  return (displaced != NULL && ptid_equal (displaced->step_ptid, ptid));
+}
+
+/* Return true if process PID has a thread doing a displaced step.  */
+
+static int
+displaced_step_in_progress (int pid)
+{
+  struct displaced_step_inferior_state *displaced;
+
+  displaced = get_displaced_stepping_state (pid);
+  if (displaced != NULL && !ptid_equal (displaced->step_ptid, null_ptid))
+    return 1;
+
+  return 0;
+}
+
 /* Add a new displaced stepping state for process PID to the displaced
    stepping state list, or return a pointer to an already existing
    entry, if it already exists.  Never returns NULL.  */
@@ -1172,7 +1591,7 @@ add_displaced_stepping_state (int pid)
     if (state->pid == pid)
       return state;
 
-  state = xcalloc (1, sizeof (*state));
+  state = XCNEW (struct displaced_step_inferior_state);
   state->pid = pid;
   state->next = displaced_step_inferior_states;
   displaced_step_inferior_states = state;
@@ -1248,7 +1667,7 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
     fprintf_filtered (file,
                      _("Debugger's willingness to use displaced stepping "
                        "to step over breakpoints is %s (currently %s).\n"),
-                     value, non_stop ? "on" : "off");
+                     value, target_is_non_stop_p () ? "on" : "off");
   else
     fprintf_filtered (file,
                      _("Debugger's willingness to use displaced stepping "
@@ -1256,15 +1675,24 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
 }
 
 /* Return non-zero if displaced stepping can/should be used to step
-   over breakpoints.  */
+   over breakpoints of thread TP.  */
 
 static int
-use_displaced_stepping (struct gdbarch *gdbarch)
+use_displaced_stepping (struct thread_info *tp)
 {
-  return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO && non_stop)
+  struct regcache *regcache = get_thread_regcache (tp->ptid);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct displaced_step_inferior_state *displaced_state;
+
+  displaced_state = get_displaced_stepping_state (ptid_get_pid (tp->ptid));
+
+  return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO
+           && target_is_non_stop_p ())
           || can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
          && gdbarch_displaced_step_copy_insn_p (gdbarch)
-         && !RECORD_IS_USED);
+         && find_record_target () == NULL
+         && (displaced_state == NULL
+             || !displaced_state->failed_before));
 }
 
 /* Clean out any stray displaced stepping state.  */
@@ -1285,7 +1713,8 @@ displaced_step_clear (struct displaced_step_inferior_state *displaced)
 static void
 displaced_step_clear_cleanup (void *arg)
 {
-  struct displaced_step_inferior_state *state = arg;
+  struct displaced_step_inferior_state *state
+    = (struct displaced_step_inferior_state *) arg;
 
   displaced_step_clear (state);
 }
@@ -1316,14 +1745,17 @@ displaced_step_dump_bytes (struct ui_file *file,
    explain how we handle this case instead.
 
    Returns 1 if preparing was successful -- this thread is going to be
-   stepped now; or 0 if displaced stepping this thread got queued.  */
+   stepped now; 0 if displaced stepping this thread got queued; or -1
+   if this instruction can't be displaced stepped.  */
+
 static int
-displaced_step_prepare (ptid_t ptid)
+displaced_step_prepare_throw (ptid_t ptid)
 {
   struct cleanup *old_cleanups, *ignore_cleanups;
   struct thread_info *tp = find_thread_ptid (ptid);
   struct regcache *regcache = get_thread_regcache (ptid);
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct address_space *aspace = get_regcache_aspace (regcache);
   CORE_ADDR original, copy;
   ULONGEST len;
   struct displaced_step_closure *closure;
@@ -1334,6 +1766,9 @@ displaced_step_prepare (ptid_t ptid)
      support displaced stepping.  */
   gdb_assert (gdbarch_displaced_step_copy_insn_p (gdbarch));
 
+  /* Nor if the thread isn't meant to step over a breakpoint.  */
+  gdb_assert (tp->control.trap_expected);
+
   /* Disable range stepping while executing in the scratch pad.  We
      want a single-step even if executing the displaced instruction in
      the scratch buffer lands within the stepping range (e.g., a
@@ -1349,28 +1784,13 @@ displaced_step_prepare (ptid_t ptid)
     {
       /* Already waiting for a displaced step to finish.  Defer this
         request and place in queue.  */
-      struct displaced_step_request *req, *new_req;
 
       if (debug_displaced)
        fprintf_unfiltered (gdb_stdlog,
-                           "displaced: defering step of %s\n",
+                           "displaced: deferring step of %s\n",
                            target_pid_to_str (ptid));
 
-      new_req = xmalloc (sizeof (*new_req));
-      new_req->ptid = ptid;
-      new_req->next = NULL;
-
-      if (displaced->step_request_queue)
-       {
-         for (req = displaced->step_request_queue;
-              req && req->next;
-              req = req->next)
-           ;
-         req->next = new_req;
-       }
-      else
-       displaced->step_request_queue = new_req;
-
+      thread_step_over_chain_enqueue (tp);
       return 0;
     }
   else
@@ -1391,8 +1811,30 @@ displaced_step_prepare (ptid_t ptid)
   copy = gdbarch_displaced_step_location (gdbarch);
   len = gdbarch_max_insn_length (gdbarch);
 
+  if (breakpoint_in_range_p (aspace, copy, len))
+    {
+      /* There's a breakpoint set in the scratch pad location range
+        (which is usually around the entry point).  We'd either
+        install it before resuming, which would overwrite/corrupt the
+        scratch pad, or if it was already inserted, this displaced
+        step would overwrite it.  The latter is OK in the sense that
+        we already assume that no thread is going to execute the code
+        in the scratch pad range (after initial startup) anyway, but
+        the former is unacceptable.  Simply punt and fallback to
+        stepping over this breakpoint in-line.  */
+      if (debug_displaced)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "displaced: breakpoint set in scratch pad.  "
+                             "Stepping over breakpoint in-line instead.\n");
+       }
+
+      do_cleanups (old_cleanups);
+      return -1;
+    }
+
   /* Save the original contents of the copy area.  */
-  displaced->step_saved_copy = xmalloc (len);
+  displaced->step_saved_copy = (gdb_byte *) xmalloc (len);
   ignore_cleanups = make_cleanup (free_current_contents,
                                  &displaced->step_saved_copy);
   status = target_read_memory (copy, displaced->step_saved_copy, len);
@@ -1412,9 +1854,14 @@ displaced_step_prepare (ptid_t ptid)
 
   closure = gdbarch_displaced_step_copy_insn (gdbarch,
                                              original, copy, regcache);
-
-  /* We don't support the fully-simulated case at present.  */
-  gdb_assert (closure);
+  if (closure == NULL)
+    {
+      /* The architecture doesn't know how or want to displaced step
+        this instruction or instruction sequence.  Fallback to
+        stepping over the breakpoint in-line.  */
+      do_cleanups (old_cleanups);
+      return -1;
+    }
 
   /* Save the information we need to fix things up if the step
      succeeds.  */
@@ -1440,16 +1887,61 @@ displaced_step_prepare (ptid_t ptid)
   return 1;
 }
 
-static void
-write_memory_ptid (ptid_t ptid, CORE_ADDR memaddr,
-                  const gdb_byte *myaddr, int len)
-{
-  struct cleanup *ptid_cleanup = save_inferior_ptid ();
+/* Wrapper for displaced_step_prepare_throw that disabled further
+   attempts at displaced stepping if we get a memory error.  */
 
-  inferior_ptid = ptid;
-  write_memory (memaddr, myaddr, len);
-  do_cleanups (ptid_cleanup);
-}
+static int
+displaced_step_prepare (ptid_t ptid)
+{
+  int prepared = -1;
+
+  TRY
+    {
+      prepared = displaced_step_prepare_throw (ptid);
+    }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      struct displaced_step_inferior_state *displaced_state;
+
+      if (ex.error != MEMORY_ERROR
+         && ex.error != NOT_SUPPORTED_ERROR)
+       throw_exception (ex);
+
+      if (debug_infrun)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: disabling displaced stepping: %s\n",
+                             ex.message);
+       }
+
+      /* Be verbose if "set displaced-stepping" is "on", silent if
+        "auto".  */
+      if (can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
+       {
+         warning (_("disabling displaced stepping: %s"),
+                  ex.message);
+       }
+
+      /* Disable further displaced stepping attempts.  */
+      displaced_state
+       = get_displaced_stepping_state (ptid_get_pid (ptid));
+      displaced_state->failed_before = 1;
+    }
+  END_CATCH
+
+  return prepared;
+}
+
+static void
+write_memory_ptid (ptid_t ptid, CORE_ADDR memaddr,
+                  const gdb_byte *myaddr, int len)
+{
+  struct cleanup *ptid_cleanup = save_inferior_ptid ();
+
+  inferior_ptid = ptid;
+  write_memory (memaddr, myaddr, len);
+  do_cleanups (ptid_cleanup);
+}
 
 /* Restore the contents of the copy area for thread PTID.  */
 
@@ -1468,28 +1960,43 @@ displaced_step_restore (struct displaced_step_inferior_state *displaced,
                                  displaced->step_copy));
 }
 
-static void
+/* If we displaced stepped an instruction successfully, adjust
+   registers and memory to yield the same effect the instruction would
+   have had if we had executed it at its original address, and return
+   1.  If the instruction didn't complete, relocate the PC and return
+   -1.  If the thread wasn't displaced stepping, return 0.  */
+
+static int
 displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
 {
   struct cleanup *old_cleanups;
   struct displaced_step_inferior_state *displaced
     = get_displaced_stepping_state (ptid_get_pid (event_ptid));
+  int ret;
 
   /* Was any thread of this process doing a displaced step?  */
   if (displaced == NULL)
-    return;
+    return 0;
 
   /* Was this event for the pid we displaced?  */
   if (ptid_equal (displaced->step_ptid, null_ptid)
       || ! ptid_equal (displaced->step_ptid, event_ptid))
-    return;
+    return 0;
 
   old_cleanups = make_cleanup (displaced_step_clear_cleanup, displaced);
 
   displaced_step_restore (displaced, displaced->step_ptid);
 
+  /* Fixup may need to read memory/registers.  Switch to the thread
+     that we're fixing up.  Also, target_stopped_by_watchpoint checks
+     the current thread.  */
+  switch_to_thread (event_ptid);
+
   /* Did the instruction complete successfully?  */
-  if (signal == GDB_SIGNAL_TRAP)
+  if (signal == GDB_SIGNAL_TRAP
+      && !(target_stopped_by_watchpoint ()
+          && (gdbarch_have_nonsteppable_watchpoint (displaced->step_gdbarch)
+              || target_have_steppable_watchpoint)))
     {
       /* Fix up the resulting state.  */
       gdbarch_displaced_step_fixup (displaced->step_gdbarch,
@@ -1497,6 +2004,7 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
                                     displaced->step_original,
                                     displaced->step_copy,
                                     get_thread_regcache (displaced->step_ptid));
+      ret = 1;
     }
   else
     {
@@ -1507,90 +2015,164 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
 
       pc = displaced->step_original + (pc - displaced->step_copy);
       regcache_write_pc (regcache, pc);
+      ret = -1;
     }
 
   do_cleanups (old_cleanups);
 
   displaced->step_ptid = null_ptid;
 
-  /* Are there any pending displaced stepping requests?  If so, run
-     one now.  Leave the state object around, since we're likely to
-     need it again soon.  */
-  while (displaced->step_request_queue)
-    {
-      struct displaced_step_request *head;
-      ptid_t ptid;
-      struct regcache *regcache;
-      struct gdbarch *gdbarch;
-      CORE_ADDR actual_pc;
-      struct address_space *aspace;
+  return ret;
+}
 
-      head = displaced->step_request_queue;
-      ptid = head->ptid;
-      displaced->step_request_queue = head->next;
-      xfree (head);
+/* Data to be passed around while handling an event.  This data is
+   discarded between events.  */
+struct execution_control_state
+{
+  ptid_t ptid;
+  /* The thread that got the event, if this was a thread event; NULL
+     otherwise.  */
+  struct thread_info *event_thread;
 
-      context_switch (ptid);
+  struct target_waitstatus ws;
+  int stop_func_filled_in;
+  CORE_ADDR stop_func_start;
+  CORE_ADDR stop_func_end;
+  const char *stop_func_name;
+  int wait_some_more;
 
-      regcache = get_thread_regcache (ptid);
-      actual_pc = regcache_read_pc (regcache);
-      aspace = get_regcache_aspace (regcache);
+  /* 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;
+};
 
-      if (breakpoint_here_p (aspace, actual_pc))
-       {
-         if (debug_displaced)
-           fprintf_unfiltered (gdb_stdlog,
-                               "displaced: stepping queued %s now\n",
-                               target_pid_to_str (ptid));
+/* Clear ECS and set it to point at TP.  */
 
-         displaced_step_prepare (ptid);
+static void
+reset_ecs (struct execution_control_state *ecs, struct thread_info *tp)
+{
+  memset (ecs, 0, sizeof (*ecs));
+  ecs->event_thread = tp;
+  ecs->ptid = tp->ptid;
+}
 
-         gdbarch = get_regcache_arch (regcache);
+static void keep_going_pass_signal (struct execution_control_state *ecs);
+static void prepare_to_wait (struct execution_control_state *ecs);
+static int keep_going_stepped_thread (struct thread_info *tp);
+static step_over_what thread_still_needs_step_over (struct thread_info *tp);
 
-         if (debug_displaced)
-           {
-             CORE_ADDR actual_pc = regcache_read_pc (regcache);
-             gdb_byte buf[4];
+/* Are there any pending step-over requests?  If so, run all we can
+   now and return true.  Otherwise, return false.  */
 
-             fprintf_unfiltered (gdb_stdlog, "displaced: run %s: ",
-                                 paddress (gdbarch, actual_pc));
-             read_memory (actual_pc, buf, sizeof (buf));
-             displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
-           }
+static int
+start_step_over (void)
+{
+  struct thread_info *tp, *next;
 
-         if (gdbarch_displaced_step_hw_singlestep (gdbarch,
-                                                   displaced->step_closure))
-           target_resume (ptid, 1, GDB_SIGNAL_0);
-         else
-           target_resume (ptid, 0, GDB_SIGNAL_0);
+  /* Don't start a new step-over if we already have an in-line
+     step-over operation ongoing.  */
+  if (step_over_info_valid_p ())
+    return 0;
+
+  for (tp = step_over_queue_head; tp != NULL; tp = next)
+    {
+      struct execution_control_state ecss;
+      struct execution_control_state *ecs = &ecss;
+      step_over_what step_what;
+      int must_be_in_line;
+
+      next = thread_step_over_chain_next (tp);
+
+      /* If this inferior already has a displaced step in process,
+        don't start a new one.  */
+      if (displaced_step_in_progress (ptid_get_pid (tp->ptid)))
+       continue;
 
-         /* Done, we're stepping a thread.  */
-         break;
+      step_what = thread_still_needs_step_over (tp);
+      must_be_in_line = ((step_what & STEP_OVER_WATCHPOINT)
+                        || ((step_what & STEP_OVER_BREAKPOINT)
+                            && !use_displaced_stepping (tp)));
+
+      /* We currently stop all threads of all processes to step-over
+        in-line.  If we need to start a new in-line step-over, let
+        any pending displaced steps finish first.  */
+      if (must_be_in_line && displaced_step_in_progress_any_inferior ())
+       return 0;
+
+      thread_step_over_chain_remove (tp);
+
+      if (step_over_queue_head == NULL)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: step-over queue now empty\n");
        }
-      else
+
+      if (tp->control.trap_expected
+         || tp->resumed
+         || tp->executing)
        {
-         int step;
-         struct thread_info *tp = inferior_thread ();
+         internal_error (__FILE__, __LINE__,
+                         "[%s] has inconsistent state: "
+                         "trap_expected=%d, resumed=%d, executing=%d\n",
+                         target_pid_to_str (tp->ptid),
+                         tp->control.trap_expected,
+                         tp->resumed,
+                         tp->executing);
+       }
 
-         /* The breakpoint we were sitting under has since been
-            removed.  */
-         tp->control.trap_expected = 0;
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: resuming [%s] for step-over\n",
+                           target_pid_to_str (tp->ptid));
+
+      /* keep_going_pass_signal skips the step-over if the breakpoint
+        is no longer inserted.  In all-stop, we want to keep looking
+        for a thread that needs a step-over instead of resuming TP,
+        because we wouldn't be able to resume anything else until the
+        target stops again.  In non-stop, the resume always resumes
+        only TP, so it's OK to let the thread resume freely.  */
+      if (!target_is_non_stop_p () && !step_what)
+       continue;
+
+      switch_to_thread (tp->ptid);
+      reset_ecs (ecs, tp);
+      keep_going_pass_signal (ecs);
 
-         /* Go back to what we were trying to do.  */
-         step = currently_stepping (tp);
+      if (!ecs->wait_some_more)
+       error (_("Command aborted."));
 
-         if (debug_displaced)
-           fprintf_unfiltered (gdb_stdlog,
-                               "displaced: breakpoint is gone: %s, step(%d)\n",
-                               target_pid_to_str (tp->ptid), step);
+      gdb_assert (tp->resumed);
 
-         target_resume (ptid, step, GDB_SIGNAL_0);
-         tp->suspend.stop_signal = GDB_SIGNAL_0;
+      /* If we started a new in-line step-over, we're done.  */
+      if (step_over_info_valid_p ())
+       {
+         gdb_assert (tp->control.trap_expected);
+         return 1;
+       }
 
-         /* This request was discarded.  See if there's any other
-            thread waiting for its turn.  */
+      if (!target_is_non_stop_p ())
+       {
+         /* On all-stop, shouldn't have resumed unless we needed a
+            step over.  */
+         gdb_assert (tp->control.trap_expected
+                     || tp->step_after_step_resume_breakpoint);
+
+         /* With remote targets (at least), in all-stop, we can't
+            issue any further remote commands until the program stops
+            again.  */
+         return 1;
        }
+
+      /* Either the thread no longer needed a step-over, or a new
+        displaced stepping sequence started.  Even in the latter
+        case, continue looking.  Maybe we can also start another
+        displaced step on a thread of other process. */
     }
+
+  return 0;
 }
 
 /* Update global variables holding ptids to hold NEW_PTID if they were
@@ -1598,28 +2180,17 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
 static void
 infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
 {
-  struct displaced_step_request *it;
   struct displaced_step_inferior_state *displaced;
 
   if (ptid_equal (inferior_ptid, old_ptid))
     inferior_ptid = 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)
     {
       if (ptid_equal (displaced->step_ptid, old_ptid))
        displaced->step_ptid = new_ptid;
-
-      for (it = displaced->step_request_queue; it; it = it->next)
-       if (ptid_equal (it->ptid, old_ptid))
-         it->ptid = new_ptid;
     }
 }
 
@@ -1630,19 +2201,24 @@ infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
 static void
 resume_cleanups (void *ignore)
 {
+  if (!ptid_equal (inferior_ptid, null_ptid))
+    delete_single_step_breakpoints (inferior_thread ());
+
   normal_stop ();
 }
 
 static const char schedlock_off[] = "off";
 static const char schedlock_on[] = "on";
 static const char schedlock_step[] = "step";
+static const char schedlock_replay[] = "replay";
 static const char *const scheduler_enums[] = {
   schedlock_off,
   schedlock_on,
   schedlock_step,
+  schedlock_replay,
   NULL
 };
-static const char *scheduler_mode = schedlock_off;
+static const char *scheduler_mode = schedlock_replay;
 static void
 show_scheduler_mode (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
@@ -1684,37 +2260,17 @@ maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc)
       && gdbarch_software_single_step (gdbarch, get_current_frame ()))
     {
       hw_step = 0;
-      /* Do not pull these breakpoints until after a `wait' in
-        `wait_for_inferior'.  */
-      singlestep_breakpoints_inserted_p = 1;
-      singlestep_ptid = inferior_ptid;
-      singlestep_pc = 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.  */
+/* See infrun.h.  */
 
 ptid_t
 user_visible_resume_ptid (int step)
 {
-  /* By default, resume all threads of all processes.  */
-  ptid_t resume_ptid = RESUME_ALL;
-
-  /* Maybe resume only all threads of the current process.  */
-  if (!sched_multi && target_supports_multi_process ())
-    {
-      resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
-    }
+  ptid_t resume_ptid;
 
-  /* Maybe resume a single thread after all.  */
   if (non_stop)
     {
       /* With non-stop mode on, threads are always handled
@@ -1722,37 +2278,166 @@ 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;
+    }
+  else if ((scheduler_mode == schedlock_replay)
+          && target_record_will_replay (minus_one_ptid, execution_direction))
     {
-      /* User-settable 'scheduler' mode requires solo thread resume.  */
+      /* User-settable 'scheduler' mode requires solo thread resume in replay
+        mode.  */
       resume_ptid = inferior_ptid;
     }
+  else if (!sched_multi && target_supports_multi_process ())
+    {
+      /* Resume all threads of the current process (and none of other
+        processes).  */
+      resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+    }
+  else
+    {
+      /* Resume all threads of all processes.  */
+      resume_ptid = RESUME_ALL;
+    }
 
   return resume_ptid;
 }
 
+/* Return a ptid representing the set of threads that we will resume,
+   in the perspective of the target, assuming run control handling
+   does not require leaving some threads stopped (e.g., stepping past
+   breakpoint).  USER_STEP indicates whether we're about to start the
+   target for a stepping command.  */
+
+static ptid_t
+internal_resume_ptid (int user_step)
+{
+  /* In non-stop, we always control threads individually.  Note that
+     the target may always work in non-stop mode even with "set
+     non-stop off", in which case user_visible_resume_ptid could
+     return a wildcard ptid.  */
+  if (target_is_non_stop_p ())
+    return inferior_ptid;
+  else
+    return user_visible_resume_ptid (user_step);
+}
+
+/* Wrapper for target_resume, that handles infrun-specific
+   bookkeeping.  */
+
+static void
+do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
+{
+  struct thread_info *tp = inferior_thread ();
+
+  /* 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
+     in-line (in any thread), we need to receive all signals to avoid
+     accidentally skipping a breakpoint during execution of a signal
+     handler.
+
+     Likewise if we're displaced stepping, otherwise a trap for a
+     breakpoint in a signal handler might be confused with the
+     displaced step finishing.  We don't make the displaced_step_fixup
+     step distinguish the cases instead, because:
+
+     - a backtrace while stopped in the signal handler would show the
+       scratch pad as frame older than the signal handler, instead of
+       the real mainline code.
+
+     - when the thread is later resumed, the signal handler would
+       return to the scratch pad area, which would no longer be
+       valid.  */
+  if (step_over_info_valid_p ()
+      || displaced_step_in_progress (ptid_get_pid (tp->ptid)))
+    target_pass_signals (0, NULL);
+  else
+    target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+
+  target_resume (resume_ptid, step, sig);
+}
+
 /* Resume the inferior, but allow a QUIT.  This is useful if the user
    wants to interrupt some lengthy single-stepping operation
    (for child processes, the SIGINT goes to the inferior, and so
    we get a SIGINT random_signal, but for remote debugging and perhaps
    other targets, that's not true).
 
-   STEP nonzero if we should step (zero to continue instead).
    SIG is the signal to give the inferior (zero for none).  */
 void
-resume (int step, enum gdb_signal sig)
+resume (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;
+  /* This represents the user's step vs continue request.  When
+     deciding whether "set scheduler-locking step" applies, it's the
+     user's intention that counts.  */
+  const int user_step = tp->control.stepping_command;
+  /* This represents what we'll actually request the target to do.
+     This can decay from a step to a continue, if e.g., we need to
+     implement single-stepping with breakpoints (software
+     single-step).  */
+  int step;
+
+  gdb_assert (!thread_is_in_step_over_chain (tp));
 
   QUIT;
 
+  if (tp->suspend.waitstatus_pending_p)
+    {
+      if (debug_infrun)
+       {
+         char *statstr;
+
+         statstr = target_waitstatus_to_string (&tp->suspend.waitstatus);
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: resume: thread %s has pending wait status %s "
+                             "(currently_stepping=%d).\n",
+                             target_pid_to_str (tp->ptid),  statstr,
+                             currently_stepping (tp));
+         xfree (statstr);
+       }
+
+      tp->resumed = 1;
+
+      /* FIXME: What should we do if we are supposed to resume this
+        thread with a signal?  Maybe we should maintain a queue of
+        pending signals to deliver.  */
+      if (sig != GDB_SIGNAL_0)
+       {
+         warning (_("Couldn't deliver signal %s to %s."),
+                  gdb_signal_to_name (sig), target_pid_to_str (tp->ptid));
+       }
+
+      tp->suspend.stop_signal = GDB_SIGNAL_0;
+      discard_cleanups (old_cleanups);
+
+      if (target_can_async_p ())
+       target_async (1);
+      return;
+    }
+
+  tp->stepped_breakpoint = 0;
+
+  /* Depends on stepped_breakpoint.  */
+  step = currently_stepping (tp);
+
   if (current_inferior ()->waiting_for_vfork_done)
     {
       /* Don't try to single-step a vfork parent that is waiting for
@@ -1774,9 +2459,10 @@ resume (int step, enum gdb_signal sig)
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
-                        "infrun: resume (step=%d, signal=%d), "
+                       "infrun: resume (step=%d, signal=%s), "
                        "trap_expected=%d, current thread [%s] at %s\n",
-                       step, sig, tp->control.trap_expected,
+                       step, gdb_signal_to_symbol_string (sig),
+                       tp->control.trap_expected,
                        target_pid_to_str (inferior_ptid),
                        paddress (gdbarch, pc));
 
@@ -1786,13 +2472,77 @@ resume (int step, enum gdb_signal sig)
      breakpoints can't be removed.  So we have to test for it here.  */
   if (breakpoint_here_p (aspace, pc) == permanent_breakpoint_here)
     {
-      if (gdbarch_skip_permanent_breakpoint_p (gdbarch))
-       gdbarch_skip_permanent_breakpoint (gdbarch, regcache);
+      if (sig != GDB_SIGNAL_0)
+       {
+         /* We have a signal to pass to the inferior.  The resume
+            may, or may not take us to the signal handler.  If this
+            is a step, we'll need to stop in the signal handler, if
+            there's one, (if the target supports stepping into
+            handlers), or in the next mainline instruction, if
+            there's no handler.  If this is a continue, we need to be
+            sure to run the handler with all breakpoints inserted.
+            In all cases, set a breakpoint at the current address
+            (where the handler returns to), and once that breakpoint
+            is hit, resume skipping the permanent breakpoint.  If
+            that breakpoint isn't hit, then we've stepped into the
+            signal handler (or hit some other event).  We'll delete
+            the step-resume breakpoint then.  */
+
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: resume: skipping permanent breakpoint, "
+                               "deliver signal first\n");
+
+         clear_step_over_info ();
+         tp->control.trap_expected = 0;
+
+         if (tp->control.step_resume_breakpoint == NULL)
+           {
+             /* Set a "high-priority" step-resume, as we don't want
+                user breakpoints at PC to trigger (again) when this
+                hits.  */
+             insert_hp_step_resume_breakpoint_at_frame (get_current_frame ());
+             gdb_assert (tp->control.step_resume_breakpoint->loc->permanent);
+
+             tp->step_after_step_resume_breakpoint = step;
+           }
+
+         insert_breakpoints ();
+       }
       else
-       error (_("\
-The program is stopped at a permanent breakpoint, but GDB does not know\n\
-how to step past a permanent breakpoint on this architecture.  Try using\n\
-a command like `return' or `jump' to continue execution."));
+       {
+         /* There's no signal to pass, we can go ahead and skip the
+            permanent breakpoint manually.  */
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: resume: skipping permanent breakpoint\n");
+         gdbarch_skip_permanent_breakpoint (gdbarch, regcache);
+         /* Update pc to reflect the new address from which we will
+            execute instructions.  */
+         pc = regcache_read_pc (regcache);
+
+         if (step)
+           {
+             /* We've already advanced the PC, so the stepping part
+                is done.  Now we need to arrange for a trap to be
+                reported to handle_inferior_event.  Set a breakpoint
+                at the current PC, and run to it.  Don't update
+                prev_pc, because if we end in
+                switch_back_to_stepped_thread, we want the "expected
+                thread advanced also" branch to be taken.  IOW, we
+                don't want this thread to step further from PC
+                (overstep).  */
+             gdb_assert (!step_over_info_valid_p ());
+             insert_single_step_breakpoint (gdbarch, aspace, pc);
+             insert_breakpoints ();
+
+             resume_ptid = internal_resume_ptid (user_step);
+             do_target_resume (resume_ptid, 0, GDB_SIGNAL_0);
+             discard_cleanups (old_cleanups);
+             tp->resumed = 1;
+             return;
+           }
+       }
     }
 
   /* If we have a breakpoint to step over, make sure to do a single
@@ -1811,34 +2561,50 @@ a command like `return' or `jump' to continue execution."));
      We can't use displaced stepping when we are waiting for vfork_done
      event, displaced stepping breaks the vfork child similarly as single
      step software breakpoint.  */
-  if (use_displaced_stepping (gdbarch)
-      && (tp->control.trap_expected
-         || (step && gdbarch_software_single_step_p (gdbarch)))
+  if (tp->control.trap_expected
+      && use_displaced_stepping (tp)
+      && !step_over_info_valid_p ()
       && sig == GDB_SIGNAL_0
       && !current_inferior ()->waiting_for_vfork_done)
     {
-      struct displaced_step_inferior_state *displaced;
+      int prepared = displaced_step_prepare (inferior_ptid);
 
-      if (!displaced_step_prepare (inferior_ptid))
+      if (prepared == 0)
        {
-         /* 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);
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "Got placed in step-over queue\n");
+
+         tp->control.trap_expected = 0;
          discard_cleanups (old_cleanups);
          return;
        }
+      else if (prepared < 0)
+       {
+         /* Fallback to stepping over the breakpoint in-line.  */
+
+         if (target_is_non_stop_p ())
+           stop_all_threads ();
+
+         set_step_over_info (get_regcache_aspace (regcache),
+                             regcache_read_pc (regcache), 0, tp->global_num);
+
+         step = maybe_software_singlestep (gdbarch, pc);
+
+         insert_breakpoints ();
+       }
+      else if (prepared > 0)
+       {
+         struct displaced_step_inferior_state *displaced;
 
-      /* Update pc to reflect the new address from which we will execute
-        instructions due to displaced stepping.  */
-      pc = regcache_read_pc (get_thread_regcache (inferior_ptid));
+         /* Update pc to reflect the new address from which we will
+            execute instructions due to displaced stepping.  */
+         pc = regcache_read_pc (get_thread_regcache (inferior_ptid));
 
-      displaced = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
-      step = gdbarch_displaced_step_hw_singlestep (gdbarch,
-                                                  displaced->step_closure);
+         displaced = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
+         step = gdbarch_displaced_step_hw_singlestep (gdbarch,
+                                                      displaced->step_closure);
+       }
     }
 
   /* Do we need to do it the hard way, w/temp breakpoints?  */
@@ -1869,8 +2635,9 @@ a command like `return' or `jump' to continue execution."));
      at the current address, deliver the signal without stepping, and
      once we arrive back at the step-resume breakpoint, actually step
      over the breakpoint we originally wanted to step over.  */
-  if (singlestep_breakpoints_inserted_p
-      && tp->control.trap_expected && sig != GDB_SIGNAL_0)
+  if (thread_has_single_step_breakpoints_set (tp)
+      && sig != GDB_SIGNAL_0
+      && step_over_info_valid_p ())
     {
       /* If we have nested signals or a pending signal is delivered
         immediately after a handler returns, might might already have
@@ -1883,121 +2650,141 @@ a command like `return' or `jump' to continue execution."));
          tp->step_after_step_resume_breakpoint = 1;
        }
 
-      remove_single_step_breakpoints ();
-      singlestep_breakpoints_inserted_p = 0;
+      delete_single_step_breakpoints (tp);
 
-      insert_breakpoints ();
+      clear_step_over_info ();
       tp->control.trap_expected = 0;
+
+      insert_breakpoints ();
     }
 
-  if (should_resume)
+  /* 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 (!(thread_has_single_step_breakpoints_set (tp) && step));
+
+  /* Decide the set of threads to ask the target to resume.  */
+  if (tp->control.trap_expected)
     {
-      ptid_t resume_ptid;
+      /* We're allowing a thread to run past a breakpoint it has
+        hit, either by single-stepping the thread with the breakpoint
+        removed, or by displaced stepping, with the breakpoint inserted.
+        In the former case, we need to single-step only this thread,
+        and keep others stopped, as they can miss this breakpoint if
+        allowed to run.  That's not really a problem for displaced
+        stepping, but, we still keep other threads stopped, in case
+        another thread is also stopped for a breakpoint waiting for
+        its turn in the displaced stepping queue.  */
+      resume_ptid = inferior_ptid;
+    }
+  else
+    resume_ptid = internal_resume_ptid (user_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));
+  if (execution_direction != EXEC_REVERSE
+      && step && breakpoint_inserted_here_p (aspace, pc))
+    {
+      /* There are two cases where we currently need to step a
+        breakpoint instruction when we have a signal to deliver:
+
+        - See handle_signal_stop where we handle random signals that
+        could take out us out of the stepping range.  Normally, in
+        that case we end up continuing (instead of stepping) over the
+        signal handler with a breakpoint at PC, but there are cases
+        where we should _always_ single-step, even if we have a
+        step-resume breakpoint, like when a software watchpoint is
+        set.  Assuming single-stepping and delivering a signal at the
+        same time would takes us to the signal handler, then we could
+        have removed the breakpoint at PC to step over it.  However,
+        some hardware step targets (like e.g., Mac OS) can't step
+        into signal handlers, and for those, we need to leave the
+        breakpoint at PC inserted, as otherwise if the handler
+        recurses and executes PC again, it'll miss the breakpoint.
+        So we leave the breakpoint inserted anyway, but we need to
+        record that we tried to step a breakpoint instruction, so
+        that adjust_pc_after_break doesn't end up confused.
+
+         - In non-stop if we insert a breakpoint (e.g., a step-resume)
+        in one thread after another thread that was stepping had been
+        momentarily paused for a step-over.  When we re-resume the
+        stepping thread, it may be resumed from that address with a
+        breakpoint that hasn't trapped yet.  Seen with
+        gdb.threads/non-stop-fair-events.exp, on targets that don't
+        do displaced stepping.  */
 
-      /* 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);
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: resume: [%s] stepped breakpoint\n",
+                           target_pid_to_str (tp->ptid));
 
-      /* 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;
-       }
+      tp->stepped_breakpoint = 1;
 
+      /* 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 (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));
-       }
-
-      /* Install inferior's terminal modes.  */
-      target_terminal_inferior ();
+       step = 0;
+    }
 
-      /* Avoid confusing the next resume, if the next stop/resume
-        happens to apply to another thread.  */
-      tp->suspend.stop_signal = GDB_SIGNAL_0;
+  if (debug_displaced
+      && tp->control.trap_expected
+      && use_displaced_stepping (tp)
+      && !step_over_info_valid_p ())
+    {
+      struct regcache *resume_regcache = get_thread_regcache (tp->ptid);
+      struct gdbarch *resume_gdbarch = get_regcache_arch (resume_regcache);
+      CORE_ADDR actual_pc = regcache_read_pc (resume_regcache);
+      gdb_byte buf[4];
 
-      /* 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));
     }
 
+  do_target_resume (resume_ptid, step, sig);
+  tp->resumed = 1;
   discard_cleanups (old_cleanups);
 }
 \f
 /* Proceeding.  */
 
+/* See infrun.h.  */
+
+/* Counter that tracks number of user visible stops.  This can be used
+   to tell whether a command has proceeded the inferior past the
+   current location.  This allows e.g., inferior function calls in
+   breakpoint commands to not interrupt the command list.  When the
+   call finishes successfully, the inferior is standing at the same
+   breakpoint as if nothing happened (and so we don't call
+   normal_stop).  */
+static ULONGEST current_stop_id;
+
+/* See infrun.h.  */
+
+ULONGEST
+get_stop_id (void)
+{
+  return current_stop_id;
+}
+
+/* Called when we report a user visible stop.  */
+
+static void
+new_stop_id (void)
+{
+  current_stop_id++;
+}
+
 /* Clear out all variables saying what to do when inferior is continued.
    First do this, then set the ones you want, then call `proceed'.  */
 
@@ -2009,6 +2796,45 @@ clear_proceed_status_thread (struct thread_info *tp)
                        "infrun: clear_proceed_status_thread (%s)\n",
                        target_pid_to_str (tp->ptid));
 
+  /* If we're starting a new sequence, then the previous finished
+     single-step is no longer relevant.  */
+  if (tp->suspend.waitstatus_pending_p)
+    {
+      if (tp->suspend.stop_reason == TARGET_STOPPED_BY_SINGLE_STEP)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: clear_proceed_status: pending "
+                               "event of %s was a finished step. "
+                               "Discarding.\n",
+                               target_pid_to_str (tp->ptid));
+
+         tp->suspend.waitstatus_pending_p = 0;
+         tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
+       }
+      else if (debug_infrun)
+       {
+         char *statstr;
+
+         statstr = target_waitstatus_to_string (&tp->suspend.waitstatus);
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: clear_proceed_status_thread: thread %s "
+                             "has pending wait status %s "
+                             "(currently_stepping=%d).\n",
+                             target_pid_to_str (tp->ptid), statstr,
+                             currently_stepping (tp));
+         xfree (statstr);
+       }
+    }
+
+  /* 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;
+
+  thread_fsm_delete (tp->thread_fsm);
+  tp->thread_fsm = NULL;
+
   tp->control.trap_expected = 0;
   tp->control.step_range_start = 0;
   tp->control.step_range_end = 0;
@@ -2016,39 +2842,53 @@ clear_proceed_status_thread (struct thread_info *tp)
   tp->control.step_frame_id = null_frame_id;
   tp->control.step_stack_frame_id = null_frame_id;
   tp->control.step_over_calls = STEP_OVER_UNDEBUGGABLE;
+  tp->control.step_start_function = NULL;
   tp->stop_requested = 0;
 
   tp->control.stop_step = 0;
 
   tp->control.proceed_to_finish = 0;
 
+  tp->control.command_interp = NULL;
+  tp->control.stepping_command = 0;
+
   /* 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)
+void
+clear_proceed_status (int step)
 {
-  if (is_exited (tp->ptid))
-    return 0;
+  /* With scheduler-locking replay, stop replaying other threads if we're
+     not replaying the user-visible resume ptid.
 
-  clear_proceed_status_thread (tp);
-  return 0;
-}
+     This is a convenience feature to not require the user to explicitly
+     stop replaying the other threads.  We're assuming that the user's
+     intent is to resume tracing the recorded process.  */
+  if (!non_stop && scheduler_mode == schedlock_replay
+      && target_record_is_replaying (minus_one_ptid)
+      && !target_record_will_replay (user_visible_resume_ptid (step),
+                                    execution_direction))
+    target_record_stop_replaying ();
 
-void
-clear_proceed_status (void)
-{
   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;
 
-  if (!ptid_equal (inferior_ptid, null_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))
     {
       struct inferior *inferior;
 
@@ -2063,90 +2903,62 @@ clear_proceed_status (void)
       inferior->control.stop_soon = NO_STOP_QUIETLY;
     }
 
-  stop_after_trap = 0;
-
   observer_notify_about_to_proceed ();
-
-  if (stop_registers)
-    {
-      regcache_xfree (stop_registers);
-      stop_registers = NULL;
-    }
 }
 
-/* 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_bp (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))
+         == ordinary_breakpoint_here)
+       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));
-
-  /* Don't switch over to WAIT_PTID if scheduler locking is on.  */
-  if (schedlock_enabled)
-    return 0;
+  return 0;
+}
 
-  /* 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;
+/* Check whether thread TP still needs to start a step-over in order
+   to make progress when resumed.  Returns an bitwise or of enum
+   step_over_what bits, indicating what needs to be stepped over.  */
 
-  /* 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);
+static step_over_what
+thread_still_needs_step_over (struct thread_info *tp)
+{
+  step_over_what what = 0;
 
-      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;
+  if (thread_still_needs_step_over_bp (tp))
+    what |= STEP_OVER_BREAKPOINT;
 
-         /* Switch back to WAIT_PID thread.  */
-         switch_to_thread (wait_ptid);
+  if (tp->stepping_over_watchpoint
+      && !target_have_steppable_watchpoint)
+    what |= STEP_OVER_WATCHPOINT;
 
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: prepare_to_proceed (step=%d), "
-                               "switched to [%s]\n",
-                               step, target_pid_to_str (inferior_ptid));
+  return what;
+}
 
-         /* 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;
-       }
-    }
+/* Returns true if scheduler locking applies.  STEP indicates whether
+   we're about to do a step/next-like command to a thread.  */
 
-  return 0;
+static int
+schedlock_applies (struct thread_info *tp)
+{
+  return (scheduler_mode == schedlock_on
+         || (scheduler_mode == schedlock_step
+             && tp->control.stepping_command)
+         || (scheduler_mode == schedlock_replay
+             && target_record_will_replay (minus_one_ptid,
+                                           execution_direction)));
 }
 
 /* Basic routine for continuing the program in various fashions.
@@ -2162,15 +2974,18 @@ prepare_to_proceed (int step)
    You should call clear_proceed_status before calling proceed.  */
 
 void
-proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
+proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 {
   struct regcache *regcache;
   struct gdbarch *gdbarch;
   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;
+  ptid_t resume_ptid;
+  struct execution_control_state ecss;
+  struct execution_control_state *ecs = &ecss;
+  struct cleanup *old_chain;
+  int started;
 
   /* If we're stopped at a fork/vfork, follow the branch set by the
      "set follow-fork-mode" command; otherwise, we'll just proceed
@@ -2191,15 +3006,17 @@ 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 ();
+
+  /* Fill in with reasonable starting values.  */
+  init_thread_stepping_state (tp);
 
-  if (step > 0)
-    step_start_function = find_pc_function (pc);
-  if (step < 0)
-    stop_after_trap = 1;
+  gdb_assert (!thread_is_in_step_over_chain (tp));
 
   if (addr == (CORE_ADDR) -1)
     {
-      if (pc == stop_pc && breakpoint_here_p (aspace, pc)
+      if (pc == stop_pc
+         && breakpoint_here_p (aspace, pc) == ordinary_breakpoint_here
          && execution_direction != EXEC_REVERSE)
        /* There is a breakpoint at the address we will resume at,
           step one instruction before inserting breakpoints so that
@@ -2209,150 +3026,185 @@ 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.  */
+  tp->control.command_interp = command_interp ();
+
+  resume_ptid = user_visible_resume_ptid (tp->control.stepping_command);
+
+  /* If an exception is thrown from this point on, make sure to
+     propagate GDB's knowledge of the executing state to the
+     frontend/user running state.  */
+  old_chain = make_cleanup (finish_thread_state_cleanup, &resume_ptid);
+
+  /* Even if RESUME_PTID is a wildcard, and we end up resuming fewer
+     threads (e.g., we might need to set threads stepping over
+     breakpoints first), 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 we pretend the inferior
+     doesn't run at all.  */
+  if (!tp->control.in_infcall)
+   set_running (resume_ptid, 1);
+
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
-                       "infrun: proceed (addr=%s, signal=%d, step=%d)\n",
-                       paddress (gdbarch, addr), siggnal, step);
+                       "infrun: proceed (addr=%s, signal=%s)\n",
+                       paddress (gdbarch, addr),
+                       gdb_signal_to_symbol_string (siggnal));
 
-  if (non_stop)
-    /* In non-stop, each thread is handled individually.  The context
-       must already be set to the right thread here.  */
-    ;
-  else
-    {
-      /* In a multi-threaded task we may select another thread and
-        then continue or step.
+  annotate_starting ();
 
-        But if the old thread was stopped at a breakpoint, it will
-        immediately cause another breakpoint stop without any
-        execution (i.e. it will report a breakpoint hit incorrectly).
-        So we must step over it first.
+  /* Make sure that output from GDB appears before output from the
+     inferior.  */
+  gdb_flush (gdb_stdout);
 
-        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;
-    }
+  /* In a multi-threaded task we may select another thread and
+     then continue or step.
 
-  /* prepare_to_proceed may change the current thread.  */
-  tp = inferior_thread ();
+     But if a thread that we're resuming had stopped at a breakpoint,
+     it will immediately cause another breakpoint stop without any
+     execution (i.e. it will report a breakpoint hit incorrectly).  So
+     we must step over it first.
+
+     Look for threads other than the current (TP) that reported a
+     breakpoint hit and haven't been resumed yet since.  */
 
-  if (force_step)
+  /* If scheduler locking applies, we can avoid iterating over all
+     threads.  */
+  if (!non_stop && !schedlock_applies (tp))
     {
-      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 ();
-    }
+      struct thread_info *current = tp;
 
-  /* 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 ();
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         /* Ignore the current thread here.  It's handled
+            afterwards.  */
+         if (tp == current)
+           continue;
 
-  if (!non_stop)
-    {
-      /* 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.  */
+         /* Ignore threads of processes we're not resuming.  */
+         if (!ptid_match (tp->ptid, resume_ptid))
+           continue;
 
-      struct thread_info *last_thread;
-      ptid_t last_ptid;
-      struct target_waitstatus last_status;
+         if (!thread_still_needs_step_over (tp))
+           continue;
 
-      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;
-           }
+         gdb_assert (!thread_is_in_step_over_chain (tp));
+
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: need to step-over [%s] first\n",
+                               target_pid_to_str (tp->ptid));
+
+         thread_step_over_chain_enqueue (tp);
        }
+
+      tp = current;
     }
 
-  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;
+  /* Enqueue the current thread last, so that we move all other
+     threads over their breakpoints first.  */
+  if (tp->stepping_over_breakpoint)
+    thread_step_over_chain_enqueue (tp);
 
-  annotate_starting ();
+  /* If the thread isn't started, we'll still need to set its prev_pc,
+     so that switch_back_to_stepped_thread knows the thread hasn't
+     advanced.  Must do this before resuming any thread, as in
+     all-stop/remote, once we resume we can't send any other packet
+     until the target stops again.  */
+  tp->prev_pc = regcache_read_pc (regcache);
 
-  /* Make sure that output from GDB appears before output from the
-     inferior.  */
-  gdb_flush (gdb_stdout);
+  started = start_step_over ();
 
-  /* Refresh prev_pc value just prior to resuming.  This used to be
-     done in stop_stepping, 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 
-     is used to initialize the starting line number in the ecs.  With an 
-     invalid value, the gdb next command ends up stopping at the position
-     represented by the next line table entry past our start position.
-     On platforms that generate one line table entry per line, this
-     is not a problem.  However, on the ia64, the compiler generates
-     extraneous line table entries that do not increase the line number.
-     When we issue the gdb next command on the ia64 after an inferior call
-     or a return command, we often end up a few instructions forward, still 
-     within the original line we started.
-
-     An attempt was made to refresh the prev_pc at the same time the
-     execution_control_state is initialized (for instance, just before
-     waiting for an inferior event).  But this approach did not work
-     because of platforms that use ptrace, where the pc register cannot
-     be read unless the inferior is stopped.  At that point, we are not
-     guaranteed the inferior is stopped and so the regcache_read_pc() call
-     can fail.  Setting the prev_pc value here ensures the value is updated
-     correctly when the inferior is stopped.  */
-  tp->prev_pc = regcache_read_pc (get_current_regcache ());
+  if (step_over_info_valid_p ())
+    {
+      /* Either this thread started a new in-line step over, or some
+        other thread was already doing one.  In either case, don't
+        resume anything else until the step-over is finished.  */
+    }
+  else if (started && !target_is_non_stop_p ())
+    {
+      /* A new displaced stepping sequence was started.  In all-stop,
+        we can't talk to the target anymore until it next stops.  */
+    }
+  else if (!non_stop && target_is_non_stop_p ())
+    {
+      /* In all-stop, but the target is always in non-stop mode.
+        Start all other threads that are implicitly resumed too.  */
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         /* Ignore threads of processes we're not resuming.  */
+         if (!ptid_match (tp->ptid, resume_ptid))
+           continue;
 
-  /* Fill in with reasonable starting values.  */
-  init_thread_stepping_state (tp);
+         if (tp->resumed)
+           {
+             if (debug_infrun)
+               fprintf_unfiltered (gdb_stdlog,
+                                   "infrun: proceed: [%s] resumed\n",
+                                   target_pid_to_str (tp->ptid));
+             gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
+             continue;
+           }
 
-  /* Reset to normal state.  */
-  init_infwait_state ();
+         if (thread_is_in_step_over_chain (tp))
+           {
+             if (debug_infrun)
+               fprintf_unfiltered (gdb_stdlog,
+                                   "infrun: proceed: [%s] needs step-over\n",
+                                   target_pid_to_str (tp->ptid));
+             continue;
+           }
 
-  /* Resume inferior.  */
-  resume (force_step || step || bpstat_should_step (),
-         tp->suspend.stop_signal);
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: proceed: resuming %s\n",
+                               target_pid_to_str (tp->ptid));
 
-  /* Wait for it to stop (if not standalone)
-     and in any case decode why it stopped, and act accordingly.  */
-  /* Do this only if we are not using the event loop, or if the target
-     does not support asynchronous execution.  */
-  if (!target_can_async_p ())
+         reset_ecs (ecs, tp);
+         switch_to_thread (tp->ptid);
+         keep_going_pass_signal (ecs);
+         if (!ecs->wait_some_more)
+           error (_("Command aborted."));
+       }
+    }
+  else if (!tp->resumed && !thread_is_in_step_over_chain (tp))
     {
-      wait_for_inferior ();
-      normal_stop ();
+      /* The thread wasn't started, and isn't queued, run it now.  */
+      reset_ecs (ecs, tp);
+      switch_to_thread (tp->ptid);
+      keep_going_pass_signal (ecs);
+      if (!ecs->wait_some_more)
+       error (_("Command aborted."));
     }
+
+  discard_cleanups (old_chain);
+
+  /* Tell the event loop to wait for it to stop.  If the target
+     supports asynchronous execution, it'll do this from within
+     target_resume.  */
+  if (!target_can_async_p ())
+    mark_async_event_handler (infrun_async_inferior_event_token);
 }
 \f
 
@@ -2399,56 +3251,17 @@ 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;
 
   previous_inferior_ptid = inferior_ptid;
-  init_infwait_state ();
 
   /* Discard any skipped inlined frames.  */
   clear_inline_frame_state (minus_one_ptid);
 }
 
 \f
-/* This enum encodes possible reasons for doing a target_wait, so that
-   wfi can call target_wait in one place.  (Ultimately the call will be
-   moved out of the infinite loop entirely.) */
-
-enum infwait_states
-{
-  infwait_normal_state,
-  infwait_thread_hop_state,
-  infwait_step_watch_state,
-  infwait_nonstep_watch_state
-};
-
-/* The PTID we'll do a target_wait on.*/
-ptid_t waiton_ptid;
-
-/* Current inferior wait state.  */
-static enum infwait_states infwait_state;
-
-/* Data to be passed around while handling an event.  This data is
-   discarded between events.  */
-struct execution_control_state
-{
-  ptid_t ptid;
-  /* The thread that got the event, if this was a thread event; NULL
-     otherwise.  */
-  struct thread_info *event_thread;
-
-  struct target_waitstatus ws;
-  int random_signal;
-  int stop_func_filled_in;
-  CORE_ADDR stop_func_start;
-  CORE_ADDR stop_func_end;
-  const char *stop_func_name;
-  int wait_some_more;
-};
 
 static void handle_inferior_event (struct execution_control_state *ecs);
 
@@ -2456,12 +3269,15 @@ static void handle_step_into_function (struct gdbarch *gdbarch,
                                       struct execution_control_state *ecs);
 static void handle_step_into_function_backward (struct gdbarch *gdbarch,
                                                struct execution_control_state *ecs);
+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 prepare_to_wait (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 keep_going (struct execution_control_state *ecs);
+static void process_event_stop_test (struct execution_control_state *ecs);
+static int switch_back_to_stepped_thread (struct execution_control_state *ecs);
 
 /* Callback for iterate over threads.  If the thread is stopped, but
    the user/frontend doesn't know about that yet, go through
@@ -2491,11 +3307,18 @@ 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.  */
       ecs->ptid = info->ptid;
-      ecs->event_thread = find_thread_ptid (info->ptid);
+      ecs->event_thread = info;
       ecs->ws.kind = TARGET_WAITKIND_STOPPED;
       ecs->ws.value.sig = GDB_SIGNAL_0;
 
@@ -2503,14 +3326,10 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
 
       if (!ecs->wait_some_more)
        {
-         struct thread_info *tp;
+         /* Cancel any running execution command.  */
+         thread_cancel_execution_command (info);
 
          normal_stop ();
-
-         /* Finish off the continuations.  */
-         tp = inferior_thread ();
-         do_all_intermediate_continuations_thread (tp, 1);
-         do_all_continuations_thread (tp, 1);
        }
 
       do_cleanups (old_chain);
@@ -2526,35 +3345,17 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
 static void
 infrun_thread_stop_requested (ptid_t ptid)
 {
-  struct displaced_step_inferior_state *displaced;
-
-  /* PTID was requested to stop.  Remove it from the displaced
-     stepping queue, so we don't try to resume it automatically.  */
-
-  for (displaced = displaced_step_inferior_states;
-       displaced;
-       displaced = displaced->next)
-    {
-      struct displaced_step_request *it, **prev_next_p;
-
-      it = displaced->step_request_queue;
-      prev_next_p = &displaced->step_request_queue;
-      while (it)
-       {
-         if (ptid_match (it->ptid, ptid))
-           {
-             *prev_next_p = it->next;
-             it->next = NULL;
-             xfree (it);
-           }
-         else
-           {
-             prev_next_p = &it->next;
-           }
+  struct thread_info *tp;
 
-         it = *prev_next_p;
-       }
-    }
+  /* PTID was requested to stop.  Remove matching threads from the
+     step-over queue, so we don't try to resume them
+     automatically.  */
+  ALL_NON_EXITED_THREADS (tp)
+    if (ptid_match (tp->ptid, ptid))
+      {
+       if (thread_is_in_step_over_chain (tp))
+         thread_step_over_chain_remove (tp);
+      }
 
   iterate_over_threads (infrun_thread_stop_requested_callback, &ptid);
 }
@@ -2566,59 +3367,76 @@ infrun_thread_thread_exit (struct thread_info *tp, int silent)
     nullify_last_target_wait_ptid ();
 }
 
-/* Callback for iterate_over_threads.  */
+/* Delete the step resume, single-step and longjmp/exception resume
+   breakpoints of TP.  */
 
-static int
-delete_step_resume_breakpoint_callback (struct thread_info *info, void *data)
+static void
+delete_thread_infrun_breakpoints (struct thread_info *tp)
 {
-  if (is_exited (info->ptid))
-    return 0;
-
-  delete_step_resume_breakpoint (info);
-  delete_exception_resume_breakpoint (info);
-  return 0;
+  delete_step_resume_breakpoint (tp);
+  delete_exception_resume_breakpoint (tp);
+  delete_single_step_breakpoints (tp);
 }
 
-/* In all-stop, delete the step resume breakpoint of any thread that
-   had one.  In non-stop, delete the step resume breakpoint of the
-   thread that just stopped.  */
+/* If the target still has execution, call FUNC for each thread that
+   just stopped.  In all-stop, that's all the non-exited threads; in
+   non-stop, that's the current thread, only.  */
+
+typedef void (*for_each_just_stopped_thread_callback_func)
+  (struct thread_info *tp);
 
 static void
-delete_step_thread_step_resume_breakpoint (void)
+for_each_just_stopped_thread (for_each_just_stopped_thread_callback_func func)
 {
-  if (!target_has_execution
-      || ptid_equal (inferior_ptid, null_ptid))
-    /* If the inferior has exited, we have already deleted the step
-       resume breakpoints out of GDB's lists.  */
+  if (!target_has_execution || ptid_equal (inferior_ptid, null_ptid))
     return;
 
-  if (non_stop)
+  if (target_is_non_stop_p ())
     {
-      /* If in non-stop mode, only delete the step-resume or
-        longjmp-resume breakpoint of the thread that just stopped
-        stepping.  */
-      struct thread_info *tp = inferior_thread ();
-
-      delete_step_resume_breakpoint (tp);
-      delete_exception_resume_breakpoint (tp);
+      /* If in non-stop mode, only the current thread stopped.  */
+      func (inferior_thread ());
     }
   else
-    /* In all-stop mode, delete all step-resume and longjmp-resume
-       breakpoints of any thread that had them.  */
-    iterate_over_threads (delete_step_resume_breakpoint_callback, NULL);
+    {
+      struct thread_info *tp;
+
+      /* In all-stop mode, all threads have stopped.  */
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         func (tp);
+       }
+    }
 }
 
-/* A cleanup wrapper.  */
+/* Delete the step resume and longjmp/exception resume breakpoints of
+   the threads that just stopped.  */
+
+static void
+delete_just_stopped_threads_infrun_breakpoints (void)
+{
+  for_each_just_stopped_thread (delete_thread_infrun_breakpoints);
+}
+
+/* Delete the single-step breakpoints of the threads that just
+   stopped.  */
 
 static void
-delete_step_thread_step_resume_breakpoint_cleanup (void *arg)
+delete_just_stopped_threads_single_step_breakpoints (void)
 {
-  delete_step_thread_step_resume_breakpoint ();
+  for_each_just_stopped_thread (delete_single_step_breakpoints);
 }
 
-/* Pretty print the results of target_wait, for debugging purposes.  */
+/* A cleanup wrapper.  */
 
 static void
+delete_just_stopped_threads_infrun_breakpoints_cleanup (void *arg)
+{
+  delete_just_stopped_threads_infrun_breakpoints ();
+}
+
+/* See infrun.h.  */
+
+void
 print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
                           const struct target_waitstatus *ws)
 {
@@ -2632,14 +3450,20 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
      is set.  */
 
   fprintf_unfiltered (tmp_stream,
-                     "infrun: target_wait (%d", PIDGET (waiton_ptid));
-  if (PIDGET (waiton_ptid) != -1)
+                     "infrun: target_wait (%d.%ld.%ld",
+                     ptid_get_pid (waiton_ptid),
+                     ptid_get_lwp (waiton_ptid),
+                     ptid_get_tid (waiton_ptid));
+  if (ptid_get_pid (waiton_ptid) != -1)
     fprintf_unfiltered (tmp_stream,
                        " [%s]", target_pid_to_str (waiton_ptid));
   fprintf_unfiltered (tmp_stream, ", status) =\n");
   fprintf_unfiltered (tmp_stream,
-                     "infrun:   %d [%s],\n",
-                     PIDGET (result_ptid), target_pid_to_str (result_ptid));
+                     "infrun:   %d.%ld.%ld [%s],\n",
+                     ptid_get_pid (result_ptid),
+                     ptid_get_lwp (result_ptid),
+                     ptid_get_tid (result_ptid),
+                     target_pid_to_str (result_ptid));
   fprintf_unfiltered (tmp_stream,
                      "infrun:   %s\n",
                      status_string);
@@ -2655,73 +3479,248 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
   ui_file_delete (tmp_stream);
 }
 
-/* Prepare and stabilize the inferior for detaching it.  E.g.,
-   detaching while a thread is displaced stepping is a recipe for
-   crashing it, as nothing would readjust the PC out of the scratch
-   pad.  */
+/* Select a thread at random, out of those which are resumed and have
+   had events.  */
 
-void
-prepare_for_detach (void)
+static struct thread_info *
+random_pending_event_thread (ptid_t waiton_ptid)
 {
-  struct inferior *inf = current_inferior ();
-  ptid_t pid_ptid = pid_to_ptid (inf->pid);
-  struct cleanup *old_chain_1;
-  struct displaced_step_inferior_state *displaced;
+  struct thread_info *event_tp;
+  int num_events = 0;
+  int random_selector;
 
-  displaced = get_displaced_stepping_state (inf->pid);
-
-  /* Is any thread of this process displaced stepping?  If not,
-     there's nothing else to do.  */
-  if (displaced == NULL || ptid_equal (displaced->step_ptid, null_ptid))
-    return;
+  /* First see how many events we have.  Count only resumed threads
+     that have an event pending.  */
+  ALL_NON_EXITED_THREADS (event_tp)
+    if (ptid_match (event_tp->ptid, waiton_ptid)
+       && event_tp->resumed
+       && event_tp->suspend.waitstatus_pending_p)
+      num_events++;
 
-  if (debug_infrun)
-    fprintf_unfiltered (gdb_stdlog,
-                       "displaced-stepping in-process while detaching");
+  if (num_events == 0)
+    return NULL;
 
-  old_chain_1 = make_cleanup_restore_integer (&inf->detaching);
-  inf->detaching = 1;
+  /* Now randomly pick a thread out of those that have had events.  */
+  random_selector = (int)
+    ((num_events * (double) rand ()) / (RAND_MAX + 1.0));
 
-  while (!ptid_equal (displaced->step_ptid, null_ptid))
-    {
-      struct cleanup *old_chain_2;
-      struct execution_control_state ecss;
-      struct execution_control_state *ecs;
+  if (debug_infrun && num_events > 1)
+    fprintf_unfiltered (gdb_stdlog,
+                       "infrun: Found %d events, selecting #%d\n",
+                       num_events, random_selector);
+
+  /* Select the Nth thread that has had an event.  */
+  ALL_NON_EXITED_THREADS (event_tp)
+    if (ptid_match (event_tp->ptid, waiton_ptid)
+       && event_tp->resumed
+       && event_tp->suspend.waitstatus_pending_p)
+      if (random_selector-- == 0)
+       break;
 
-      ecs = &ecss;
-      memset (ecs, 0, sizeof (*ecs));
+  return event_tp;
+}
 
-      overlay_cache_invalid = 1;
+/* Wrapper for target_wait that first checks whether threads have
+   pending statuses to report before actually asking the target for
+   more events.  */
 
-      if (deprecated_target_wait_hook)
-       ecs->ptid = deprecated_target_wait_hook (pid_ptid, &ecs->ws, 0);
-      else
-       ecs->ptid = target_wait (pid_ptid, &ecs->ws, 0);
+static ptid_t
+do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
+{
+  ptid_t event_ptid;
+  struct thread_info *tp;
 
+  /* First check if there is a resumed thread with a wait status
+     pending.  */
+  if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
+    {
+      tp = random_pending_event_thread (ptid);
+    }
+  else
+    {
       if (debug_infrun)
-       print_target_wait_results (pid_ptid, ecs->ptid, &ecs->ws);
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: Waiting for specific thread %s.\n",
+                           target_pid_to_str (ptid));
 
-      /* If an error happens while handling the event, propagate GDB's
-        knowledge of the executing state to the frontend/user running
-        state.  */
-      old_chain_2 = make_cleanup (finish_thread_state_cleanup,
-                                 &minus_one_ptid);
+      /* We have a specific thread to check.  */
+      tp = find_thread_ptid (ptid);
+      gdb_assert (tp != NULL);
+      if (!tp->suspend.waitstatus_pending_p)
+       tp = NULL;
+    }
 
-      /* Now figure out what to do with the result of the result.  */
-      handle_inferior_event (ecs);
+  if (tp != NULL
+      && (tp->suspend.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
+         || tp->suspend.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT))
+    {
+      struct regcache *regcache = get_thread_regcache (tp->ptid);
+      struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      CORE_ADDR pc;
+      int discard = 0;
 
-      /* No error, don't finish the state yet.  */
-      discard_cleanups (old_chain_2);
+      pc = regcache_read_pc (regcache);
 
-      /* Breakpoints and watchpoints are not installed on the target
-        at this point, and signals are passed directly to the
-        inferior, so this must mean the process is gone.  */
-      if (!ecs->wait_some_more)
+      if (pc != tp->suspend.stop_pc)
        {
-         discard_cleanups (old_chain_1);
-         error (_("Program exited while detaching"));
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: PC of %s changed.  was=%s, now=%s\n",
+                               target_pid_to_str (tp->ptid),
+                               paddress (gdbarch, tp->prev_pc),
+                               paddress (gdbarch, pc));
+         discard = 1;
        }
-    }
+      else if (!breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: previous breakpoint of %s, at %s gone\n",
+                               target_pid_to_str (tp->ptid),
+                               paddress (gdbarch, pc));
+
+         discard = 1;
+       }
+
+      if (discard)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: pending event of %s cancelled.\n",
+                               target_pid_to_str (tp->ptid));
+
+         tp->suspend.waitstatus.kind = TARGET_WAITKIND_SPURIOUS;
+         tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
+       }
+    }
+
+  if (tp != NULL)
+    {
+      if (debug_infrun)
+       {
+         char *statstr;
+
+         statstr = target_waitstatus_to_string (&tp->suspend.waitstatus);
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: Using pending wait status %s for %s.\n",
+                             statstr,
+                             target_pid_to_str (tp->ptid));
+         xfree (statstr);
+       }
+
+      /* Now that we've selected our final event LWP, un-adjust its PC
+        if it was a software breakpoint (and the target doesn't
+        always adjust the PC itself).  */
+      if (tp->suspend.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
+         && !target_supports_stopped_by_sw_breakpoint ())
+       {
+         struct regcache *regcache;
+         struct gdbarch *gdbarch;
+         int decr_pc;
+
+         regcache = get_thread_regcache (tp->ptid);
+         gdbarch = get_regcache_arch (regcache);
+
+         decr_pc = gdbarch_decr_pc_after_break (gdbarch);
+         if (decr_pc != 0)
+           {
+             CORE_ADDR pc;
+
+             pc = regcache_read_pc (regcache);
+             regcache_write_pc (regcache, pc + decr_pc);
+           }
+       }
+
+      tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
+      *status = tp->suspend.waitstatus;
+      tp->suspend.waitstatus_pending_p = 0;
+
+      /* Wake up the event loop again, until all pending events are
+        processed.  */
+      if (target_is_async_p ())
+       mark_async_event_handler (infrun_async_inferior_event_token);
+      return tp->ptid;
+    }
+
+  /* But if we don't find one, we'll have to wait.  */
+
+  if (deprecated_target_wait_hook)
+    event_ptid = deprecated_target_wait_hook (ptid, status, options);
+  else
+    event_ptid = target_wait (ptid, status, options);
+
+  return event_ptid;
+}
+
+/* Prepare and stabilize the inferior for detaching it.  E.g.,
+   detaching while a thread is displaced stepping is a recipe for
+   crashing it, as nothing would readjust the PC out of the scratch
+   pad.  */
+
+void
+prepare_for_detach (void)
+{
+  struct inferior *inf = current_inferior ();
+  ptid_t pid_ptid = pid_to_ptid (inf->pid);
+  struct cleanup *old_chain_1;
+  struct displaced_step_inferior_state *displaced;
+
+  displaced = get_displaced_stepping_state (inf->pid);
+
+  /* Is any thread of this process displaced stepping?  If not,
+     there's nothing else to do.  */
+  if (displaced == NULL || ptid_equal (displaced->step_ptid, null_ptid))
+    return;
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+                       "displaced-stepping in-process while detaching");
+
+  old_chain_1 = make_cleanup_restore_integer (&inf->detaching);
+  inf->detaching = 1;
+
+  while (!ptid_equal (displaced->step_ptid, null_ptid))
+    {
+      struct cleanup *old_chain_2;
+      struct execution_control_state ecss;
+      struct execution_control_state *ecs;
+
+      ecs = &ecss;
+      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 ();
+
+      ecs->ptid = do_target_wait (pid_ptid, &ecs->ws, 0);
+
+      if (debug_infrun)
+       print_target_wait_results (pid_ptid, ecs->ptid, &ecs->ws);
+
+      /* If an error happens while handling the event, propagate GDB's
+        knowledge of the executing state to the frontend/user running
+        state.  */
+      old_chain_2 = make_cleanup (finish_thread_state_cleanup,
+                                 &minus_one_ptid);
+
+      /* Now figure out what to do with the result of the result.  */
+      handle_inferior_event (ecs);
+
+      /* No error, don't finish the state yet.  */
+      discard_cleanups (old_chain_2);
+
+      /* Breakpoints and watchpoints are not installed on the target
+        at this point, and signals are passed directly to the
+        inferior, so this must mean the process is gone.  */
+      if (!ecs->wait_some_more)
+       {
+         discard_cleanups (old_chain_1);
+         error (_("Program exited while detaching"));
+       }
+    }
 
   discard_cleanups (old_chain_1);
 }
@@ -2737,50 +3736,154 @@ void
 wait_for_inferior (void)
 {
   struct cleanup *old_cleanups;
+  struct cleanup *thread_state_chain;
 
   if (debug_infrun)
     fprintf_unfiltered
       (gdb_stdlog, "infrun: wait_for_inferior ()\n");
 
-  old_cleanups =
-    make_cleanup (delete_step_thread_step_resume_breakpoint_cleanup, NULL);
+  old_cleanups
+    = make_cleanup (delete_just_stopped_threads_infrun_breakpoints_cleanup,
+                   NULL);
+
+  /* If an error happens while handling the event, propagate GDB's
+     knowledge of the executing state to the frontend/user running
+     state.  */
+  thread_state_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
 
   while (1)
     {
       struct execution_control_state ecss;
       struct execution_control_state *ecs = &ecss;
-      struct cleanup *old_chain;
+      ptid_t waiton_ptid = minus_one_ptid;
 
       memset (ecs, 0, sizeof (*ecs));
 
       overlay_cache_invalid = 1;
 
-      if (deprecated_target_wait_hook)
-       ecs->ptid = deprecated_target_wait_hook (waiton_ptid, &ecs->ws, 0);
-      else
-       ecs->ptid = target_wait (waiton_ptid, &ecs->ws, 0);
+      /* 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 ();
+
+      ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws, 0);
 
       if (debug_infrun)
        print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
 
-      /* If an error happens while handling the event, propagate GDB's
-        knowledge of the executing state to the frontend/user running
-        state.  */
-      old_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
-
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
 
-      /* No error, don't finish the state yet.  */
-      discard_cleanups (old_chain);
-
       if (!ecs->wait_some_more)
        break;
     }
 
+  /* No error, don't finish the state yet.  */
+  discard_cleanups (thread_state_chain);
+
   do_cleanups (old_cleanups);
 }
 
+/* Cleanup that reinstalls the readline callback handler, if the
+   target is running in the background.  If while handling the target
+   event something triggered a secondary prompt, like e.g., a
+   pagination prompt, we'll have removed the callback handler (see
+   gdb_readline_wrapper_line).  Need to do this as we go back to the
+   event loop, ready to process further input.  Note this has no
+   effect if the handler hasn't actually been removed, because calling
+   rl_callback_handler_install resets the line buffer, thus losing
+   input.  */
+
+static void
+reinstall_readline_callback_handler_cleanup (void *arg)
+{
+  struct ui *ui = current_ui;
+
+  if (!ui->async)
+    {
+      /* We're not going back to the top level event loop yet.  Don't
+        install the readline callback, as it'd prep the terminal,
+        readline-style (raw, noecho) (e.g., --batch).  We'll install
+        it the next time the prompt is displayed, when we're ready
+        for input.  */
+      return;
+    }
+
+  if (ui->command_editing && ui->prompt_state != PROMPT_BLOCKED)
+    gdb_rl_callback_handler_reinstall ();
+}
+
+/* Clean up the FSMs of threads that are now stopped.  In non-stop,
+   that's just the event thread.  In all-stop, that's all threads.  */
+
+static void
+clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs)
+{
+  struct thread_info *thr = ecs->event_thread;
+
+  if (thr != NULL && thr->thread_fsm != NULL)
+    thread_fsm_clean_up (thr->thread_fsm);
+
+  if (!non_stop)
+    {
+      ALL_NON_EXITED_THREADS (thr)
+        {
+         if (thr->thread_fsm == NULL)
+           continue;
+         if (thr == ecs->event_thread)
+           continue;
+
+         switch_to_thread (thr->ptid);
+         thread_fsm_clean_up (thr->thread_fsm);
+       }
+
+      if (ecs->event_thread != NULL)
+       switch_to_thread (ecs->event_thread->ptid);
+    }
+}
+
+/* Helper for all_uis_check_sync_execution_done that works on the
+   current UI.  */
+
+static void
+check_curr_ui_sync_execution_done (void)
+{
+  struct ui *ui = current_ui;
+
+  if (ui->prompt_state == PROMPT_NEEDED
+      && ui->async
+      && !gdb_in_secondary_prompt_p (ui))
+    {
+      target_terminal_ours ();
+      observer_notify_sync_execution_done ();
+    }
+}
+
+/* See infrun.h.  */
+
+void
+all_uis_check_sync_execution_done (void)
+{
+  struct switch_thru_all_uis state;
+
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      check_curr_ui_sync_execution_done ();
+    }
+}
+
+/* A cleanup that restores the execution direction to the value saved
+   in *ARG.  */
+
+static void
+restore_execution_direction (void *arg)
+{
+  enum exec_direction_kind *save_exec_dir = (enum exec_direction_kind *) arg;
+
+  execution_direction = *save_exec_dir;
+}
+
 /* Asynchronous version of wait_for_inferior.  It is called by the
    event loop whenever a change of state is detected on the file
    descriptor corresponding to the target.  It can be called more than
@@ -2797,11 +3900,21 @@ fetch_inferior_event (void *client_data)
   struct execution_control_state *ecs = &ecss;
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   struct cleanup *ts_old_chain;
-  int was_sync = sync_execution;
+  enum exec_direction_kind save_exec_dir = execution_direction;
   int cmd_done = 0;
+  ptid_t waiton_ptid = minus_one_ptid;
 
   memset (ecs, 0, sizeof (*ecs));
 
+  /* Events are always processed with the main UI as current UI.  This
+     way, warnings, debug output, etc. are always consistently sent to
+     the main console.  */
+  make_cleanup (restore_ui_cleanup, current_ui);
+  current_ui = main_ui;
+
+  /* End up with readline processing input, if necessary.  */
+  make_cleanup (reinstall_readline_callback_handler_cleanup, NULL);
+
   /* We're handling a live event, so make sure we're doing live
      debugging.  If we're looking at traceframes while the target is
      running, we're going to need to get back to that mode after
@@ -2820,15 +3933,17 @@ 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);
+  make_cleanup (restore_execution_direction, &save_exec_dir);
   execution_direction = target_execution_direction ();
 
-  if (deprecated_target_wait_hook)
-    ecs->ptid =
-      deprecated_target_wait_hook (waiton_ptid, &ecs->ws, TARGET_WNOHANG);
-  else
-    ecs->ptid = target_wait (waiton_ptid, &ecs->ws, TARGET_WNOHANG);
+  ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
+                             target_can_async_p () ? TARGET_WNOHANG : 0);
 
   if (debug_infrun)
     print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
@@ -2836,7 +3951,7 @@ fetch_inferior_event (void *client_data)
   /* If an error happens while handling the event, propagate GDB's
      knowledge of the executing state to the frontend/user running
      state.  */
-  if (!non_stop)
+  if (!target_is_non_stop_p ())
     ts_old_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
   else
     ts_old_chain = make_cleanup (finish_thread_state_cleanup, &ecs->ptid);
@@ -2845,30 +3960,56 @@ fetch_inferior_event (void *client_data)
      still for the thread which has thrown the exception.  */
   make_bpstat_clear_actions_cleanup ();
 
+  make_cleanup (delete_just_stopped_threads_infrun_breakpoints_cleanup, NULL);
+
   /* Now figure out what to do with the result of the result.  */
   handle_inferior_event (ecs);
 
   if (!ecs->wait_some_more)
     {
-      struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
+      struct inferior *inf = find_inferior_ptid (ecs->ptid);
+      int should_stop = 1;
+      struct thread_info *thr = ecs->event_thread;
+      int should_notify_stop = 1;
+
+      delete_just_stopped_threads_infrun_breakpoints ();
 
-      delete_step_thread_step_resume_breakpoint ();
+      if (thr != NULL)
+       {
+         struct thread_fsm *thread_fsm = thr->thread_fsm;
 
-      /* We may not find an inferior if this was a process exit.  */
-      if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
-       normal_stop ();
+         if (thread_fsm != NULL)
+           should_stop = thread_fsm_should_stop (thread_fsm);
+       }
 
-      if (target_has_execution
-         && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED
-         && ecs->ws.kind != TARGET_WAITKIND_EXITED
-         && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-         && ecs->event_thread->step_multi
-         && ecs->event_thread->control.stop_step)
-       inferior_event_handler (INF_EXEC_CONTINUE, NULL);
+      if (!should_stop)
+       {
+         keep_going (ecs);
+       }
       else
        {
-         inferior_event_handler (INF_EXEC_COMPLETE, NULL);
-         cmd_done = 1;
+         clean_up_just_stopped_threads_fsms (ecs);
+
+         if (thr != NULL && thr->thread_fsm != NULL)
+           {
+             should_notify_stop
+               = thread_fsm_should_notify_stop (thr->thread_fsm);
+           }
+
+         if (should_notify_stop)
+           {
+             int proceeded = 0;
+
+             /* We may not find an inferior if this was a process exit.  */
+             if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
+               proceeded = normal_stop ();
+
+             if (!proceeded)
+               {
+                 inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+                 cmd_done = 1;
+               }
+           }
        }
     }
 
@@ -2878,14 +4019,12 @@ fetch_inferior_event (void *client_data)
   /* Revert thread and frame.  */
   do_cleanups (old_chain);
 
-  /* If the inferior was in sync execution mode, and now isn't,
-     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);
+  /* If a UI was in sync execution mode, and now isn't, restore its
+     prompt (a synchronous execution command has finished, and we're
+     ready for input).  */
+  all_uis_check_sync_execution_done ();
 
   if (cmd_done
-      && !was_sync
       && exec_done_display_p
       && (ptid_equal (inferior_ptid, null_ptid)
          || !is_running (inferior_ptid)))
@@ -2910,10 +4049,21 @@ set_step_info (struct frame_info *frame, struct symtab_and_line sal)
 void
 init_thread_stepping_state (struct thread_info *tss)
 {
+  tss->stepped_breakpoint = 0;
   tss->stepping_over_breakpoint = 0;
+  tss->stepping_over_watchpoint = 0;
   tss->step_after_step_resume_breakpoint = 0;
 }
 
+/* Set the cached copy of the last ptid/waitstatus.  */
+
+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
@@ -2948,13 +4098,19 @@ context_switch (ptid_t ptid)
   switch_to_thread (ptid);
 }
 
+/* If the target can't tell whether we've hit breakpoints
+   (target_supports_stopped_by_sw_breakpoint), and we got a SIGTRAP,
+   check whether that could have been caused by a breakpoint.  If so,
+   adjust the PC, per gdbarch_decr_pc_after_break.  */
+
 static void
-adjust_pc_after_break (struct execution_control_state *ecs)
+adjust_pc_after_break (struct thread_info *thread,
+                      struct target_waitstatus *ws)
 {
   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.
@@ -2977,10 +4133,10 @@ adjust_pc_after_break (struct execution_control_state *ecs)
      target with both of these set in GDB history, and it seems unlikely to be
      correct, so gdbarch_have_nonsteppable_watchpoint is not checked here.  */
 
-  if (ecs->ws.kind != TARGET_WAITKIND_STOPPED)
+  if (ws->kind != TARGET_WAITKIND_STOPPED)
     return;
 
-  if (ecs->ws.value.sig != GDB_SIGNAL_TRAP)
+  if (ws->value.sig != GDB_SIGNAL_TRAP)
     return;
 
   /* In reverse execution, when a breakpoint is hit, the instruction
@@ -3012,19 +4168,37 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   if (execution_direction == EXEC_REVERSE)
     return;
 
+  /* If the target can tell whether the thread hit a SW breakpoint,
+     trust it.  Targets that can tell also adjust the PC
+     themselves.  */
+  if (target_supports_stopped_by_sw_breakpoint ())
+    return;
+
+  /* Note that relying on whether a breakpoint is planted in memory to
+     determine this can fail.  E.g,. the breakpoint could have been
+     removed since.  Or the thread could have been told to step an
+     instruction the size of a breakpoint instruction, and only
+     _after_ was a breakpoint inserted at its address.  */
+
   /* If this target does not decrement the PC after breakpoints, then
      we have nothing to do.  */
-  regcache = get_thread_regcache (ecs->ptid);
+  regcache = get_thread_regcache (thread->ptid);
   gdbarch = get_regcache_arch (regcache);
-  if (gdbarch_decr_pc_after_break (gdbarch) == 0)
+
+  decr_pc = gdbarch_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;
+
+  /* If the target can't tell whether a software breakpoint triggered,
+     fallback to figuring it out based on breakpoints we think were
+     inserted in the target, and on whether the thread was stepped or
+     continued.  */
 
   /* Check whether there actually is a software breakpoint inserted at
      that location.
@@ -3033,13 +4207,17 @@ adjust_pc_after_break (struct execution_control_state *ecs)
      removed a breakpoint, but stop events for that breakpoint were
      already queued and arrive later.  To suppress those spurious
      SIGTRAPs, we keep a list of such breakpoint locations for a bit,
-     and retire them after a number of stop events are reported.  */
+     and retire them after a number of stop events are reported.  Note
+     this is an heuristic and can thus get confused.  The real fix is
+     to get the "stopped by SW BP and needs adjustment" info out of
+     the target/kernel (and thus never reach here; see above).  */
   if (software_breakpoint_inserted_here_p (aspace, breakpoint_pc)
-      || (non_stop && moribund_breakpoint_here_p (aspace, breakpoint_pc)))
+      || (target_is_non_stop_p ()
+         && moribund_breakpoint_here_p (aspace, breakpoint_pc)))
     {
       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
@@ -3049,7 +4227,6 @@ adjust_pc_after_break (struct execution_control_state *ecs)
 
         The SIGTRAP can be due to a completed hardware single-step only if 
          - we didn't insert software single-step breakpoints
-         - the thread to be examined is still the current thread
          - this thread is currently being stepped
 
         If any of these events did not occur, we must have stopped due
@@ -3060,23 +4237,16 @@ adjust_pc_after_break (struct execution_control_state *ecs)
         software breakpoint.  In this case (prev_pc == breakpoint_pc),
         we also need to back up to the breakpoint address.  */
 
-      if (singlestep_breakpoints_inserted_p
-         || !ptid_equal (ecs->ptid, inferior_ptid)
-         || !currently_stepping (ecs->event_thread)
-         || ecs->event_thread->prev_pc == breakpoint_pc)
+      if (thread_has_single_step_breakpoints_set (thread)
+         || !currently_stepping (thread)
+         || (thread->stepped_breakpoint
+             && thread->prev_pc == breakpoint_pc))
        regcache_write_pc (regcache, breakpoint_pc);
 
       do_cleanups (old_cleanups);
     }
 }
 
-static void
-init_infwait_state (void)
-{
-  waiton_ptid = pid_to_ptid (-1);
-  infwait_state = infwait_normal_state;
-}
-
 static int
 stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
 {
@@ -3114,8 +4284,6 @@ handle_syscall_event (struct execution_control_state *ecs)
   if (catch_syscall_enabled () > 0
       && catching_syscall_number (syscall_number) > 0)
     {
-      enum bpstat_signal_value sval;
-
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: syscall number = '%d'\n",
                             syscall_number);
@@ -3124,34 +4292,18 @@ handle_syscall_event (struct execution_control_state *ecs)
        = bpstat_stop_status (get_regcache_aspace (regcache),
                              stop_pc, ecs->ptid, &ecs->ws);
 
-      sval = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
-      ecs->random_signal = sval == BPSTAT_SIGNAL_NO;
-
-      if (!ecs->random_signal)
+      if (bpstat_causes_stop (ecs->event_thread->control.stop_bpstat))
        {
          /* Catchpoint hit.  */
-         ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_TRAP;
          return 0;
        }
     }
 
   /* If no catchpoint triggered for this, then keep going.  */
-  ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
   keep_going (ecs);
   return 1;
 }
 
-/* Clear the supplied execution_control_state's stop_func_* fields.  */
-
-static void
-clear_stop_func (struct execution_control_state *ecs)
-{
-  ecs->stop_func_filled_in = 0;
-  ecs->stop_func_start = 0;
-  ecs->stop_func_end = 0;
-  ecs->stop_func_name = NULL;
-}
-
 /* Lazily fill in the execution_control_state's stop_func_* fields.  */
 
 static void
@@ -3167,84 +4319,562 @@ 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;
     }
 }
 
-/* Given an execution control state that has been freshly filled in
-   by an event from the inferior, figure out what it means and take
-   appropriate action.  */
 
-static void
-handle_inferior_event (struct execution_control_state *ecs)
+/* Return the STOP_SOON field of the inferior pointed at by PTID.  */
+
+static enum stop_kind
+get_inferior_stop_soon (ptid_t ptid)
 {
-  struct frame_info *frame;
-  struct gdbarch *gdbarch;
-  int stopped_by_watchpoint;
-  int stepped_after_stopped_by_watchpoint = 0;
-  struct symtab_and_line stop_pc_sal;
-  enum stop_kind stop_soon;
+  struct inferior *inf = find_inferior_ptid (ptid);
 
-  if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
-    {
-      /* We had an event in the inferior, but we are not interested in
-        handling it at this level.  The lower layers have already
-        done what needs to be done, if anything.
+  gdb_assert (inf != NULL);
+  return inf->control.stop_soon;
+}
 
-        One of the possible circumstances for this is when the
-        inferior produces output for the console.  The inferior has
-        not stopped, and we are ignoring the event.  Another possible
-        circumstance is any event which the lower level knows will be
-        reported multiple times without an intervening resume.  */
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
-      prepare_to_wait (ecs);
-      return;
-    }
+/* Wait for one event.  Store the resulting waitstatus in WS, and
+   return the event ptid.  */
 
-  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED
-      && target_can_async_p () && !sync_execution)
-    {
-      /* There were no unwaited-for children left in the target, but,
-        we're not synchronously waiting for events either.  Just
-        ignore.  Otherwise, if we were running a synchronous
-        execution command, we need to cancel it and give the user
-        back the terminal.  */
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog,
-                           "infrun: TARGET_WAITKIND_NO_RESUMED (ignoring)\n");
-      prepare_to_wait (ecs);
-      return;
-    }
+static ptid_t
+wait_one (struct target_waitstatus *ws)
+{
+  ptid_t event_ptid;
+  ptid_t wait_ptid = minus_one_ptid;
 
-  if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-      && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
-    {
-      struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
+  overlay_cache_invalid = 1;
 
-      gdb_assert (inf);
-      stop_soon = inf->control.stop_soon;
-    }
-  else
-    stop_soon = NO_STOP_QUIETLY;
+  /* 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 ();
 
-  /* Cache the last pid/waitstatus.  */
-  target_last_wait_ptid = ecs->ptid;
-  target_last_waitstatus = ecs->ws;
+  if (deprecated_target_wait_hook)
+    event_ptid = deprecated_target_wait_hook (wait_ptid, ws, 0);
+  else
+    event_ptid = target_wait (wait_ptid, ws, 0);
 
-  /* Always clear state belonging to the previous time we stopped.  */
-  stop_stack_dummy = STOP_NONE;
+  if (debug_infrun)
+    print_target_wait_results (wait_ptid, event_ptid, ws);
+
+  return event_ptid;
+}
+
+/* Generate a wrapper for target_stopped_by_REASON that works on PTID
+   instead of the current thread.  */
+#define THREAD_STOPPED_BY(REASON)              \
+static int                                     \
+thread_stopped_by_ ## REASON (ptid_t ptid)     \
+{                                              \
+  struct cleanup *old_chain;                   \
+  int res;                                     \
+                                               \
+  old_chain = save_inferior_ptid ();           \
+  inferior_ptid = ptid;                                \
+                                               \
+  res = target_stopped_by_ ## REASON ();       \
+                                               \
+  do_cleanups (old_chain);                     \
+                                               \
+  return res;                                  \
+}
+
+/* Generate thread_stopped_by_watchpoint.  */
+THREAD_STOPPED_BY (watchpoint)
+/* Generate thread_stopped_by_sw_breakpoint.  */
+THREAD_STOPPED_BY (sw_breakpoint)
+/* Generate thread_stopped_by_hw_breakpoint.  */
+THREAD_STOPPED_BY (hw_breakpoint)
+
+/* Cleanups that switches to the PTID pointed at by PTID_P.  */
 
-  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED)
-    {
-      /* No unwaited-for children left.  IOW, all resumed children
-        have exited.  */
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
+static void
+switch_to_thread_cleanup (void *ptid_p)
+{
+  ptid_t ptid = *(ptid_t *) ptid_p;
+
+  switch_to_thread (ptid);
+}
+
+/* Save the thread's event and stop reason to process it later.  */
+
+static void
+save_waitstatus (struct thread_info *tp, struct target_waitstatus *ws)
+{
+  struct regcache *regcache;
+  struct address_space *aspace;
+
+  if (debug_infrun)
+    {
+      char *statstr;
+
+      statstr = target_waitstatus_to_string (ws);
+      fprintf_unfiltered (gdb_stdlog,
+                         "infrun: saving status %s for %d.%ld.%ld\n",
+                         statstr,
+                         ptid_get_pid (tp->ptid),
+                         ptid_get_lwp (tp->ptid),
+                         ptid_get_tid (tp->ptid));
+      xfree (statstr);
+    }
+
+  /* Record for later.  */
+  tp->suspend.waitstatus = *ws;
+  tp->suspend.waitstatus_pending_p = 1;
+
+  regcache = get_thread_regcache (tp->ptid);
+  aspace = get_regcache_aspace (regcache);
+
+  if (ws->kind == TARGET_WAITKIND_STOPPED
+      && ws->value.sig == GDB_SIGNAL_TRAP)
+    {
+      CORE_ADDR pc = regcache_read_pc (regcache);
+
+      adjust_pc_after_break (tp, &tp->suspend.waitstatus);
+
+      if (thread_stopped_by_watchpoint (tp->ptid))
+       {
+         tp->suspend.stop_reason
+           = TARGET_STOPPED_BY_WATCHPOINT;
+       }
+      else if (target_supports_stopped_by_sw_breakpoint ()
+              && thread_stopped_by_sw_breakpoint (tp->ptid))
+       {
+         tp->suspend.stop_reason
+           = TARGET_STOPPED_BY_SW_BREAKPOINT;
+       }
+      else if (target_supports_stopped_by_hw_breakpoint ()
+              && thread_stopped_by_hw_breakpoint (tp->ptid))
+       {
+         tp->suspend.stop_reason
+           = TARGET_STOPPED_BY_HW_BREAKPOINT;
+       }
+      else if (!target_supports_stopped_by_hw_breakpoint ()
+              && hardware_breakpoint_inserted_here_p (aspace,
+                                                      pc))
+       {
+         tp->suspend.stop_reason
+           = TARGET_STOPPED_BY_HW_BREAKPOINT;
+       }
+      else if (!target_supports_stopped_by_sw_breakpoint ()
+              && software_breakpoint_inserted_here_p (aspace,
+                                                      pc))
+       {
+         tp->suspend.stop_reason
+           = TARGET_STOPPED_BY_SW_BREAKPOINT;
+       }
+      else if (!thread_has_single_step_breakpoints_set (tp)
+              && currently_stepping (tp))
+       {
+         tp->suspend.stop_reason
+           = TARGET_STOPPED_BY_SINGLE_STEP;
+       }
+    }
+}
+
+/* A cleanup that disables thread create/exit events.  */
+
+static void
+disable_thread_events (void *arg)
+{
+  target_thread_events (0);
+}
+
+/* See infrun.h.  */
+
+void
+stop_all_threads (void)
+{
+  /* We may need multiple passes to discover all threads.  */
+  int pass;
+  int iterations = 0;
+  ptid_t entry_ptid;
+  struct cleanup *old_chain;
+
+  gdb_assert (target_is_non_stop_p ());
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog, "infrun: stop_all_threads\n");
+
+  entry_ptid = inferior_ptid;
+  old_chain = make_cleanup (switch_to_thread_cleanup, &entry_ptid);
+
+  target_thread_events (1);
+  make_cleanup (disable_thread_events, NULL);
+
+  /* Request threads to stop, and then wait for the stops.  Because
+     threads we already know about can spawn more threads while we're
+     trying to stop them, and we only learn about new threads when we
+     update the thread list, do this in a loop, and keep iterating
+     until two passes find no threads that need to be stopped.  */
+  for (pass = 0; pass < 2; pass++, iterations++)
+    {
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: stop_all_threads, pass=%d, "
+                           "iterations=%d\n", pass, iterations);
+      while (1)
+       {
+         ptid_t event_ptid;
+         struct target_waitstatus ws;
+         int need_wait = 0;
+         struct thread_info *t;
+
+         update_thread_list ();
+
+         /* Go through all threads looking for threads that we need
+            to tell the target to stop.  */
+         ALL_NON_EXITED_THREADS (t)
+           {
+             if (t->executing)
+               {
+                 /* If already stopping, don't request a stop again.
+                    We just haven't seen the notification yet.  */
+                 if (!t->stop_requested)
+                   {
+                     if (debug_infrun)
+                       fprintf_unfiltered (gdb_stdlog,
+                                           "infrun:   %s executing, "
+                                           "need stop\n",
+                                           target_pid_to_str (t->ptid));
+                     target_stop (t->ptid);
+                     t->stop_requested = 1;
+                   }
+                 else
+                   {
+                     if (debug_infrun)
+                       fprintf_unfiltered (gdb_stdlog,
+                                           "infrun:   %s executing, "
+                                           "already stopping\n",
+                                           target_pid_to_str (t->ptid));
+                   }
+
+                 if (t->stop_requested)
+                   need_wait = 1;
+               }
+             else
+               {
+                 if (debug_infrun)
+                   fprintf_unfiltered (gdb_stdlog,
+                                       "infrun:   %s not executing\n",
+                                       target_pid_to_str (t->ptid));
+
+                 /* The thread may be not executing, but still be
+                    resumed with a pending status to process.  */
+                 t->resumed = 0;
+               }
+           }
+
+         if (!need_wait)
+           break;
+
+         /* If we find new threads on the second iteration, restart
+            over.  We want to see two iterations in a row with all
+            threads stopped.  */
+         if (pass > 0)
+           pass = -1;
+
+         event_ptid = wait_one (&ws);
+         if (ws.kind == TARGET_WAITKIND_NO_RESUMED)
+           {
+             /* All resumed threads exited.  */
+           }
+         else if (ws.kind == TARGET_WAITKIND_THREAD_EXITED
+                  || ws.kind == TARGET_WAITKIND_EXITED
+                  || ws.kind == TARGET_WAITKIND_SIGNALLED)
+           {
+             if (debug_infrun)
+               {
+                 ptid_t ptid = pid_to_ptid (ws.value.integer);
+
+                 fprintf_unfiltered (gdb_stdlog,
+                                     "infrun: %s exited while "
+                                     "stopping threads\n",
+                                     target_pid_to_str (ptid));
+               }
+           }
+         else
+           {
+             struct inferior *inf;
+
+             t = find_thread_ptid (event_ptid);
+             if (t == NULL)
+               t = add_thread (event_ptid);
+
+             t->stop_requested = 0;
+             t->executing = 0;
+             t->resumed = 0;
+             t->control.may_range_step = 0;
+
+             /* This may be the first time we see the inferior report
+                a stop.  */
+             inf = find_inferior_ptid (event_ptid);
+             if (inf->needs_setup)
+               {
+                 switch_to_thread_no_regs (t);
+                 setup_inferior (0);
+               }
+
+             if (ws.kind == TARGET_WAITKIND_STOPPED
+                 && ws.value.sig == GDB_SIGNAL_0)
+               {
+                 /* We caught the event that we intended to catch, so
+                    there's no event pending.  */
+                 t->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
+                 t->suspend.waitstatus_pending_p = 0;
+
+                 if (displaced_step_fixup (t->ptid, GDB_SIGNAL_0) < 0)
+                   {
+                     /* Add it back to the step-over queue.  */
+                     if (debug_infrun)
+                       {
+                         fprintf_unfiltered (gdb_stdlog,
+                                             "infrun: displaced-step of %s "
+                                             "canceled: adding back to the "
+                                             "step-over queue\n",
+                                             target_pid_to_str (t->ptid));
+                       }
+                     t->control.trap_expected = 0;
+                     thread_step_over_chain_enqueue (t);
+                   }
+               }
+             else
+               {
+                 enum gdb_signal sig;
+                 struct regcache *regcache;
+
+                 if (debug_infrun)
+                   {
+                     char *statstr;
+
+                     statstr = target_waitstatus_to_string (&ws);
+                     fprintf_unfiltered (gdb_stdlog,
+                                         "infrun: target_wait %s, saving "
+                                         "status for %d.%ld.%ld\n",
+                                         statstr,
+                                         ptid_get_pid (t->ptid),
+                                         ptid_get_lwp (t->ptid),
+                                         ptid_get_tid (t->ptid));
+                     xfree (statstr);
+                   }
+
+                 /* Record for later.  */
+                 save_waitstatus (t, &ws);
+
+                 sig = (ws.kind == TARGET_WAITKIND_STOPPED
+                        ? ws.value.sig : GDB_SIGNAL_0);
+
+                 if (displaced_step_fixup (t->ptid, sig) < 0)
+                   {
+                     /* Add it back to the step-over queue.  */
+                     t->control.trap_expected = 0;
+                     thread_step_over_chain_enqueue (t);
+                   }
+
+                 regcache = get_thread_regcache (t->ptid);
+                 t->suspend.stop_pc = regcache_read_pc (regcache);
+
+                 if (debug_infrun)
+                   {
+                     fprintf_unfiltered (gdb_stdlog,
+                                         "infrun: saved stop_pc=%s for %s "
+                                         "(currently_stepping=%d)\n",
+                                         paddress (target_gdbarch (),
+                                                   t->suspend.stop_pc),
+                                         target_pid_to_str (t->ptid),
+                                         currently_stepping (t));
+                   }
+               }
+           }
+       }
+    }
+
+  do_cleanups (old_chain);
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog, "infrun: stop_all_threads done\n");
+}
+
+/* Handle a TARGET_WAITKIND_NO_RESUMED event.  */
+
+static int
+handle_no_resumed (struct execution_control_state *ecs)
+{
+  struct inferior *inf;
+  struct thread_info *thread;
+
+  if (target_can_async_p ())
+    {
+      struct ui *ui;
+      int any_sync = 0;
+
+      ALL_UIS (ui)
+       {
+         if (ui->prompt_state == PROMPT_BLOCKED)
+           {
+             any_sync = 1;
+             break;
+           }
+       }
+      if (!any_sync)
+       {
+         /* There were no unwaited-for children left in the target, but,
+            we're not synchronously waiting for events either.  Just
+            ignore.  */
+
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: TARGET_WAITKIND_NO_RESUMED "
+                               "(ignoring: bg)\n");
+         prepare_to_wait (ecs);
+         return 1;
+       }
+    }
+
+  /* Otherwise, if we were running a synchronous execution command, we
+     may need to cancel it and give the user back the terminal.
+
+     In non-stop mode, the target can't tell whether we've already
+     consumed previous stop events, so it can end up sending us a
+     no-resumed event like so:
+
+       #0 - thread 1 is left stopped
+
+       #1 - thread 2 is resumed and hits breakpoint
+               -> TARGET_WAITKIND_STOPPED
+
+       #2 - thread 3 is resumed and exits
+            this is the last resumed thread, so
+              -> TARGET_WAITKIND_NO_RESUMED
+
+       #3 - gdb processes stop for thread 2 and decides to re-resume
+            it.
+
+       #4 - gdb processes the TARGET_WAITKIND_NO_RESUMED event.
+            thread 2 is now resumed, so the event should be ignored.
+
+     IOW, if the stop for thread 2 doesn't end a foreground command,
+     then we need to ignore the following TARGET_WAITKIND_NO_RESUMED
+     event.  But it could be that the event meant that thread 2 itself
+     (or whatever other thread was the last resumed thread) exited.
+
+     To address this we refresh the thread list and check whether we
+     have resumed threads _now_.  In the example above, this removes
+     thread 3 from the thread list.  If thread 2 was re-resumed, we
+     ignore this event.  If we find no thread resumed, then we cancel
+     the synchronous command show "no unwaited-for " to the user.  */
+  update_thread_list ();
+
+  ALL_NON_EXITED_THREADS (thread)
+    {
+      if (thread->executing
+         || thread->suspend.waitstatus_pending_p)
+       {
+         /* There were no unwaited-for children left in the target at
+            some point, but there are now.  Just ignore.  */
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: TARGET_WAITKIND_NO_RESUMED "
+                               "(ignoring: found resumed)\n");
+         prepare_to_wait (ecs);
+         return 1;
+       }
+    }
+
+  /* Note however that we may find no resumed thread because the whole
+     process exited meanwhile (thus updating the thread list results
+     in an empty thread list).  In this case we know we'll be getting
+     a process exit event shortly.  */
+  ALL_INFERIORS (inf)
+    {
+      if (inf->pid == 0)
+       continue;
+
+      thread = any_live_thread_of_process (inf->pid);
+      if (thread == NULL)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: TARGET_WAITKIND_NO_RESUMED "
+                               "(expect process exit)\n");
+         prepare_to_wait (ecs);
+         return 1;
+       }
+    }
+
+  /* Go ahead and report the event.  */
+  return 0;
+}
+
+/* Given an execution control state that has been freshly filled in by
+   an event from the inferior, figure out what it means and take
+   appropriate action.
+
+   The alternatives are:
+
+   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
+   ecs->event_thread->stepping_over_breakpoint to 1 to single step
+   once).  */
+
+static void
+handle_inferior_event_1 (struct execution_control_state *ecs)
+{
+  enum stop_kind stop_soon;
+
+  if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
+    {
+      /* We had an event in the inferior, but we are not interested in
+        handling it at this level.  The lower layers have already
+        done what needs to be done, if anything.
+
+        One of the possible circumstances for this is when the
+        inferior produces output for the console.  The inferior has
+        not stopped, and we are ignoring the event.  Another possible
+        circumstance is any event which the lower level knows will be
+        reported multiple times without an intervening resume.  */
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
+      prepare_to_wait (ecs);
+      return;
+    }
+
+  if (ecs->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
+    {
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_EXITED\n");
+      prepare_to_wait (ecs);
+      return;
+    }
+
+  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED
+      && handle_no_resumed (ecs))
+    return;
+
+  /* Cache the last pid/waitstatus.  */
+  set_last_target_status (ecs->ptid, ecs->ws);
+
+  /* Always clear state belonging to the previous time we stopped.  */
+  stop_stack_dummy = STOP_NONE;
+
+  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED)
+    {
+      /* No unwaited-for children left.  IOW, all resumed children
+        have exited.  */
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
 
       stop_print_frame = 0;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
     }
 
@@ -3262,7 +4892,7 @@ handle_inferior_event (struct execution_control_state *ecs)
     }
 
   /* Dependent on valid ECS->EVENT_THREAD.  */
-  adjust_pc_after_break (ecs);
+  adjust_pc_after_break (ecs->event_thread, &ecs->ws);
 
   /* Dependent on the current PC value modified by adjust_pc_after_break.  */
   reinit_frame_cache ();
@@ -3298,73 +4928,59 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   /* Mark the non-executing threads accordingly.  In all-stop, all
      threads of all processes are stopped when we get any event
-     reported.  In non-stop mode, only the event thread stops.  If
-     we're handling a process exit in non-stop mode, there's nothing
-     to do, as threads of the dead process are gone, and threads of
-     any other process were left running.  */
-  if (!non_stop)
-    set_executing (minus_one_ptid, 0);
-  else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
-          && ecs->ws.kind != TARGET_WAITKIND_EXITED)
-    set_executing (ecs->ptid, 0);
-
-  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");
-      break;
-
-    case infwait_step_watch_state:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: infwait_step_watch_state\n");
-
-      stepped_after_stopped_by_watchpoint = 1;
-      break;
+     reported.  In non-stop mode, only the event thread stops.  */
+  {
+    ptid_t mark_ptid;
 
-    case infwait_nonstep_watch_state:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: infwait_nonstep_watch_state\n");
-      insert_breakpoints ();
+    if (!target_is_non_stop_p ())
+      mark_ptid = minus_one_ptid;
+    else if (ecs->ws.kind == TARGET_WAITKIND_SIGNALLED
+            || ecs->ws.kind == TARGET_WAITKIND_EXITED)
+      {
+       /* If we're handling a process exit in non-stop mode, even
+          though threads haven't been deleted yet, one would think
+          that there is nothing to do, as threads of the dead process
+          will be soon deleted, and threads of any other process were
+          left running.  However, on some targets, threads survive a
+          process exit event.  E.g., for the "checkpoint" command,
+          when the current checkpoint/fork exits, linux-fork.c
+          automatically switches to another fork from within
+          target_mourn_inferior, by associating the same
+          inferior/thread to another fork.  We haven't mourned yet at
+          this point, but we must mark any threads left in the
+          process as not-executing so that finish_thread_state marks
+          them stopped (in the user's perspective) if/when we present
+          the stop to the user.  */
+       mark_ptid = pid_to_ptid (ptid_get_pid (ecs->ptid));
+      }
+    else
+      mark_ptid = ecs->ptid;
 
-      /* FIXME-maybe: is this cleaner than setting a flag?  Does it
-         handle things like signals arriving and other things happening
-         in combination correctly?  */
-      stepped_after_stopped_by_watchpoint = 1;
-      break;
+    set_executing (mark_ptid, 0);
 
-    default:
-      internal_error (__FILE__, __LINE__, _("bad switch"));
-    }
-
-  infwait_state = infwait_normal_state;
-  waiton_ptid = pid_to_ptid (-1);
+    /* Likewise the resumed flag.  */
+    set_resumed (mark_ptid, 0);
+  }
 
   switch (ecs->ws.kind)
     {
     case TARGET_WAITKIND_LOADED:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_LOADED\n");
+      if (!ptid_equal (ecs->ptid, inferior_ptid))
+       context_switch (ecs->ptid);
       /* Ignore gracefully during startup of the inferior, as it might
          be the shell which has just loaded some objects, otherwise
          add the symbols for the newly loaded objects.  Also ignore at
          the beginning of an attach or remote session; we will query
          the full list of libraries once the connection is
          established.  */
+
+      stop_soon = get_inferior_stop_soon (ecs->ptid);
       if (stop_soon == NO_STOP_QUIETLY)
        {
          struct regcache *regcache;
-         enum bpstat_signal_value sval;
 
-         if (!ptid_equal (ecs->ptid, inferior_ptid))
-           context_switch (ecs->ptid);
          regcache = get_thread_regcache (ecs->ptid);
 
          handle_solib_event ();
@@ -3373,15 +4989,11 @@ handle_inferior_event (struct execution_control_state *ecs)
            = bpstat_stop_status (get_regcache_aspace (regcache),
                                  stop_pc, ecs->ptid, &ecs->ws);
 
-         sval
-           = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
-         ecs->random_signal = sval == BPSTAT_SIGNAL_NO;
-
-         if (!ecs->random_signal)
+         if (bpstat_causes_stop (ecs->event_thread->control.stop_bpstat))
            {
              /* A catchpoint triggered.  */
-             ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_TRAP;
-             goto process_event_stop_test;
+             process_event_stop_test (ecs);
+             return;
            }
 
          /* If requested, stop when the dynamic linker notifies
@@ -3395,41 +5007,57 @@ handle_inferior_event (struct execution_control_state *ecs)
                 normal_stop.  */
              stop_print_frame = 1;
 
-             stop_stepping (ecs);
+             stop_waiting (ecs);
              return;
            }
        }
 
       /* If we are skipping through a shell, or through shared library
         loading that we aren't interested in, resume the program.  If
-        we're running the program normally, also resume.  But stop if
-        we're attaching or setting up a remote connection.  */
+        we're running the program normally, also resume.  */
       if (stop_soon == STOP_QUIETLY || stop_soon == NO_STOP_QUIETLY)
        {
-         if (!ptid_equal (ecs->ptid, inferior_ptid))
-           context_switch (ecs->ptid);
-
          /* 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);
+         resume (GDB_SIGNAL_0);
          prepare_to_wait (ecs);
          return;
        }
 
-      break;
+      /* But stop if we're attaching or setting up a remote
+        connection.  */
+      if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
+         || stop_soon == STOP_QUIETLY_REMOTE)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
+         stop_waiting (ecs);
+         return;
+       }
+
+      internal_error (__FILE__, __LINE__,
+                     _("unhandled stop_soon: %d"), (int) stop_soon);
 
     case TARGET_WAITKIND_SPURIOUS:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n");
       if (!ptid_equal (ecs->ptid, inferior_ptid))
        context_switch (ecs->ptid);
-      resume (0, GDB_SIGNAL_0);
+      resume (GDB_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
 
+    case TARGET_WAITKIND_THREAD_CREATED:
+      if (debug_infrun)
+        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_CREATED\n");
+      if (!ptid_equal (ecs->ptid, inferior_ptid))
+       context_switch (ecs->ptid);
+      if (!switch_back_to_stepped_thread (ecs))
+       keep_going (ecs);
+      return;
+
     case TARGET_WAITKIND_EXITED:
     case TARGET_WAITKIND_SIGNALLED:
       if (debug_infrun)
@@ -3443,11 +5071,14 @@ handle_inferior_event (struct execution_control_state *ecs)
        }
 
       inferior_ptid = ecs->ptid;
-      set_current_inferior (find_inferior_pid (ptid_get_pid (ecs->ptid)));
+      set_current_inferior (find_inferior_ptid (ecs->ptid));
       set_current_program_space (current_inferior ()->pspace);
       handle_vfork_child_exec_or_exit (0);
       target_terminal_ours (); /* Must do this before mourn anyway.  */
 
+      /* Clearing any previous state of convenience variables.  */
+      clear_exit_convenience_vars ();
+
       if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
        {
          /* Record the exit code in the convenience variable $_exitcode, so
@@ -3459,17 +5090,45 @@ 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
-       print_signal_exited_reason (ecs->ws.value.sig);
+       {
+         struct regcache *regcache = get_thread_regcache (ecs->ptid);
+         struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+         if (gdbarch_gdb_signal_to_target_p (gdbarch))
+           {
+             /* Set the value of the internal variable $_exitsignal,
+                which holds the signal uncaught by the inferior.  */
+             set_internalvar_integer (lookup_internalvar ("_exitsignal"),
+                                      gdbarch_gdb_signal_to_target (gdbarch,
+                                                         ecs->ws.value.sig));
+           }
+         else
+           {
+             /* We don't have access to the target's method used for
+                converting between signal numbers (GDB's internal
+                representation <-> target's representation).
+                Therefore, we cannot do a good job at displaying this
+                information to the user.  It's better to just warn
+                her about it (if infrun debugging is enabled), and
+                give up.  */
+             if (debug_infrun)
+               fprintf_filtered (gdb_stdlog, _("\
+Cannot fill $_exitsignal with the correct signal number.\n"));
+           }
+
+         observer_notify_signal_exited (ecs->ws.value.sig);
+       }
 
       gdb_flush (gdb_stdout);
       target_mourn_inferior ();
-      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;
@@ -3488,15 +5147,13 @@ handle_inferior_event (struct execution_control_state *ecs)
       {
        struct regcache *regcache = get_thread_regcache (ecs->ptid);
        struct gdbarch *gdbarch = get_regcache_arch (regcache);
-       struct displaced_step_inferior_state *displaced
-         = get_displaced_stepping_state (ptid_get_pid (ecs->ptid));
 
        /* If checking displaced stepping is supported, and thread
           ecs->ptid is displaced stepping.  */
-       if (displaced && ptid_equal (displaced->step_ptid, ecs->ptid))
+       if (displaced_step_in_progress_thread (ecs->ptid))
          {
            struct inferior *parent_inf
-             = find_inferior_pid (ptid_get_pid (ecs->ptid));
+             = find_inferior_ptid (ecs->ptid);
            struct regcache *child_regcache;
            CORE_ADDR parent_pc;
 
@@ -3506,9 +5163,15 @@ handle_inferior_event (struct execution_control_state *ecs)
               that this operation also cleans up the child process for vfork,
               because their pages are shared.  */
            displaced_step_fixup (ecs->ptid, GDB_SIGNAL_TRAP);
+           /* Start a new step-over in another thread if there's one
+              that needs it.  */
+           start_step_over ();
 
            if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
              {
+               struct displaced_step_inferior_state *displaced
+                 = get_displaced_stepping_state (ptid_get_pid (ecs->ptid));
+
                /* Restore scratch pad for child process.  */
                displaced_step_restore (displaced, ecs->ws.value.related_pid);
              }
@@ -3560,12 +5223,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          detach_breakpoints (ecs->ws.value.related_pid);
        }
 
-      if (singlestep_breakpoints_inserted_p)
-       {
-         /* Pull the single step breakpoints out of the target.  */
-         remove_single_step_breakpoints ();
-         singlestep_breakpoints_inserted_p = 0;
-       }
+      delete_just_stopped_threads_single_step_breakpoints ();
 
       /* In case the event is caught by a catchpoint, remember that
         the event is to be followed at the next resume of the thread,
@@ -3578,15 +5236,11 @@ handle_inferior_event (struct execution_control_state *ecs)
        = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
                              stop_pc, ecs->ptid, &ecs->ws);
 
-      /* Note that we're interested in knowing the bpstat actually
-        causes a stop, not just if it may explain the signal.
-        Software watchpoints, for example, always appear in the
-        bpstat.  */
-      ecs->random_signal
-       = !bpstat_causes_stop (ecs->event_thread->control.stop_bpstat);
-
-      /* If no catchpoint triggered for this, then keep going.  */
-      if (ecs->random_signal)
+      /* If no catchpoint triggered for this, then keep going.  Note
+        that we're interested in knowing the bpstat actually causes a
+        stop, not just if it may explain the signal.  Software
+        watchpoints, for example, always appear in the bpstat.  */
+      if (!bpstat_causes_stop (ecs->event_thread->control.stop_bpstat))
        {
          ptid_t parent;
          ptid_t child;
@@ -3601,8 +5255,20 @@ handle_inferior_event (struct execution_control_state *ecs)
          parent = ecs->ptid;
          child = ecs->ws.value.related_pid;
 
+         /* At this point, the parent is marked running, and the
+            child is marked stopped.  */
+
+         /* If not resuming the parent, mark it stopped.  */
+         if (follow_child && !detach_fork && !non_stop && !sched_multi)
+           set_running (parent, 0);
+
+         /* If resuming the child, mark it running.  */
+         if (follow_child || (!detach_fork && (non_stop || sched_multi)))
+           set_running (child, 1);
+
          /* In non-stop mode, also resume the other branch.  */
-         if (non_stop && !detach_fork)
+         if (!detach_fork && (non_stop
+                              || (sched_multi && target_is_non_stop_p ())))
            {
              if (follow_child)
                switch_to_thread (parent);
@@ -3625,11 +5291,11 @@ handle_inferior_event (struct execution_control_state *ecs)
          if (should_resume)
            keep_going (ecs);
          else
-           stop_stepping (ecs);
+           stop_waiting (ecs);
          return;
        }
-      ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_TRAP;
-      goto process_event_stop_test;
+      process_event_stop_test (ecs);
+      return;
 
     case TARGET_WAITKIND_VFORK_DONE:
       /* Done with the shared memory region.  Re-insert breakpoints in
@@ -3656,9 +5322,6 @@ handle_inferior_event (struct execution_control_state *ecs)
       if (!ptid_equal (ecs->ptid, inferior_ptid))
        context_switch (ecs->ptid);
 
-      singlestep_breakpoints_inserted_p = 0;
-      cancel_single_step_breakpoints ();
-
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
       /* Do whatever is necessary to the parent branch of the vfork.  */
@@ -3669,12 +5332,14 @@ handle_inferior_event (struct execution_control_state *ecs)
          stop.  */
       follow_exec (inferior_ptid, ecs->ws.value.execd_pathname);
 
+      /* In follow_exec we may have deleted the original thread and
+        created a new one.  Make sure that the event thread is the
+        execd thread for that case (this is a nop otherwise).  */
+      ecs->event_thread = inferior_thread ();
+
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
                              stop_pc, ecs->ptid, &ecs->ws);
-      ecs->random_signal
-       = (bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
-          == BPSTAT_SIGNAL_NO);
 
       /* Note that this may be referenced from inside
         bpstat_stop_status above, through inferior_has_execd.  */
@@ -3682,14 +5347,14 @@ handle_inferior_event (struct execution_control_state *ecs)
       ecs->ws.value.execd_pathname = NULL;
 
       /* If no catchpoint triggered for this, then keep going.  */
-      if (ecs->random_signal)
+      if (!bpstat_causes_stop (ecs->event_thread->control.stop_bpstat))
        {
          ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
          keep_going (ecs);
          return;
        }
-      ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_TRAP;
-      goto process_event_stop_test;
+      process_event_stop_test (ecs);
+      return;
 
       /* Be careful not to try to gather much state about a thread
          that's in a syscall.  It's frequently a losing proposition.  */
@@ -3698,9 +5363,9 @@ handle_inferior_event (struct execution_control_state *ecs)
         fprintf_unfiltered (gdb_stdlog,
                            "infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n");
       /* Getting the current syscall number.  */
-      if (handle_syscall_event (ecs) != 0)
-        return;
-      goto process_event_stop_test;
+      if (handle_syscall_event (ecs) == 0)
+       process_event_stop_test (ecs);
+      return;
 
       /* Before examining the threads further, step this thread to
          get it entirely out of the syscall.  (We get notice of the
@@ -3711,51 +5376,313 @@ handle_inferior_event (struct execution_control_state *ecs)
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog,
                            "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
-      if (handle_syscall_event (ecs) != 0)
-        return;
-      goto process_event_stop_test;
+      if (handle_syscall_event (ecs) == 0)
+       process_event_stop_test (ecs);
+      return;
 
     case TARGET_WAITKIND_STOPPED:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
       ecs->event_thread->suspend.stop_signal = ecs->ws.value.sig;
-      break;
+      handle_signal_stop (ecs);
+      return;
+
+    case TARGET_WAITKIND_NO_HISTORY:
+      if (debug_infrun)
+        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
+      /* Reverse execution: target ran out of history info.  */
+
+      /* Switch to the stopped thread.  */
+      if (!ptid_equal (ecs->ptid, inferior_ptid))
+       context_switch (ecs->ptid);
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
+
+      delete_just_stopped_threads_single_step_breakpoints ();
+      stop_pc = regcache_read_pc (get_thread_regcache (inferior_ptid));
+      observer_notify_no_history ();
+      stop_waiting (ecs);
+      return;
+    }
+}
+
+/* A wrapper around handle_inferior_event_1, which also makes sure
+   that all temporary struct value objects that were created during
+   the handling of the event get deleted at the end.  */
+
+static void
+handle_inferior_event (struct execution_control_state *ecs)
+{
+  struct value *mark = value_mark ();
+
+  handle_inferior_event_1 (ecs);
+  /* Purge all temporary values created during the event handling,
+     as it could be a long time before we return to the command level
+     where such values would otherwise be purged.  */
+  value_free_to_mark (mark);
+}
+
+/* Restart threads back to what they were trying to do back when we
+   paused them for an in-line step-over.  The EVENT_THREAD thread is
+   ignored.  */
+
+static void
+restart_threads (struct thread_info *event_thread)
+{
+  struct thread_info *tp;
+
+  /* In case the instruction just stepped spawned a new thread.  */
+  update_thread_list ();
+
+  ALL_NON_EXITED_THREADS (tp)
+    {
+      if (tp == event_thread)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: restart threads: "
+                               "[%s] is event thread\n",
+                               target_pid_to_str (tp->ptid));
+         continue;
+       }
+
+      if (!(tp->state == THREAD_RUNNING || tp->control.in_infcall))
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: restart threads: "
+                               "[%s] not meant to be running\n",
+                               target_pid_to_str (tp->ptid));
+         continue;
+       }
+
+      if (tp->resumed)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: restart threads: [%s] resumed\n",
+                               target_pid_to_str (tp->ptid));
+         gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
+         continue;
+       }
+
+      if (thread_is_in_step_over_chain (tp))
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: restart threads: "
+                               "[%s] needs step-over\n",
+                               target_pid_to_str (tp->ptid));
+         gdb_assert (!tp->resumed);
+         continue;
+       }
+
+
+      if (tp->suspend.waitstatus_pending_p)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: restart threads: "
+                               "[%s] has pending status\n",
+                               target_pid_to_str (tp->ptid));
+         tp->resumed = 1;
+         continue;
+       }
+
+      /* If some thread needs to start a step-over at this point, it
+        should still be in the step-over queue, and thus skipped
+        above.  */
+      if (thread_still_needs_step_over (tp))
+       {
+         internal_error (__FILE__, __LINE__,
+                         "thread [%s] needs a step-over, but not in "
+                         "step-over queue\n",
+                         target_pid_to_str (tp->ptid));
+       }
+
+      if (currently_stepping (tp))
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: restart threads: [%s] was stepping\n",
+                               target_pid_to_str (tp->ptid));
+         keep_going_stepped_thread (tp);
+       }
+      else
+       {
+         struct execution_control_state ecss;
+         struct execution_control_state *ecs = &ecss;
+
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: restart threads: [%s] continuing\n",
+                               target_pid_to_str (tp->ptid));
+         reset_ecs (ecs, tp);
+         switch_to_thread (tp->ptid);
+         keep_going_pass_signal (ecs);
+       }
+    }
+}
+
+/* Callback for iterate_over_threads.  Find a resumed thread that has
+   a pending waitstatus.  */
+
+static int
+resumed_thread_with_pending_status (struct thread_info *tp,
+                                   void *arg)
+{
+  return (tp->resumed
+         && tp->suspend.waitstatus_pending_p);
+}
+
+/* Called when we get an event that may finish an in-line or
+   out-of-line (displaced stepping) step-over started previously.
+   Return true if the event is processed and we should go back to the
+   event loop; false if the caller should continue processing the
+   event.  */
+
+static int
+finish_step_over (struct execution_control_state *ecs)
+{
+  int had_step_over_info;
+
+  displaced_step_fixup (ecs->ptid,
+                       ecs->event_thread->suspend.stop_signal);
+
+  had_step_over_info = step_over_info_valid_p ();
+
+  if (had_step_over_info)
+    {
+      /* If we're stepping over a breakpoint with all threads locked,
+        then only the thread that was stepped should be reporting
+        back an event.  */
+      gdb_assert (ecs->event_thread->control.trap_expected);
+
+      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
+       clear_step_over_info ();
+    }
+
+  if (!target_is_non_stop_p ())
+    return 0;
+
+  /* Start a new step-over in another thread if there's one that
+     needs it.  */
+  start_step_over ();
+
+  /* If we were stepping over a breakpoint before, and haven't started
+     a new in-line step-over sequence, then restart all other threads
+     (except the event thread).  We can't do this in all-stop, as then
+     e.g., we wouldn't be able to issue any other remote packet until
+     these other threads stop.  */
+  if (had_step_over_info && !step_over_info_valid_p ())
+    {
+      struct thread_info *pending;
+
+      /* If we only have threads with pending statuses, the restart
+        below won't restart any thread and so nothing re-inserts the
+        breakpoint we just stepped over.  But we need it inserted
+        when we later process the pending events, otherwise if
+        another thread has a pending event for this breakpoint too,
+        we'd discard its event (because the breakpoint that
+        originally caused the event was no longer inserted).  */
+      context_switch (ecs->ptid);
+      insert_breakpoints ();
+
+      restart_threads (ecs->event_thread);
+
+      /* If we have events pending, go through handle_inferior_event
+        again, picking up a pending event at random.  This avoids
+        thread starvation.  */
+
+      /* But not if we just stepped over a watchpoint in order to let
+        the instruction execute so we can evaluate its expression.
+        The set of watchpoints that triggered is recorded in the
+        breakpoint objects themselves (see bp->watchpoint_triggered).
+        If we processed another event first, that other event could
+        clobber this info.  */
+      if (ecs->event_thread->stepping_over_watchpoint)
+       return 0;
+
+      pending = iterate_over_threads (resumed_thread_with_pending_status,
+                                     NULL);
+      if (pending != NULL)
+       {
+         struct thread_info *tp = ecs->event_thread;
+         struct regcache *regcache;
+
+         if (debug_infrun)
+           {
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: found resumed threads with "
+                                 "pending events, saving status\n");
+           }
+
+         gdb_assert (pending != tp);
+
+         /* Record the event thread's event for later.  */
+         save_waitstatus (tp, &ecs->ws);
+         /* This was cleared early, by handle_inferior_event.  Set it
+            so this pending event is considered by
+            do_target_wait.  */
+         tp->resumed = 1;
+
+         gdb_assert (!tp->executing);
+
+         regcache = get_thread_regcache (tp->ptid);
+         tp->suspend.stop_pc = regcache_read_pc (regcache);
+
+         if (debug_infrun)
+           {
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: saved stop_pc=%s for %s "
+                                 "(currently_stepping=%d)\n",
+                                 paddress (target_gdbarch (),
+                                           tp->suspend.stop_pc),
+                                 target_pid_to_str (tp->ptid),
+                                 currently_stepping (tp));
+           }
+
+         /* This in-line step-over finished; clear this so we won't
+            start a new one.  This is what handle_signal_stop would
+            do, if we returned false.  */
+         tp->stepping_over_breakpoint = 0;
 
-    case TARGET_WAITKIND_NO_HISTORY:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
-      /* Reverse execution: target ran out of history info.  */
+         /* Wake up the event loop again.  */
+         mark_async_event_handler (infrun_async_inferior_event_token);
 
-      /* 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;
+         prepare_to_wait (ecs);
+         return 1;
        }
-      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
-      print_no_history_reason ();
-      stop_stepping (ecs);
-      return;
     }
 
-  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);
+  return 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).  */
+/* Come here when the program has stopped with a 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;
-    }
+static void
+handle_signal_stop (struct execution_control_state *ecs)
+{
+  struct frame_info *frame;
+  struct gdbarch *gdbarch;
+  int stopped_by_watchpoint;
+  enum stop_kind stop_soon;
+  int random_signal;
+
+  gdb_assert (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.)  */
+  if (finish_step_over (ecs))
+    return;
+
+  /* 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));
 
@@ -3787,229 +5714,50 @@ handle_inferior_event (struct execution_control_state *ecs)
       do_cleanups (old_chain);
     }
 
-  if (stepping_past_singlestep_breakpoint)
+  /* This is originated from start_remote(), start_inferior() and
+     shared libraries hook functions.  */
+  stop_soon = get_inferior_stop_soon (ecs->ptid);
+  if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
     {
-      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->random_signal = 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 (ecs->ptid, inferior_ptid))
+       context_switch (ecs->ptid);
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
+      stop_print_frame = 1;
+      stop_waiting (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;
-    }
+  /* This originates from attach_command().  We need to overwrite
+     the stop_signal here, because some kernels don't ignore a
+     SIGSTOP in a subsequent ptrace(PTRACE_CONT,SIGSTOP) call.
+     See more comments in inferior.h.  On the other hand, if we
+     get a non-SIGSTOP, report it to the user - assume the backend
+     will handle the SIGSTOP if it should show up later.
 
-  /* 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.  */
+     Also consider that the attach is complete when we see a
+     SIGTRAP.  Some systems (e.g. Windows), and stubs supporting
+     target extended-remote report it instead of a SIGSTOP
+     (e.g. gdbserver).  We already rely on SIGTRAP being our
+     signal, so this is no exception.
 
-  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
+     Also consider that the attach is complete when we see a
+     GDB_SIGNAL_0.  In non-stop mode, GDB will explicitly tell
+     the target to stop all threads of the inferior, in case the
+     low level attach operation doesn't stop them implicitly.  If
+     they weren't stopped implicitly, then the stub will report a
+     GDB_SIGNAL_0, meaning: stopped for no particular reason
+     other than GDB's request.  */
+  if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
+      && (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_STOP
+         || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+         || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0))
     {
-      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))
-       {
-         ecs->random_signal = 0;
-         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));
-
-         ecs->random_signal = 0;
-         /* 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;
-           }
-       }
-      else if (singlestep_breakpoints_inserted_p)
-       {
-         ecs->random_signal = 0;
-       }
+      stop_print_frame = 1;
+      stop_waiting (ecs);
+      ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+      return;
     }
-  else
-    ecs->random_signal = 1;
 
   /* See if something interesting happened to the non-current thread.  If
      so, then switch to that thread.  */
@@ -4021,21 +5769,58 @@ handle_inferior_event (struct execution_control_state *ecs)
       context_switch (ecs->ptid);
 
       if (deprecated_context_hook)
-       deprecated_context_hook (pid_to_thread_id (ecs->ptid));
+       deprecated_context_hook (ptid_to_global_thread_id (ecs->ptid));
     }
 
   /* At this point, get hold of the now-current thread's frame.  */
   frame = get_current_frame ();
   gdbarch = get_frame_arch (frame);
 
-  if (singlestep_breakpoints_inserted_p)
+  /* Pull the single step breakpoints out of the target.  */
+  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
     {
-      /* Pull the single step breakpoints out of the target.  */
-      remove_single_step_breakpoints ();
-      singlestep_breakpoints_inserted_p = 0;
+      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);
+
+      /* However, before doing so, if this single-step breakpoint was
+        actually for another thread, set this thread up for moving
+        past it.  */
+      if (!thread_has_single_step_breakpoint_here (ecs->event_thread,
+                                                  aspace, pc))
+       {
+         if (single_step_breakpoint_inserted_here_p (aspace, pc))
+           {
+             if (debug_infrun)
+               {
+                 fprintf_unfiltered (gdb_stdlog,
+                                     "infrun: [%s] hit another thread's "
+                                     "single-step breakpoint\n",
+                                     target_pid_to_str (ecs->ptid));
+               }
+             ecs->hit_singlestep_breakpoint = 1;
+           }
+       }
+      else
+       {
+         if (debug_infrun)
+           {
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: [%s] hit its "
+                                 "single-step breakpoint\n",
+                                 target_pid_to_str (ecs->ptid));
+           }
+       }
     }
+  delete_just_stopped_threads_single_step_breakpoints ();
 
-  if (stepped_after_stopped_by_watchpoint)
+  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+      && ecs->event_thread->control.trap_expected
+      && ecs->event_thread->stepping_over_watchpoint)
     stopped_by_watchpoint = 0;
   else
     stopped_by_watchpoint = watchpoints_triggered (&ecs->ws);
@@ -4058,41 +5843,31 @@ handle_inferior_event (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.
 
         It is far more common to need to disable a watchpoint to step
         the inferior over it.  If we have non-steppable watchpoints,
         we must disable the current watchpoint; it's simplest to
-        disable all watchpoints and breakpoints.  */
-      int hw_step = 1;
-
-      if (!target_have_steppable_watchpoint)
-       {
-         remove_breakpoints ();
-         /* See comment in resume why we need to stop bypassing signals
-            while breakpoints have been removed.  */
-         target_pass_signals (0, NULL);
-       }
-       /* Single step */
-      hw_step = maybe_software_singlestep (gdbarch, stop_pc);
-      target_resume (ecs->ptid, hw_step, GDB_SIGNAL_0);
-      waiton_ptid = ecs->ptid;
-      if (target_have_steppable_watchpoint)
-       infwait_state = infwait_step_watch_state;
-      else
-       infwait_state = infwait_nonstep_watch_state;
-      prepare_to_wait (ecs);
+        disable all watchpoints.
+
+        Any breakpoint at PC must also be stepped over -- if there's
+        one, it will have already triggered before the watchpoint
+        triggered, and we either already reported it to the user, or
+        it didn't cause a stop and we called keep_going.  In either
+        case, if there was a breakpoint at PC, we must be trying to
+        step past it.  */
+      ecs->event_thread->stepping_over_watchpoint = 1;
+      keep_going (ecs);
       return;
     }
 
-  clear_stop_func (ecs);
   ecs->event_thread->stepping_over_breakpoint = 0;
+  ecs->event_thread->stepping_over_watchpoint = 0;
   bpstat_clear (&ecs->event_thread->control.stop_bpstat);
   ecs->event_thread->control.stop_step = 0;
   stop_print_frame = 1;
-  ecs->random_signal = 0;
   stopped_by_random_signal = 0;
 
   /* Hide inlined functions starting here, unless we just performed stepi or
@@ -4170,64 +5945,6 @@ handle_inferior_event (struct execution_control_state *ecs)
        }
     }
 
-  /* Look at the cause of the stop, and decide what to do.
-     The alternatives are:
-     1) stop_stepping and return; to really stop and return to the debugger,
-     2) keep_going and return to start up again
-     (set ecs->event_thread->stepping_over_breakpoint to 1 to single step once)
-     3) set ecs->random_signal to 1, and the decision between 1 and 2
-     will be made according to the signal handling tables.  */
-
-  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-      && stop_after_trap)
-    {
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
-      stop_print_frame = 0;
-      stop_stepping (ecs);
-      return;
-    }
-
-  /* This is originated from start_remote(), start_inferior() and
-     shared libraries hook functions.  */
-  if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
-    {
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
-      stop_stepping (ecs);
-      return;
-    }
-
-  /* This originates from attach_command().  We need to overwrite
-     the stop_signal here, because some kernels don't ignore a
-     SIGSTOP in a subsequent ptrace(PTRACE_CONT,SIGSTOP) call.
-     See more comments in inferior.h.  On the other hand, if we
-     get a non-SIGSTOP, report it to the user - assume the backend
-     will handle the SIGSTOP if it should show up later.
-
-     Also consider that the attach is complete when we see a
-     SIGTRAP.  Some systems (e.g. Windows), and stubs supporting
-     target extended-remote report it instead of a SIGSTOP
-     (e.g. gdbserver).  We already rely on SIGTRAP being our
-     signal, so this is no exception.
-
-     Also consider that the attach is complete when we see a
-     GDB_SIGNAL_0.  In non-stop mode, GDB will explicitly tell
-     the target to stop all threads of the inferior, in case the
-     low level attach operation doesn't stop them implicitly.  If
-     they weren't stopped implicitly, then the stub will report a
-     GDB_SIGNAL_0, meaning: stopped for no particular reason
-     other than GDB's request.  */
-  if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
-      && (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_STOP
-         || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-         || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0))
-    {
-      stop_stepping (ecs);
-      ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
-      return;
-    }
-
   /* See if there is a breakpoint/watchpoint/catchpoint/etc. that
      handles this event.  */
   ecs->event_thread->control.stop_bpstat
@@ -4248,14 +5965,14 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   if (debug_infrun
       && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-      && (bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
-         == BPSTAT_SIGNAL_NO)
+      && !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat,
+                                 GDB_SIGNAL_TRAP)
       && stopped_by_watchpoint)
     fprintf_unfiltered (gdb_stdlog,
                        "infrun: no user watchpoint explains "
                        "watchpoint SIGTRAP, ignoring\n");
 
-  /* NOTE: cagney/2003-03-29: These two checks for a random signal
+  /* NOTE: cagney/2003-03-29: These checks for a random signal
      at one stage in the past included checks for an inferior
      function call's call dummy's return breakpoint.  The original
      comment, that went with the test, read:
@@ -4275,55 +5992,89 @@ handle_inferior_event (struct execution_control_state *ecs)
      be necessary for call dummies on a non-executable stack on
      SPARC.  */
 
-  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
-    ecs->random_signal
-      = !((bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
-          != BPSTAT_SIGNAL_NO)
-         || stopped_by_watchpoint
-         || ecs->event_thread->control.trap_expected
-         || (ecs->event_thread->control.step_range_end
-             && (ecs->event_thread->control.step_resume_breakpoint
-                 == NULL)));
-  else
+  /* See if the breakpoints module can explain the signal.  */
+  random_signal
+    = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat,
+                              ecs->event_thread->suspend.stop_signal);
+
+  /* Maybe this was a trap for a software breakpoint that has since
+     been removed.  */
+  if (random_signal && target_stopped_by_sw_breakpoint ())
     {
-      enum bpstat_signal_value sval;
+      if (program_breakpoint_here_p (gdbarch, stop_pc))
+       {
+         struct regcache *regcache;
+         int decr_pc;
+
+         /* Re-adjust PC to what the program would see if GDB was not
+            debugging it.  */
+         regcache = get_thread_regcache (ecs->event_thread->ptid);
+         decr_pc = gdbarch_decr_pc_after_break (gdbarch);
+         if (decr_pc != 0)
+           {
+             struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);
+
+             if (record_full_is_used ())
+               record_full_gdb_operation_disable_set ();
+
+             regcache_write_pc (regcache, stop_pc + decr_pc);
 
-      sval = bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
-      ecs->random_signal = (sval == BPSTAT_SIGNAL_NO);
+             do_cleanups (old_cleanups);
+           }
+       }
+      else
+       {
+         /* A delayed software breakpoint event.  Ignore the trap.  */
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: delayed software breakpoint "
+                               "trap, ignoring\n");
+         random_signal = 0;
+       }
+    }
 
-      if (sval == BPSTAT_SIGNAL_HIDE)
-       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_TRAP;
+  /* Maybe this was a trap for a hardware breakpoint/watchpoint that
+     has since been removed.  */
+  if (random_signal && target_stopped_by_hw_breakpoint ())
+    {
+      /* A delayed hardware breakpoint event.  Ignore the trap.  */
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: delayed hardware breakpoint/watchpoint "
+                           "trap, ignoring\n");
+      random_signal = 0;
     }
 
-process_event_stop_test:
+  /* If not, perhaps stepping/nexting can.  */
+  if (random_signal)
+    random_signal = !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+                     && currently_stepping (ecs->event_thread));
 
-  /* Re-fetch current thread's frame in case we did a
-     "goto process_event_stop_test" above.  */
-  frame = get_current_frame ();
-  gdbarch = get_frame_arch (frame);
+  /* 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;
 
   /* For the program's own signals, act according to
      the signal handling tables.  */
 
-  if (ecs->random_signal)
+  if (random_signal)
     {
       /* Signal not for debugging purposes.  */
-      int printed = 0;
-      struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
+      struct inferior *inf = find_inferior_ptid (ecs->ptid);
+      enum gdb_signal stop_signal = ecs->event_thread->suspend.stop_signal;
 
       if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: random signal %d\n",
-                            ecs->event_thread->suspend.stop_signal);
+        fprintf_unfiltered (gdb_stdlog, "infrun: random signal (%s)\n",
+                            gdb_signal_to_symbol_string (stop_signal));
 
       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.  */
@@ -4332,13 +6083,20 @@ process_event_stop_test:
          || (!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)
@@ -4348,6 +6106,8 @@ process_event_stop_test:
          && ecs->event_thread->control.trap_expected
          && ecs->event_thread->control.step_resume_breakpoint == NULL)
        {
+         int was_in_line;
+
          /* We were just starting a new sequence, attempting to
             single-step off of a breakpoint and expecting a SIGTRAP.
             Instead this signal arrives.  This signal will take us out
@@ -4363,17 +6123,44 @@ process_event_stop_test:
                                 "infrun: signal arrived while stepping over "
                                 "breakpoint\n");
 
+         was_in_line = step_over_info_valid_p ();
+         clear_step_over_info ();
          insert_hp_step_resume_breakpoint_at_frame (frame);
          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 (target_is_non_stop_p ())
+           {
+             /* Either "set non-stop" is "on", or the target is
+                always in non-stop mode.  In this case, we have a bit
+                more work to do.  Resume the current thread, and if
+                we had paused all threads, restart them while the
+                signal handler runs.  */
+             keep_going (ecs);
+
+             if (was_in_line)
+               {
+                 restart_threads (ecs->event_thread);
+               }
+             else if (debug_infrun)
+               {
+                 fprintf_unfiltered (gdb_stdlog,
+                                     "infrun: no need to restart threads\n");
+               }
+             return;
+           }
+
+         /* 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;
        }
 
-      if (ecs->event_thread->control.step_range_end != 0
-         && ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_0
-         && pc_in_thread_step_range (stop_pc, ecs->event_thread)
+      if (ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_0
+         && (pc_in_thread_step_range (stop_pc, ecs->event_thread)
+             || ecs->event_thread->control.step_range_end == 1)
          && frame_id_eq (get_stack_frame_id (frame),
                          ecs->event_thread->control.step_stack_frame_id)
          && ecs->event_thread->control.step_resume_breakpoint == NULL)
@@ -4392,7 +6179,9 @@ process_event_stop_test:
                                 "infrun: signal may take us out of "
                                 "single-step range\n");
 
+         clear_step_over_info ();
          insert_hp_step_resume_breakpoint_at_frame (frame);
+         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);
@@ -4405,304 +6194,295 @@ process_event_stop_test:
         (leaving the inferior at the step-resume-breakpoint without
         actually executing it).  Either way continue until the
         breakpoint is really hit.  */
+
+      if (!switch_back_to_stepped_thread (ecs))
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: random signal, keep going\n");
+
+         keep_going (ecs);
+       }
+      return;
     }
-  else
-    {
-      /* Handle cases caused by hitting a breakpoint.  */
 
-      CORE_ADDR jmp_buf_pc;
-      struct bpstat_what what;
+  process_event_stop_test (ecs);
+}
+
+/* Come here when we've got some debug event / signal we can explain
+   (IOW, not a random signal), and test whether it should cause a
+   stop, or whether we should resume the inferior (transparently).
+   E.g., could be a breakpoint whose condition evaluates false; we
+   could be still stepping within the line; etc.  */
+
+static void
+process_event_stop_test (struct execution_control_state *ecs)
+{
+  struct symtab_and_line stop_pc_sal;
+  struct frame_info *frame;
+  struct gdbarch *gdbarch;
+  CORE_ADDR jmp_buf_pc;
+  struct bpstat_what what;
+
+  /* Handle cases caused by hitting a breakpoint.  */
 
-      what = bpstat_what (ecs->event_thread->control.stop_bpstat);
+  frame = get_current_frame ();
+  gdbarch = get_frame_arch (frame);
 
-      if (what.call_dummy)
-       {
-         stop_stack_dummy = what.call_dummy;
-       }
+  what = bpstat_what (ecs->event_thread->control.stop_bpstat);
 
-      /* If we hit an internal event that triggers symbol changes, the
-        current frame will be invalidated within bpstat_what (e.g.,
-        if we hit an internal solib event).  Re-fetch it.  */
-      frame = get_current_frame ();
-      gdbarch = get_frame_arch (frame);
+  if (what.call_dummy)
+    {
+      stop_stack_dummy = what.call_dummy;
+    }
 
-      switch (what.main_action)
-       {
-       case BPSTAT_WHAT_SET_LONGJMP_RESUME:
-         /* If we hit the breakpoint at longjmp while stepping, we
-            install a momentary breakpoint at the target of the
-            jmp_buf.  */
+  /* A few breakpoint types have callbacks associated (e.g.,
+     bp_jit_event).  Run them now.  */
+  bpstat_run_callbacks (ecs->event_thread->control.stop_bpstat);
 
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
+  /* If we hit an internal event that triggers symbol changes, the
+     current frame will be invalidated within bpstat_what (e.g., if we
+     hit an internal solib event).  Re-fetch it.  */
+  frame = get_current_frame ();
+  gdbarch = get_frame_arch (frame);
 
-         ecs->event_thread->stepping_over_breakpoint = 1;
+  switch (what.main_action)
+    {
+    case BPSTAT_WHAT_SET_LONGJMP_RESUME:
+      /* If we hit the breakpoint at longjmp while stepping, we
+        install a momentary breakpoint at the target of the
+        jmp_buf.  */
 
-         if (what.is_longjmp)
-           {
-             struct value *arg_value;
-
-             /* If we set the longjmp breakpoint via a SystemTap
-                probe, then use it to extract the arguments.  The
-                destination PC is the third argument to the
-                probe.  */
-             arg_value = probe_safe_evaluate_at_pc (frame, 2);
-             if (arg_value)
-               jmp_buf_pc = value_as_address (arg_value);
-             else if (!gdbarch_get_longjmp_target_p (gdbarch)
-                      || !gdbarch_get_longjmp_target (gdbarch,
-                                                      frame, &jmp_buf_pc))
-               {
-                 if (debug_infrun)
-                   fprintf_unfiltered (gdb_stdlog,
-                                       "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
-                                       "(!gdbarch_get_longjmp_target)\n");
-                 keep_going (ecs);
-                 return;
-               }
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
 
-             /* Insert a breakpoint at resume address.  */
-             insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
-           }
-         else
-           check_exception_resume (ecs, frame);
-         keep_going (ecs);
-         return;
+      ecs->event_thread->stepping_over_breakpoint = 1;
 
-       case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
-         {
-           struct frame_info *init_frame;
+      if (what.is_longjmp)
+       {
+         struct value *arg_value;
+
+         /* If we set the longjmp breakpoint via a SystemTap probe,
+            then use it to extract the arguments.  The destination PC
+            is the third argument to the probe.  */
+         arg_value = probe_safe_evaluate_at_pc (frame, 2);
+         if (arg_value)
+           {
+             jmp_buf_pc = value_as_address (arg_value);
+             jmp_buf_pc = gdbarch_addr_bits_remove (gdbarch, jmp_buf_pc);
+           }
+         else if (!gdbarch_get_longjmp_target_p (gdbarch)
+                  || !gdbarch_get_longjmp_target (gdbarch,
+                                                  frame, &jmp_buf_pc))
+           {
+             if (debug_infrun)
+               fprintf_unfiltered (gdb_stdlog,
+                                   "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
+                                   "(!gdbarch_get_longjmp_target)\n");
+             keep_going (ecs);
+             return;
+           }
 
-           /* There are several cases to consider.
+         /* Insert a breakpoint at resume address.  */
+         insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
+       }
+      else
+       check_exception_resume (ecs, frame);
+      keep_going (ecs);
+      return;
 
-              1. The initiating frame no longer exists.  In this case
-              we must stop, because the exception or longjmp has gone
-              too far.
+    case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
+      {
+       struct frame_info *init_frame;
 
-              2. The initiating frame exists, and is the same as the
-              current frame.  We stop, because the exception or
-              longjmp has been caught.
+       /* There are several cases to consider.
 
-              3. The initiating frame exists and is different from
-              the current frame.  This means the exception or longjmp
-              has been caught beneath the initiating frame, so keep
-              going.
+          1. The initiating frame no longer exists.  In this case we
+          must stop, because the exception or longjmp has gone too
+          far.
 
-              4. longjmp breakpoint has been placed just to protect
-              against stale dummy frames and user is not interested
-              in stopping around longjmps.  */
+          2. The initiating frame exists, and is the same as the
+          current frame.  We stop, because the exception or longjmp
+          has been caught.
 
-           if (debug_infrun)
-             fprintf_unfiltered (gdb_stdlog,
-                                 "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
+          3. The initiating frame exists and is different from the
+          current frame.  This means the exception or longjmp has
+          been caught beneath the initiating frame, so keep going.
 
-           gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
-                       != NULL);
-           delete_exception_resume_breakpoint (ecs->event_thread);
+          4. longjmp breakpoint has been placed just to protect
+          against stale dummy frames and user is not interested in
+          stopping around longjmps.  */
 
-           if (what.is_longjmp)
-             {
-               check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
+       if (debug_infrun)
+         fprintf_unfiltered (gdb_stdlog,
+                             "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
 
-               if (!frame_id_p (ecs->event_thread->initiating_frame))
-                 {
-                   /* Case 4.  */
-                   keep_going (ecs);
-                   return;
-                 }
-             }
+       gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
+                   != NULL);
+       delete_exception_resume_breakpoint (ecs->event_thread);
 
-           init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
+       if (what.is_longjmp)
+         {
+           check_longjmp_breakpoint_for_call_dummy (ecs->event_thread);
 
-           if (init_frame)
+           if (!frame_id_p (ecs->event_thread->initiating_frame))
              {
-               struct frame_id current_id
-                 = get_frame_id (get_current_frame ());
-               if (frame_id_eq (current_id,
-                                ecs->event_thread->initiating_frame))
-                 {
-                   /* Case 2.  Fall through.  */
-                 }
-               else
-                 {
-                   /* Case 3.  */
-                   keep_going (ecs);
-                   return;
-                 }
+               /* Case 4.  */
+               keep_going (ecs);
+               return;
              }
+         }
 
-           /* For Cases 1 and 2, remove the step-resume breakpoint,
-              if it exists.  */
-           delete_step_resume_breakpoint (ecs->event_thread);
+       init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
 
-           ecs->event_thread->control.stop_step = 1;
-           print_end_stepping_range_reason ();
-           stop_stepping (ecs);
+       if (init_frame)
+         {
+           struct frame_id current_id
+             = get_frame_id (get_current_frame ());
+           if (frame_id_eq (current_id,
+                            ecs->event_thread->initiating_frame))
+             {
+               /* Case 2.  Fall through.  */
+             }
+           else
+             {
+               /* Case 3.  */
+               keep_going (ecs);
+               return;
+             }
          }
-         return;
 
-       case BPSTAT_WHAT_SINGLE:
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
-         ecs->event_thread->stepping_over_breakpoint = 1;
-         /* Still need to check other stuff, at least the case where
-            we are stepping and step out of the right range.  */
-         break;
-
-       case BPSTAT_WHAT_STEP_RESUME:
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
+       /* For Cases 1 and 2, remove the step-resume breakpoint, if it
+          exists.  */
+       delete_step_resume_breakpoint (ecs->event_thread);
 
-         delete_step_resume_breakpoint (ecs->event_thread);
-         if (ecs->event_thread->control.proceed_to_finish
-             && execution_direction == EXEC_REVERSE)
-           {
-             struct thread_info *tp = ecs->event_thread;
-
-             /* We are finishing a function in reverse, and just hit
-                the step-resume breakpoint at the start address of
-                the function, and we're almost there -- just need to
-                back up by one more single-step, which should take us
-                back to the function call.  */
-             tp->control.step_range_start = tp->control.step_range_end = 1;
-             keep_going (ecs);
-             return;
-           }
-         fill_in_stop_func (gdbarch, ecs);
-         if (stop_pc == ecs->stop_func_start
-             && execution_direction == EXEC_REVERSE)
-           {
-             /* We are stepping over a function call in reverse, and
-                just hit the step-resume breakpoint at the start
-                address of the function.  Go back to single-stepping,
-                which should take us back to the function call.  */
-             ecs->event_thread->stepping_over_breakpoint = 1;
-             keep_going (ecs);
-             return;
-           }
-         break;
+       end_stepping_range (ecs);
+      }
+      return;
 
-       case BPSTAT_WHAT_STOP_NOISY:
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
-         stop_print_frame = 1;
+    case BPSTAT_WHAT_SINGLE:
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
+      ecs->event_thread->stepping_over_breakpoint = 1;
+      /* Still need to check other stuff, at least the case where we
+        are stepping and step out of the right range.  */
+      break;
 
-         /* We are about to nuke the step_resume_breakpointt via the
-            cleanup chain, so no need to worry about it here.  */
+    case BPSTAT_WHAT_STEP_RESUME:
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
 
-         stop_stepping (ecs);
+      delete_step_resume_breakpoint (ecs->event_thread);
+      if (ecs->event_thread->control.proceed_to_finish
+         && execution_direction == EXEC_REVERSE)
+       {
+         struct thread_info *tp = ecs->event_thread;
+
+         /* We are finishing a function in reverse, and just hit the
+            step-resume breakpoint at the start address of the
+            function, and we're almost there -- just need to back up
+            by one more single-step, which should take us back to the
+            function call.  */
+         tp->control.step_range_start = tp->control.step_range_end = 1;
+         keep_going (ecs);
+         return;
+       }
+      fill_in_stop_func (gdbarch, ecs);
+      if (stop_pc == ecs->stop_func_start
+         && execution_direction == EXEC_REVERSE)
+       {
+         /* We are stepping over a function call in reverse, and just
+            hit the step-resume breakpoint at the start address of
+            the function.  Go back to single-stepping, which should
+            take us back to the function call.  */
+         ecs->event_thread->stepping_over_breakpoint = 1;
+         keep_going (ecs);
          return;
+       }
+      break;
 
-       case BPSTAT_WHAT_STOP_SILENT:
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
-         stop_print_frame = 0;
+    case BPSTAT_WHAT_STOP_NOISY:
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
+      stop_print_frame = 1;
 
-         /* We are about to nuke the step_resume_breakpoin 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);
-         return;
+      stop_waiting (ecs);
+      return;
 
-       case BPSTAT_WHAT_HP_STEP_RESUME:
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
+    case BPSTAT_WHAT_STOP_SILENT:
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
+      stop_print_frame = 0;
 
-         delete_step_resume_breakpoint (ecs->event_thread);
-         if (ecs->event_thread->step_after_step_resume_breakpoint)
-           {
-             /* Back when the step-resume breakpoint was inserted, we
-                were trying to single-step off a breakpoint.  Go back
-                to doing that.  */
-             ecs->event_thread->step_after_step_resume_breakpoint = 0;
-             ecs->event_thread->stepping_over_breakpoint = 1;
-             keep_going (ecs);
-             return;
-           }
-         break;
+      /* 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:
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
 
-       case BPSTAT_WHAT_KEEP_CHECKING:
-         break;
+      delete_step_resume_breakpoint (ecs->event_thread);
+      if (ecs->event_thread->step_after_step_resume_breakpoint)
+       {
+         /* Back when the step-resume breakpoint was inserted, we
+            were trying to single-step off a breakpoint.  Go back to
+            doing that.  */
+         ecs->event_thread->step_after_step_resume_breakpoint = 0;
+         ecs->event_thread->stepping_over_breakpoint = 1;
+         keep_going (ecs);
+         return;
        }
-    }
+      break;
 
-  /* We come here if we hit a breakpoint but should not
-     stop for it.  Possibly we also were stepping
-     and should stop for that.  So fall through and
-     test for stepping.  But, if not stepping,
-     do not stop.  */
+    case BPSTAT_WHAT_KEEP_CHECKING:
+      break;
+    }
 
-  /* In all-stop mode, if we're currently stepping but have stopped in
-     some other thread, we need to switch back to the stepped thread.  */
-  if (!non_stop)
+  /* If we stepped a permanent breakpoint and we had a high priority
+     step-resume breakpoint for the address we stepped, but we didn't
+     hit it, then we must have stepped into the signal handler.  The
+     step-resume was only necessary to catch the case of _not_
+     stepping into the handler, so delete it, and fall through to
+     checking whether the step finished.  */
+  if (ecs->event_thread->stepped_breakpoint)
     {
-      struct thread_info *tp;
+      struct breakpoint *sr_bp
+       = ecs->event_thread->control.step_resume_breakpoint;
 
-      tp = iterate_over_threads (currently_stepping_or_nexting_callback,
-                                ecs->event_thread);
-      if (tp)
+      if (sr_bp != NULL
+         && sr_bp->loc->permanent
+         && sr_bp->type == bp_hp_step_resume
+         && sr_bp->loc->address == ecs->event_thread->prev_pc)
        {
-         /* However, if the current thread is blocked on some internal
-            breakpoint, and we simply need to step over that breakpoint
-            to get it going again, do that first.  */
-         if ((ecs->event_thread->control.trap_expected
-              && ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_TRAP)
-             || ecs->event_thread->stepping_over_breakpoint)
-           {
-             keep_going (ecs);
-             return;
-           }
-
-         /* If the stepping thread exited, then don't try to switch
-            back and resume it, which could fail in several different
-            ways depending on the target.  Instead, just keep going.
-
-            We can find a stepping dead thread in the thread list in
-            two cases:
-
-            - The target supports thread exit events, and when the
-            target tries to delete the thread from the thread list,
-            inferior_ptid pointed at the exiting thread.  In such
-            case, calling delete_thread does not really remove the
-            thread from the list; instead, the thread is left listed,
-            with 'exited' state.
-
-            - The target's debug interface does not support thread
-            exit events, and so we have no idea whatsoever if the
-            previously stepping thread is still alive.  For that
-            reason, we need to synchronously query the target
-            now.  */
-         if (is_exited (tp->ptid)
-             || !target_thread_alive (tp->ptid))
-           {
-             if (debug_infrun)
-               fprintf_unfiltered (gdb_stdlog,
-                                   "infrun: not switching back to "
-                                   "stepped thread, it has vanished\n");
-
-             delete_thread (tp->ptid);
-             keep_going (ecs);
-             return;
-           }
-
-         /* Otherwise, we no longer expect a trap in the current thread.
-            Clear the trap_expected flag before switching back -- this is
-            what keep_going would do as well, if we called it.  */
-         ecs->event_thread->control.trap_expected = 0;
-
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
-                               "infrun: switching back to stepped thread\n");
-
-         ecs->event_thread = tp;
-         ecs->ptid = tp->ptid;
-         context_switch (ecs->ptid);
-         keep_going (ecs);
-         return;
+                               "infrun: stepped permanent breakpoint, stopped in "
+                               "handler\n");
+         delete_step_resume_breakpoint (ecs->event_thread);
+         ecs->event_thread->step_after_step_resume_breakpoint = 0;
        }
     }
 
+  /* We come here if we hit a breakpoint but should not stop for it.
+     Possibly we also were stepping and should stop for that.  So fall
+     through and test for stepping.  But, if not stepping, do not
+     stop.  */
+
+  /* In all-stop mode, if we're currently stepping but have stopped in
+     some other thread, we need to switch back to the stepped thread.  */
+  if (switch_back_to_stepped_thread (ecs))
+    return;
+
   if (ecs->event_thread->control.step_resume_breakpoint)
     {
       if (debug_infrun)
@@ -4764,11 +6544,7 @@ process_event_stop_test:
       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);
 
@@ -4900,28 +6676,21 @@ process_event_stop_test:
                       ecs->event_thread->control.step_stack_frame_id)
          && (!frame_id_eq (ecs->event_thread->control.step_stack_frame_id,
                            outer_frame_id)
-             || step_start_function != find_pc_function (stop_pc))))
+             || (ecs->event_thread->control.step_start_function
+                 != find_pc_function (stop_pc)))))
     {
       CORE_ADDR real_stop_pc;
 
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: stepped into subroutine\n");
 
-      if ((ecs->event_thread->control.step_over_calls == STEP_OVER_NONE)
-         || ((ecs->event_thread->control.step_range_end == 1)
-             && in_prologue (gdbarch, ecs->event_thread->prev_pc,
-                             ecs->stop_func_start)))
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_NONE)
        {
          /* I presume that step_over_calls is only 0 when we're
             supposed to be stepping at the assembly language level
             ("stepi").  Just stop.  */
-         /* Also, maybe we just did a "nexti" inside a prolog, so we
-            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;
        }
 
@@ -4962,7 +6731,7 @@ process_event_stop_test:
                 or stepped back out of a signal handler to the first instruction
                 of the function.  Just keep going, which will single-step back
                 to the caller.  */
-             if (ecs->stop_func_start != stop_pc)
+             if (ecs->stop_func_start != stop_pc && ecs->stop_func_start != 0)
                {
                  struct symtab_and_line sr_sal;
 
@@ -5035,9 +6804,7 @@ process_event_stop_test:
       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;
        }
 
@@ -5131,9 +6898,7 @@ process_event_stop_test:
          /* 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
@@ -5152,9 +6917,7 @@ process_event_stop_test:
          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;
     }
 
@@ -5166,9 +6929,7 @@ process_event_stop_test:
          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;
     }
 
@@ -5199,9 +6960,7 @@ process_event_stop_test:
              && 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
@@ -5213,11 +6972,7 @@ process_event_stop_test:
              && 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;
        }
     }
@@ -5235,54 +6990,308 @@ process_event_stop_test:
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: stepping through inlined function\n");
+                           "infrun: stepping through inlined function\n");
+
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
+       keep_going (ecs);
+      else
+       end_stepping_range (ecs);
+      return;
+    }
+
+  if ((stop_pc == stop_pc_sal.pc)
+      && (ecs->event_thread->current_line != stop_pc_sal.line
+         || ecs->event_thread->current_symtab != stop_pc_sal.symtab))
+    {
+      /* We are at the start of a different line.  So stop.  Note that
+         we don't stop if we step into the middle of a different line.
+         That is said to make things like for (;;) statements work
+         better.  */
+      if (debug_infrun)
+        fprintf_unfiltered (gdb_stdlog,
+                            "infrun: stepped to a different line\n");
+      end_stepping_range (ecs);
+      return;
+    }
+
+  /* We aren't done stepping.
+
+     Optimize by setting the stepping range to the line.
+     (We might not be in the original line, but if we entered a
+     new line in mid-statement, we continue stepping.  This makes
+     things like for(;;) statements work better.)  */
+
+  ecs->event_thread->control.step_range_start = stop_pc_sal.pc;
+  ecs->event_thread->control.step_range_end = stop_pc_sal.end;
+  ecs->event_thread->control.may_range_step = 1;
+  set_step_info (frame, stop_pc_sal);
+
+  if (debug_infrun)
+     fprintf_unfiltered (gdb_stdlog, "infrun: keep going\n");
+  keep_going (ecs);
+}
+
+/* In all-stop mode, if we're currently stepping but have stopped in
+   some other thread, we may need to switch back to the stepped
+   thread.  Returns true we set the inferior running, false if we left
+   it stopped (and the event needs further processing).  */
+
+static int
+switch_back_to_stepped_thread (struct execution_control_state *ecs)
+{
+  if (!target_is_non_stop_p ())
+    {
+      struct thread_info *tp;
+      struct thread_info *stepping_thread;
+
+      /* If any thread is blocked on some internal breakpoint, and we
+        simply need to step over that breakpoint to get it going
+        again, do that first.  */
+
+      /* 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;
+       }
+
+      /* If this thread needs yet another step-over (e.g., stepping
+        through a delay slot), do it first before moving on to
+        another thread.  */
+      if (thread_still_needs_step_over (ecs->event_thread))
+       {
+         if (debug_infrun)
+           {
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: thread [%s] still needs step-over\n",
+                                 target_pid_to_str (ecs->event_thread->ptid));
+           }
+         keep_going (ecs);
+         return 1;
+       }
+
+      /* 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 (ecs->event_thread))
+       return 0;
+
+      /* 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;
+
+      /* Do all pending step-overs before actually proceeding with
+        step/next/etc.  */
+      if (start_step_over ())
+       {
+         prepare_to_wait (ecs);
+         return 1;
+       }
+
+      /* Look for the stepping/nexting thread.  */
+      stepping_thread = NULL;
+
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         /* Ignore threads of processes the caller is not
+            resuming.  */
+         if (!sched_multi
+             && ptid_get_pid (tp->ptid) != ptid_get_pid (ecs->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.  */
+         if (tp->control.trap_expected)
+           {
+             internal_error (__FILE__, __LINE__,
+                             "[%s] has inconsistent state: "
+                             "trap_expected=%d\n",
+                             target_pid_to_str (tp->ptid),
+                             tp->control.trap_expected);
+           }
+
+         /* 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 (tp));
+
+             stepping_thread = tp;
+           }
+       }
+
+      if (stepping_thread != NULL)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: switching back to stepped thread\n");
+
+         if (keep_going_stepped_thread (stepping_thread))
+           {
+             prepare_to_wait (ecs);
+             return 1;
+           }
+       }
+    }
+
+  return 0;
+}
+
+/* Set a previously stepped thread back to stepping.  Returns true on
+   success, false if the resume is not possible (e.g., the thread
+   vanished).  */
+
+static int
+keep_going_stepped_thread (struct thread_info *tp)
+{
+  struct frame_info *frame;
+  struct execution_control_state ecss;
+  struct execution_control_state *ecs = &ecss;
+
+  /* If the stepping thread exited, then don't try to switch back and
+     resume it, which could fail in several different ways depending
+     on the target.  Instead, just keep going.
+
+     We can find a stepping dead thread in the thread list in two
+     cases:
+
+     - The target supports thread exit events, and when the target
+       tries to delete the thread from the thread list, inferior_ptid
+       pointed at the exiting thread.  In such case, calling
+       delete_thread does not really remove the thread from the list;
+       instead, the thread is left listed, with 'exited' state.
+
+     - The target's debug interface does not support thread exit
+       events, and so we have no idea whatsoever if the previously
+       stepping thread is still alive.  For that reason, we need to
+       synchronously query the target now.  */
+
+  if (is_exited (tp->ptid)
+      || !target_thread_alive (tp->ptid))
+    {
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: not resuming previously  "
+                           "stepped thread, it has vanished\n");
 
-      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);
-       }
-      return;
+      delete_thread (tp->ptid);
+      return 0;
     }
 
-  if ((stop_pc == stop_pc_sal.pc)
-      && (ecs->event_thread->current_line != stop_pc_sal.line
-         || ecs->event_thread->current_symtab != stop_pc_sal.symtab))
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+                       "infrun: resuming previously stepped thread\n");
+
+  reset_ecs (ecs, tp);
+  switch_to_thread (tp->ptid);
+
+  stop_pc = regcache_read_pc (get_thread_regcache (tp->ptid));
+  frame = get_current_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 (stop_pc != tp->prev_pc)
     {
-      /* We are at the start of a different line.  So stop.  Note that
-         we don't stop if we step into the middle of a different line.
-         That is said to make things like for (;;) statements work
-         better.  */
-      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);
-      return;
-    }
+      ptid_t resume_ptid;
 
-  /* We aren't done stepping.
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: expected thread advanced also (%s -> %s)\n",
+                           paddress (target_gdbarch (), tp->prev_pc),
+                           paddress (target_gdbarch (), stop_pc));
+
+      /* Clear the info of the previous step-over, as it's no longer
+        valid (if the thread was trying to step over a breakpoint, it
+        has already succeeded).  It's what keep_going would do too,
+        if we called it.  Do this before trying to insert the sss
+        breakpoint, otherwise if we were previously trying to step
+        over this exact address in another thread, the breakpoint is
+        skipped.  */
+      clear_step_over_info ();
+      tp->control.trap_expected = 0;
 
-     Optimize by setting the stepping range to the line.
-     (We might not be in the original line, but if we entered a
-     new line in mid-statement, we continue stepping.  This makes
-     things like for(;;) statements work better.)  */
+      insert_single_step_breakpoint (get_frame_arch (frame),
+                                    get_frame_address_space (frame),
+                                    stop_pc);
 
-  ecs->event_thread->control.step_range_start = stop_pc_sal.pc;
-  ecs->event_thread->control.step_range_end = stop_pc_sal.end;
-  ecs->event_thread->control.may_range_step = 1;
-  set_step_info (frame, stop_pc_sal);
+      tp->resumed = 1;
+      resume_ptid = internal_resume_ptid (tp->control.stepping_command);
+      do_target_resume (resume_ptid, 0, GDB_SIGNAL_0);
+    }
+  else
+    {
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: expected thread still hasn't advanced\n");
 
-  if (debug_infrun)
-     fprintf_unfiltered (gdb_stdlog, "infrun: keep going\n");
-  keep_going (ecs);
+      keep_going_pass_signal (ecs);
+    }
+  return 1;
 }
 
-/* Is thread TP in the middle of single-stepping?  */
+/* Is thread TP in the middle of (software or hardware)
+   single-stepping?  (Note the result of this function must never be
+   passed directly as target_resume's STEP parameter.)  */
 
 static int
 currently_stepping (struct thread_info *tp)
@@ -5290,22 +7299,10 @@ currently_stepping (struct thread_info *tp)
   return ((tp->control.step_range_end
           && tp->control.step_resume_breakpoint == NULL)
          || tp->control.trap_expected
+         || tp->stepped_breakpoint
          || 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.  */
@@ -5314,13 +7311,13 @@ static void
 handle_step_into_function (struct gdbarch *gdbarch,
                           struct execution_control_state *ecs)
 {
-  struct symtab *s;
+  struct compunit_symtab *cust;
   struct symtab_and_line stop_func_sal, sr_sal;
 
   fill_in_stop_func (gdbarch, ecs);
 
-  s = find_pc_symtab (stop_pc);
-  if (s && s->language != language_asm)
+  cust = find_pc_compunit_symtab (stop_pc);
+  if (cust != NULL && compunit_language (cust) != language_asm)
     ecs->stop_func_start = gdbarch_skip_prologue (gdbarch,
                                                  ecs->stop_func_start);
 
@@ -5362,9 +7359,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
@@ -5395,13 +7390,13 @@ static void
 handle_step_into_function_backward (struct gdbarch *gdbarch,
                                    struct execution_control_state *ecs)
 {
-  struct symtab *s;
+  struct compunit_symtab *cust;
   struct symtab_and_line stop_func_sal;
 
   fill_in_stop_func (gdbarch, ecs);
 
-  s = find_pc_symtab (stop_pc);
-  if (s && s->language != language_asm)
+  cust = find_pc_compunit_symtab (stop_pc);
+  if (cust != NULL && compunit_language (cust) != language_asm)
     ecs->stop_func_start = gdbarch_skip_prologue (gdbarch,
                                                  ecs->stop_func_start);
 
@@ -5411,9 +7406,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
     {
@@ -5553,22 +7546,19 @@ 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)
 {
-  volatile struct gdb_exception e;
-
-  /* We want to ignore errors here.  */
-  TRY_CATCH (e, RETURN_MASK_ERROR)
+  TRY
     {
-      struct symbol *vsym;
+      struct block_symbol vsym;
       struct value *value;
       CORE_ADDR handler;
       struct breakpoint *bp;
 
       vsym = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), b, VAR_DOMAIN, NULL);
-      value = read_var_value (vsym, frame);
+      value = read_var_value (vsym.symbol, vsym.block, frame);
       /* If the value was optimized out, revert to the old behavior.  */
       if (! value_optimized_out (value))
        {
@@ -5585,10 +7575,15 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
          /* set_momentary_breakpoint_at_pc invalidates FRAME.  */
          frame = NULL;
 
-         bp->thread = tp->num;
+         bp->thread = tp->global_num;
          inferior_thread ()->control.exception_resume_breakpoint = bp;
        }
     }
+  CATCH (e, RETURN_MASK_ERROR)
+    {
+      /* We want to ignore errors here.  */
+    }
+  END_CATCH
 }
 
 /* A helper for check_exception_resume that sets an
@@ -5596,7 +7591,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;
@@ -5617,7 +7612,7 @@ insert_exception_resume_from_probe (struct thread_info *tp,
 
   bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
                                       handler, bp_exception_resume);
-  bp->thread = tp->num;
+  bp->thread = tp->global_num;
   inferior_thread ()->control.exception_resume_breakpoint = bp;
 }
 
@@ -5629,8 +7624,7 @@ static void
 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
@@ -5638,9 +7632,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;
     }
 
@@ -5648,9 +7642,9 @@ check_exception_resume (struct execution_control_state *ecs,
   if (!func)
     return;
 
-  TRY_CATCH (e, RETURN_MASK_ERROR)
+  TRY
     {
-      struct block *b;
+      const struct block *b;
       struct block_iterator iter;
       struct symbol *sym;
       int argno = 0;
@@ -5685,117 +7679,183 @@ check_exception_resume (struct execution_control_state *ecs,
            }
        }
     }
+  CATCH (e, RETURN_MASK_ERROR)
+    {
+    }
+  END_CATCH
 }
 
 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;
+
+  /* If all-stop, but the target is always in non-stop mode, stop all
+     threads now that we're presenting the stop to the user.  */
+  if (!non_stop && target_is_non_stop_p ())
+    stop_all_threads ();
 }
 
-/* This function handles various cases where we need to continue
-   waiting for the inferior.  */
-/* (Used to be the keep_going: label in the old wait_for_inferior).  */
+/* Like keep_going, but passes the signal to the inferior, even if the
+   signal is set to nopass.  */
 
 static void
-keep_going (struct execution_control_state *ecs)
+keep_going_pass_signal (struct execution_control_state *ecs)
 {
   /* Make sure normal_stop is called if we get a QUIT handled before
      reaching resume.  */
   struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
 
+  gdb_assert (ptid_equal (ecs->event_thread->ptid, inferior_ptid));
+  gdb_assert (!ecs->event_thread->resumed);
+
   /* Save the pc before execution, to compare with pc after stop.  */
   ecs->event_thread->prev_pc
     = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
-  /* If we did not do break;, it means we should keep running the
-     inferior and not return to debugger.  */
+  if (ecs->event_thread->control.trap_expected)
+    {
+      struct thread_info *tp = ecs->event_thread;
 
-  if (ecs->event_thread->control.trap_expected
-      && ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_TRAP)
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: %s has trap_expected set, "
+                           "resuming to collect trap\n",
+                           target_pid_to_str (tp->ptid));
+
+      /* We haven't yet gotten our trap, and either: intercepted a
+        non-signal event (e.g., a fork); or took a signal which we
+        are supposed to pass through to the inferior.  Simply
+        continue.  */
+      discard_cleanups (old_cleanups);
+      resume (ecs->event_thread->suspend.stop_signal);
+    }
+  else if (step_over_info_valid_p ())
     {
-      /* We took a signal (which we are supposed to pass through to
-        the inferior, else we'd not get here) and we haven't yet
-        gotten our trap.  Simply continue.  */
+      /* Another thread is stepping over a breakpoint in-line.  If
+        this thread needs a step-over too, queue the request.  In
+        either case, this resume must be deferred for later.  */
+      struct thread_info *tp = ecs->event_thread;
+
+      if (ecs->hit_singlestep_breakpoint
+         || thread_still_needs_step_over (tp))
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: step-over already in progress: "
+                               "step-over for %s deferred\n",
+                               target_pid_to_str (tp->ptid));
+         thread_step_over_chain_enqueue (tp);
+       }
+      else
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: step-over in progress: "
+                               "resume of %s deferred\n",
+                               target_pid_to_str (tp->ptid));
+       }
 
       discard_cleanups (old_cleanups);
-      resume (currently_stepping (ecs->event_thread),
-             ecs->event_thread->suspend.stop_signal);
     }
   else
     {
+      struct regcache *regcache = get_current_regcache ();
+      int remove_bp;
+      int remove_wps;
+      step_over_what step_what;
+
       /* Either the trap was not expected, but we are continuing
-         anyway (the user asked that this signal be passed to the
-         child)
-         -- or --
-         The signal was SIGTRAP, e.g. it was our signal, but we
-         decided we should resume from it.
+        anyway (if we got a signal, the user asked it be passed to
+        the child)
+        -- or --
+        We got our expected trap, but decided we should resume from
+        it.
 
-         We're going to run this baby now!  
+        We're going to run this baby now!
 
         Note that insert_breakpoints won't try to re-insert
         already inserted breakpoints.  Therefore, we don't
         care if breakpoints were already inserted, or not.  */
-      
-      if (ecs->event_thread->stepping_over_breakpoint)
-       {
-         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 ();
-       }
-      else
-       {
-         volatile struct gdb_exception e;
 
-         /* Stop stepping when inserting breakpoints
-            has failed.  */
-         TRY_CATCH (e, RETURN_MASK_ERROR)
-           {
-             insert_breakpoints ();
-           }
-         if (e.reason < 0)
-           {
-             exception_print (gdb_stderr, e);
-             stop_stepping (ecs);
-             return;
-           }
-       }
+      /* 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.  */
 
-      ecs->event_thread->control.trap_expected
-       = ecs->event_thread->stepping_over_breakpoint;
+      step_what = thread_still_needs_step_over (ecs->event_thread);
 
-      /* Do not deliver SIGNAL_TRAP (except when the user explicitly
-         specifies that such a signal should be delivered to the
-         target program).
+      remove_bp = (ecs->hit_singlestep_breakpoint
+                  || (step_what & STEP_OVER_BREAKPOINT));
+      remove_wps = (step_what & STEP_OVER_WATCHPOINT);
 
-         Typically, this would occure when a user is debugging a
-         target monitor on a simulator: the target monitor sets a
-         breakpoint; the simulator encounters this break-point and
-         halts the simulation handing control to GDB; GDB, noteing
-         that the break-point isn't valid, returns control back to the
-         simulator; the simulator then delivers the hardware
-         equivalent of a SIGNAL_TRAP to the program being debugged.  */
+      /* We can't use displaced stepping if we need to step past a
+        watchpoint.  The instruction copied to the scratch pad would
+        still trigger the watchpoint.  */
+      if (remove_bp
+         && (remove_wps || !use_displaced_stepping (ecs->event_thread)))
+       {
+         set_step_over_info (get_regcache_aspace (regcache),
+                             regcache_read_pc (regcache), remove_wps,
+                             ecs->event_thread->global_num);
+       }
+      else if (remove_wps)
+       set_step_over_info (NULL, 0, remove_wps, -1);
+
+      /* If we now need to do an in-line step-over, we need to stop
+        all other threads.  Note this must be done before
+        insert_breakpoints below, because that removes the breakpoint
+        we're about to step over, otherwise other threads could miss
+        it.  */
+      if (step_over_info_valid_p () && target_is_non_stop_p ())
+       stop_all_threads ();
+
+      /* Stop stepping if inserting breakpoints fails.  */
+      TRY
+       {
+         insert_breakpoints ();
+       }
+      CATCH (e, RETURN_MASK_ERROR)
+       {
+         exception_print (gdb_stderr, e);
+         stop_waiting (ecs);
+         discard_cleanups (old_cleanups);
+         return;
+       }
+      END_CATCH
 
-      if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-         && !signal_program[ecs->event_thread->suspend.stop_signal])
-       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+      ecs->event_thread->control.trap_expected = (remove_bp || remove_wps);
 
       discard_cleanups (old_cleanups);
-      resume (currently_stepping (ecs->event_thread),
-             ecs->event_thread->suspend.stop_signal);
+      resume (ecs->event_thread->suspend.stop_signal);
     }
 
   prepare_to_wait (ecs);
 }
 
+/* Called when we should continue running the inferior, because the
+   current event doesn't cause a user visible stop.  This does the
+   resuming part; waiting for the next event is done elsewhere.  */
+
+static void
+keep_going (struct execution_control_state *ecs)
+{
+  if (ecs->event_thread->control.trap_expected
+      && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
+    ecs->event_thread->control.trap_expected = 0;
+
+  if (!signal_program[ecs->event_thread->suspend.stop_signal])
+    ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+  keep_going_pass_signal (ecs);
+}
+
 /* This function normally comes after a resume, before
    handle_inferior_event exits.  It takes care of any last bits of
    housekeeping, and sets the all-important wait_some_more flag.  */
@@ -5806,10 +7866,20 @@ prepare_to_wait (struct execution_control_state *ecs)
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog, "infrun: prepare_to_wait\n");
 
-  /* This is the old end of the while loop.  Let everybody know we
-     want to wait for the inferior some more and get called again
-     soon.  */
   ecs->wait_some_more = 1;
+
+  if (!target_is_async_p ())
+    mark_infrun_async_event_handler ();
+}
+
+/* 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.
@@ -5817,30 +7887,27 @@ prepare_to_wait (struct execution_control_state *ecs)
    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
@@ -5859,124 +7926,355 @@ 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.  */
+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));
+
+  annotate_exited (exitstatus);
+  if (exitstatus)
+    {
+      if (ui_out_is_mi_like_p (uiout))
+       ui_out_field_string (uiout, "reason", 
+                            async_reason_lookup (EXEC_ASYNC_EXITED));
+      ui_out_text (uiout, "[Inferior ");
+      ui_out_text (uiout, plongest (inf->num));
+      ui_out_text (uiout, " (");
+      ui_out_text (uiout, pidstr);
+      ui_out_text (uiout, ") exited with code ");
+      ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) exitstatus);
+      ui_out_text (uiout, "]\n");
+    }
+  else
+    {
+      if (ui_out_is_mi_like_p (uiout))
+       ui_out_field_string
+         (uiout, "reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
+      ui_out_text (uiout, "[Inferior ");
+      ui_out_text (uiout, plongest (inf->num));
+      ui_out_text (uiout, " (");
+      ui_out_text (uiout, pidstr);
+      ui_out_text (uiout, ") exited normally]\n");
+    }
+}
+
+/* Some targets/architectures can do extra processing/display of
+   segmentation faults.  E.g., Intel MPX boundary faults.
+   Call the architecture dependent function to handle the fault.  */
+
+static void
+handle_segmentation_fault (struct ui_out *uiout)
+{
+  struct regcache *regcache = get_current_regcache ();
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+  if (gdbarch_handle_segmentation_fault_p (gdbarch))
+    gdbarch_handle_segmentation_fault (gdbarch, uiout);
+}
+
+void
+print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
+{
+  struct thread_info *thr = inferior_thread ();
+
+  annotate_signal ();
+
+  if (ui_out_is_mi_like_p (uiout))
+    ;
+  else if (show_thread_that_caused_stop ())
+    {
+      const char *name;
+
+      ui_out_text (uiout, "\nThread ");
+      ui_out_field_fmt (uiout, "thread-id", "%s", print_thread_id (thr));
+
+      name = thr->name != NULL ? thr->name : target_thread_name (thr);
+      if (name != NULL)
+       {
+         ui_out_text (uiout, " \"");
+         ui_out_field_fmt (uiout, "name", "%s", name);
+         ui_out_text (uiout, "\"");
+       }
+    }
+  else
+    ui_out_text (uiout, "\nProgram");
+
+  if (siggnal == GDB_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
+    ui_out_text (uiout, " stopped");
+  else
+    {
+      ui_out_text (uiout, " received signal ");
+      annotate_signal_name ();
+      if (ui_out_is_mi_like_p (uiout))
+       ui_out_field_string
+         (uiout, "reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
+      ui_out_field_string (uiout, "signal-name",
+                          gdb_signal_to_name (siggnal));
+      annotate_signal_name_end ();
+      ui_out_text (uiout, ", ");
+      annotate_signal_string ();
+      ui_out_field_string (uiout, "signal-meaning",
+                          gdb_signal_to_string (siggnal));
+
+      if (siggnal == GDB_SIGNAL_SEGV)
+       handle_segmentation_fault (uiout);
+
+      annotate_signal_string_end ();
+    }
+  ui_out_text (uiout, ".\n");
+}
+
+void
+print_no_history_reason (struct ui_out *uiout)
+{
+  ui_out_text (uiout, "\nNo more reverse-execution history.\n");
+}
+
+/* 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.  */
+
+static void
+print_stop_location (struct target_waitstatus *ws)
+{
+  int bpstat_ret;
+  enum print_what 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 ()))
+         && tp->control.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);
+}
+
+/* Cleanup that restores a previous current uiout.  */
+
+static void
+restore_current_uiout_cleanup (void *arg)
+{
+  struct ui_out *saved_uiout = (struct ui_out *) arg;
+
+  current_uiout = saved_uiout;
+}
+
+/* See infrun.h.  */
+
+void
+print_stop_event (struct ui_out *uiout)
+{
+  struct cleanup *old_chain;
+  struct target_waitstatus last;
+  ptid_t last_ptid;
+  struct thread_info *tp;
+
+  get_last_target_status (&last_ptid, &last);
+
+  old_chain = make_cleanup (restore_current_uiout_cleanup, current_uiout);
+  current_uiout = uiout;
+
+  print_stop_location (&last);
+
+  /* Display the auto-display expressions.  */
+  do_displays ();
+
+  do_cleanups (old_chain);
+
+  tp = inferior_thread ();
+  if (tp->thread_fsm != NULL
+      && thread_fsm_finished_p (tp->thread_fsm))
+    {
+      struct return_value_info *rv;
+
+      rv = thread_fsm_return_value (tp->thread_fsm);
+      if (rv != NULL)
+       print_return_value (uiout, rv);
+    }
+}
+
+/* See infrun.h.  */
 
-static void
-print_exited_reason (int exitstatus)
+void
+maybe_remove_breakpoints (void)
 {
-  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)
-    {
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string (uiout, "reason", 
-                            async_reason_lookup (EXEC_ASYNC_EXITED));
-      ui_out_text (uiout, "[Inferior ");
-      ui_out_text (uiout, plongest (inf->num));
-      ui_out_text (uiout, " (");
-      ui_out_text (uiout, pidstr);
-      ui_out_text (uiout, ") exited with code ");
-      ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) exitstatus);
-      ui_out_text (uiout, "]\n");
-    }
-  else
+  if (!breakpoints_should_be_inserted_now () && target_has_execution)
     {
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string
-         (uiout, "reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
-      ui_out_text (uiout, "[Inferior ");
-      ui_out_text (uiout, plongest (inf->num));
-      ui_out_text (uiout, " (");
-      ui_out_text (uiout, pidstr);
-      ui_out_text (uiout, ") exited normally]\n");
+      if (remove_breakpoints ())
+       {
+         target_terminal_ours_for_output ();
+         printf_filtered (_("Cannot remove breakpoints because "
+                            "program is no longer writable.\nFurther "
+                            "execution is probably impossible.\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.  */
+/* The execution context that just caused a normal stop.  */
 
-static void
-print_signal_received_reason (enum gdb_signal siggnal)
+struct stop_context
 {
-  struct ui_out *uiout = current_uiout;
+  /* The stop ID.  */
+  ULONGEST stop_id;
 
-  annotate_signal ();
+  /* The event PTID.  */
 
-  if (siggnal == GDB_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
-    {
-      struct thread_info *t = inferior_thread ();
+  ptid_t ptid;
 
-      ui_out_text (uiout, "\n[");
-      ui_out_field_string (uiout, "thread-name",
-                          target_pid_to_str (t->ptid));
-      ui_out_field_fmt (uiout, "thread-id", "] #%d", t->num);
-      ui_out_text (uiout, " stopped");
-    }
-  else
+  /* If stopp for a thread event, this is the thread that caused the
+     stop.  */
+  struct thread_info *thread;
+
+  /* The inferior that caused the stop.  */
+  int inf_num;
+};
+
+/* Returns a new stop context.  If stopped for a thread event, this
+   takes a strong reference to the thread.  */
+
+static struct stop_context *
+save_stop_context (void)
+{
+  struct stop_context *sc = XNEW (struct stop_context);
+
+  sc->stop_id = get_stop_id ();
+  sc->ptid = inferior_ptid;
+  sc->inf_num = current_inferior ()->num;
+
+  if (!ptid_equal (inferior_ptid, null_ptid))
     {
-      ui_out_text (uiout, "\nProgram received signal ");
-      annotate_signal_name ();
-      if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string
-         (uiout, "reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
-      ui_out_field_string (uiout, "signal-name",
-                          gdb_signal_to_name (siggnal));
-      annotate_signal_name_end ();
-      ui_out_text (uiout, ", ");
-      annotate_signal_string ();
-      ui_out_field_string (uiout, "signal-meaning",
-                          gdb_signal_to_string (siggnal));
-      annotate_signal_string_end ();
+      /* Take a strong reference so that the thread can't be deleted
+        yet.  */
+      sc->thread = inferior_thread ();
+      sc->thread->refcount++;
     }
-  ui_out_text (uiout, ".\n");
+  else
+    sc->thread = NULL;
+
+  return sc;
 }
 
-/* Reverse execution: target ran out of history info, print why the inferior
-   has stopped.  */
+/* Release a stop context previously created with save_stop_context.
+   Releases the strong reference to the thread as well. */
 
 static void
-print_no_history_reason (void)
+release_stop_context_cleanup (void *arg)
 {
-  ui_out_text (current_uiout, "\nNo more reverse-execution history.\n");
+  struct stop_context *sc = (struct stop_context *) arg;
+
+  if (sc->thread != NULL)
+    sc->thread->refcount--;
+  xfree (sc);
 }
 
-/* Here to return control to GDB when the inferior stops for real.
-   Print appropriate messages, remove breakpoints, give terminal our modes.
+/* Return true if the current context no longer matches the saved stop
+   context.  */
+
+static int
+stop_context_changed (struct stop_context *prev)
+{
+  if (!ptid_equal (prev->ptid, inferior_ptid))
+    return 1;
+  if (prev->inf_num != current_inferior ()->num)
+    return 1;
+  if (prev->thread != NULL && prev->thread->state != THREAD_STOPPED)
+    return 1;
+  if (get_stop_id () != prev->stop_id)
+    return 1;
+  return 0;
+}
 
-   STOP_PRINT_FRAME nonzero means print the executing frame
-   (pc, function, args, file, line number and line text).
-   BREAKPOINTS_FAILED nonzero means stop was due to error
-   attempting to insert breakpoints.  */
+/* See infrun.h.  */
 
-void
+int
 normal_stop (void)
 {
   struct target_waitstatus last;
   ptid_t last_ptid;
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+  ptid_t pid_ptid;
+  struct switch_thru_all_uis state;
 
   get_last_target_status (&last_ptid, &last);
 
+  new_stop_id ();
+
   /* If an exception is thrown from this point on, make sure to
      propagate GDB's knowledge of the executing state to the
      frontend/user running state.  A QUIT is an easy exception to see
      here, so do this before any filtered output.  */
   if (!non_stop)
     make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
-  else if (last.kind != TARGET_WAITKIND_SIGNALLED
-          && last.kind != TARGET_WAITKIND_EXITED
-          && last.kind != TARGET_WAITKIND_NO_RESUMED)
+  else if (last.kind == TARGET_WAITKIND_SIGNALLED
+          || last.kind == TARGET_WAITKIND_EXITED)
+    {
+      /* On some targets, we may still have live threads in the
+        inferior when we get a process exit event.  E.g., for
+        "checkpoint", when the current checkpoint/fork exits,
+        linux-fork.c automatically switches to another fork from
+        within target_mourn_inferior.  */
+      if (!ptid_equal (inferior_ptid, null_ptid))
+       {
+         pid_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+         make_cleanup (finish_thread_state_cleanup, &pid_ptid);
+       }
+    }
+  else if (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
@@ -5984,7 +8282,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
@@ -5992,31 +8299,28 @@ normal_stop (void)
       && last.kind != TARGET_WAITKIND_EXITED
       && last.kind != TARGET_WAITKIND_NO_RESUMED)
     {
-      target_terminal_ours_for_output ();
-      printf_filtered (_("[Switching to %s]\n"),
-                      target_pid_to_str (inferior_ptid));
-      annotate_thread_changed ();
+      SWITCH_THRU_ALL_UIS (state)
+       {
+         target_terminal_ours_for_output ();
+         printf_filtered (_("[Switching to %s]\n"),
+                          target_pid_to_str (inferior_ptid));
+         annotate_thread_changed ();
+       }
       previous_inferior_ptid = inferior_ptid;
     }
 
   if (last.kind == TARGET_WAITKIND_NO_RESUMED)
     {
-      gdb_assert (sync_execution || !target_can_async_p ());
-
-      target_terminal_ours_for_output ();
-      printf_filtered (_("No unwaited-for children left.\n"));
+      SWITCH_THRU_ALL_UIS (state)
+       if (current_ui->prompt_state == PROMPT_BLOCKED)
+         {
+           target_terminal_ours_for_output ();
+           printf_filtered (_("No unwaited-for children left.\n"));
+         }
     }
 
-  if (!breakpoints_always_inserted_mode () && target_has_execution)
-    {
-      if (remove_breakpoints ())
-       {
-         target_terminal_ours_for_output ();
-         printf_filtered (_("Cannot remove breakpoints because "
-                            "program is no longer writable.\nFurther "
-                            "execution is probably impossible.\n"));
-       }
-    }
+  /* Note: this depends on the update_thread_list call above.  */
+  maybe_remove_breakpoints ();
 
   /* If an auto-display called a function and that got a signal,
      delete that auto-display to avoid an infinite recursion.  */
@@ -6024,176 +8328,75 @@ 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 */
-  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;
-
-  target_terminal_ours ();
-  async_enable_stdin ();
-
-  /* Set the current source location.  This will also happen if we
-     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);
+  SWITCH_THRU_ALL_UIS (state)
+    {
+      async_enable_stdin ();
+    }
 
   /* Let the user/frontend see the threads as stopped.  */
   do_cleanups (old_chain);
 
-  /* Look up the hook_stop and run it (CLI internally handles problem
-     of stop_command's pre-hook not existing).  */
-  if (stop_command)
-    catch_errors (hook_stop_stub, stop_command,
-                 "Error while running hook_stop:\n", RETURN_MASK_ALL);
-
-  if (!has_stack_frames ())
-    goto done;
-
-  if (last.kind == TARGET_WAITKIND_SIGNALLED
-      || last.kind == TARGET_WAITKIND_EXITED)
-    goto done;
-
   /* Select innermost stack frame - i.e., current frame is frame 0,
-     and current location is based on that.
-     Don't do this on return from a stack dummy routine,
-     or if the program has exited.  */
-
-  if (!stop_stack_dummy)
-    {
-      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)
+     and current location is based on that.  Handle the case where the
+     dummy call is returning after being stopped.  E.g. the dummy call
+     previously hit a breakpoint.  (If the dummy call returns
+     normally, we won't reach here.)  Do this before the stop hook is
+     run, so that it doesn't get to see the temporary dummy frame,
+     which is not where we'll present the stop.  */
+  if (has_stack_frames ())
+    {
+      if (stop_stack_dummy == STOP_STACK_DUMMY)
        {
-         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);
-
-         /* Display the auto-display expressions.  */
-         do_displays ();
+         /* Pop the empty frame that contains the stack dummy.  This
+            also restores inferior state prior to the call (struct
+            infcall_suspend_state).  */
+         struct frame_info *frame = get_current_frame ();
+
+         gdb_assert (get_frame_type (frame) == DUMMY_FRAME);
+         frame_pop (frame);
+         /* frame_pop calls reinit_frame_cache as the last thing it
+            does which means there's now no selected frame.  */
        }
-    }
 
-  /* Save the function value return registers, if we care.
-     We might be about to restore their previous contents.  */
-  if (inferior_thread ()->control.proceed_to_finish
-      && execution_direction != EXEC_REVERSE)
-    {
-      /* This should not be necessary.  */
-      if (stop_registers)
-       regcache_xfree (stop_registers);
+      select_frame (get_current_frame ());
 
-      /* NB: The copy goes through to the target picking up the value of
-        all the registers.  */
-      stop_registers = regcache_dup (get_current_regcache ());
+      /* Set the current source location.  */
+      set_current_sal_from_frame (get_current_frame ());
     }
 
-  if (stop_stack_dummy == STOP_STACK_DUMMY)
+  /* Look up the hook_stop and run it (CLI internally handles problem
+     of stop_command's pre-hook not existing).  */
+  if (stop_command != NULL)
     {
-      /* Pop the empty frame that contains the stack dummy.
-        This also restores inferior state prior to the call
-        (struct infcall_suspend_state).  */
-      struct frame_info *frame = get_current_frame ();
-
-      gdb_assert (get_frame_type (frame) == DUMMY_FRAME);
-      frame_pop (frame);
-      /* frame_pop() calls reinit_frame_cache as the last thing it
-        does which means there's currently no selected frame.  We
-        don't need to re-establish a selected frame if the dummy call
-        returns normally, that will be done by
-        restore_infcall_control_state.  However, we do have to handle
-        the case where the dummy call is returning after being
-        stopped (e.g. the dummy call previously hit a breakpoint).
-        We can't know which case we have so just always re-establish
-        a selected frame here.  */
-      select_frame (get_current_frame ());
-    }
-
-done:
-  annotate_stopped ();
-
-  /* Suppress the stop observer if we're in the middle of:
+      struct stop_context *saved_context = save_stop_context ();
+      struct cleanup *old_chain
+       = make_cleanup (release_stop_context_cleanup, saved_context);
 
-     - a step n (n > 1), as there still more steps to be done.
+      catch_errors (hook_stop_stub, stop_command,
+                   "Error while running hook_stop:\n", RETURN_MASK_ALL);
 
-     - a "finish" command, as the observer will be called in
-       finish_command_continuation, so it can include the inferior
-       function's return value.
+      /* If the stop hook resumes the target, then there's no point in
+        trying to notify about the previous stop; its context is
+        gone.  Likewise if the command switches thread or inferior --
+        the observers would print a stop for the wrong
+        thread/inferior.  */
+      if (stop_context_changed (saved_context))
+       {
+         do_cleanups (old_chain);
+         return 1;
+       }
+      do_cleanups (old_chain);
+    }
 
-     - calling an inferior function, as we pretend we inferior didn't
-       run at all.  The return value of the call is handled by the
-       expression evaluator, through call_function_by_hand.  */
+  /* Notify observers about the stop.  This is where the interpreters
+     print the stop event.  */
+  if (!ptid_equal (inferior_ptid, null_ptid))
+    observer_notify_normal_stop (inferior_thread ()->control.stop_bpstat,
+                                stop_print_frame);
+  else
+    observer_notify_normal_stop (NULL, stop_print_frame);
 
-  if (!target_has_execution
-      || last.kind == TARGET_WAITKIND_SIGNALLED
-      || last.kind == TARGET_WAITKIND_EXITED
-      || last.kind == TARGET_WAITKIND_NO_RESUMED
-      || (!(inferior_thread ()->step_multi
-           && inferior_thread ()->control.stop_step)
-         && !(inferior_thread ()->control.stop_bpstat
-              && inferior_thread ()->control.proceed_to_finish)
-         && !inferior_thread ()->control.in_infcall))
-    {
-      if (!ptid_equal (inferior_ptid, null_ptid))
-       observer_notify_normal_stop (inferior_thread ()->control.stop_bpstat,
-                                    stop_print_frame);
-      else
-       observer_notify_normal_stop (NULL, stop_print_frame);
-    }
+  annotate_stopped ();
 
   if (target_has_execution)
     {
@@ -6208,6 +8411,8 @@ done:
      longer needed.  Keeping those around slows down things linearly.
      Note that this never removes the current inferior.  */
   prune_inferiors ();
+
+  return 0;
 }
 
 static int
@@ -6494,7 +8699,7 @@ Are you sure you want to change it? "),
            sig_print_header ();
            for (; signum < nsigs; signum++)
              if (sigs[signum])
-               sig_print_info (signum);
+               sig_print_info ((enum gdb_signal) signum);
          }
 
        break;
@@ -6533,72 +8738,6 @@ handle_completer (struct cmd_list_element *ignore,
   return return_val;
 }
 
-static void
-xdb_handle_command (char *args, int from_tty)
-{
-  char **argv;
-  struct cleanup *old_chain;
-
-  if (args == NULL)
-    error_no_arg (_("xdb command"));
-
-  /* Break the command line up into args.  */
-
-  argv = gdb_buildargv (args);
-  old_chain = make_cleanup_freeargv (argv);
-  if (argv[1] != (char *) NULL)
-    {
-      char *argBuf;
-      int bufLen;
-
-      bufLen = strlen (argv[0]) + 20;
-      argBuf = (char *) xmalloc (bufLen);
-      if (argBuf)
-       {
-         int validFlag = 1;
-         enum gdb_signal oursig;
-
-         oursig = gdb_signal_from_name (argv[0]);
-         memset (argBuf, 0, bufLen);
-         if (strcmp (argv[1], "Q") == 0)
-           sprintf (argBuf, "%s %s", argv[0], "noprint");
-         else
-           {
-             if (strcmp (argv[1], "s") == 0)
-               {
-                 if (!signal_stop[oursig])
-                   sprintf (argBuf, "%s %s", argv[0], "stop");
-                 else
-                   sprintf (argBuf, "%s %s", argv[0], "nostop");
-               }
-             else if (strcmp (argv[1], "i") == 0)
-               {
-                 if (!signal_program[oursig])
-                   sprintf (argBuf, "%s %s", argv[0], "pass");
-                 else
-                   sprintf (argBuf, "%s %s", argv[0], "nopass");
-               }
-             else if (strcmp (argv[1], "r") == 0)
-               {
-                 if (!signal_print[oursig])
-                   sprintf (argBuf, "%s %s", argv[0], "print");
-                 else
-                   sprintf (argBuf, "%s %s", argv[0], "noprint");
-               }
-             else
-               validFlag = 0;
-           }
-         if (validFlag)
-           handle_command (argBuf, from_tty);
-         else
-           printf_filtered (_("Invalid signal handling flag.\n"));
-         if (argBuf)
-           xfree (argBuf);
-       }
-    }
-  do_cleanups (old_chain);
-}
-
 enum gdb_signal
 gdb_signal_from_command (int num)
 {
@@ -6651,25 +8790,6 @@ signals_info (char *signum_exp, int from_tty)
                     "to change these tables.\n"));
 }
 
-/* Check if it makes sense to read $_siginfo from the current thread
-   at this point.  If not, throw an error.  */
-
-static void
-validate_siginfo_access (void)
-{
-  /* No current inferior, no siginfo.  */
-  if (ptid_equal (inferior_ptid, null_ptid))
-    error (_("No thread selected."));
-
-  /* Don't try to read from a dead thread.  */
-  if (is_exited (inferior_ptid))
-    error (_("The current thread has terminated"));
-
-  /* ... or from a spinning thread.  */
-  if (is_running (inferior_ptid))
-    error (_("Selected thread is running."));
-}
-
 /* The $_siginfo convenience variable is a bit special.  We don't know
    for sure the type of the value until we actually have a chance to
    fetch the data.  The type can change depending on gdbarch, so it is
@@ -6688,7 +8808,9 @@ siginfo_value_read (struct value *v)
 {
   LONGEST transferred;
 
-  validate_siginfo_access ();
+  /* If we can access registers, so can we access $_siginfo.  Likewise
+     vice versa.  */
+  validate_registers_access ();
 
   transferred =
     target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO,
@@ -6709,7 +8831,9 @@ siginfo_value_write (struct value *v, struct value *fromval)
 {
   LONGEST transferred;
 
-  validate_siginfo_access ();
+  /* If we can access registers, so can we access $_siginfo.  Likewise
+     vice versa.  */
+  validate_registers_access ();
 
   transferred = target_write (&current_target,
                              TARGET_OBJECT_SIGNAL_INFO,
@@ -6758,9 +8882,6 @@ siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
 struct infcall_suspend_state
 {
   struct thread_suspend_state thread_suspend;
-#if 0 /* Currently unused and empty structures are not valid C.  */
-  struct inferior_suspend_state inferior_suspend;
-#endif
 
   /* Other fields:  */
   CORE_ADDR stop_pc;
@@ -6780,9 +8901,6 @@ save_infcall_suspend_state (void)
 {
   struct infcall_suspend_state *inf_state;
   struct thread_info *tp = inferior_thread ();
-#if 0
-  struct inferior *inf = current_inferior ();
-#endif
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   gdb_byte *siginfo_data = NULL;
@@ -6793,7 +8911,7 @@ save_infcall_suspend_state (void)
       size_t len = TYPE_LENGTH (type);
       struct cleanup *back_to;
 
-      siginfo_data = xmalloc (len);
+      siginfo_data = (gdb_byte *) xmalloc (len);
       back_to = make_cleanup (xfree, siginfo_data);
 
       if (target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
@@ -6807,7 +8925,7 @@ save_infcall_suspend_state (void)
        }
     }
 
-  inf_state = XZALLOC (struct infcall_suspend_state);
+  inf_state = XCNEW (struct infcall_suspend_state);
 
   if (siginfo_data)
     {
@@ -6816,9 +8934,6 @@ save_infcall_suspend_state (void)
     }
 
   inf_state->thread_suspend = tp->suspend;
-#if 0 /* Currently unused and empty structures are not valid C.  */
-  inf_state->inferior_suspend = inf->suspend;
-#endif
 
   /* run_inferior_call will not use the signal due to its `proceed' call with
      GDB_SIGNAL_0 anyway.  */
@@ -6837,16 +8952,10 @@ void
 restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
 {
   struct thread_info *tp = inferior_thread ();
-#if 0
-  struct inferior *inf = current_inferior ();
-#endif
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
   tp->suspend = inf_state->thread_suspend;
-#if 0 /* Currently unused and empty structures are not valid C.  */
-  inf->suspend = inf_state->inferior_suspend;
-#endif
 
   stop_pc = inf_state->stop_pc;
 
@@ -6871,7 +8980,7 @@ restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
 static void
 do_restore_infcall_suspend_state_cleanup (void *state)
 {
-  restore_infcall_suspend_state (state);
+  restore_infcall_suspend_state ((struct infcall_suspend_state *) state);
 }
 
 struct cleanup *
@@ -6907,7 +9016,6 @@ struct infcall_control_state
   /* Other fields:  */
   enum stop_stack_kind stop_stack_dummy;
   int stopped_by_random_signal;
-  int stop_after_trap;
 
   /* ID if the selected frame when the inferior function call was made.  */
   struct frame_id selected_frame_id;
@@ -6919,7 +9027,8 @@ struct infcall_control_state
 struct infcall_control_state *
 save_infcall_control_state (void)
 {
-  struct infcall_control_state *inf_status = xmalloc (sizeof (*inf_status));
+  struct infcall_control_state *inf_status =
+    XNEW (struct infcall_control_state);
   struct thread_info *tp = inferior_thread ();
   struct inferior *inf = current_inferior ();
 
@@ -6938,7 +9047,6 @@ save_infcall_control_state (void)
   /* Other fields:  */
   inf_status->stop_stack_dummy = stop_stack_dummy;
   inf_status->stopped_by_random_signal = stopped_by_random_signal;
-  inf_status->stop_after_trap = stop_after_trap;
 
   inf_status->selected_frame_id = get_frame_id (get_selected_frame (NULL));
 
@@ -6990,7 +9098,6 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
   /* Other fields:  */
   stop_stack_dummy = inf_status->stop_stack_dummy;
   stopped_by_random_signal = inf_status->stopped_by_random_signal;
-  stop_after_trap = inf_status->stop_after_trap;
 
   if (target_has_stack)
     {
@@ -7012,7 +9119,7 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
 static void
 do_restore_infcall_control_state_cleanup (void *sts)
 {
-  restore_infcall_control_state (sts);
+  restore_infcall_control_state ((struct infcall_control_state *) sts);
 }
 
 struct cleanup *
@@ -7039,20 +9146,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().  */
@@ -7060,7 +9153,7 @@ ptid_match (ptid_t ptid, ptid_t filter)
 static void
 restore_inferior_ptid (void *arg)
 {
-  ptid_t *saved_ptid_ptr = arg;
+  ptid_t *saved_ptid_ptr = (ptid_t *) arg;
 
   inferior_ptid = *saved_ptid_ptr;
   xfree (arg);
@@ -7073,19 +9166,27 @@ restore_inferior_ptid (void *arg)
 struct cleanup *
 save_inferior_ptid (void)
 {
-  ptid_t *saved_ptid_ptr;
+  ptid_t *saved_ptid_ptr = XNEW (ptid_t);
 
-  saved_ptid_ptr = xmalloc (sizeof (ptid_t));
   *saved_ptid_ptr = inferior_ptid;
   return make_cleanup (restore_inferior_ptid, saved_ptid_ptr);
 }
+
+/* See infrun.h.  */
+
+void
+clear_exit_convenience_vars (void)
+{
+  clear_internalvar (lookup_internalvar ("_exitsignal"));
+  clear_internalvar (lookup_internalvar ("_exitcode"));
+}
 \f
 
 /* User interface for reverse debugging:
    Set exec-direction / show exec-direction commands
    (returns error unless target implements to_set_exec_direction method).  */
 
-int execution_direction = EXEC_FORWARD;
+enum exec_direction_kind execution_direction = EXEC_FORWARD;
 static const char exec_forward[] = "forward";
 static const char exec_reverse[] = "reverse";
 static const char *exec_direction = exec_forward;
@@ -7131,32 +9232,6 @@ show_exec_direction_func (struct ui_file *out, int from_tty,
   }
 }
 
-/* User interface for non-stop mode.  */
-
-int non_stop = 0;
-
-static void
-set_non_stop (char *args, int from_tty,
-             struct cmd_list_element *c)
-{
-  if (target_has_execution)
-    {
-      non_stop_1 = non_stop;
-      error (_("Cannot change this setting while the inferior is running."));
-    }
-
-  non_stop = non_stop_1;
-}
-
-static void
-show_non_stop (struct ui_file *file, int from_tty,
-              struct cmd_list_element *c, const char *value)
-{
-  fprintf_filtered (file,
-                   _("Controlling the inferior in non-stop mode is %s.\n"),
-                   value);
-}
-
 static void
 show_schedule_multiple (struct ui_file *file, int from_tty,
                        struct cmd_list_element *c, const char *value)
@@ -7174,6 +9249,15 @@ static const struct internalvar_funcs siginfo_funcs =
   NULL
 };
 
+/* Callback for infrun's target events source.  This is marked when a
+   thread has a pending status to process.  */
+
+static void
+infrun_async_inferior_event_handler (gdb_client_data data)
+{
+  inferior_event_handler (INF_REG_EVENT, NULL);
+}
+
 void
 _initialize_infrun (void)
 {
@@ -7181,6 +9265,10 @@ _initialize_infrun (void)
   int numsigs;
   struct cmd_list_element *c;
 
+  /* Register extra event sources in the event loop.  */
+  infrun_async_inferior_event_token
+    = create_async_event_handler (infrun_async_inferior_event_handler, NULL);
+
   add_info ("signals", signals_info, _("\
 What debugger does when program gets various signals.\n\
 Specify a signal as argument to print info on that signal only."));
@@ -7212,29 +9300,6 @@ may be interspersed with actions, with the actions being performed for\n\
 all signals cumulatively specified."));
   set_cmd_completer (c, handle_completer);
 
-  if (xdb_commands)
-    {
-      add_com ("lz", class_info, signals_info, _("\
-What debugger does when program gets various signals.\n\
-Specify a signal as argument to print info on that signal only."));
-      add_com ("z", class_run, xdb_handle_command, _("\
-Specify how to handle a signal.\n\
-Args are signals and actions to apply to those signals.\n\
-Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
-from 1-15 are allowed for compatibility with old versions of GDB.\n\
-Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
-The special arg \"all\" is recognized to mean all signals except those\n\
-used by the debugger, typically SIGTRAP and SIGINT.\n\
-Recognized actions include \"s\" (toggles between stop and nostop),\n\
-\"r\" (toggles between print and noprint), \"i\" (toggles between pass and \
-nopass), \"Q\" (noprint)\n\
-Stop means reenter debugger if this signal happens (implies print).\n\
-Print means print a message if this signal happens.\n\
-Pass means let program see this signal; otherwise program doesn't know.\n\
-Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
-Pass and Stop may be combined."));
-    }
-
   if (!dbx_commands)
     stop_command = add_cmd ("stop", class_obscure,
                            not_just_help_class_command, _("\
@@ -7280,15 +9345,11 @@ leave it stopped or free to run as needed."),
                           &showlist);
 
   numsigs = (int) GDB_SIGNAL_LAST;
-  signal_stop = (unsigned char *) xmalloc (sizeof (signal_stop[0]) * numsigs);
-  signal_print = (unsigned char *)
-    xmalloc (sizeof (signal_print[0]) * numsigs);
-  signal_program = (unsigned char *)
-    xmalloc (sizeof (signal_program[0]) * numsigs);
-  signal_catch = (unsigned char *)
-    xmalloc (sizeof (signal_catch[0]) * numsigs);
-  signal_pass = (unsigned char *)
-    xmalloc (sizeof (signal_program[0]) * numsigs);
+  signal_stop = XNEWVEC (unsigned char, numsigs);
+  signal_print = XNEWVEC (unsigned char, numsigs);
+  signal_program = XNEWVEC (unsigned char, numsigs);
+  signal_catch = XNEWVEC (unsigned char, numsigs);
+  signal_pass = XNEWVEC (unsigned char, numsigs);
   for (i = 0; i < numsigs; i++)
     {
       signal_stop[i] = 1;
@@ -7297,8 +9358,19 @@ leave it stopped or free to run as needed."),
       signal_catch[i] = 0;
     }
 
-  /* Signals caused by debugger's own actions
-     should not be given to the program afterwards.  */
+  /* Signals caused by debugger's own actions should not be given to
+     the program afterwards.
+
+     Do not deliver GDB_SIGNAL_TRAP by default, except when the user
+     explicitly specifies that it should be delivered to the target
+     program.  Typically, that would occur when a user is debugging a
+     target monitor on a simulator: the target monitor sets a
+     breakpoint; the simulator encounters this breakpoint and halts
+     the simulation handing control to GDB; GDB, noting that the stop
+     address doesn't map to any known breakpoint, returns control back
+     to the simulator; the simulator then delivers the hardware
+     equivalent of a GDB_SIGNAL_TRAP to the program being
+     debugged.  */
   signal_program[GDB_SIGNAL_TRAP] = 0;
   signal_program[GDB_SIGNAL_INT] = 0;
 
@@ -7389,11 +9461,13 @@ By default, the debugger will use the same inferior."),
                        scheduler_enums, &scheduler_mode, _("\
 Set mode for locking scheduler during execution."), _("\
 Show mode for locking scheduler during execution."), _("\
-off  == no locking (threads may preempt at any time)\n\
-on   == full locking (no thread except the current thread may run)\n\
-step == scheduler locked during every single-step operation.\n\
-       In this mode, no other thread may run during a step command.\n\
-       Other threads may run while stepping over a function call ('next')."), 
+off    == no locking (threads may preempt at any time)\n\
+on     == full locking (no thread except the current thread may run)\n\
+          This applies to both normal execution and replay mode.\n\
+step   == scheduler locked during stepping commands (step, next, stepi, nexti).\n\
+          In this mode, other threads may run during other commands.\n\
+          This applies to both normal execution and replay mode.\n\
+replay == scheduler locked in replay mode and unlocked during normal execution."),
                        set_schedlock_func,     /* traps on target vector */
                        show_scheduler_mode,
                        &setlist, &showlist);
This page took 0.130146 seconds and 4 git commands to generate.