Update comment for struct type's length field, introduce type_length_units
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 9ec236395097abc4db138d7a19722fe6023ff63b..445a61252c8cb43bc116d9e301b015313fe87e48 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986-2014 Free Software Foundation, Inc.
+   Copyright (C) 1986-2015 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 <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"
@@ -61,6 +59,8 @@
 #include "completer.h"
 #include "target-descriptions.h"
 #include "target-dcache.h"
+#include "terminal.h"
+#include "solist.h"
 
 /* Prototypes for local functions */
 
@@ -80,23 +80,15 @@ 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 void xdb_handle_command (char *args, int from_tty);
-
-static void print_exited_reason (int exitstatus);
-
-static void print_signal_exited_reason (enum gdb_signal siggnal);
-
-static void print_no_history_reason (void);
-
-static void print_signal_received_reason (enum gdb_signal siggnal);
-
-static void print_end_stepping_range_reason (void);
-
 void _initialize_infrun (void);
 
 void nullify_last_target_wait_ptid (void);
@@ -107,6 +99,8 @@ static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
 
 static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
 
+static int maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc);
+
 /* When set, stop the 'step' command if we enter a function which has
    no line number information.  The normal behavior is that we step
    over such function.  */
@@ -242,7 +236,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;
     }
@@ -334,10 +327,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;
@@ -364,13 +353,6 @@ show_stop_on_solib_events (struct ui_file *file, int from_tty,
 
 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;
@@ -385,8 +367,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";
 
@@ -408,6 +388,250 @@ 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.  */
+      && (!target_is_async_p () || sync_execution)
+      && !(follow_child || detach_fork || sched_multi))
+    {
+      /* The parent stays blocked inside the vfork syscall until the
+        child execs or exits.  If we don't let the child run, then
+        the parent stays blocked.  If we're telling the parent to run
+        in the foreground, the user will not be able to ctrl-c to get
+        back the terminal, effectively hanging the debug session.  */
+      fprintf_filtered (gdb_stderr, _("\
+Can not resume the parent process over vfork in the foreground while\n\
+holding the child stopped.  Try \"set detach-on-fork\" or \
+\"set schedule-multiple\".\n"));
+      /* FIXME output string > 80 columns.  */
+      return 1;
+    }
+
+  if (!follow_child)
+    {
+      /* Detach new forked process?  */
+      if (detach_fork)
+       {
+         struct cleanup *old_chain;
+
+         /* Before detaching from the child, remove all breakpoints
+            from it.  If we forked, then this has already been taken
+            care of by infrun.c.  If we vforked however, any
+            breakpoint inserted in the parent is visible in the
+            child, even those added while stopped in a vfork
+            catchpoint.  This will remove the breakpoints from the
+            parent also, but they'll be reinserted below.  */
+         if (has_vforked)
+           {
+             /* Keep breakpoints list in sync.  */
+             remove_breakpoints_pid (ptid_get_pid (inferior_ptid));
+           }
+
+         if (info_verbose || debug_infrun)
+           {
+             /* 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.  */
@@ -498,9 +722,10 @@ follow_fork (void)
        parent = inferior_ptid;
        child = tp->pending_follow.value.related_pid;
 
-       /* Tell the target to do whatever is necessary to follow
-          either parent or child.  */
-       if (target_follow_fork (follow_child, detach_fork))
+       /* Set up inferior(s) as specified by the caller, and tell the
+          target to do whatever is necessary to follow either parent
+          or child.  */
+       if (follow_fork_inferior (follow_child, detach_fork))
          {
            /* Target refused to follow, or there's some other reason
               we shouldn't resume.  */
@@ -572,14 +797,16 @@ follow_fork (void)
   return should_resume;
 }
 
-void
+static void
 follow_inferior_reset_breakpoints (void)
 {
   struct thread_info *tp = inferior_thread ();
 
   /* Was there a step_resume breakpoint?  (There was if the user
      did a "next" at the fork() call.)  If so, explicitly reset its
-     thread number.
+     thread number.  Cloned step_resume breakpoints are disabled on
+     creation, so enable it here now that it is associated with the
+     correct thread.
 
      step_resumes are a form of bp that are made to be per-thread.
      Since we created the step_resume bp when the parent process
@@ -589,10 +816,17 @@ follow_inferior_reset_breakpoints (void)
      it is for, or it'll be ignored when it triggers.  */
 
   if (tp->control.step_resume_breakpoint)
-    breakpoint_re_set_thread (tp->control.step_resume_breakpoint);
+    {
+      breakpoint_re_set_thread (tp->control.step_resume_breakpoint);
+      tp->control.step_resume_breakpoint->loc->enabled = 1;
+    }
 
+  /* Treat exception_resume breakpoints like step_resume breakpoints.  */
   if (tp->control.exception_resume_breakpoint)
-    breakpoint_re_set_thread (tp->control.exception_resume_breakpoint);
+    {
+      breakpoint_re_set_thread (tp->control.exception_resume_breakpoint);
+      tp->control.exception_resume_breakpoint->loc->enabled = 1;
+    }
 
   /* Reinsert all breakpoints in the child.  The user may have set
      breakpoints after catching the fork, in which case those
@@ -624,8 +858,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;
@@ -692,18 +926,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);
@@ -813,10 +1051,11 @@ 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);
 
   /* 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
@@ -841,23 +1080,47 @@ 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?  */
   printf_unfiltered (_("%s is executing new program: %s\n"),
                     target_pid_to_str (inferior_ptid),
@@ -870,15 +1133,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 = alloca (strlen (name) + 1);
+      strcpy (execd_pathname, name);
+      xfree (name);
     }
 
   /* Reset the shared library package.  This ensures that we get a
@@ -960,27 +1221,20 @@ 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 thread we inserted single-step breakpoints for.  */
-static ptid_t singlestep_ptid;
-
-/* PC when we started this single-step.  */
-static CORE_ADDR singlestep_pc;
-
-/* Info about an instruction that is being stepped over.  Invalid if
-   ASPACE is NULL.  */
+/* Info about an instruction that is being stepped over.  */
 
 struct step_over_info
 {
-  /* The instruction's address space.  */
+  /* 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;
-
-  /* The instruction's address.  */
   CORE_ADDR address;
+
+  /* The instruction being stepped over triggers a nonsteppable
+     watchpoint.  If true, we'll skip inserting watchpoints.  */
+  int nonsteppable_watchpoint_p;
 };
 
 /* The step-over info of the location that is being stepped over.
@@ -1013,10 +1267,12 @@ static struct step_over_info step_over_info;
    stepping over.  */
 
 static void
-set_step_over_info (struct address_space *aspace, CORE_ADDR address)
+set_step_over_info (struct address_space *aspace, CORE_ADDR address,
+                   int nonsteppable_watchpoint_p)
 {
   step_over_info.aspace = aspace;
   step_over_info.address = address;
+  step_over_info.nonsteppable_watchpoint_p = nonsteppable_watchpoint_p;
 }
 
 /* Called when we're not longer stepping over a breakpoint / an
@@ -1027,9 +1283,10 @@ clear_step_over_info (void)
 {
   step_over_info.aspace = NULL;
   step_over_info.address = 0;
+  step_over_info.nonsteppable_watchpoint_p = 0;
 }
 
-/* See inferior.h.  */
+/* See infrun.h.  */
 
 int
 stepping_past_instruction_at (struct address_space *aspace,
@@ -1041,6 +1298,23 @@ stepping_past_instruction_at (struct address_space *aspace,
                                       step_over_info.address));
 }
 
+/* See infrun.h.  */
+
+int
+stepping_past_nonsteppable_watchpoint (void)
+{
+  return step_over_info.nonsteppable_watchpoint_p;
+}
+
+/* Returns true if step-over info is valid.  */
+
+static int
+step_over_info_valid_p (void)
+{
+  return (step_over_info.aspace != NULL
+         || stepping_past_nonsteppable_watchpoint ());
+}
+
 \f
 /* Displaced stepping.  */
 
@@ -1189,6 +1463,20 @@ get_displaced_stepping_state (int pid)
   return NULL;
 }
 
+/* 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.  */
@@ -1520,8 +1808,16 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
 
   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,
@@ -1567,6 +1863,7 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
       regcache = get_thread_regcache (ptid);
       actual_pc = regcache_read_pc (regcache);
       aspace = get_regcache_aspace (regcache);
+      gdbarch = get_regcache_arch (regcache);
 
       if (breakpoint_here_p (aspace, actual_pc))
        {
@@ -1577,8 +1874,6 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
 
          displaced_step_prepare (ptid);
 
-         gdbarch = get_regcache_arch (regcache);
-
          if (debug_displaced)
            {
              CORE_ADDR actual_pc = regcache_read_pc (regcache);
@@ -1611,6 +1906,9 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
          /* Go back to what we were trying to do.  */
          step = currently_stepping (tp);
 
+         if (step)
+           step = maybe_software_singlestep (gdbarch, actual_pc);
+
          if (debug_displaced)
            fprintf_unfiltered (gdb_stdlog,
                                "displaced: breakpoint is gone: %s, step(%d)\n",
@@ -1636,9 +1934,6 @@ infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
   if (ptid_equal (inferior_ptid, old_ptid))
     inferior_ptid = new_ptid;
 
-  if (ptid_equal (singlestep_ptid, old_ptid))
-    singlestep_ptid = new_ptid;
-
   for (displaced = displaced_step_inferior_states;
        displaced;
        displaced = displaced->next)
@@ -1659,6 +1954,9 @@ 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 ();
 }
 
@@ -1713,37 +2011,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
@@ -1751,26 +2029,79 @@ 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.  */
+      /* User-settable 'scheduler' mode requires solo thread
+        resume.  */
       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;
 }
 
+/* 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)
 {
   struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
   struct regcache *regcache = get_current_regcache ();
@@ -1779,9 +2110,23 @@ resume (int step, enum gdb_signal sig)
   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;
+
+  tp->stepped_breakpoint = 0;
 
   QUIT;
 
+  /* 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
@@ -1816,13 +2161,76 @@ 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 = user_visible_resume_ptid (user_step);
+             do_target_resume (resume_ptid, 0, GDB_SIGNAL_0);
+             discard_cleanups (old_cleanups);
+             return;
+           }
+       }
     }
 
   /* If we have a breakpoint to step over, make sure to do a single
@@ -1842,8 +2250,8 @@ a command like `return' or `jump' to continue execution."));
      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)))
+      && tp->control.trap_expected
+      && !step_over_info_valid_p ()
       && sig == GDB_SIGNAL_0
       && !current_inferior ()->waiting_for_vfork_done)
     {
@@ -1853,11 +2261,11 @@ a command like `return' or `jump' to continue execution."));
        {
          /* Got placed in displaced stepping queue.  Will be resumed
             later when all the currently queued displaced stepping
-            requests finish.  The thread is not executing at this point,
-            and the call to set_executing will be made later.  But we
-            need to call set_running here, since from frontend point of view,
-            the thread is running.  */
-         set_running (inferior_ptid, 1);
+            requests finish.  The thread is not executing at this
+            point, and the call to set_executing will be made later.
+            But we need to call set_running here, since from the
+            user/frontend's point of view, threads were set running.  */
+         set_running (user_visible_resume_ptid (user_step), 1);
          discard_cleanups (old_cleanups);
          return;
        }
@@ -1899,8 +2307,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
@@ -1913,8 +2322,7 @@ 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);
 
       clear_step_over_info ();
       tp->control.trap_expected = 0;
@@ -1925,15 +2333,21 @@ a command like `return' or `jump' to continue execution."));
   /* 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));
+  gdb_assert (!(thread_has_single_step_breakpoints_set (tp) && step));
 
   /* Decide the set of threads to ask the target to resume.  Start
      by assuming everything will be resumed, than narrow the set
      by applying increasingly restricting conditions.  */
-  resume_ptid = user_visible_resume_ptid (step);
+  resume_ptid = user_visible_resume_ptid (user_step);
+
+  /* Even if RESUME_PTID is a wildcard, and we end up resuming less
+     (e.g., we might need to step over a breakpoint), from the
+     user/frontend's point of view, all threads in RESUME_PTID are now
+     running.  */
+  set_running (resume_ptid, 1);
 
   /* Maybe resume a single thread after all.  */
-  if ((step || singlestep_breakpoints_inserted_p)
+  if ((step || thread_has_single_step_breakpoints_set (tp))
       && tp->control.trap_expected)
     {
       /* We're allowing a thread to run past a breakpoint it has
@@ -1944,20 +2358,44 @@ a command like `return' or `jump' to continue execution."));
       resume_ptid = inferior_ptid;
     }
 
-  if (gdbarch_cannot_step_breakpoint (gdbarch))
-    {
+  if (execution_direction != EXEC_REVERSE
+      && step && breakpoint_inserted_here_p (aspace, pc))
+    {
+      /* The only case we currently need to step a breakpoint
+        instruction is 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.  */
+      gdb_assert (sig != GDB_SIGNAL_0);
+
+      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 (step && breakpoint_inserted_here_p (aspace, pc))
+      if (gdbarch_cannot_step_breakpoint (gdbarch))
        step = 0;
     }
 
   if (debug_displaced
       && use_displaced_stepping (gdbarch)
-      && tp->control.trap_expected)
+      && tp->control.trap_expected
+      && !step_over_info_valid_p ())
     {
-      struct regcache *resume_regcache = get_thread_regcache (resume_ptid);
+      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];
@@ -1978,27 +2416,7 @@ a command like `return' or `jump' to continue execution."));
       gdb_assert (pc_in_thread_step_range (pc, tp));
     }
 
-  /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
-
-  /* Avoid confusing the next resume, if the next stop/resume
-     happens to apply to another thread.  */
-  tp->suspend.stop_signal = GDB_SIGNAL_0;
-
-  /* Advise target which signals may be handled silently.  If we have
-     removed breakpoints because we are stepping over one (which can
-     happen only if we are not using displaced stepping), we need to
-     receive all signals to avoid accidentally skipping a breakpoint
-     during execution of a signal handler.  */
-  if ((step || singlestep_breakpoints_inserted_p)
-      && tp->control.trap_expected
-      && !use_displaced_stepping (gdbarch))
-    target_pass_signals (0, NULL);
-  else
-    target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
-
-  target_resume (resume_ptid, step, sig);
-
+  do_target_resume (resume_ptid, step, sig);
   discard_cleanups (old_cleanups);
 }
 \f
@@ -2015,6 +2433,11 @@ clear_proceed_status_thread (struct thread_info *tp)
                        "infrun: clear_proceed_status_thread (%s)\n",
                        target_pid_to_str (tp->ptid));
 
+  /* If this signal should not be seen by program, give it zero.
+     Used for debugging signals.  */
+  if (!signal_pass_state (tp->suspend.stop_signal))
+    tp->suspend.stop_signal = GDB_SIGNAL_0;
+
   tp->control.trap_expected = 0;
   tp->control.step_range_start = 0;
   tp->control.step_range_end = 0;
@@ -2022,6 +2445,7 @@ 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;
@@ -2029,31 +2453,30 @@ clear_proceed_status_thread (struct thread_info *tp)
   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)
-{
-  if (is_exited (tp->ptid))
-    return 0;
-
-  clear_proceed_status_thread (tp);
-  return 0;
-}
-
 void
-clear_proceed_status (void)
+clear_proceed_status (int step)
 {
   if (!non_stop)
     {
-      /* In all-stop mode, delete the per-thread status of all
-        threads, even if inferior_ptid is null_ptid, there may be
-        threads on the list.  E.g., we may be launching a new
-        process, while selecting the executable.  */
-      iterate_over_threads (clear_proceed_status_callback, NULL);
+      struct thread_info *tp;
+      ptid_t resume_ptid;
+
+      resume_ptid = user_visible_resume_ptid (step);
+
+      /* In all-stop mode, delete the per-thread status of all threads
+        we're about to resume, implicitly and explicitly.  */
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         if (!ptid_match (tp->ptid, resume_ptid))
+           continue;
+         clear_proceed_status_thread (tp);
+       }
     }
 
   if (!ptid_equal (inferior_ptid, null_ptid))
@@ -2076,12 +2499,6 @@ clear_proceed_status (void)
   clear_step_over_info ();
 
   observer_notify_about_to_proceed ();
-
-  if (stop_registers)
-    {
-      regcache_xfree (stop_registers);
-      stop_registers = NULL;
-    }
 }
 
 /* Returns true if TP is still stopped at a breakpoint that needs
@@ -2096,7 +2513,8 @@ thread_still_needs_step_over (struct thread_info *tp)
       struct regcache *regcache = get_thread_regcache (tp->ptid);
 
       if (breakpoint_here_p (get_regcache_aspace (regcache),
-                            regcache_read_pc (regcache)))
+                            regcache_read_pc (regcache))
+         == ordinary_breakpoint_here)
        return 1;
 
       tp->stepping_over_breakpoint = 0;
@@ -2109,21 +2527,19 @@ thread_still_needs_step_over (struct thread_info *tp)
    we're about to do a step/next-like command to a thread.  */
 
 static int
-schedlock_applies (int step)
+schedlock_applies (struct thread_info *tp)
 {
   return (scheduler_mode == schedlock_on
          || (scheduler_mode == schedlock_step
-             && step));
+             && tp->control.stepping_command));
 }
 
 /* Look a thread other than EXCEPT that has previously reported a
    breakpoint event, and thus needs a step-over in order to make
-   progress.  Returns NULL is none is found.  STEP indicates whether
-   we're about to step the current thread, in order to decide whether
-   "set scheduler-locking step" applies.  */
+   progress.  Returns NULL is none is found.  */
 
 static struct thread_info *
-find_thread_needs_step_over (int step, struct thread_info *except)
+find_thread_needs_step_over (struct thread_info *except)
 {
   struct thread_info *tp, *current;
 
@@ -2134,7 +2550,7 @@ find_thread_needs_step_over (int step, struct thread_info *except)
 
   /* If scheduler locking applies, we can avoid iterating over all
      threads.  */
-  if (schedlock_applies (step))
+  if (schedlock_applies (except))
     {
       if (except != current
          && thread_still_needs_step_over (current))
@@ -2143,7 +2559,7 @@ find_thread_needs_step_over (int step, struct thread_info *except)
       return NULL;
     }
 
-  ALL_THREADS (tp)
+  ALL_NON_EXITED_THREADS (tp)
     {
       /* Ignore the EXCEPT thread.  */
       if (tp == except)
@@ -2173,7 +2589,7 @@ find_thread_needs_step_over (int step, struct thread_info *except)
    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;
@@ -2202,17 +2618,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
   pc = regcache_read_pc (regcache);
   tp = inferior_thread ();
 
-  if (step > 0)
-    step_start_function = find_pc_function (pc);
-  if (step < 0)
-    stop_after_trap = 1;
-
   /* Fill in with reasonable starting values.  */
   init_thread_stepping_state (tp);
 
   if (addr == (CORE_ADDR) -1)
     {
-      if (pc == stop_pc && breakpoint_here_p (aspace, pc)
+      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
@@ -2235,6 +2647,9 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
       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
@@ -2245,9 +2660,9 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
-                       "infrun: proceed (addr=%s, signal=%s, step=%d)\n",
+                       "infrun: proceed (addr=%s, signal=%s)\n",
                        paddress (gdbarch, addr),
-                       gdb_signal_to_symbol_string (siggnal), step);
+                       gdb_signal_to_symbol_string (siggnal));
 
   if (non_stop)
     /* In non-stop, each thread is handled individually.  The context
@@ -2267,7 +2682,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
 
         Look for a thread other than the current (TP) that reported a
         breakpoint hit and hasn't been resumed yet since.  */
-      step_over = find_thread_needs_step_over (step, tp);
+      step_over = find_thread_needs_step_over (tp);
       if (step_over != NULL)
        {
          if (debug_infrun)
@@ -2276,7 +2691,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
                                target_pid_to_str (step_over->ptid));
 
          /* Store the prev_pc for the stepping thread too, needed by
-            switch_back_to_stepping thread.  */
+            switch_back_to_stepped_thread.  */
          tp->prev_pc = regcache_read_pc (get_current_regcache ());
          switch_to_thread (step_over->ptid);
          tp = step_over;
@@ -2292,7 +2707,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
       struct regcache *regcache = get_current_regcache ();
 
       set_step_over_info (get_regcache_aspace (regcache),
-                         regcache_read_pc (regcache));
+                         regcache_read_pc (regcache), 0);
     }
   else
     clear_step_over_info ();
@@ -2301,38 +2716,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
 
   tp->control.trap_expected = tp->stepping_over_breakpoint;
 
-  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.  */
-
-      struct thread_info *last_thread;
-      ptid_t last_ptid;
-      struct target_waitstatus last_status;
-
-      get_last_target_status (&last_ptid, &last_status);
-      if (!ptid_equal (inferior_ptid, last_ptid)
-         && !ptid_equal (last_ptid, null_ptid)
-         && !ptid_equal (last_ptid, minus_one_ptid))
-       {
-         last_thread = find_thread_ptid (last_ptid);
-         if (last_thread)
-           {
-             tp->suspend.stop_signal = last_thread->suspend.stop_signal;
-             last_thread->suspend.stop_signal = GDB_SIGNAL_0;
-           }
-       }
-    }
-
-  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;
-
   annotate_starting ();
 
   /* Make sure that output from GDB appears before output from the
@@ -2340,7 +2723,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
   gdb_flush (gdb_stdout);
 
   /* Refresh prev_pc value just prior to resuming.  This used to be
-     done in stop_stepping, however, setting prev_pc there did not handle
+     done in stop_waiting, however, setting prev_pc there did not handle
      scenarios such as inferior function calls or returning from
      a function via the return command.  In those cases, the prev_pc
      value was not set properly for subsequent commands.  The prev_pc value 
@@ -2364,12 +2747,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
      correctly when the inferior is stopped.  */
   tp->prev_pc = regcache_read_pc (get_current_regcache ());
 
-  /* Reset to normal state.  */
-  init_infwait_state ();
-
   /* Resume inferior.  */
-  resume (tp->control.trap_expected || step || bpstat_should_step (),
-         tp->suspend.stop_signal);
+  resume (tp->suspend.stop_signal);
 
   /* Wait for it to stop (if not standalone)
      and in any case decode why it stopped, and act accordingly.  */
@@ -2426,38 +2805,17 @@ init_wait_for_inferior (void)
 
   breakpoint_init_inferior (inf_starting);
 
-  clear_proceed_status ();
+  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);
-
-  singlestep_ptid = null_ptid;
-  singlestep_pc = 0;
 }
 
 \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_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
@@ -2474,11 +2832,6 @@ struct execution_control_state
   const char *stop_func_name;
   int wait_some_more;
 
-  /* We were in infwait_step_watch_state or
-     infwait_nonstep_watch_state state, and the thread reported an
-     event.  */
-  int stepped_after_stopped_by_watchpoint;
-
   /* True if the event thread hit the single-step breakpoint of
      another thread.  Thus the event doesn't cause a stop, the thread
      needs to be single-stepped past the single-step breakpoint before
@@ -2496,7 +2849,8 @@ static void handle_signal_stop (struct execution_control_state *ecs);
 static void check_exception_resume (struct execution_control_state *,
                                    struct frame_info *);
 
-static void stop_stepping (struct execution_control_state *ecs);
+static void end_stepping_range (struct execution_control_state *ecs);
+static void stop_waiting (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
 static void keep_going (struct execution_control_state *ecs);
 static void process_event_stop_test (struct execution_control_state *ecs);
@@ -2612,54 +2966,71 @@ 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 void
+delete_thread_infrun_breakpoints (struct thread_info *tp)
+{
+  delete_step_resume_breakpoint (tp);
+  delete_exception_resume_breakpoint (tp);
+  delete_single_step_breakpoints (tp);
+}
+
+/* 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
+for_each_just_stopped_thread (for_each_just_stopped_thread_callback_func func)
+{
+  if (!target_has_execution || ptid_equal (inferior_ptid, null_ptid))
+    return;
+
+  if (non_stop)
+    {
+      /* If in non-stop mode, only the current thread stopped.  */
+      func (inferior_thread ());
+    }
+  else
+    {
+      struct thread_info *tp;
+
+      /* In all-stop mode, all threads have stopped.  */
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         func (tp);
+       }
+    }
+}
+
+/* Delete the step resume and longjmp/exception resume breakpoints of
+   the threads that just stopped.  */
 
-static int
-delete_step_resume_breakpoint_callback (struct thread_info *info, void *data)
+static void
+delete_just_stopped_threads_infrun_breakpoints (void)
 {
-  if (is_exited (info->ptid))
-    return 0;
-
-  delete_step_resume_breakpoint (info);
-  delete_exception_resume_breakpoint (info);
-  return 0;
+  for_each_just_stopped_thread (delete_thread_infrun_breakpoints);
 }
 
-/* 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.  */
+/* Delete the single-step breakpoints of the threads that just
+   stopped.  */
 
 static void
-delete_step_thread_step_resume_breakpoint (void)
+delete_just_stopped_threads_single_step_breakpoints (void)
 {
-  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.  */
-    return;
-
-  if (non_stop)
-    {
-      /* 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);
-    }
-  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);
+  for_each_just_stopped_thread (delete_single_step_breakpoints);
 }
 
 /* A cleanup wrapper.  */
 
 static void
-delete_step_thread_step_resume_breakpoint_cleanup (void *arg)
+delete_just_stopped_threads_infrun_breakpoints_cleanup (void *arg)
 {
-  delete_step_thread_step_resume_breakpoint ();
+  delete_just_stopped_threads_infrun_breakpoints ();
 }
 
 /* Pretty print the results of target_wait, for debugging purposes.  */
@@ -2678,14 +3049,19 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
      is set.  */
 
   fprintf_unfiltered (tmp_stream,
-                     "infrun: target_wait (%d", ptid_get_pid (waiton_ptid));
+                     "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",
+                     "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",
@@ -2789,19 +3165,26 @@ 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));
 
@@ -2821,24 +3204,46 @@ wait_for_inferior (void)
       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)
+{
+  if (!interpreter_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 (async_command_editing_p && !sync_execution)
+    gdb_rl_callback_handler_reinstall ();
+}
+
 /* 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
@@ -2857,9 +3262,13 @@ fetch_inferior_event (void *client_data)
   struct cleanup *ts_old_chain;
   int was_sync = sync_execution;
   int cmd_done = 0;
+  ptid_t waiton_ptid = minus_one_ptid;
 
   memset (ecs, 0, sizeof (*ecs));
 
+  /* 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
@@ -2908,14 +3317,16 @@ 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);
 
-      delete_step_thread_step_resume_breakpoint ();
+      delete_just_stopped_threads_infrun_breakpoints ();
 
       /* We may not find an inferior if this was a process exit.  */
       if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
@@ -2945,7 +3356,7 @@ fetch_inferior_event (void *client_data)
      restore the prompt (a synchronous execution command has finished,
      and we're ready for input).  */
   if (interpreter_async && was_sync && !sync_execution)
-    display_gdb_prompt (0);
+    observer_notify_sync_execution_done ();
 
   if (cmd_done
       && !was_sync
@@ -2973,7 +3384,9 @@ 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;
 }
 
@@ -3084,12 +3497,24 @@ 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);
   gdbarch = get_regcache_arch (regcache);
 
-  decr_pc = target_decr_pc_after_break (gdbarch);
+  decr_pc = gdbarch_decr_pc_after_break (gdbarch);
   if (decr_pc == 0)
     return;
 
@@ -3099,6 +3524,11 @@ adjust_pc_after_break (struct execution_control_state *ecs)
      breakpoint would be.  */
   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.
 
@@ -3106,7 +3536,10 @@ 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)))
     {
@@ -3122,7 +3555,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
@@ -3133,23 +3565,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)
+      if (thread_has_single_step_breakpoints_set (ecs->event_thread)
          || !currently_stepping (ecs->event_thread)
-         || ecs->event_thread->prev_pc == breakpoint_pc)
+         || (ecs->event_thread->stepped_breakpoint
+             && ecs->event_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)
 {
@@ -3236,7 +3661,7 @@ fill_in_stop_func (struct gdbarch *gdbarch,
 static enum stop_kind
 get_inferior_stop_soon (ptid_t ptid)
 {
-  struct inferior *inf = find_inferior_pid (ptid_get_pid (ptid));
+  struct inferior *inf = find_inferior_ptid (ptid);
 
   gdb_assert (inf != NULL);
   return inf->control.stop_soon;
@@ -3248,7 +3673,7 @@ get_inferior_stop_soon (ptid_t ptid)
 
    The alternatives are:
 
-   1) stop_stepping and return; to really stop and return to the
+   1) stop_waiting and return; to really stop and return to the
    debugger.
 
    2) keep_going and return; to wait for the next event (set
@@ -3256,7 +3681,7 @@ get_inferior_stop_soon (ptid_t ptid)
    once).  */
 
 static void
-handle_inferior_event (struct execution_control_state *ecs)
+handle_inferior_event_1 (struct execution_control_state *ecs)
 {
   enum stop_kind stop_soon;
 
@@ -3306,7 +3731,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
 
       stop_print_frame = 0;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
     }
 
@@ -3370,40 +3795,6 @@ handle_inferior_event (struct execution_control_state *ecs)
           && ecs->ws.kind != TARGET_WAITKIND_EXITED)
     set_executing (ecs->ptid, 0);
 
-  switch (infwait_state)
-    {
-    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");
-
-      ecs->stepped_after_stopped_by_watchpoint = 1;
-      break;
-
-    case infwait_nonstep_watch_state:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: infwait_nonstep_watch_state\n");
-      insert_breakpoints ();
-
-      /* FIXME-maybe: is this cleaner than setting a flag?  Does it
-         handle things like signals arriving and other things happening
-         in combination correctly?  */
-      ecs->stepped_after_stopped_by_watchpoint = 1;
-      break;
-
-    default:
-      internal_error (__FILE__, __LINE__, _("bad switch"));
-    }
-
-  infwait_state = infwait_normal_state;
-  waiton_ptid = pid_to_ptid (-1);
-
   switch (ecs->ws.kind)
     {
     case TARGET_WAITKIND_LOADED:
@@ -3449,7 +3840,7 @@ handle_inferior_event (struct execution_control_state *ecs)
                 normal_stop.  */
              stop_print_frame = 1;
 
-             stop_stepping (ecs);
+             stop_waiting (ecs);
              return;
            }
        }
@@ -3461,10 +3852,9 @@ handle_inferior_event (struct execution_control_state *ecs)
        {
          /* Loading of shared libraries might have changed breakpoint
             addresses.  Make sure new breakpoints are inserted.  */
-         if (stop_soon == NO_STOP_QUIETLY
-             && !breakpoints_always_inserted_mode ())
+         if (stop_soon == NO_STOP_QUIETLY)
            insert_breakpoints ();
-         resume (0, GDB_SIGNAL_0);
+         resume (GDB_SIGNAL_0);
          prepare_to_wait (ecs);
          return;
        }
@@ -3476,7 +3866,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        {
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
-         stop_stepping (ecs);
+         stop_waiting (ecs);
          return;
        }
 
@@ -3488,7 +3878,7 @@ handle_inferior_event (struct execution_control_state *ecs)
         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;
 
@@ -3505,7 +3895,7 @@ 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.  */
@@ -3524,7 +3914,10 @@ handle_inferior_event (struct execution_control_state *ecs)
          current_inferior ()->has_exit_code = 1;
          current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
 
-         print_exited_reason (ecs->ws.value.integer);
+         /* Support the --return-child-result option.  */
+         return_child_result_value = ecs->ws.value.integer;
+
+         observer_notify_exited (ecs->ws.value.integer);
        }
       else
        {
@@ -3553,15 +3946,13 @@ handle_inferior_event (struct execution_control_state *ecs)
 Cannot fill $_exitsignal with the correct signal number.\n"));
            }
 
-         print_signal_exited_reason (ecs->ws.value.sig);
+         observer_notify_signal_exited (ecs->ws.value.sig);
        }
 
       gdb_flush (gdb_stdout);
       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;
@@ -3588,7 +3979,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
        if (displaced && ptid_equal (displaced->step_ptid, 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;
 
@@ -3652,12 +4043,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          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,
@@ -3713,7 +4099,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          if (should_resume)
            keep_going (ecs);
          else
-           stop_stepping (ecs);
+           stop_waiting (ecs);
          return;
        }
       process_event_stop_test (ecs);
@@ -3744,9 +4130,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       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.  */
@@ -3812,21 +4195,30 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
       /* Reverse execution: target ran out of history info.  */
 
-      /* 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;
-       }
+      delete_just_stopped_threads_single_step_breakpoints ();
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
-      print_no_history_reason ();
-      stop_stepping (ecs);
+      observer_notify_no_history ();
+      stop_waiting (ecs);
       return;
     }
 }
 
+/* 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);
+}
+
 /* Come here when the program has stopped with a signal.  */
 
 static void
@@ -3893,7 +4285,7 @@ handle_signal_stop (struct execution_control_state *ecs)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
       stop_print_frame = 1;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
     }
 
@@ -3905,7 +4297,7 @@ handle_signal_stop (struct execution_control_state *ecs)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
       stop_print_frame = 0;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
     }
 
@@ -3935,7 +4327,7 @@ handle_signal_stop (struct execution_control_state *ecs)
          || ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0))
     {
       stop_print_frame = 1;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
       return;
     }
@@ -3958,40 +4350,50 @@ handle_signal_stop (struct execution_control_state *ecs)
   gdbarch = get_frame_arch (frame);
 
   /* Pull the single step breakpoints out of the target.  */
-  if (singlestep_breakpoints_inserted_p)
+  if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
     {
+      struct regcache *regcache;
+      struct address_space *aspace;
+      CORE_ADDR pc;
+
+      regcache = get_thread_regcache (ecs->ptid);
+      aspace = get_regcache_aspace (regcache);
+      pc = regcache_read_pc (regcache);
+
       /* However, before doing so, if this single-step breakpoint was
         actually for another thread, set this thread up for moving
         past it.  */
-      if (!ptid_equal (ecs->ptid, singlestep_ptid)
-         && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
+      if (!thread_has_single_step_breakpoint_here (ecs->event_thread,
+                                                  aspace, pc))
        {
-         struct regcache *regcache;
-         struct address_space *aspace;
-         CORE_ADDR pc;
-
-         regcache = get_thread_regcache (ecs->ptid);
-         aspace = get_regcache_aspace (regcache);
-         pc = regcache_read_pc (regcache);
          if (single_step_breakpoint_inserted_here_p (aspace, pc))
            {
              if (debug_infrun)
                {
                  fprintf_unfiltered (gdb_stdlog,
-                                     "infrun: [%s] hit step over single-step"
-                                     " breakpoint of [%s]\n",
-                                     target_pid_to_str (ecs->ptid),
-                                     target_pid_to_str (singlestep_ptid));
+                                     "infrun: [%s] hit another thread's "
+                                     "single-step breakpoint\n",
+                                     target_pid_to_str (ecs->ptid));
                }
              ecs->hit_singlestep_breakpoint = 1;
            }
        }
-
-      remove_single_step_breakpoints ();
-      singlestep_breakpoints_inserted_p = 0;
+      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 (ecs->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);
@@ -4014,36 +4416,28 @@ handle_signal_stop (struct execution_control_state *ecs)
          watchpoint expression.  We do this by single-stepping the
         target.
 
-        It may not be necessary to disable the watchpoint to stop over
+        It may not be necessary to disable the watchpoint to step over
         it.  For example, the PA can (with some kernel cooperation)
         single step over a watchpoint without disabling the watchpoint.
 
         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;
     }
 
   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;
@@ -4176,6 +4570,54 @@ handle_signal_stop (struct execution_control_state *ecs)
     = !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 ())
+    {
+      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);
+
+             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;
+       }
+    }
+
+  /* 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;
+    }
+
   /* If not, perhaps stepping/nexting can.  */
   if (random_signal)
     random_signal = !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
@@ -4197,8 +4639,7 @@ handle_signal_stop (struct execution_control_state *ecs)
   if (random_signal)
     {
       /* Signal not for debugging purposes.  */
-      int printed = 0;
-      struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
+      struct inferior *inf = find_inferior_ptid (ecs->ptid);
       enum gdb_signal stop_signal = ecs->event_thread->suspend.stop_signal;
 
       if (debug_infrun)
@@ -4207,13 +4648,6 @@ handle_signal_stop (struct execution_control_state *ecs)
 
       stopped_by_random_signal = 1;
 
-      if (signal_print[ecs->event_thread->suspend.stop_signal])
-       {
-         printed = 1;
-         target_terminal_ours_for_output ();
-         print_signal_received_reason
-                                    (ecs->event_thread->suspend.stop_signal);
-       }
       /* Always stop on signals if we're either just gaining control
         of the program, or the user explicitly requested this thread
         to remain stopped.  */
@@ -4222,13 +4656,20 @@ handle_signal_stop (struct execution_control_state *ecs)
          || (!inf->detaching
              && signal_stop_state (ecs->event_thread->suspend.stop_signal)))
        {
-         stop_stepping (ecs);
+         stop_waiting (ecs);
          return;
        }
-      /* If not going to stop, give terminal back
-         if we took it away.  */
-      else if (printed)
-       target_terminal_inferior ();
+
+      /* Notify observers the signal has "handle print" set.  Note we
+        returned early above if stopping; normal_stop handles the
+        printing in that case.  */
+      if (signal_print[ecs->event_thread->suspend.stop_signal])
+       {
+         /* The signal table tells us to print about this signal.  */
+         target_terminal_ours_for_output ();
+         observer_notify_signal_received (ecs->event_thread->suspend.stop_signal);
+         target_terminal_inferior ();
+       }
 
       /* Clear the signal if it should not be passed.  */
       if (signal_program[ecs->event_thread->suspend.stop_signal] == 0)
@@ -4265,9 +4706,9 @@ handle_signal_stop (struct execution_control_state *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)
@@ -4287,6 +4728,7 @@ handle_signal_stop (struct execution_control_state *ecs)
                                 "single-step range\n");
 
          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);
@@ -4369,7 +4811,10 @@ process_event_stop_test (struct execution_control_state *ecs)
             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 = 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))
@@ -4422,7 +4867,7 @@ process_event_stop_test (struct execution_control_state *ecs)
 
        if (what.is_longjmp)
          {
-           check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
+           check_longjmp_breakpoint_for_call_dummy (ecs->event_thread);
 
            if (!frame_id_p (ecs->event_thread->initiating_frame))
              {
@@ -4455,9 +4900,7 @@ process_event_stop_test (struct execution_control_state *ecs)
           exists.  */
        delete_step_resume_breakpoint (ecs->event_thread);
 
-       ecs->event_thread->control.stop_step = 1;
-       print_end_stepping_range_reason ();
-       stop_stepping (ecs);
+       end_stepping_range (ecs);
       }
       return;
 
@@ -4512,7 +4955,7 @@ process_event_stop_test (struct execution_control_state *ecs)
         resumed.  */
       ecs->event_thread->stepping_over_breakpoint = 1;
 
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
 
     case BPSTAT_WHAT_STOP_SILENT:
@@ -4524,7 +4967,7 @@ process_event_stop_test (struct execution_control_state *ecs)
         whether a/the breakpoint is there when the thread is next
         resumed.  */
       ecs->event_thread->stepping_over_breakpoint = 1;
-      stop_stepping (ecs);
+      stop_waiting (ecs);
       return;
 
     case BPSTAT_WHAT_HP_STEP_RESUME:
@@ -4548,6 +4991,31 @@ process_event_stop_test (struct execution_control_state *ecs)
       break;
     }
 
+  /* 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 breakpoint *sr_bp
+       = ecs->event_thread->control.step_resume_breakpoint;
+
+      if (sr_bp != NULL
+         && sr_bp->loc->permanent
+         && sr_bp->type == bp_hp_step_resume
+         && sr_bp->loc->address == ecs->event_thread->prev_pc)
+       {
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "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
@@ -4619,11 +5087,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (stop_pc == ecs->event_thread->control.step_range_start
          && stop_pc != ecs->stop_func_start
          && execution_direction == EXEC_REVERSE)
-       {
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
-       }
+       end_stepping_range (ecs);
       else
        keep_going (ecs);
 
@@ -4755,28 +5219,21 @@ process_event_stop_test (struct execution_control_state *ecs)
                       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;
        }
 
@@ -4890,9 +5347,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
          && step_stop_if_no_debug)
        {
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
+         end_stepping_range (ecs);
          return;
        }
 
@@ -4986,9 +5441,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          /* If we have no line number and the step-stop-if-no-debug
             is set, we stop the step so that the user has a chance to
             switch in assembly mode.  */
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
+         end_stepping_range (ecs);
          return;
        }
       else
@@ -5007,9 +5460,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          one instruction.  */
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: stepi/nexti\n");
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
       return;
     }
 
@@ -5021,9 +5472,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          or can this happen as a result of a return or longjmp?).  */
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: no line number info\n");
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
       return;
     }
 
@@ -5054,9 +5503,7 @@ process_event_stop_test (struct execution_control_state *ecs)
              && call_sal.symtab == ecs->event_thread->current_symtab)
            step_into_inline_frame (ecs->ptid);
 
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
+         end_stepping_range (ecs);
          return;
        }
       else
@@ -5068,11 +5515,7 @@ process_event_stop_test (struct execution_control_state *ecs)
              && call_sal.symtab == ecs->event_thread->current_symtab)
            keep_going (ecs);
          else
-           {
-             ecs->event_thread->control.stop_step = 1;
-             print_end_stepping_range_reason ();
-             stop_stepping (ecs);
-           }
+           end_stepping_range (ecs);
          return;
        }
     }
@@ -5095,11 +5538,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
        keep_going (ecs);
       else
-       {
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
-       }
+       end_stepping_range (ecs);
       return;
     }
 
@@ -5114,9 +5553,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog,
                             "infrun: stepped to a different line\n");
-      ecs->event_thread->control.stop_step = 1;
-      print_end_stepping_range_reason ();
-      stop_stepping (ecs);
+      end_stepping_range (ecs);
       return;
     }
 
@@ -5197,12 +5634,16 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
         what keep_going does as well, if we call it.  */
       ecs->event_thread->control.trap_expected = 0;
 
+      /* Likewise, clear the signal if it should not be passed.  */
+      if (!signal_program[ecs->event_thread->suspend.stop_signal])
+       ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
+
       /* If scheduler locking applies even if not stepping, there's no
         need to walk over threads.  Above we've checked whether the
         current thread is stepping.  If some other thread not the
         event thread is stepping, then it must be that scheduler
         locking is not in effect.  */
-      if (schedlock_applies (0))
+      if (schedlock_applies (ecs->event_thread))
        return 0;
 
       /* Look for the stepping/nexting thread, and check if any other
@@ -5211,7 +5652,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
         step/next/etc.  */
       stepping_thread = NULL;
       step_over = NULL;
-      ALL_THREADS (tp)
+      ALL_NON_EXITED_THREADS (tp)
         {
          /* Ignore threads of processes we're not resuming.  */
          if (!sched_multi
@@ -5238,7 +5679,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
                 stepping, then scheduler locking can't be in effect,
                 otherwise we wouldn't have resumed the current event
                 thread in the first place.  */
-             gdb_assert (!schedlock_applies (1));
+             gdb_assert (!schedlock_applies (tp));
 
              stepping_thread = tp;
            }
@@ -5340,22 +5781,29 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
             breakpoint forward, one instruction at a time,
             overstepping.  */
 
-         if (gdbarch_software_single_step_p (gdbarch)
-             && stop_pc != tp->prev_pc)
+         if (stop_pc != tp->prev_pc)
            {
+             ptid_t resume_ptid;
+
              if (debug_infrun)
                fprintf_unfiltered (gdb_stdlog,
                                    "infrun: expected thread advanced also\n");
 
+             /* Clear the info of the previous step-over, as it's no
+                longer valid.  It's what keep_going would do too, if
+                we called it.  Must 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 ends up not installed.  */
+             clear_step_over_info ();
+
              insert_single_step_breakpoint (get_frame_arch (frame),
                                             get_frame_address_space (frame),
                                             stop_pc);
-             singlestep_breakpoints_inserted_p = 1;
-             ecs->event_thread->control.trap_expected = 1;
-             singlestep_ptid = inferior_ptid;
-             singlestep_pc = stop_pc;
 
-             resume (0, GDB_SIGNAL_0);
+             resume_ptid = user_visible_resume_ptid (tp->control.stepping_command);
+             do_target_resume (resume_ptid,
+                               currently_stepping (tp), GDB_SIGNAL_0);
              prepare_to_wait (ecs);
            }
          else
@@ -5381,6 +5829,7 @@ 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 ());
 }
 
@@ -5392,13 +5841,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);
 
@@ -5440,9 +5889,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
@@ -5473,13 +5920,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);
 
@@ -5489,9 +5936,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
     {
@@ -5631,14 +6076,11 @@ 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 value *value;
@@ -5667,6 +6109,11 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
          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
@@ -5707,7 +6154,6 @@ static void
 check_exception_resume (struct execution_control_state *ecs,
                        struct frame_info *frame)
 {
-  volatile struct gdb_exception e;
   struct bound_probe probe;
   struct symbol *func;
 
@@ -5726,9 +6172,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;
@@ -5763,13 +6209,17 @@ 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 ();
 
@@ -5800,13 +6250,13 @@ keep_going (struct execution_control_state *ecs)
         are supposed to pass through to the inferior.  Simply
         continue.  */
       discard_cleanups (old_cleanups);
-      resume (currently_stepping (ecs->event_thread),
-             ecs->event_thread->suspend.stop_signal);
+      resume (ecs->event_thread->suspend.stop_signal);
     }
   else
     {
-      volatile struct gdb_exception e;
       struct regcache *regcache = get_current_regcache ();
+      int remove_bp;
+      int remove_wps;
 
       /* Either the trap was not expected, but we are continuing
         anyway (if we got a signal, the user asked it be passed to
@@ -5826,31 +6276,42 @@ keep_going (struct execution_control_state *ecs)
         (watchpoints, etc.) but the one we're stepping over, step one
         instruction, and then re-insert the breakpoint when that step
         is finished.  */
-      if ((ecs->hit_singlestep_breakpoint
-          || thread_still_needs_step_over (ecs->event_thread))
-         && !use_displaced_stepping (get_regcache_arch (regcache)))
+
+      remove_bp = (ecs->hit_singlestep_breakpoint
+                  || thread_still_needs_step_over (ecs->event_thread));
+      remove_wps = (ecs->event_thread->stepping_over_watchpoint
+                   && !target_have_steppable_watchpoint);
+
+      /* 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 (get_regcache_arch (regcache))))
        {
          set_step_over_info (get_regcache_aspace (regcache),
-                             regcache_read_pc (regcache));
+                             regcache_read_pc (regcache), remove_wps);
        }
+      else if (remove_wps)
+       set_step_over_info (NULL, 0, remove_wps);
       else
        clear_step_over_info ();
 
       /* Stop stepping if inserting breakpoints fails.  */
-      TRY_CATCH (e, RETURN_MASK_ERROR)
+      TRY
        {
          insert_breakpoints ();
        }
-      if (e.reason < 0)
+      CATCH (e, RETURN_MASK_ERROR)
        {
          exception_print (gdb_stderr, e);
-         stop_stepping (ecs);
+         stop_waiting (ecs);
+         discard_cleanups (old_cleanups);
          return;
        }
+      END_CATCH
 
-      ecs->event_thread->control.trap_expected
-       = (ecs->event_thread->stepping_over_breakpoint
-          || ecs->hit_singlestep_breakpoint);
+      ecs->event_thread->control.trap_expected = (remove_bp || remove_wps);
 
       /* Do not deliver GDB_SIGNAL_TRAP (except when the user
         explicitly specifies that such a signal should be delivered
@@ -5867,8 +6328,7 @@ keep_going (struct execution_control_state *ecs)
        ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
 
       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);
@@ -5890,35 +6350,42 @@ prepare_to_wait (struct execution_control_state *ecs)
   ecs->wait_some_more = 1;
 }
 
+/* We are done with the step range of a step/next/si/ni command.
+   Called once for each n of a "step n" operation.  */
+
+static void
+end_stepping_range (struct execution_control_state *ecs)
+{
+  ecs->event_thread->control.stop_step = 1;
+  stop_waiting (ecs);
+}
+
 /* Several print_*_reason functions to print why the inferior has stopped.
    We always print something when the inferior exits, or receives a signal.
    The rest of the cases are dealt with later on in normal_stop and
    print_it_typical.  Ideally there should be a call to one of these
    print_*_reason functions functions from handle_inferior_event each time
-   stop_stepping is called.  */
+   stop_waiting is called.
 
-/* Print why the inferior has stopped.  
-   We are done with a step/next/si/ni command, print why the inferior has
-   stopped.  For now print nothing.  Print a message only if not in the middle
-   of doing a "step n" operation for n > 1.  */
+   Note that we don't call these directly, instead we delegate that to
+   the interpreters, through observers.  Interpreters then call these
+   with whatever uiout is right.  */
 
-static void
-print_end_stepping_range_reason (void)
+void
+print_end_stepping_range_reason (struct ui_out *uiout)
 {
-  if ((!inferior_thread ()->step_multi
-       || !inferior_thread ()->control.stop_step)
-      && ui_out_is_mi_like_p (current_uiout))
-    ui_out_field_string (current_uiout, "reason",
-                         async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
-}
+  /* For CLI-like interpreters, print nothing.  */
 
-/* The inferior was terminated by a signal, print why it stopped.  */
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason",
+                          async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
+    }
+}
 
-static void
-print_signal_exited_reason (enum gdb_signal siggnal)
+void
+print_signal_exited_reason (struct ui_out *uiout, enum gdb_signal siggnal)
 {
-  struct ui_out *uiout = current_uiout;
-
   annotate_signalled ();
   if (ui_out_is_mi_like_p (uiout))
     ui_out_field_string
@@ -5937,14 +6404,11 @@ print_signal_exited_reason (enum gdb_signal siggnal)
   ui_out_text (uiout, "The program no longer exists.\n");
 }
 
-/* The inferior program is finished, print why it stopped.  */
-
-static void
-print_exited_reason (int exitstatus)
+void
+print_exited_reason (struct ui_out *uiout, int exitstatus)
 {
   struct inferior *inf = current_inferior ();
   const char *pidstr = target_pid_to_str (pid_to_ptid (inf->pid));
-  struct ui_out *uiout = current_uiout;
 
   annotate_exited (exitstatus);
   if (exitstatus)
@@ -5971,18 +6435,11 @@ print_exited_reason (int exitstatus)
       ui_out_text (uiout, pidstr);
       ui_out_text (uiout, ") exited normally]\n");
     }
-  /* Support the --return-child-result option.  */
-  return_child_result_value = exitstatus;
 }
 
-/* Signal received, print why the inferior has stopped.  The signal table
-   tells us to print about it.  */
-
-static void
-print_signal_received_reason (enum gdb_signal siggnal)
+void
+print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
 {
-  struct ui_out *uiout = current_uiout;
-
   annotate_signal ();
 
   if (siggnal == GDB_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
@@ -6014,13 +6471,10 @@ print_signal_received_reason (enum gdb_signal siggnal)
   ui_out_text (uiout, ".\n");
 }
 
-/* Reverse execution: target ran out of history info, print why the inferior
-   has stopped.  */
-
-static void
-print_no_history_reason (void)
+void
+print_no_history_reason (struct ui_out *uiout)
 {
-  ui_out_text (current_uiout, "\nNo more reverse-execution history.\n");
+  ui_out_text (uiout, "\nNo more reverse-execution history.\n");
 }
 
 /* Print current location without a level number, if we have changed
@@ -6046,7 +6500,7 @@ print_stop_event (struct target_waitstatus *ws)
       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))
+         && tp->control.step_start_function == find_pc_function (stop_pc))
        {
          /* Finished step, just print source line.  */
          source_flag = SRC_LINE;
@@ -6113,6 +6567,19 @@ normal_stop (void)
           && last.kind != TARGET_WAITKIND_NO_RESUMED)
     make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
 
+  /* 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
      the inferior actually stops.
@@ -6151,7 +6618,8 @@ normal_stop (void)
       printf_filtered (_("No unwaited-for children left.\n"));
     }
 
-  if (!breakpoints_always_inserted_mode () && target_has_execution)
+  /* Note: this depends on the update_thread_list call above.  */
+  if (!breakpoints_should_be_inserted_now () && target_has_execution)
     {
       if (remove_breakpoints ())
        {
@@ -6168,14 +6636,19 @@ normal_stop (void)
   if (stopped_by_random_signal)
     disable_current_display ();
 
-  /* Don't print a message if in the middle of doing a "step n"
-     operation for n > 1 */
+  /* Notify observers if we finished a "step"-like command, etc.  */
   if (target_has_execution
       && last.kind != TARGET_WAITKIND_SIGNALLED
       && last.kind != TARGET_WAITKIND_EXITED
-      && inferior_thread ()->step_multi
       && inferior_thread ()->control.stop_step)
-    goto done;
+    {
+      /* But not if in the middle of doing a "step n" operation for
+        n > 1 */
+      if (inferior_thread ()->step_multi)
+       goto done;
+
+      observer_notify_end_stepping_range ();
+    }
 
   target_terminal_ours ();
   async_enable_stdin ();
@@ -6186,8 +6659,18 @@ normal_stop (void)
   if (has_stack_frames () && !stop_stack_dummy)
     set_current_sal_from_frame (get_current_frame ());
 
-  /* Let the user/frontend see the threads as stopped.  */
-  do_cleanups (old_chain);
+  /* Let the user/frontend see the threads as stopped, but defer to
+     call_function_by_hand if the thread finished an infcall
+     successfully.  We may be e.g., evaluating a breakpoint condition.
+     In that case, the thread had state THREAD_RUNNING before the
+     infcall, and shall remain marked running, all without informing
+     the user/frontend about state transition changes.  */
+  if (target_has_execution
+      && inferior_thread ()->control.in_infcall
+      && stop_stack_dummy == STOP_STACK_DUMMY)
+    discard_cleanups (old_chain);
+  else
+    do_cleanups (old_chain);
 
   /* Look up the hook_stop and run it (CLI internally handles problem
      of stop_command's pre-hook not existing).  */
@@ -6218,20 +6701,6 @@ normal_stop (void)
        print_stop_event (&last);
     }
 
-  /* 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);
-
-      /* NB: The copy goes through to the target picking up the value of
-        all the registers.  */
-      stop_registers = regcache_dup (get_current_regcache ());
-    }
-
   if (stop_stack_dummy == STOP_STACK_DUMMY)
     {
       /* Pop the empty frame that contains the stack dummy.
@@ -6623,72 +7092,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)
 {
@@ -6848,9 +7251,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;
@@ -6870,9 +7270,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;
@@ -6906,9 +7303,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.  */
@@ -6927,16 +7321,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;
 
@@ -7156,7 +7544,7 @@ save_inferior_ptid (void)
   return make_cleanup (restore_inferior_ptid, saved_ptid_ptr);
 }
 
-/* See inferior.h.  */
+/* See infrun.h.  */
 
 void
 clear_exit_convenience_vars (void)
@@ -7271,29 +7659,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, _("\
@@ -7347,7 +7712,7 @@ leave it stopped or free to run as needed."),
   signal_catch = (unsigned char *)
     xmalloc (sizeof (signal_catch[0]) * numsigs);
   signal_pass = (unsigned char *)
-    xmalloc (sizeof (signal_program[0]) * numsigs);
+    xmalloc (sizeof (signal_pass[0]) * numsigs);
   for (i = 0; i < numsigs; i++)
     {
       signal_stop[i] = 1;
@@ -7450,9 +7815,8 @@ 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')."), 
+step == scheduler locked during stepping commands (step, next, stepi, nexti).\n\
+       In this mode, other threads may run during other commands."),
                        set_schedlock_func,     /* traps on target vector */
                        show_scheduler_mode,
                        &setlist, &showlist);
This page took 0.062111 seconds and 4 git commands to generate.