Check all inline frames if they are marked for skip
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 223e836ededdd3f547caeee65be5ca00694a68a8..7ddd21dd09977c8340cb7037108789307481177d 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986-2018 Free Software Foundation, Inc.
+   Copyright (C) 1986-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "frame.h"
 #include "inferior.h"
 #include "breakpoint.h"
-#include "gdb_wait.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
-#include "cli/cli-script.h"
 #include "target.h"
 #include "gdbthread.h"
 #include "annotate.h"
 #include "symfile.h"
 #include "top.h"
-#include <signal.h>
 #include "inf-loop.h"
 #include "regcache.h"
 #include "value.h"
@@ -42,7 +39,6 @@
 #include "language.h"
 #include "solib.h"
 #include "main.h"
-#include "dictionary.h"
 #include "block.h"
 #include "mi/mi-common.h"
 #include "event-top.h"
@@ -51,8 +47,6 @@
 #include "inline-frame.h"
 #include "jit.h"
 #include "tracepoint.h"
-#include "continuations.h"
-#include "interps.h"
 #include "skip.h"
 #include "probe.h"
 #include "objfiles.h"
 #include "solist.h"
 #include "event-loop.h"
 #include "thread-fsm.h"
-#include "common/enum-flags.h"
+#include "gdbsupport/enum-flags.h"
 #include "progspace-and-thread.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/gdb_optional.h"
 #include "arch-utils.h"
+#include "gdbsupport/scope-exit.h"
+#include "gdbsupport/forward-scope-exit.h"
 
 /* Prototypes for local functions */
 
@@ -92,6 +88,8 @@ static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
 
 static int maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc);
 
+static void resume (gdb_signal sig);
+
 /* Asynchronous signal handler registered as event loop source for
    when we have pending events ready to be passed to the core.  */
 static struct async_event_handler *infrun_async_inferior_event_token;
@@ -132,7 +130,7 @@ mark_infrun_async_event_handler (void)
 /* 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.  */
-int step_stop_if_no_debug = 0;
+bool step_stop_if_no_debug = false;
 static void
 show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
@@ -151,9 +149,9 @@ static ptid_t previous_inferior_ptid;
    Exactly which branch is detached depends on 'set follow-fork-mode'
    setting.  */
 
-static int detach_fork = 1;
+static bool detach_fork = true;
 
-int debug_displaced = 0;
+bool debug_displaced = false;
 static void
 show_debug_displaced (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
@@ -172,7 +170,7 @@ show_debug_infrun (struct ui_file *file, int from_tty,
 
 /* Support for disabling address space randomization.  */
 
-int disable_randomization = 1;
+bool disable_randomization = true;
 
 static void
 show_disable_randomization (struct ui_file *file, int from_tty,
@@ -201,8 +199,8 @@ set_disable_randomization (const char *args, int from_tty,
 
 /* User interface for non-stop mode.  */
 
-int non_stop = 0;
-static int non_stop_1 = 0;
+bool non_stop = false;
+static bool non_stop_1 = false;
 
 static void
 set_non_stop (const char *args, int from_tty,
@@ -230,8 +228,8 @@ show_non_stop (struct ui_file *file, int from_tty,
    non-stop, in which all GDB operations that might affect the
    target's execution have been disabled.  */
 
-int observer_mode = 0;
-static int observer_mode_1 = 0;
+bool observer_mode = false;
+static bool observer_mode_1 = false;
 
 static void
 set_observer_mode (const char *args, int from_tty,
@@ -252,7 +250,7 @@ set_observer_mode (const char *args, int from_tty,
   /* We can insert fast tracepoints in or out of observer mode,
      but enable them if we're going into this mode.  */
   if (observer_mode)
-    may_insert_fast_tracepoints = 1;
+    may_insert_fast_tracepoints = true;
   may_stop = !observer_mode;
   update_target_permissions ();
 
@@ -261,7 +259,7 @@ set_observer_mode (const char *args, int from_tty,
   if (observer_mode)
     {
       pagination_enabled = 0;
-      non_stop = non_stop_1 = 1;
+      non_stop = non_stop_1 = true;
     }
 
   if (from_tty)
@@ -285,13 +283,11 @@ show_observer_mode (struct ui_file *file, int from_tty,
 void
 update_observer_mode (void)
 {
-  int newval;
-
-  newval = (!may_insert_breakpoints
-           && !may_insert_tracepoints
-           && may_insert_fast_tracepoints
-           && !may_stop
-           && non_stop);
+  bool newval = (!may_insert_breakpoints
+                && !may_insert_tracepoints
+                && may_insert_fast_tracepoints
+                && !may_stop
+                && non_stop);
 
   /* Let the user know if things change.  */
   if (newval != observer_mode)
@@ -303,20 +299,19 @@ update_observer_mode (void)
 
 /* Tables of how to react to signals; the user sets them.  */
 
-static unsigned char *signal_stop;
-static unsigned char *signal_print;
-static unsigned char *signal_program;
+static unsigned char signal_stop[GDB_SIGNAL_LAST];
+static unsigned char signal_print[GDB_SIGNAL_LAST];
+static unsigned char signal_program[GDB_SIGNAL_LAST];
 
 /* Table of signals that are registered with "catch signal".  A
    non-zero entry indicates that the signal is caught by some "catch
-   signal" command.  This has size GDB_SIGNAL_LAST, to accommodate all
-   signals.  */
-static unsigned char *signal_catch;
+   signal" command.  */
+static unsigned char signal_catch[GDB_SIGNAL_LAST];
 
 /* Table of signals that the target may silently handle.
    This is automatically determined from the flags above,
    and simply cached here.  */
-static unsigned char *signal_pass;
+static unsigned char signal_pass[GDB_SIGNAL_LAST];
 
 #define SET_SIGS(nsigs,sigs,flags) \
   do { \
@@ -340,7 +335,7 @@ static unsigned char *signal_pass;
 void
 update_signals_program_target (void)
 {
-  target_program_signals ((int) GDB_SIGNAL_LAST, signal_program);
+  target_program_signals (signal_program);
 }
 
 /* Value to pass to target_resume() to cause all threads to resume.  */
@@ -383,8 +378,6 @@ static int stop_print_frame;
 static ptid_t target_last_wait_ptid;
 static struct target_waitstatus target_last_waitstatus;
 
-static void context_switch (ptid_t ptid);
-
 void init_thread_stepping_state (struct thread_info *tss);
 
 static const char follow_fork_mode_child[] = "child";
@@ -439,7 +432,6 @@ follow_fork_inferior (int follow_child, int detach_fork)
 Can not resume the parent process over vfork in the foreground while\n\
 holding the child stopped.  Try \"set detach-on-fork\" or \
 \"set schedule-multiple\".\n"));
-      /* FIXME output string > 80 columns.  */
       return 1;
     }
 
@@ -458,19 +450,19 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
          if (has_vforked)
            {
              /* Keep breakpoints list in sync.  */
-             remove_breakpoints_pid (ptid_get_pid (inferior_ptid));
+             remove_breakpoints_inf (current_inferior ());
            }
 
          if (print_inferior_events)
            {
              /* Ensure that we have a process ptid.  */
-             ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
+             ptid_t process_ptid = ptid_t (child_ptid.pid ());
 
              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));
+                               target_pid_to_str (process_ptid).c_str ());
            }
        }
       else
@@ -478,7 +470,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
          struct inferior *parent_inf, *child_inf;
 
          /* Add process to GDB's tables.  */
-         child_inf = add_inferior (ptid_get_pid (child_ptid));
+         child_inf = add_inferior (child_ptid.pid ());
 
          parent_inf = current_inferior ();
          child_inf->attach_flag = parent_inf->attach_flag;
@@ -565,7 +557,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
       /* 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));
+      child_inf = add_inferior (child_ptid.pid ());
 
       parent_inf = current_inferior ();
       child_inf->attach_flag = parent_inf->attach_flag;
@@ -600,13 +592,13 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
          if (print_inferior_events)
            {
              /* Ensure that we have a process ptid.  */
-             ptid_t process_ptid = pid_to_ptid (ptid_get_pid (parent_ptid));
+             ptid_t process_ptid = ptid_t (parent_ptid.pid ());
 
              target_terminal::ours_for_output ();
              fprintf_filtered (gdb_stdlog,
                                _("[Detaching after fork from "
                                  "parent %s]\n"),
-                               target_pid_to_str (process_ptid));
+                               target_pid_to_str (process_ptid).c_str ());
            }
 
          target_detach (parent_inf, 0);
@@ -689,14 +681,16 @@ follow_fork (void)
 
       /* Check if we switched over from WAIT_PTID, since the event was
         reported.  */
-      if (!ptid_equal (wait_ptid, minus_one_ptid)
-         && !ptid_equal (inferior_ptid, wait_ptid))
+      if (wait_ptid != minus_one_ptid
+         && inferior_ptid != wait_ptid)
        {
          /* We did.  Switch back to WAIT_PTID thread, to tell the
             target to follow it (in either direction).  We'll
             afterwards refuse to resume, and inform the user what
             happened.  */
-         switch_to_thread (wait_ptid);
+         thread_info *wait_thread
+           = find_thread_ptid (wait_ptid);
+         switch_to_thread (wait_thread);
          should_resume = 0;
        }
     }
@@ -767,7 +761,8 @@ follow_fork (void)
            /* If we followed the child, switch to it...  */
            if (follow_child)
              {
-               switch_to_thread (child);
+               thread_info *child_thr = find_thread_ptid (child);
+               switch_to_thread (child_thr);
 
                /* ... and preserve the stepping state, in case the
                   user was stepping over the fork call.  */
@@ -798,8 +793,6 @@ follow_fork (void)
                /* Reset breakpoints in the child as appropriate.  */
                follow_inferior_reset_breakpoints ();
              }
-           else
-             switch_to_thread (parent);
          }
       }
       break;
@@ -865,18 +858,18 @@ proceed_after_vfork_done (struct thread_info *thread,
 {
   int pid = * (int *) arg;
 
-  if (ptid_get_pid (thread->ptid) == pid
-      && is_running (thread->ptid)
-      && !is_executing (thread->ptid)
+  if (thread->ptid.pid () == pid
+      && thread->state == THREAD_RUNNING
+      && !thread->executing
       && !thread->stop_requested
       && thread->suspend.stop_signal == GDB_SIGNAL_0)
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resuming vfork parent thread %s\n",
-                           target_pid_to_str (thread->ptid));
+                           target_pid_to_str (thread->ptid).c_str ());
 
-      switch_to_thread (thread->ptid);
+      switch_to_thread (thread);
       clear_proceed_status (0);
       proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
@@ -913,10 +906,14 @@ handle_vfork_child_exec_or_exit (int exec)
       int resume_parent = -1;
 
       /* This exec or exit marks the end of the shared memory region
-        between the parent and the child.  If the user wanted to
-        detach from the parent, now is the time.  */
+        between the parent and the child.  Break the bonds.  */
+      inferior *vfork_parent = inf->vfork_parent;
+      inf->vfork_parent->vfork_child = NULL;
+      inf->vfork_parent = NULL;
 
-      if (inf->vfork_parent->pending_detach)
+      /* If the user wanted to detach from the parent, now is the
+        time.  */
+      if (vfork_parent->pending_detach)
        {
          struct thread_info *tp;
          struct program_space *pspace;
@@ -924,7 +921,7 @@ handle_vfork_child_exec_or_exit (int exec)
 
          /* follow-fork child, detach-on-fork on.  */
 
-         inf->vfork_parent->pending_detach = 0;
+         vfork_parent->pending_detach = 0;
 
          gdb::optional<scoped_restore_exited_inferior>
            maybe_restore_inferior;
@@ -939,8 +936,8 @@ handle_vfork_child_exec_or_exit (int exec)
            maybe_restore_thread.emplace ();
 
          /* We're letting loose of the parent.  */
-         tp = any_live_thread_of_process (inf->vfork_parent->pid);
-         switch_to_thread (tp->ptid);
+         tp = any_live_thread_of_inferior (vfork_parent);
+         switch_to_thread (tp);
 
          /* We're about to detach from the parent, which implicitly
             removes breakpoints from its address space.  There's a
@@ -961,8 +958,8 @@ handle_vfork_child_exec_or_exit (int exec)
 
          if (print_inferior_events)
            {
-             const char *pidstr
-               = target_pid_to_str (pid_to_ptid (inf->vfork_parent->pid));
+             std::string pidstr
+               = target_pid_to_str (ptid_t (vfork_parent->pid));
 
              target_terminal::ours_for_output ();
 
@@ -970,17 +967,17 @@ handle_vfork_child_exec_or_exit (int exec)
                {
                  fprintf_filtered (gdb_stdlog,
                                    _("[Detaching vfork parent %s "
-                                     "after child exec]\n"), pidstr);
+                                     "after child exec]\n"), pidstr.c_str ());
                }
              else
                {
                  fprintf_filtered (gdb_stdlog,
                                    _("[Detaching vfork parent %s "
-                                     "after child exit]\n"), pidstr);
+                                     "after child exit]\n"), pidstr.c_str ());
                }
            }
 
-         target_detach (inf->vfork_parent, 0);
+         target_detach (vfork_parent, 0);
 
          /* Put it back.  */
          inf->pspace = pspace;
@@ -995,10 +992,7 @@ handle_vfork_child_exec_or_exit (int exec)
          inf->removable = 1;
          set_current_program_space (inf->pspace);
 
-         resume_parent = inf->vfork_parent->pid;
-
-         /* Break the bonds.  */
-         inf->vfork_parent->vfork_child = NULL;
+         resume_parent = vfork_parent->pid;
        }
       else
        {
@@ -1028,17 +1022,13 @@ handle_vfork_child_exec_or_exit (int exec)
          set_current_program_space (pspace);
          inf->removable = 1;
          inf->symfile_flags = SYMFILE_NO_READ;
-         clone_program_space (pspace, inf->vfork_parent->pspace);
+         clone_program_space (pspace, vfork_parent->pspace);
          inf->pspace = pspace;
          inf->aspace = pspace->aspace;
 
-         resume_parent = inf->vfork_parent->pid;
-         /* Break the bonds.  */
-         inf->vfork_parent->vfork_child = NULL;
+         resume_parent = vfork_parent->pid;
        }
 
-      inf->vfork_parent = NULL;
-
       gdb_assert (current_program_space == inf->pspace);
 
       if (non_stop && resume_parent != -1)
@@ -1079,13 +1069,16 @@ show_follow_exec_mode_string (struct ui_file *file, int from_tty,
 /* EXEC_FILE_TARGET is assumed to be non-NULL.  */
 
 static void
-follow_exec (ptid_t ptid, char *exec_file_target)
+follow_exec (ptid_t ptid, const char *exec_file_target)
 {
-  struct thread_info *th, *tmp;
   struct inferior *inf = current_inferior ();
-  int pid = ptid_get_pid (ptid);
+  int pid = ptid.pid ();
   ptid_t process_ptid;
 
+  /* Switch terminal for any messages produced e.g. by
+     breakpoint_re_set.  */
+  target_terminal::ours_for_output ();
+
   /* 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
      momentary bp's, etc.
@@ -1104,7 +1097,7 @@ follow_exec (ptid_t ptid, char *exec_file_target)
 
      And, we DON'T want to call delete_breakpoints() here, since
      that may write the bp's "shadow contents" (the instruction
-     value that was overwritten witha TRAP instruction).  Since
+     value that was overwritten with a TRAP instruction).  Since
      we now have a new a.out, those shadow contents aren't valid.  */
 
   mark_breakpoints_out ();
@@ -1128,15 +1121,15 @@ follow_exec (ptid_t ptid, char *exec_file_target)
      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);
+  for (thread_info *th : all_threads_safe ())
+    if (th->ptid.pid () == pid && th->ptid != ptid)
+      delete_thread (th);
 
   /* 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 ();
+  thread_info *th = inferior_thread ();
   th->control.step_resume_breakpoint = NULL;
   th->control.exception_resume_breakpoint = NULL;
   th->control.single_step_breakpoints = NULL;
@@ -1151,16 +1144,14 @@ follow_exec (ptid_t ptid, char *exec_file_target)
   update_breakpoints_after_exec ();
 
   /* What is this a.out's name?  */
-  process_ptid = pid_to_ptid (pid);
+  process_ptid = ptid_t (pid);
   printf_unfiltered (_("%s is executing new program: %s\n"),
-                    target_pid_to_str (process_ptid),
+                    target_pid_to_str (process_ptid).c_str (),
                     exec_file_target);
 
   /* We've followed the inferior through an exec.  Therefore, the
      inferior has essentially been killed & reborn.  */
 
-  gdb_flush (gdb_stdout);
-
   breakpoint_init_inferior (inf_execd);
 
   gdb::unique_xmalloc_ptr<char> exec_file_host
@@ -1188,17 +1179,20 @@ follow_exec (ptid_t ptid, char *exec_file_target)
       /* The user wants to keep the old inferior and program spaces
         around.  Create a new fresh one, and switch to it.  */
 
-      /* Do exit processing for the original inferior before adding
-        the new inferior so we don't have two active inferiors with
-        the same ptid, which can confuse find_inferior_ptid.  */
-      exit_inferior_num_silent (current_inferior ()->num);
-
+      /* Do exit processing for the original inferior before setting the new
+        inferior's pid.  Having two inferiors with the same pid would confuse
+        find_inferior_p(t)id.  Transfer the terminal state and info from the
+         old to the new inferior.  */
       inf = add_inferior_with_spaces ();
+      swap_terminal_info (inf, current_inferior ());
+      exit_inferior_silent (current_inferior ());
+
       inf->pid = pid;
       target_follow_exec (inf, exec_file_target);
 
       set_current_inferior (inf);
       set_current_program_space (inf->pspace);
+      add_thread (ptid);
     }
   else
     {
@@ -1228,11 +1222,6 @@ follow_exec (ptid_t ptid, char *exec_file_target)
      registers.  */
   target_find_description ();
 
-  /* The add_thread call ends up reading registers, so do it after updating the
-     target description.  */
-  if (follow_exec_mode_string == follow_exec_mode_new)
-    add_thread (ptid);
-
   solib_create_inferior_hook (0);
 
   jit_inferior_created_hook ();
@@ -1433,7 +1422,7 @@ step_over_info_valid_p (void)
      register contents, and memory.  We use this in step n1.
 
    - gdbarch_displaced_step_fixup adjusts registers and memory after
-     we have successfuly single-stepped the instruction, to yield the
+     we have successfully single-stepped the instruction, to yield the
      same effect the instruction would have had if we had executed it
      at its original address.  We use this in step n3.
 
@@ -1478,126 +1467,46 @@ step_over_info_valid_p (void)
 
 displaced_step_closure::~displaced_step_closure () = default;
 
-/* Per-inferior displaced stepping state.  */
-struct displaced_step_inferior_state
-{
-  /* Pointer to next in linked list.  */
-  struct displaced_step_inferior_state *next;
-
-  /* The process this displaced step state refers to.  */
-  int pid;
-
-  /* True if preparing a displaced step ever failed.  If so, we won't
-     try displaced stepping for this inferior again.  */
-  int failed_before;
-
-  /* If this is not null_ptid, this is the thread carrying out a
-     displaced single-step in process PID.  This thread's state will
-     require fixing up once it has completed its step.  */
-  ptid_t step_ptid;
-
-  /* The architecture the thread had when we stepped it.  */
-  struct gdbarch *step_gdbarch;
-
-  /* The closure provided gdbarch_displaced_step_copy_insn, to be used
-     for post-step cleanup.  */
-  struct displaced_step_closure *step_closure;
-
-  /* The address of the original instruction, and the copy we
-     made.  */
-  CORE_ADDR step_original, step_copy;
-
-  /* Saved contents of copy area.  */
-  gdb_byte *step_saved_copy;
-};
-
-/* The list of states of processes involved in displaced stepping
-   presently.  */
-static struct displaced_step_inferior_state *displaced_step_inferior_states;
-
 /* Get the displaced stepping state of process PID.  */
 
-static struct displaced_step_inferior_state *
-get_displaced_stepping_state (int pid)
+static displaced_step_inferior_state *
+get_displaced_stepping_state (inferior *inf)
 {
-  struct displaced_step_inferior_state *state;
-
-  for (state = displaced_step_inferior_states;
-       state != NULL;
-       state = state->next)
-    if (state->pid == pid)
-      return state;
-
-  return NULL;
+  return &inf->displaced_step_state;
 }
 
 /* Returns true if any inferior has a thread doing a displaced
    step.  */
 
-static int
-displaced_step_in_progress_any_inferior (void)
+static bool
+displaced_step_in_progress_any_inferior ()
 {
-  struct displaced_step_inferior_state *state;
-
-  for (state = displaced_step_inferior_states;
-       state != NULL;
-       state = state->next)
-    if (!ptid_equal (state->step_ptid, null_ptid))
-      return 1;
+  for (inferior *i : all_inferiors ())
+    {
+      if (i->displaced_step_state.step_thread != nullptr)
+       return true;
+    }
 
-  return 0;
+  return false;
 }
 
 /* Return true if thread represented by PTID is doing a displaced
    step.  */
 
 static int
-displaced_step_in_progress_thread (ptid_t ptid)
+displaced_step_in_progress_thread (thread_info *thread)
 {
-  struct displaced_step_inferior_state *displaced;
-
-  gdb_assert (!ptid_equal (ptid, null_ptid));
+  gdb_assert (thread != NULL);
 
-  displaced = get_displaced_stepping_state (ptid_get_pid (ptid));
-
-  return (displaced != NULL && ptid_equal (displaced->step_ptid, ptid));
+  return get_displaced_stepping_state (thread->inf)->step_thread == thread;
 }
 
 /* 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.  */
-
-static struct displaced_step_inferior_state *
-add_displaced_stepping_state (int pid)
+displaced_step_in_progress (inferior *inf)
 {
-  struct displaced_step_inferior_state *state;
-
-  for (state = displaced_step_inferior_states;
-       state != NULL;
-       state = state->next)
-    if (state->pid == pid)
-      return state;
-
-  state = XCNEW (struct displaced_step_inferior_state);
-  state->pid = pid;
-  state->next = displaced_step_inferior_states;
-  displaced_step_inferior_states = state;
-
-  return state;
+  return get_displaced_stepping_state (inf)->step_thread != nullptr;
 }
 
 /* If inferior is in displaced stepping, and ADDR equals to starting address
@@ -1607,46 +1516,21 @@ add_displaced_stepping_state (int pid)
 struct displaced_step_closure*
 get_displaced_step_closure_by_addr (CORE_ADDR addr)
 {
-  struct displaced_step_inferior_state *displaced
-    = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
+  displaced_step_inferior_state *displaced
+    = get_displaced_stepping_state (current_inferior ());
 
   /* If checking the mode of displaced instruction in copy area.  */
-  if (displaced && !ptid_equal (displaced->step_ptid, null_ptid)
-     && (displaced->step_copy == addr))
+  if (displaced->step_thread != nullptr
+      && displaced->step_copy == addr)
     return displaced->step_closure;
 
   return NULL;
 }
 
-/* Remove the displaced stepping state of process PID.  */
-
-static void
-remove_displaced_stepping_state (int pid)
-{
-  struct displaced_step_inferior_state *it, **prev_next_p;
-
-  gdb_assert (pid != 0);
-
-  it = displaced_step_inferior_states;
-  prev_next_p = &displaced_step_inferior_states;
-  while (it)
-    {
-      if (it->pid == pid)
-       {
-         *prev_next_p = it->next;
-         xfree (it);
-         return;
-       }
-
-      prev_next_p = &it->next;
-      it = *prev_next_p;
-    }
-}
-
 static void
 infrun_inferior_exit (struct inferior *inf)
 {
-  remove_displaced_stepping_state (inf->pid);
+  inf->displaced_step_state.reset ();
 }
 
 /* If ON, and the architecture supports it, GDB will use displaced
@@ -1681,19 +1565,17 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
 static int
 use_displaced_stepping (struct thread_info *tp)
 {
-  struct regcache *regcache = get_thread_regcache (tp->ptid);
+  struct regcache *regcache = get_thread_regcache (tp);
   struct gdbarch *gdbarch = regcache->arch ();
-  struct displaced_step_inferior_state *displaced_state;
-
-  displaced_state = get_displaced_stepping_state (ptid_get_pid (tp->ptid));
+  displaced_step_inferior_state *displaced_state
+    = get_displaced_stepping_state (tp->inf);
 
   return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO
            && target_is_non_stop_p ())
           || can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
          && gdbarch_displaced_step_copy_insn_p (gdbarch)
          && find_record_target () == NULL
-         && (displaced_state == NULL
-             || !displaced_state->failed_before));
+         && !displaced_state->failed_before);
 }
 
 /* Clean out any stray displaced stepping state.  */
@@ -1701,20 +1583,15 @@ static void
 displaced_step_clear (struct displaced_step_inferior_state *displaced)
 {
   /* Indicate that there is no cleanup pending.  */
-  displaced->step_ptid = null_ptid;
+  displaced->step_thread = nullptr;
 
   delete displaced->step_closure;
   displaced->step_closure = NULL;
 }
 
-static void
-displaced_step_clear_cleanup (void *arg)
-{
-  struct displaced_step_inferior_state *state
-    = (struct displaced_step_inferior_state *) arg;
-
-  displaced_step_clear (state);
-}
+/* A cleanup that wraps displaced_step_clear.  */
+using displaced_step_clear_cleanup
+  = FORWARD_SCOPE_EXIT (displaced_step_clear);
 
 /* Dump LEN bytes at BUF in hex to FILE, followed by a newline.  */
 void
@@ -1746,17 +1623,14 @@ displaced_step_dump_bytes (struct ui_file *file,
    if this instruction can't be displaced stepped.  */
 
 static int
-displaced_step_prepare_throw (ptid_t ptid)
+displaced_step_prepare_throw (thread_info *tp)
 {
-  struct cleanup *ignore_cleanups;
-  struct thread_info *tp = find_thread_ptid (ptid);
-  struct regcache *regcache = get_thread_regcache (ptid);
+  regcache *regcache = get_thread_regcache (tp);
   struct gdbarch *gdbarch = regcache->arch ();
   const address_space *aspace = regcache->aspace ();
   CORE_ADDR original, copy;
   ULONGEST len;
   struct displaced_step_closure *closure;
-  struct displaced_step_inferior_state *displaced;
   int status;
 
   /* We should never reach this function if the architecture does not
@@ -1775,9 +1649,10 @@ displaced_step_prepare_throw (ptid_t ptid)
   /* We have to displaced step one thread at a time, as we only have
      access to a single scratch space per inferior.  */
 
-  displaced = add_displaced_stepping_state (ptid_get_pid (ptid));
+  displaced_step_inferior_state *displaced
+    = get_displaced_stepping_state (tp->inf);
 
-  if (!ptid_equal (displaced->step_ptid, null_ptid))
+  if (displaced->step_thread != nullptr)
     {
       /* Already waiting for a displaced step to finish.  Defer this
         request and place in queue.  */
@@ -1785,7 +1660,7 @@ displaced_step_prepare_throw (ptid_t ptid)
       if (debug_displaced)
        fprintf_unfiltered (gdb_stdlog,
                            "displaced: deferring step of %s\n",
-                           target_pid_to_str (ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
 
       thread_step_over_chain_enqueue (tp);
       return 0;
@@ -1795,13 +1670,14 @@ displaced_step_prepare_throw (ptid_t ptid)
       if (debug_displaced)
        fprintf_unfiltered (gdb_stdlog,
                            "displaced: stepping %s now\n",
-                           target_pid_to_str (ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
     }
 
   displaced_step_clear (displaced);
 
-  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
-  inferior_ptid = ptid;
+  scoped_restore_current_thread restore_thread;
+
+  switch_to_thread (tp);
 
   original = regcache_read_pc (regcache);
 
@@ -1830,10 +1706,8 @@ displaced_step_prepare_throw (ptid_t ptid)
     }
 
   /* Save the original contents of the copy area.  */
-  displaced->step_saved_copy = (gdb_byte *) xmalloc (len);
-  ignore_cleanups = make_cleanup (free_current_contents,
-                                 &displaced->step_saved_copy);
-  status = target_read_memory (copy, displaced->step_saved_copy, len);
+  displaced->step_saved_copy.resize (len);
+  status = target_read_memory (copy, displaced->step_saved_copy.data (), len);
   if (status != 0)
     throw_error (MEMORY_ERROR,
                 _("Error accessing memory address %s (%s) for "
@@ -1844,7 +1718,7 @@ displaced_step_prepare_throw (ptid_t ptid)
       fprintf_unfiltered (gdb_stdlog, "displaced: saved %s: ",
                          paddress (gdbarch, copy));
       displaced_step_dump_bytes (gdb_stdlog,
-                                displaced->step_saved_copy,
+                                displaced->step_saved_copy.data (),
                                 len);
     };
 
@@ -1855,24 +1729,25 @@ displaced_step_prepare_throw (ptid_t ptid)
       /* The architecture doesn't know how or want to displaced step
         this instruction or instruction sequence.  Fallback to
         stepping over the breakpoint in-line.  */
-      do_cleanups (ignore_cleanups);
       return -1;
     }
 
   /* Save the information we need to fix things up if the step
      succeeds.  */
-  displaced->step_ptid = ptid;
+  displaced->step_thread = tp;
   displaced->step_gdbarch = gdbarch;
   displaced->step_closure = closure;
   displaced->step_original = original;
   displaced->step_copy = copy;
 
-  make_cleanup (displaced_step_clear_cleanup, displaced);
+  {
+    displaced_step_clear_cleanup cleanup (displaced);
 
-  /* Resume execution at the copy.  */
-  regcache_write_pc (regcache, copy);
+    /* Resume execution at the copy.  */
+    regcache_write_pc (regcache, copy);
 
-  discard_cleanups (ignore_cleanups);
+    cleanup.release ();
+  }
 
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to %s\n",
@@ -1885,27 +1760,27 @@ displaced_step_prepare_throw (ptid_t ptid)
    attempts at displaced stepping if we get a memory error.  */
 
 static int
-displaced_step_prepare (ptid_t ptid)
+displaced_step_prepare (thread_info *thread)
 {
   int prepared = -1;
 
-  TRY
+  try
     {
-      prepared = displaced_step_prepare_throw (ptid);
+      prepared = displaced_step_prepare_throw (thread);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       struct displaced_step_inferior_state *displaced_state;
 
       if (ex.error != MEMORY_ERROR
          && ex.error != NOT_SUPPORTED_ERROR)
-       throw_exception (ex);
+       throw;
 
       if (debug_infrun)
        {
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: disabling displaced stepping: %s\n",
-                             ex.message);
+                             ex.what ());
        }
 
       /* Be verbose if "set displaced-stepping" is "on", silent if
@@ -1913,15 +1788,14 @@ displaced_step_prepare (ptid_t ptid)
       if (can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
        {
          warning (_("disabling displaced stepping: %s"),
-                  ex.message);
+                  ex.what ());
        }
 
       /* Disable further displaced stepping attempts.  */
       displaced_state
-       = get_displaced_stepping_state (ptid_get_pid (ptid));
+       = get_displaced_stepping_state (thread->inf);
       displaced_state->failed_before = 1;
     }
-  END_CATCH
 
   return prepared;
 }
@@ -1945,10 +1819,10 @@ displaced_step_restore (struct displaced_step_inferior_state *displaced,
   ULONGEST len = gdbarch_max_insn_length (displaced->step_gdbarch);
 
   write_memory_ptid (ptid, displaced->step_copy,
-                    displaced->step_saved_copy, len);
+                    displaced->step_saved_copy.data (), len);
   if (debug_displaced)
     fprintf_unfiltered (gdb_stdlog, "displaced: restored %s %s\n",
-                       target_pid_to_str (ptid),
+                       target_pid_to_str (ptid).c_str (),
                        paddress (displaced->step_gdbarch,
                                  displaced->step_copy));
 }
@@ -1960,30 +1834,24 @@ displaced_step_restore (struct displaced_step_inferior_state *displaced,
    -1.  If the thread wasn't displaced stepping, return 0.  */
 
 static int
-displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
+displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
 {
-  struct cleanup *old_cleanups;
   struct displaced_step_inferior_state *displaced
-    = get_displaced_stepping_state (ptid_get_pid (event_ptid));
+    = get_displaced_stepping_state (event_thread->inf);
   int ret;
 
-  /* Was any thread of this process doing a displaced step?  */
-  if (displaced == NULL)
-    return 0;
-
-  /* Was this event for the pid we displaced?  */
-  if (ptid_equal (displaced->step_ptid, null_ptid)
-      || ! ptid_equal (displaced->step_ptid, event_ptid))
+  /* Was this event for the thread we displaced?  */
+  if (displaced->step_thread != event_thread)
     return 0;
 
-  old_cleanups = make_cleanup (displaced_step_clear_cleanup, displaced);
+  displaced_step_clear_cleanup cleanup (displaced);
 
-  displaced_step_restore (displaced, displaced->step_ptid);
+  displaced_step_restore (displaced, displaced->step_thread->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);
+  switch_to_thread (event_thread);
 
   /* Did the instruction complete successfully?  */
   if (signal == GDB_SIGNAL_TRAP
@@ -1996,14 +1864,14 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
                                     displaced->step_closure,
                                     displaced->step_original,
                                     displaced->step_copy,
-                                    get_thread_regcache (displaced->step_ptid));
+                                    get_thread_regcache (displaced->step_thread));
       ret = 1;
     }
   else
     {
       /* Since the instruction didn't complete, all we can do is
          relocate the PC.  */
-      struct regcache *regcache = get_thread_regcache (event_ptid);
+      struct regcache *regcache = get_thread_regcache (event_thread);
       CORE_ADDR pc = regcache_read_pc (regcache);
 
       pc = displaced->step_original + (pc - displaced->step_copy);
@@ -2011,10 +1879,6 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
       ret = -1;
     }
 
-  do_cleanups (old_cleanups);
-
-  displaced->step_ptid = null_ptid;
-
   return ret;
 }
 
@@ -2082,7 +1946,7 @@ start_step_over (void)
 
       /* If this inferior already has a displaced step in process,
         don't start a new one.  */
-      if (displaced_step_in_progress (ptid_get_pid (tp->ptid)))
+      if (displaced_step_in_progress (tp->inf))
        continue;
 
       step_what = thread_still_needs_step_over (tp);
@@ -2112,7 +1976,7 @@ start_step_over (void)
          internal_error (__FILE__, __LINE__,
                          "[%s] has inconsistent state: "
                          "trap_expected=%d, resumed=%d, executing=%d\n",
-                         target_pid_to_str (tp->ptid),
+                         target_pid_to_str (tp->ptid).c_str (),
                          tp->control.trap_expected,
                          tp->resumed,
                          tp->executing);
@@ -2121,7 +1985,7 @@ start_step_over (void)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resuming [%s] for step-over\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
 
       /* keep_going_pass_signal skips the step-over if the breakpoint
         is no longer inserted.  In all-stop, we want to keep looking
@@ -2132,7 +1996,7 @@ start_step_over (void)
       if (!target_is_non_stop_p () && !step_what)
        continue;
 
-      switch_to_thread (tp->ptid);
+      switch_to_thread (tp);
       reset_ecs (ecs, tp);
       keep_going_pass_signal (ecs);
 
@@ -2175,18 +2039,8 @@ start_step_over (void)
 static void
 infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
 {
-  struct displaced_step_inferior_state *displaced;
-
-  if (ptid_equal (inferior_ptid, old_ptid))
+  if (inferior_ptid == old_ptid)
     inferior_ptid = new_ptid;
-
-  for (displaced = displaced_step_inferior_states;
-       displaced;
-       displaced = displaced->next)
-    {
-      if (ptid_equal (displaced->step_ptid, old_ptid))
-       displaced->step_ptid = new_ptid;
-    }
 }
 
 \f
@@ -2226,7 +2080,7 @@ set_schedlock_func (const char *args, int from_tty, struct cmd_list_element *c)
 /* True if execution commands resume all threads of all processes by
    default; otherwise, resume only threads of the current inferior
    process.  */
-int sched_multi = 0;
+bool sched_multi = false;
 
 /* Try to setup for software single stepping over the specified location.
    Return 1 if target_resume() should use hardware single step.
@@ -2277,7 +2131,7 @@ user_visible_resume_ptid (int step)
     {
       /* Resume all threads of the current process (and none of other
         processes).  */
-      resume_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+      resume_ptid = ptid_t (inferior_ptid.pid ());
     }
   else
     {
@@ -2344,10 +2198,10 @@ do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
        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);
+      || displaced_step_in_progress (tp->inf))
+    target_pass_signals ({});
   else
-    target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+    target_pass_signals (signal_pass);
 
   target_resume (resume_ptid, step, sig);
 
@@ -2390,7 +2244,8 @@ resume_1 (enum gdb_signal sig)
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: resume: thread %s has pending wait "
                              "status %s (currently_stepping=%d).\n",
-                             target_pid_to_str (tp->ptid), statstr.c_str (),
+                             target_pid_to_str (tp->ptid).c_str (),
+                             statstr.c_str (),
                              currently_stepping (tp));
        }
 
@@ -2402,13 +2257,18 @@ resume_1 (enum gdb_signal sig)
       if (sig != GDB_SIGNAL_0)
        {
          warning (_("Couldn't deliver signal %s to %s."),
-                  gdb_signal_to_name (sig), target_pid_to_str (tp->ptid));
+                  gdb_signal_to_name (sig),
+                  target_pid_to_str (tp->ptid).c_str ());
        }
 
       tp->suspend.stop_signal = GDB_SIGNAL_0;
 
       if (target_can_async_p ())
-       target_async (1);
+       {
+         target_async (1);
+         /* Tell the event loop we have an event to process. */
+         mark_async_event_handler (infrun_async_inferior_event_token);
+       }
       return;
     }
 
@@ -2442,7 +2302,7 @@ resume_1 (enum gdb_signal sig)
                        "trap_expected=%d, current thread [%s] at %s\n",
                        step, gdb_signal_to_symbol_string (sig),
                        tp->control.trap_expected,
-                       target_pid_to_str (inferior_ptid),
+                       target_pid_to_str (inferior_ptid).c_str (),
                        paddress (gdbarch, pc));
 
   /* Normally, by the time we reach `resume', the breakpoints are either
@@ -2545,7 +2405,7 @@ resume_1 (enum gdb_signal sig)
       && sig == GDB_SIGNAL_0
       && !current_inferior ()->waiting_for_vfork_done)
     {
-      int prepared = displaced_step_prepare (inferior_ptid);
+      int prepared = displaced_step_prepare (tp);
 
       if (prepared == 0)
        {
@@ -2576,9 +2436,9 @@ resume_1 (enum gdb_signal sig)
 
          /* Update pc to reflect the new address from which we will
             execute instructions due to displaced stepping.  */
-         pc = regcache_read_pc (get_thread_regcache (inferior_ptid));
+         pc = regcache_read_pc (get_thread_regcache (tp));
 
-         displaced = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
+         displaced = get_displaced_stepping_state (tp->inf);
          step = gdbarch_displaced_step_hw_singlestep (gdbarch,
                                                       displaced->step_closure);
        }
@@ -2691,7 +2551,7 @@ resume_1 (enum gdb_signal sig)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: resume: [%s] stepped breakpoint\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
 
       tp->stepped_breakpoint = 1;
 
@@ -2707,7 +2567,7 @@ resume_1 (enum gdb_signal sig)
       && use_displaced_stepping (tp)
       && !step_over_info_valid_p ())
     {
-      struct regcache *resume_regcache = get_thread_regcache (tp->ptid);
+      struct regcache *resume_regcache = get_thread_regcache (tp);
       struct gdbarch *resume_gdbarch = resume_regcache->arch ();
       CORE_ADDR actual_pc = regcache_read_pc (resume_regcache);
       gdb_byte buf[4];
@@ -2736,14 +2596,14 @@ resume_1 (enum gdb_signal sig)
    (GDB_SIGNAL_0 for none).  This is a wrapper around 'resume_1' that
    rolls back state on error.  */
 
-void
+static void
 resume (gdb_signal sig)
 {
-  TRY
+  try
     {
       resume_1 (sig);
     }
-  CATCH (ex, RETURN_MASK_ALL)
+  catch (const gdb_exception &ex)
     {
       /* If resuming is being aborted for any reason, delete any
         single-step breakpoint resume_1 may have created, to avoid
@@ -2752,9 +2612,8 @@ resume (gdb_signal sig)
         we're running in non-stop mode.  */
       if (inferior_ptid != null_ptid)
        delete_single_step_breakpoints (inferior_thread ());
-      throw_exception (ex);
+      throw;
     }
-  END_CATCH
 }
 
 \f
@@ -2796,7 +2655,7 @@ clear_proceed_status_thread (struct thread_info *tp)
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog,
                        "infrun: clear_proceed_status_thread (%s)\n",
-                       target_pid_to_str (tp->ptid));
+                       target_pid_to_str (tp->ptid).c_str ());
 
   /* If we're starting a new sequence, then the previous finished
      single-step is no longer relevant.  */
@@ -2809,7 +2668,7 @@ clear_proceed_status_thread (struct thread_info *tp)
                                "infrun: clear_proceed_status: pending "
                                "event of %s was a finished step. "
                                "Discarding.\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          tp->suspend.waitstatus_pending_p = 0;
          tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
@@ -2823,7 +2682,8 @@ clear_proceed_status_thread (struct thread_info *tp)
                              "infrun: clear_proceed_status_thread: thread %s "
                              "has pending wait status %s "
                              "(currently_stepping=%d).\n",
-                             target_pid_to_str (tp->ptid), statstr.c_str (),
+                             target_pid_to_str (tp->ptid).c_str (),
+                             statstr.c_str (),
                              currently_stepping (tp));
        }
     }
@@ -2833,7 +2693,7 @@ clear_proceed_status_thread (struct thread_info *tp)
   if (!signal_pass_state (tp->suspend.stop_signal))
     tp->suspend.stop_signal = GDB_SIGNAL_0;
 
-  thread_fsm_delete (tp->thread_fsm);
+  delete tp->thread_fsm;
   tp->thread_fsm = NULL;
 
   tp->control.trap_expected = 0;
@@ -2871,24 +2731,17 @@ clear_proceed_status (int step)
                                     execution_direction))
     target_record_stop_replaying ();
 
-  if (!non_stop)
+  if (!non_stop && inferior_ptid != null_ptid)
     {
-      struct thread_info *tp;
-      ptid_t resume_ptid;
-
-      resume_ptid = user_visible_resume_ptid (step);
+      ptid_t 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);
-       }
+      for (thread_info *tp : all_non_exited_threads (resume_ptid))
+       clear_proceed_status_thread (tp);
     }
 
-  if (!ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid != null_ptid)
     {
       struct inferior *inferior;
 
@@ -2915,7 +2768,7 @@ thread_still_needs_step_over_bp (struct thread_info *tp)
 {
   if (tp->stepping_over_breakpoint)
     {
-      struct regcache *regcache = get_thread_regcache (tp->ptid);
+      struct regcache *regcache = get_thread_regcache (tp);
 
       if (breakpoint_here_p (regcache->aspace (),
                             regcache_read_pc (regcache))
@@ -2964,12 +2817,8 @@ schedlock_applies (struct thread_info *tp)
 /* Basic routine for continuing the program in various fashions.
 
    ADDR is the address to resume at, or -1 for resume where stopped.
-   SIGGNAL is the signal to give it, or 0 for none,
-   or -1 for act according to how it stopped.
-   STEP is nonzero if should trap after one instruction.
-   -1 means return after that and print nothing.
-   You should probably set various step_... variables
-   before calling here, if you are stepping.
+   SIGGNAL is the signal to give it, or GDB_SIGNAL_0 for none,
+   or GDB_SIGNAL_DEFAULT for act according to how it stopped.
 
    You should call clear_proceed_status before calling proceed.  */
 
@@ -2978,7 +2827,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 {
   struct regcache *regcache;
   struct gdbarch *gdbarch;
-  struct thread_info *tp;
   CORE_ADDR pc;
   ptid_t resume_ptid;
   struct execution_control_state ecss;
@@ -3005,16 +2853,16 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
   const address_space *aspace = regcache->aspace ();
 
   pc = regcache_read_pc (regcache);
-  tp = inferior_thread ();
+  thread_info *cur_thr = inferior_thread ();
 
   /* Fill in with reasonable starting values.  */
-  init_thread_stepping_state (tp);
+  init_thread_stepping_state (cur_thr);
 
-  gdb_assert (!thread_is_in_step_over_chain (tp));
+  gdb_assert (!thread_is_in_step_over_chain (cur_thr));
 
   if (addr == (CORE_ADDR) -1)
     {
-      if (pc == stop_pc
+      if (pc == cur_thr->suspend.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,
@@ -3025,13 +2873,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
           Note, we don't do this in reverse, because we won't
           actually be executing the breakpoint insn anyway.
           We'll be (un-)executing the previous instruction.  */
-       tp->stepping_over_breakpoint = 1;
+       cur_thr->stepping_over_breakpoint = 1;
       else if (gdbarch_single_step_through_delay_p (gdbarch)
               && gdbarch_single_step_through_delay (gdbarch,
                                                     get_current_frame ()))
        /* We stepped onto an instruction that needs to be stepped
           again before re-inserting the breakpoint, do so.  */
-       tp->stepping_over_breakpoint = 1;
+       cur_thr->stepping_over_breakpoint = 1;
     }
   else
     {
@@ -3039,9 +2887,9 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
     }
 
   if (siggnal != GDB_SIGNAL_DEFAULT)
-    tp->suspend.stop_signal = siggnal;
+    cur_thr->suspend.stop_signal = siggnal;
 
-  resume_ptid = user_visible_resume_ptid (tp->control.stepping_command);
+  resume_ptid = user_visible_resume_ptid (cur_thr->control.stepping_command);
 
   /* If an exception is thrown from this point on, make sure to
      propagate GDB's knowledge of the executing state to the
@@ -3054,7 +2902,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
      threads in RESUME_PTID are now running.  Unless we're calling an
      inferior function, as in that case we pretend the inferior
      doesn't run at all.  */
-  if (!tp->control.in_infcall)
+  if (!cur_thr->control.in_infcall)
    set_running (resume_ptid, 1);
 
   if (debug_infrun)
@@ -3088,19 +2936,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 
   /* If scheduler locking applies, we can avoid iterating over all
      threads.  */
-  if (!non_stop && !schedlock_applies (tp))
+  if (!non_stop && !schedlock_applies (cur_thr))
     {
-      struct thread_info *current = tp;
-
-      ALL_NON_EXITED_THREADS (tp)
-        {
+      for (thread_info *tp : all_non_exited_threads (resume_ptid))
+       {
          /* Ignore the current thread here.  It's handled
             afterwards.  */
-         if (tp == current)
-           continue;
-
-         /* Ignore threads of processes we're not resuming.  */
-         if (!ptid_match (tp->ptid, resume_ptid))
+         if (tp == cur_thr)
            continue;
 
          if (!thread_still_needs_step_over (tp))
@@ -3111,25 +2953,23 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: need to step-over [%s] first\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          thread_step_over_chain_enqueue (tp);
        }
-
-      tp = current;
     }
 
   /* Enqueue the current thread last, so that we move all other
      threads over their breakpoints first.  */
-  if (tp->stepping_over_breakpoint)
-    thread_step_over_chain_enqueue (tp);
+  if (cur_thr->stepping_over_breakpoint)
+    thread_step_over_chain_enqueue (cur_thr);
 
   /* If the thread isn't started, we'll still need to set its prev_pc,
      so that switch_back_to_stepped_thread knows the thread hasn't
      advanced.  Must do this before resuming any thread, as in
      all-stop/remote, once we resume we can't send any other packet
      until the target stops again.  */
-  tp->prev_pc = regcache_read_pc (regcache);
+  cur_thr->prev_pc = regcache_read_pc (regcache);
 
   {
     scoped_restore save_defer_tc = make_scoped_defer_target_commit_resume ();
@@ -3151,18 +2991,14 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
       {
        /* In all-stop, but the target is always in non-stop mode.
           Start all other threads that are implicitly resumed too.  */
-       ALL_NON_EXITED_THREADS (tp)
+      for (thread_info *tp : all_non_exited_threads (resume_ptid))
         {
-         /* Ignore threads of processes we're not resuming.  */
-         if (!ptid_match (tp->ptid, resume_ptid))
-           continue;
-
          if (tp->resumed)
            {
              if (debug_infrun)
                fprintf_unfiltered (gdb_stdlog,
                                    "infrun: proceed: [%s] resumed\n",
-                                   target_pid_to_str (tp->ptid));
+                                   target_pid_to_str (tp->ptid).c_str ());
              gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
              continue;
            }
@@ -3172,27 +3008,27 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
              if (debug_infrun)
                fprintf_unfiltered (gdb_stdlog,
                                    "infrun: proceed: [%s] needs step-over\n",
-                                   target_pid_to_str (tp->ptid));
+                                   target_pid_to_str (tp->ptid).c_str ());
              continue;
            }
 
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: proceed: resuming %s\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          reset_ecs (ecs, tp);
-         switch_to_thread (tp->ptid);
+         switch_to_thread (tp);
          keep_going_pass_signal (ecs);
          if (!ecs->wait_some_more)
            error (_("Command aborted."));
        }
       }
-    else if (!tp->resumed && !thread_is_in_step_over_chain (tp))
+    else if (!cur_thr->resumed && !thread_is_in_step_over_chain (cur_thr))
       {
        /* The thread wasn't started, and isn't queued, run it now.  */
-       reset_ecs (ecs, tp);
-       switch_to_thread (tp->ptid);
+       reset_ecs (ecs, cur_thr);
+       switch_to_thread (cur_thr);
        keep_going_pass_signal (ecs);
        if (!ecs->wait_some_more)
          error (_("Command aborted."));
@@ -3240,7 +3076,7 @@ start_remote (int from_tty)
   /* Now that the inferior has stopped, do any bookkeeping like
      loading shared libraries.  We want to do this before normal_stop,
      so that the displayed frame is up to date.  */
-  post_create_inferior (&current_target, from_tty);
+  post_create_inferior (current_top_target (), from_tty);
 
   normal_stop ();
 }
@@ -3259,9 +3095,6 @@ init_wait_for_inferior (void)
   target_last_wait_ptid = minus_one_ptid;
 
   previous_inferior_ptid = inferior_ptid;
-
-  /* Discard any skipped inlined frames.  */
-  clear_inline_frame_state (minus_one_ptid);
 }
 
 \f
@@ -3289,59 +3122,56 @@ static int switch_back_to_stepped_thread (struct execution_control_state *ecs);
 static void
 infrun_thread_stop_requested (ptid_t ptid)
 {
-  struct thread_info *tp;
-
   /* PTID was requested to stop.  If the thread was already stopped,
      but the user/frontend doesn't know about that yet (e.g., the
      thread had been temporarily paused for some step-over), set up
      for reporting the stop now.  */
-  ALL_NON_EXITED_THREADS (tp)
-    if (ptid_match (tp->ptid, ptid))
-      {
-       if (tp->state != THREAD_RUNNING)
-         continue;
-       if (tp->executing)
-         continue;
+  for (thread_info *tp : all_threads (ptid))
+    {
+      if (tp->state != THREAD_RUNNING)
+       continue;
+      if (tp->executing)
+       continue;
 
-       /* Remove matching threads from the step-over queue, so
-          start_step_over doesn't try to resume them
-          automatically.  */
-       if (thread_is_in_step_over_chain (tp))
-         thread_step_over_chain_remove (tp);
-
-       /* If the thread is stopped, but the user/frontend doesn't
-          know about that yet, queue a pending event, as if the
-          thread had just stopped now.  Unless the thread already had
-          a pending event.  */
-       if (!tp->suspend.waitstatus_pending_p)
-         {
-           tp->suspend.waitstatus_pending_p = 1;
-           tp->suspend.waitstatus.kind = TARGET_WAITKIND_STOPPED;
-           tp->suspend.waitstatus.value.sig = GDB_SIGNAL_0;
-         }
+      /* Remove matching threads from the step-over queue, so
+        start_step_over doesn't try to resume them
+        automatically.  */
+      if (thread_is_in_step_over_chain (tp))
+       thread_step_over_chain_remove (tp);
+
+      /* If the thread is stopped, but the user/frontend doesn't
+        know about that yet, queue a pending event, as if the
+        thread had just stopped now.  Unless the thread already had
+        a pending event.  */
+      if (!tp->suspend.waitstatus_pending_p)
+       {
+         tp->suspend.waitstatus_pending_p = 1;
+         tp->suspend.waitstatus.kind = TARGET_WAITKIND_STOPPED;
+         tp->suspend.waitstatus.value.sig = GDB_SIGNAL_0;
+       }
 
-       /* Clear the inline-frame state, since we're re-processing the
-          stop.  */
-       clear_inline_frame_state (tp->ptid);
+      /* Clear the inline-frame state, since we're re-processing the
+        stop.  */
+      clear_inline_frame_state (tp->ptid);
 
-       /* If this thread was paused because some other thread was
-          doing an inline-step over, let that finish first.  Once
-          that happens, we'll restart all threads and consume pending
-          stop events then.  */
-       if (step_over_info_valid_p ())
-         continue;
+      /* If this thread was paused because some other thread was
+        doing an inline-step over, let that finish first.  Once
+        that happens, we'll restart all threads and consume pending
+        stop events then.  */
+      if (step_over_info_valid_p ())
+       continue;
 
-       /* Otherwise we can process the (new) pending event now.  Set
-          it so this pending event is considered by
-          do_target_wait.  */
-       tp->resumed = 1;
-      }
+      /* Otherwise we can process the (new) pending event now.  Set
+        it so this pending event is considered by
+        do_target_wait.  */
+      tp->resumed = 1;
+    }
 }
 
 static void
 infrun_thread_thread_exit (struct thread_info *tp, int silent)
 {
-  if (ptid_equal (target_last_wait_ptid, tp->ptid))
+  if (target_last_wait_ptid == tp->ptid)
     nullify_last_target_wait_ptid ();
 }
 
@@ -3366,7 +3196,7 @@ typedef void (*for_each_just_stopped_thread_callback_func)
 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))
+  if (!target_has_execution || inferior_ptid == null_ptid)
     return;
 
   if (target_is_non_stop_p ())
@@ -3376,13 +3206,9 @@ for_each_just_stopped_thread (for_each_just_stopped_thread_callback_func func)
     }
   else
     {
-      struct thread_info *tp;
-
       /* In all-stop mode, all threads have stopped.  */
-      ALL_NON_EXITED_THREADS (tp)
-        {
-         func (tp);
-       }
+      for (thread_info *tp : all_non_exited_threads ())
+       func (tp);
     }
 }
 
@@ -3404,14 +3230,6 @@ delete_just_stopped_threads_single_step_breakpoints (void)
   for_each_just_stopped_thread (delete_single_step_breakpoints);
 }
 
-/* A cleanup wrapper.  */
-
-static void
-delete_just_stopped_threads_infrun_breakpoints_cleanup (void *arg)
-{
-  delete_just_stopped_threads_infrun_breakpoints ();
-}
-
 /* See infrun.h.  */
 
 void
@@ -3427,17 +3245,17 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
      is set.  */
 
   stb.printf ("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)
-    stb.printf (" [%s]", target_pid_to_str (waiton_ptid));
+             waiton_ptid.pid (),
+             waiton_ptid.lwp (),
+             waiton_ptid.tid ());
+  if (waiton_ptid.pid () != -1)
+    stb.printf (" [%s]", target_pid_to_str (waiton_ptid).c_str ());
   stb.printf (", status) =\n");
   stb.printf ("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));
+             result_ptid.pid (),
+             result_ptid.lwp (),
+             result_ptid.tid (),
+             target_pid_to_str (result_ptid).c_str ());
   stb.printf ("infrun:   %s\n", status_string.c_str ());
 
   /* This uses %s in part to handle %'s in the text, but also to avoid
@@ -3451,24 +3269,26 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
 static struct thread_info *
 random_pending_event_thread (ptid_t waiton_ptid)
 {
-  struct thread_info *event_tp;
   int num_events = 0;
-  int random_selector;
+
+  auto has_event = [] (thread_info *tp)
+    {
+      return (tp->resumed
+             && tp->suspend.waitstatus_pending_p);
+    };
 
   /* First see how many events we have.  Count only resumed threads
      that have an event pending.  */
-  ALL_NON_EXITED_THREADS (event_tp)
-    if (ptid_match (event_tp->ptid, waiton_ptid)
-       && event_tp->resumed
-       && event_tp->suspend.waitstatus_pending_p)
+  for (thread_info *tp : all_non_exited_threads (waiton_ptid))
+    if (has_event (tp))
       num_events++;
 
   if (num_events == 0)
     return NULL;
 
   /* Now randomly pick a thread out of those that have had events.  */
-  random_selector = (int)
-    ((num_events * (double) rand ()) / (RAND_MAX + 1.0));
+  int random_selector = (int) ((num_events * (double) rand ())
+                              / (RAND_MAX + 1.0));
 
   if (debug_infrun && num_events > 1)
     fprintf_unfiltered (gdb_stdlog,
@@ -3476,14 +3296,12 @@ random_pending_event_thread (ptid_t waiton_ptid)
                        num_events, random_selector);
 
   /* Select the Nth thread that has had an event.  */
-  ALL_NON_EXITED_THREADS (event_tp)
-    if (ptid_match (event_tp->ptid, waiton_ptid)
-       && event_tp->resumed
-       && event_tp->suspend.waitstatus_pending_p)
+  for (thread_info *tp : all_non_exited_threads (waiton_ptid))
+    if (has_event (tp))
       if (random_selector-- == 0)
-       break;
+       return tp;
 
-  return event_tp;
+  gdb_assert_not_reached ("event thread not found");
 }
 
 /* Wrapper for target_wait that first checks whether threads have
@@ -3498,7 +3316,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
 
   /* First check if there is a resumed thread with a wait status
      pending.  */
-  if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
+  if (ptid == minus_one_ptid || ptid.is_pid ())
     {
       tp = random_pending_event_thread (ptid);
     }
@@ -3507,7 +3325,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: Waiting for specific thread %s.\n",
-                           target_pid_to_str (ptid));
+                           target_pid_to_str (ptid).c_str ());
 
       /* We have a specific thread to check.  */
       tp = find_thread_ptid (ptid);
@@ -3520,7 +3338,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
       && (tp->suspend.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
          || tp->suspend.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT))
     {
-      struct regcache *regcache = get_thread_regcache (tp->ptid);
+      struct regcache *regcache = get_thread_regcache (tp);
       struct gdbarch *gdbarch = regcache->arch ();
       CORE_ADDR pc;
       int discard = 0;
@@ -3532,8 +3350,8 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: PC of %s changed.  was=%s, now=%s\n",
-                               target_pid_to_str (tp->ptid),
-                               paddress (gdbarch, tp->prev_pc),
+                               target_pid_to_str (tp->ptid).c_str (),
+                               paddress (gdbarch, tp->suspend.stop_pc),
                                paddress (gdbarch, pc));
          discard = 1;
        }
@@ -3542,7 +3360,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: previous breakpoint of %s, at %s gone\n",
-                               target_pid_to_str (tp->ptid),
+                               target_pid_to_str (tp->ptid).c_str (),
                                paddress (gdbarch, pc));
 
          discard = 1;
@@ -3553,7 +3371,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: pending event of %s cancelled.\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
 
          tp->suspend.waitstatus.kind = TARGET_WAITKIND_SPURIOUS;
          tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
@@ -3570,7 +3388,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          fprintf_unfiltered (gdb_stdlog,
                              "infrun: Using pending wait status %s for %s.\n",
                              statstr.c_str (),
-                             target_pid_to_str (tp->ptid));
+                             target_pid_to_str (tp->ptid).c_str ());
        }
 
       /* Now that we've selected our final event LWP, un-adjust its PC
@@ -3583,7 +3401,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          struct gdbarch *gdbarch;
          int decr_pc;
 
-         regcache = get_thread_regcache (tp->ptid);
+         regcache = get_thread_regcache (tp);
          gdbarch = regcache->arch ();
 
          decr_pc = gdbarch_decr_pc_after_break (gdbarch);
@@ -3626,14 +3444,13 @@ void
 prepare_for_detach (void)
 {
   struct inferior *inf = current_inferior ();
-  ptid_t pid_ptid = pid_to_ptid (inf->pid);
-  struct displaced_step_inferior_state *displaced;
+  ptid_t pid_ptid = ptid_t (inf->pid);
 
-  displaced = get_displaced_stepping_state (inf->pid);
+  displaced_step_inferior_state *displaced = get_displaced_stepping_state (inf);
 
   /* Is any thread of this process displaced stepping?  If not,
      there's nothing else to do.  */
-  if (displaced == NULL || ptid_equal (displaced->step_ptid, null_ptid))
+  if (displaced->step_thread == nullptr)
     return;
 
   if (debug_infrun)
@@ -3642,7 +3459,7 @@ prepare_for_detach (void)
 
   scoped_restore restore_detaching = make_scoped_restore (&inf->detaching, true);
 
-  while (!ptid_equal (displaced->step_ptid, null_ptid))
+  while (displaced->step_thread != nullptr)
     {
       struct execution_control_state ecss;
       struct execution_control_state *ecs;
@@ -3696,15 +3513,11 @@ prepare_for_detach (void)
 void
 wait_for_inferior (void)
 {
-  struct cleanup *old_cleanups;
-
   if (debug_infrun)
     fprintf_unfiltered
       (gdb_stdlog, "infrun: wait_for_inferior ()\n");
 
-  old_cleanups
-    = make_cleanup (delete_just_stopped_threads_infrun_breakpoints_cleanup,
-                   NULL);
+  SCOPE_EXIT { delete_just_stopped_threads_infrun_breakpoints (); };
 
   /* If an error happens while handling the event, propagate GDB's
      knowledge of the executing state to the frontend/user running
@@ -3741,8 +3554,6 @@ wait_for_inferior (void)
 
   /* No error, don't finish the state yet.  */
   finish_state.release ();
-
-  do_cleanups (old_cleanups);
 }
 
 /* Cleanup that reinstalls the readline callback handler, if the
@@ -3756,7 +3567,7 @@ wait_for_inferior (void)
    input.  */
 
 static void
-reinstall_readline_callback_handler_cleanup (void *arg)
+reinstall_readline_callback_handler_cleanup ()
 {
   struct ui *ui = current_ui;
 
@@ -3780,26 +3591,25 @@ reinstall_readline_callback_handler_cleanup (void *arg)
 static void
 clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs)
 {
-  struct thread_info *thr = ecs->event_thread;
-
-  if (thr != NULL && thr->thread_fsm != NULL)
-    thread_fsm_clean_up (thr->thread_fsm, thr);
+  if (ecs->event_thread != NULL
+      && ecs->event_thread->thread_fsm != NULL)
+    ecs->event_thread->thread_fsm->clean_up (ecs->event_thread);
 
   if (!non_stop)
     {
-      ALL_NON_EXITED_THREADS (thr)
+      for (thread_info *thr : all_non_exited_threads ())
         {
          if (thr->thread_fsm == NULL)
            continue;
          if (thr == ecs->event_thread)
            continue;
 
-         switch_to_thread (thr->ptid);
-         thread_fsm_clean_up (thr->thread_fsm, thr);
+         switch_to_thread (thr);
+         thr->thread_fsm->clean_up (thr);
        }
 
       if (ecs->event_thread != NULL)
-       switch_to_thread (ecs->event_thread->ptid);
+       switch_to_thread (ecs->event_thread);
     }
 }
 
@@ -3858,7 +3668,6 @@ fetch_inferior_event (void *client_data)
 {
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   int cmd_done = 0;
   ptid_t waiton_ptid = minus_one_ptid;
 
@@ -3870,114 +3679,116 @@ fetch_inferior_event (void *client_data)
   scoped_restore save_ui = make_scoped_restore (&current_ui, main_ui);
 
   /* End up with readline processing input, if necessary.  */
-  make_cleanup (reinstall_readline_callback_handler_cleanup, NULL);
-
-  /* We're handling a live event, so make sure we're doing live
-     debugging.  If we're looking at traceframes while the target is
-     running, we're going to need to get back to that mode after
-     handling the event.  */
-  gdb::optional<scoped_restore_current_traceframe> maybe_restore_traceframe;
-  if (non_stop)
-    {
-      maybe_restore_traceframe.emplace ();
-      set_current_traceframe (-1);
-    }
-
-  gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
-
-  if (non_stop)
-    /* In non-stop mode, the user/frontend should not notice a thread
-       switch due to internal events.  Make sure we reverse to the
-       user selected thread and frame after handling the event and
-       running any breakpoint commands.  */
-    maybe_restore_thread.emplace ();
-
-  overlay_cache_invalid = 1;
-  /* Flush target cache before starting to handle each event.  Target
-     was running and cache could be stale.  This is just a heuristic.
-     Running threads may modify target memory, but we don't get any
-     event.  */
-  target_dcache_invalidate ();
-
-  scoped_restore save_exec_dir
-    = make_scoped_restore (&execution_direction, target_execution_direction ());
-
-  ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
-                             target_can_async_p () ? TARGET_WNOHANG : 0);
-
-  if (debug_infrun)
-    print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
-
-  /* If an error happens while handling the event, propagate GDB's
-     knowledge of the executing state to the frontend/user running
-     state.  */
-  ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
-  scoped_finish_thread_state finish_state (finish_ptid);
-
-  /* Get executed before make_cleanup_restore_current_thread above to apply
-     still for the thread which has thrown the exception.  */
-  struct cleanup *ts_old_chain = 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);
+  {
+    SCOPE_EXIT { reinstall_readline_callback_handler_cleanup (); };
+
+    /* 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
+       handling the event.  */
+    gdb::optional<scoped_restore_current_traceframe> maybe_restore_traceframe;
+    if (non_stop)
+      {
+       maybe_restore_traceframe.emplace ();
+       set_current_traceframe (-1);
+      }
 
-  if (!ecs->wait_some_more)
-    {
-      struct inferior *inf = find_inferior_ptid (ecs->ptid);
-      int should_stop = 1;
-      struct thread_info *thr = ecs->event_thread;
-      int should_notify_stop = 1;
+    gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
+
+    if (non_stop)
+      /* In non-stop mode, the user/frontend should not notice a thread
+        switch due to internal events.  Make sure we reverse to the
+        user selected thread and frame after handling the event and
+        running any breakpoint commands.  */
+      maybe_restore_thread.emplace ();
+
+    overlay_cache_invalid = 1;
+    /* Flush target cache before starting to handle each event.  Target
+       was running and cache could be stale.  This is just a heuristic.
+       Running threads may modify target memory, but we don't get any
+       event.  */
+    target_dcache_invalidate ();
+
+    scoped_restore save_exec_dir
+      = make_scoped_restore (&execution_direction,
+                            target_execution_direction ());
+
+    ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
+                               target_can_async_p () ? TARGET_WNOHANG : 0);
+
+    if (debug_infrun)
+      print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
+
+    /* If an error happens while handling the event, propagate GDB's
+       knowledge of the executing state to the frontend/user running
+       state.  */
+    ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
+    scoped_finish_thread_state finish_state (finish_ptid);
+
+    /* Get executed before scoped_restore_current_thread above to apply
+       still for the thread which has thrown the exception.  */
+    auto defer_bpstat_clear
+      = make_scope_exit (bpstat_clear_actions);
+    auto defer_delete_threads
+      = make_scope_exit (delete_just_stopped_threads_infrun_breakpoints);
+
+    /* 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_ptid (ecs->ptid);
+       int should_stop = 1;
+       struct thread_info *thr = ecs->event_thread;
 
-      delete_just_stopped_threads_infrun_breakpoints ();
+       delete_just_stopped_threads_infrun_breakpoints ();
 
-      if (thr != NULL)
-       {
-         struct thread_fsm *thread_fsm = thr->thread_fsm;
+       if (thr != NULL)
+         {
+           struct thread_fsm *thread_fsm = thr->thread_fsm;
 
-         if (thread_fsm != NULL)
-           should_stop = thread_fsm_should_stop (thread_fsm, thr);
-       }
+           if (thread_fsm != NULL)
+             should_stop = thread_fsm->should_stop (thr);
+         }
 
-      if (!should_stop)
-       {
-         keep_going (ecs);
-       }
-      else
-       {
-         clean_up_just_stopped_threads_fsms (ecs);
+       if (!should_stop)
+         {
+           keep_going (ecs);
+         }
+       else
+         {
+           bool should_notify_stop = true;
+           int proceeded = 0;
 
-         if (thr != NULL && thr->thread_fsm != NULL)
-           {
-             should_notify_stop
-               = thread_fsm_should_notify_stop (thr->thread_fsm);
-           }
+           clean_up_just_stopped_threads_fsms (ecs);
 
-         if (should_notify_stop)
-           {
-             int proceeded = 0;
+           if (thr != NULL && thr->thread_fsm != NULL)
+             should_notify_stop = thr->thread_fsm->should_notify_stop ();
 
-             /* We may not find an inferior if this was a process exit.  */
-             if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
-               proceeded = normal_stop ();
+           if (should_notify_stop)
+             {
+               /* We may not find an inferior if this was a process exit.  */
+               if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
+                 proceeded = normal_stop ();
+             }
 
-             if (!proceeded)
-               {
-                 inferior_event_handler (INF_EXEC_COMPLETE, NULL);
-                 cmd_done = 1;
-               }
-           }
-       }
-    }
+           if (!proceeded)
+             {
+               inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+               cmd_done = 1;
+             }
+         }
+      }
 
-  discard_cleanups (ts_old_chain);
+    defer_delete_threads.release ();
+    defer_bpstat_clear.release ();
 
-  /* No error, don't finish the thread states yet.  */
-  finish_state.release ();
+    /* No error, don't finish the thread states yet.  */
+    finish_state.release ();
 
-  /* Revert thread and frame.  */
-  do_cleanups (old_chain);
+    /* This scope is used to ensure that readline callbacks are
+       reinstalled here.  */
+  }
 
   /* If a UI was in sync execution mode, and now isn't, restore its
      prompt (a synchronous execution command has finished, and we're
@@ -3986,8 +3797,8 @@ fetch_inferior_event (void *client_data)
 
   if (cmd_done
       && exec_done_display_p
-      && (ptid_equal (inferior_ptid, null_ptid)
-         || !is_running (inferior_ptid)))
+      && (inferior_ptid == null_ptid
+         || inferior_thread ()->state != THREAD_RUNNING))
     printf_unfiltered (_("completed.\n"));
 }
 
@@ -4045,17 +3856,19 @@ nullify_last_target_wait_ptid (void)
 /* Switch thread contexts.  */
 
 static void
-context_switch (ptid_t ptid)
+context_switch (execution_control_state *ecs)
 {
-  if (debug_infrun && !ptid_equal (ptid, inferior_ptid))
+  if (debug_infrun
+      && ecs->ptid != inferior_ptid
+      && ecs->event_thread != inferior_thread ())
     {
       fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ",
-                         target_pid_to_str (inferior_ptid));
+                         target_pid_to_str (inferior_ptid).c_str ());
       fprintf_unfiltered (gdb_stdlog, "to %s\n",
-                         target_pid_to_str (ptid));
+                         target_pid_to_str (ecs->ptid).c_str ());
     }
 
-  switch_to_thread (ptid);
+  switch_to_thread (ecs->event_thread);
 }
 
 /* If the target can't tell whether we've hit breakpoints
@@ -4141,7 +3954,7 @@ adjust_pc_after_break (struct thread_info *thread,
 
   /* If this target does not decrement the PC after breakpoints, then
      we have nothing to do.  */
-  regcache = get_thread_regcache (thread->ptid);
+  regcache = get_thread_regcache (thread);
   gdbarch = regcache->arch ();
 
   decr_pc = gdbarch_decr_pc_after_break (gdbarch);
@@ -4221,6 +4034,45 @@ stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
   return 0;
 }
 
+/* Look for an inline frame that is marked for skip.
+   If PREV_FRAME is TRUE start at the previous frame,
+   otherwise start at the current frame.  Stop at the
+   first non-inline frame, or at the frame where the
+   step started.  */
+
+static bool
+inline_frame_is_marked_for_skip (bool prev_frame, struct thread_info *tp)
+{
+  struct frame_info *frame = get_current_frame ();
+
+  if (prev_frame)
+    frame = get_prev_frame (frame);
+
+  for (; frame != NULL; frame = get_prev_frame (frame))
+    {
+      const char *fn = NULL;
+      symtab_and_line sal;
+      struct symbol *sym;
+
+      if (frame_id_eq (get_frame_id (frame), tp->control.step_frame_id))
+       break;
+      if (get_frame_type (frame) != INLINE_FRAME)
+       break;
+
+      sal = find_frame_sal (frame);
+      sym = get_frame_function (frame);
+
+      if (sym != NULL)
+       fn = sym->print_name ();
+
+      if (sal.line != 0
+         && function_name_is_marked_for_skip (fn, sal))
+       return true;
+    }
+
+  return false;
+}
+
 /* If the event thread has the stop requested flag set, pretend it
    stopped for a GDB_SIGNAL_0 (i.e., as if it stopped due to
    target_stop).  */
@@ -4249,12 +4101,11 @@ handle_syscall_event (struct execution_control_state *ecs)
   struct regcache *regcache;
   int syscall_number;
 
-  if (!ptid_equal (ecs->ptid, inferior_ptid))
-    context_switch (ecs->ptid);
+  context_switch (ecs);
 
-  regcache = get_thread_regcache (ecs->ptid);
+  regcache = get_thread_regcache (ecs->event_thread);
   syscall_number = ecs->ws.value.syscall_number;
-  stop_pc = regcache_read_pc (regcache);
+  ecs->event_thread->suspend.stop_pc = regcache_read_pc (regcache);
 
   if (catch_syscall_enabled () > 0
       && catching_syscall_number (syscall_number) > 0)
@@ -4265,7 +4116,8 @@ handle_syscall_event (struct execution_control_state *ecs)
 
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (regcache->aspace (),
-                             stop_pc, ecs->ptid, &ecs->ws);
+                             ecs->event_thread->suspend.stop_pc,
+                             ecs->event_thread, &ecs->ws);
 
       if (handle_stop_requested (ecs))
        return 0;
@@ -4293,28 +4145,47 @@ fill_in_stop_func (struct gdbarch *gdbarch,
 {
   if (!ecs->stop_func_filled_in)
     {
+      const block *block;
+
       /* Don't care about return value; stop_func_start and stop_func_name
         will both be 0 if it doesn't work.  */
-      find_pc_partial_function (stop_pc, &ecs->stop_func_name,
-                               &ecs->stop_func_start, &ecs->stop_func_end);
-      ecs->stop_func_start
-       += gdbarch_deprecated_function_start_offset (gdbarch);
-
-      if (gdbarch_skip_entrypoint_p (gdbarch))
-       ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch,
-                                                       ecs->stop_func_start);
+      find_pc_partial_function (ecs->event_thread->suspend.stop_pc,
+                               &ecs->stop_func_name,
+                               &ecs->stop_func_start,
+                               &ecs->stop_func_end,
+                               &block);
+
+      /* The call to find_pc_partial_function, above, will set
+        stop_func_start and stop_func_end to the start and end
+        of the range containing the stop pc.  If this range
+        contains the entry pc for the block (which is always the
+        case for contiguous blocks), advance stop_func_start past
+        the function's start offset and entrypoint.  Note that
+        stop_func_start is NOT advanced when in a range of a
+        non-contiguous block that does not contain the entry pc.  */
+      if (block != nullptr
+         && ecs->stop_func_start <= BLOCK_ENTRY_PC (block)
+         && BLOCK_ENTRY_PC (block) < ecs->stop_func_end)
+       {
+         ecs->stop_func_start
+           += gdbarch_deprecated_function_start_offset (gdbarch);
+
+         if (gdbarch_skip_entrypoint_p (gdbarch))
+           ecs->stop_func_start
+             = gdbarch_skip_entrypoint (gdbarch, ecs->stop_func_start);
+       }
 
       ecs->stop_func_filled_in = 1;
     }
 }
 
 
-/* Return the STOP_SOON field of the inferior pointed at by PTID.  */
+/* Return the STOP_SOON field of the inferior pointed at by ECS.  */
 
 static enum stop_kind
-get_inferior_stop_soon (ptid_t ptid)
+get_inferior_stop_soon (execution_control_state *ecs)
 {
-  struct inferior *inf = find_inferior_ptid (ptid);
+  struct inferior *inf = find_inferior_ptid (ecs->ptid);
 
   gdb_assert (inf != NULL);
   return inf->control.stop_soon;
@@ -4367,23 +4238,11 @@ THREAD_STOPPED_BY (sw_breakpoint)
 /* Generate thread_stopped_by_hw_breakpoint.  */
 THREAD_STOPPED_BY (hw_breakpoint)
 
-/* Cleanups that switches to the PTID pointed at by PTID_P.  */
-
-static void
-switch_to_thread_cleanup (void *ptid_p)
-{
-  ptid_t ptid = *(ptid_t *) ptid_p;
-
-  switch_to_thread (ptid);
-}
-
 /* Save the thread's event and stop reason to process it later.  */
 
 static void
 save_waitstatus (struct thread_info *tp, struct target_waitstatus *ws)
 {
-  struct regcache *regcache;
-
   if (debug_infrun)
     {
       std::string statstr = target_waitstatus_to_string (ws);
@@ -4391,16 +4250,16 @@ save_waitstatus (struct thread_info *tp, struct target_waitstatus *ws)
       fprintf_unfiltered (gdb_stdlog,
                          "infrun: saving status %s for %d.%ld.%ld\n",
                          statstr.c_str (),
-                         ptid_get_pid (tp->ptid),
-                         ptid_get_lwp (tp->ptid),
-                         ptid_get_tid (tp->ptid));
+                         tp->ptid.pid (),
+                         tp->ptid.lwp (),
+                         tp->ptid.tid ());
     }
 
   /* Record for later.  */
   tp->suspend.waitstatus = *ws;
   tp->suspend.waitstatus_pending_p = 1;
 
-  regcache = get_thread_regcache (tp->ptid);
+  struct regcache *regcache = get_thread_regcache (tp);
   const address_space *aspace = regcache->aspace ();
 
   if (ws->kind == TARGET_WAITKIND_STOPPED
@@ -4450,14 +4309,6 @@ save_waitstatus (struct thread_info *tp, struct target_waitstatus *ws)
     }
 }
 
-/* A cleanup that disables thread create/exit events.  */
-
-static void
-disable_thread_events (void *arg)
-{
-  target_thread_events (0);
-}
-
 /* See infrun.h.  */
 
 void
@@ -4466,19 +4317,16 @@ stop_all_threads (void)
   /* We may need multiple passes to discover all threads.  */
   int pass;
   int iterations = 0;
-  ptid_t entry_ptid;
-  struct cleanup *old_chain;
 
   gdb_assert (target_is_non_stop_p ());
 
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog, "infrun: stop_all_threads\n");
 
-  entry_ptid = inferior_ptid;
-  old_chain = make_cleanup (switch_to_thread_cleanup, &entry_ptid);
+  scoped_restore_current_thread restore_thread;
 
   target_thread_events (1);
-  make_cleanup (disable_thread_events, NULL);
+  SCOPE_EXIT { target_thread_events (0); };
 
   /* Request threads to stop, and then wait for the stops.  Because
      threads we already know about can spawn more threads while we're
@@ -4496,13 +4344,12 @@ stop_all_threads (void)
          ptid_t event_ptid;
          struct target_waitstatus ws;
          int need_wait = 0;
-         struct thread_info *t;
 
          update_thread_list ();
 
          /* Go through all threads looking for threads that we need
             to tell the target to stop.  */
-         ALL_NON_EXITED_THREADS (t)
+         for (thread_info *t : all_non_exited_threads ())
            {
              if (t->executing)
                {
@@ -4514,7 +4361,7 @@ stop_all_threads (void)
                        fprintf_unfiltered (gdb_stdlog,
                                            "infrun:   %s executing, "
                                            "need stop\n",
-                                           target_pid_to_str (t->ptid));
+                                           target_pid_to_str (t->ptid).c_str ());
                      target_stop (t->ptid);
                      t->stop_requested = 1;
                    }
@@ -4524,7 +4371,7 @@ stop_all_threads (void)
                        fprintf_unfiltered (gdb_stdlog,
                                            "infrun:   %s executing, "
                                            "already stopping\n",
-                                           target_pid_to_str (t->ptid));
+                                           target_pid_to_str (t->ptid).c_str ());
                    }
 
                  if (t->stop_requested)
@@ -4535,7 +4382,7 @@ stop_all_threads (void)
                  if (debug_infrun)
                    fprintf_unfiltered (gdb_stdlog,
                                        "infrun:   %s not executing\n",
-                                       target_pid_to_str (t->ptid));
+                                       target_pid_to_str (t->ptid).c_str ());
 
                  /* The thread may be not executing, but still be
                     resumed with a pending status to process.  */
@@ -4553,29 +4400,25 @@ stop_all_threads (void)
            pass = -1;
 
          event_ptid = wait_one (&ws);
-         if (ws.kind == TARGET_WAITKIND_NO_RESUMED)
+         if (debug_infrun)
            {
-             /* All resumed threads exited.  */
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: stop_all_threads %s %s\n",
+                                 target_waitstatus_to_string (&ws).c_str (),
+                                 target_pid_to_str (event_ptid).c_str ());
            }
-         else if (ws.kind == TARGET_WAITKIND_THREAD_EXITED
-                  || ws.kind == TARGET_WAITKIND_EXITED
-                  || ws.kind == TARGET_WAITKIND_SIGNALLED)
-           {
-             if (debug_infrun)
-               {
-                 ptid_t ptid = pid_to_ptid (ws.value.integer);
 
-                 fprintf_unfiltered (gdb_stdlog,
-                                     "infrun: %s exited while "
-                                     "stopping threads\n",
-                                     target_pid_to_str (ptid));
-               }
+         if (ws.kind == TARGET_WAITKIND_NO_RESUMED
+             || ws.kind == TARGET_WAITKIND_THREAD_EXITED
+             || ws.kind == TARGET_WAITKIND_EXITED
+             || ws.kind == TARGET_WAITKIND_SIGNALLED)
+           {
+             /* All resumed threads exited
+                or one thread/process exited/signalled.  */
            }
          else
            {
-             struct inferior *inf;
-
-             t = find_thread_ptid (event_ptid);
+             thread_info *t = find_thread_ptid (event_ptid);
              if (t == NULL)
                t = add_thread (event_ptid);
 
@@ -4586,7 +4429,7 @@ stop_all_threads (void)
 
              /* This may be the first time we see the inferior report
                 a stop.  */
-             inf = find_inferior_ptid (event_ptid);
+             inferior *inf = find_inferior_ptid (event_ptid);
              if (inf->needs_setup)
                {
                  switch_to_thread_no_regs (t);
@@ -4601,7 +4444,7 @@ stop_all_threads (void)
                  t->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
                  t->suspend.waitstatus_pending_p = 0;
 
-                 if (displaced_step_fixup (t->ptid, GDB_SIGNAL_0) < 0)
+                 if (displaced_step_fixup (t, GDB_SIGNAL_0) < 0)
                    {
                      /* Add it back to the step-over queue.  */
                      if (debug_infrun)
@@ -4610,7 +4453,7 @@ stop_all_threads (void)
                                              "infrun: displaced-step of %s "
                                              "canceled: adding back to the "
                                              "step-over queue\n",
-                                             target_pid_to_str (t->ptid));
+                                             target_pid_to_str (t->ptid).c_str ());
                        }
                      t->control.trap_expected = 0;
                      thread_step_over_chain_enqueue (t);
@@ -4629,9 +4472,9 @@ stop_all_threads (void)
                                          "infrun: target_wait %s, saving "
                                          "status for %d.%ld.%ld\n",
                                          statstr.c_str (),
-                                         ptid_get_pid (t->ptid),
-                                         ptid_get_lwp (t->ptid),
-                                         ptid_get_tid (t->ptid));
+                                         t->ptid.pid (),
+                                         t->ptid.lwp (),
+                                         t->ptid.tid ());
                    }
 
                  /* Record for later.  */
@@ -4640,14 +4483,14 @@ stop_all_threads (void)
                  sig = (ws.kind == TARGET_WAITKIND_STOPPED
                         ? ws.value.sig : GDB_SIGNAL_0);
 
-                 if (displaced_step_fixup (t->ptid, sig) < 0)
+                 if (displaced_step_fixup (t, sig) < 0)
                    {
                      /* Add it back to the step-over queue.  */
                      t->control.trap_expected = 0;
                      thread_step_over_chain_enqueue (t);
                    }
 
-                 regcache = get_thread_regcache (t->ptid);
+                 regcache = get_thread_regcache (t);
                  t->suspend.stop_pc = regcache_read_pc (regcache);
 
                  if (debug_infrun)
@@ -4657,7 +4500,7 @@ stop_all_threads (void)
                                          "(currently_stepping=%d)\n",
                                          paddress (target_gdbarch (),
                                                    t->suspend.stop_pc),
-                                         target_pid_to_str (t->ptid),
+                                         target_pid_to_str (t->ptid).c_str (),
                                          currently_stepping (t));
                    }
                }
@@ -4665,8 +4508,6 @@ stop_all_threads (void)
        }
     }
 
-  do_cleanups (old_chain);
-
   if (debug_infrun)
     fprintf_unfiltered (gdb_stdlog, "infrun: stop_all_threads done\n");
 }
@@ -4676,9 +4517,6 @@ stop_all_threads (void)
 static int
 handle_no_resumed (struct execution_control_state *ecs)
 {
-  struct inferior *inf;
-  struct thread_info *thread;
-
   if (target_can_async_p ())
     {
       struct ui *ui;
@@ -4741,7 +4579,7 @@ handle_no_resumed (struct execution_control_state *ecs)
      the synchronous command show "no unwaited-for " to the user.  */
   update_thread_list ();
 
-  ALL_NON_EXITED_THREADS (thread)
+  for (thread_info *thread : all_non_exited_threads ())
     {
       if (thread->executing
          || thread->suspend.waitstatus_pending_p)
@@ -4761,12 +4599,12 @@ handle_no_resumed (struct execution_control_state *ecs)
      process exited meanwhile (thus updating the thread list results
      in an empty thread list).  In this case we know we'll be getting
      a process exit event shortly.  */
-  ALL_INFERIORS (inf)
+  for (inferior *inf : all_inferiors ())
     {
       if (inf->pid == 0)
        continue;
 
-      thread = any_live_thread_of_process (inf->pid);
+      thread_info *thread = any_live_thread_of_inferior (inf);
       if (thread == NULL)
        {
          if (debug_infrun)
@@ -4796,10 +4634,19 @@ handle_no_resumed (struct execution_control_state *ecs)
    once).  */
 
 static void
-handle_inferior_event_1 (struct execution_control_state *ecs)
+handle_inferior_event (struct execution_control_state *ecs)
 {
+  /* Make sure that all temporary struct value objects that were
+     created during the handling of the event get deleted at the
+     end.  */
+  scoped_value_mark free_values;
+
   enum stop_kind stop_soon;
 
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog, "infrun: handle_inferior_event %s\n",
+                       target_waitstatus_to_string (&ecs->ws).c_str ());
+
   if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
     {
       /* We had an event in the inferior, but we are not interested in
@@ -4811,16 +4658,12 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
         not stopped, and we are ignoring the event.  Another possible
         circumstance is any event which the lower level knows will be
         reported multiple times without an intervening resume.  */
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
       prepare_to_wait (ecs);
       return;
     }
 
   if (ecs->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
     {
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_EXITED\n");
       prepare_to_wait (ecs);
       return;
     }
@@ -4839,9 +4682,6 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
     {
       /* No unwaited-for children left.  IOW, all resumed children
         have exited.  */
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
-
       stop_print_frame = 0;
       stop_waiting (ecs);
       return;
@@ -4883,7 +4723,7 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
          || ecs->ws.value.sig == GDB_SIGNAL_SEGV
          || ecs->ws.value.sig == GDB_SIGNAL_EMT))
     {
-      struct regcache *regcache = get_thread_regcache (ecs->ptid);
+      struct regcache *regcache = get_thread_regcache (ecs->event_thread);
 
       if (breakpoint_inserted_here_p (regcache->aspace (),
                                      regcache_read_pc (regcache)))
@@ -4920,7 +4760,7 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
           process as not-executing so that finish_thread_state marks
           them stopped (in the user's perspective) if/when we present
           the stop to the user.  */
-       mark_ptid = pid_to_ptid (ptid_get_pid (ecs->ptid));
+       mark_ptid = ptid_t (ecs->ptid.pid ());
       }
     else
       mark_ptid = ecs->ptid;
@@ -4934,10 +4774,7 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
   switch (ecs->ws.kind)
     {
     case TARGET_WAITKIND_LOADED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_LOADED\n");
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
+      context_switch (ecs);
       /* Ignore gracefully during startup of the inferior, as it might
          be the shell which has just loaded some objects, otherwise
          add the symbols for the newly loaded objects.  Also ignore at
@@ -4945,18 +4782,19 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
          the full list of libraries once the connection is
          established.  */
 
-      stop_soon = get_inferior_stop_soon (ecs->ptid);
+      stop_soon = get_inferior_stop_soon (ecs);
       if (stop_soon == NO_STOP_QUIETLY)
        {
          struct regcache *regcache;
 
-         regcache = get_thread_regcache (ecs->ptid);
+         regcache = get_thread_regcache (ecs->event_thread);
 
          handle_solib_event ();
 
          ecs->event_thread->control.stop_bpstat
            = bpstat_stop_status (regcache->aspace (),
-                                 stop_pc, ecs->ptid, &ecs->ws);
+                                 ecs->event_thread->suspend.stop_pc,
+                                 ecs->event_thread, &ecs->ws);
 
          if (handle_stop_requested (ecs))
            return;
@@ -5013,39 +4851,23 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
                      _("unhandled stop_soon: %d"), (int) stop_soon);
 
     case TARGET_WAITKIND_SPURIOUS:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n");
       if (handle_stop_requested (ecs))
        return;
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
+      context_switch (ecs);
       resume (GDB_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
 
     case TARGET_WAITKIND_THREAD_CREATED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_CREATED\n");
       if (handle_stop_requested (ecs))
        return;
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
+      context_switch (ecs);
       if (!switch_back_to_stepped_thread (ecs))
        keep_going (ecs);
       return;
 
     case TARGET_WAITKIND_EXITED:
     case TARGET_WAITKIND_SIGNALLED:
-      if (debug_infrun)
-       {
-         if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: TARGET_WAITKIND_EXITED\n");
-         else
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: TARGET_WAITKIND_SIGNALLED\n");
-       }
-
       inferior_ptid = ecs->ptid;
       set_current_inferior (find_inferior_ptid (ecs->ptid));
       set_current_program_space (current_inferior ()->pspace);
@@ -5073,8 +4895,7 @@ handle_inferior_event_1 (struct execution_control_state *ecs)
        }
       else
        {
-         struct regcache *regcache = get_thread_regcache (ecs->ptid);
-         struct gdbarch *gdbarch = regcache->arch ();
+         struct gdbarch *gdbarch = current_inferior ()->gdbarch;
 
          if (gdbarch_gdb_signal_to_target_p (gdbarch))
            {
@@ -5111,22 +4932,14 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          the above cases end in a continue or goto.  */
     case TARGET_WAITKIND_FORKED:
     case TARGET_WAITKIND_VFORKED:
-      if (debug_infrun)
-       {
-         if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
-           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
-         else
-           fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_VFORKED\n");
-       }
-
       /* Check whether the inferior is displaced stepping.  */
       {
-       struct regcache *regcache = get_thread_regcache (ecs->ptid);
+       struct regcache *regcache = get_thread_regcache (ecs->event_thread);
        struct gdbarch *gdbarch = regcache->arch ();
 
        /* If checking displaced stepping is supported, and thread
           ecs->ptid is displaced stepping.  */
-       if (displaced_step_in_progress_thread (ecs->ptid))
+       if (displaced_step_in_progress_thread (ecs->event_thread))
          {
            struct inferior *parent_inf
              = find_inferior_ptid (ecs->ptid);
@@ -5138,7 +4951,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
               has been done.  Perform cleanup for parent process here.  Note
               that this operation also cleans up the child process for vfork,
               because their pages are shared.  */
-           displaced_step_fixup (ecs->ptid, GDB_SIGNAL_TRAP);
+           displaced_step_fixup (ecs->event_thread, GDB_SIGNAL_TRAP);
            /* Start a new step-over in another thread if there's one
               that needs it.  */
            start_step_over ();
@@ -5146,7 +4959,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
            if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
              {
                struct displaced_step_inferior_state *displaced
-                 = get_displaced_stepping_state (ptid_get_pid (ecs->ptid));
+                 = get_displaced_stepping_state (parent_inf);
 
                /* Restore scratch pad for child process.  */
                displaced_step_restore (displaced, ecs->ws.value.related_pid);
@@ -5177,8 +4990,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          }
       }
 
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
+      context_switch (ecs);
 
       /* Immediately detach breakpoints from the child before there's
         any chance of letting the user delete breakpoints from the
@@ -5206,11 +5018,13 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
         and not immediately.  */
       ecs->event_thread->pending_follow = ecs->ws;
 
-      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
+      ecs->event_thread->suspend.stop_pc
+       = regcache_read_pc (get_thread_regcache (ecs->event_thread));
 
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_current_regcache ()->aspace (),
-                             stop_pc, ecs->ptid, &ecs->ws);
+                             ecs->event_thread->suspend.stop_pc,
+                             ecs->event_thread, &ecs->ws);
 
       if (handle_stop_requested (ecs))
        return;
@@ -5221,8 +5035,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
         watchpoints, for example, always appear in the bpstat.  */
       if (!bpstat_causes_stop (ecs->event_thread->control.stop_bpstat))
        {
-         ptid_t parent;
-         ptid_t child;
          int should_resume;
          int follow_child
            = (follow_fork_mode_string == follow_fork_mode_child);
@@ -5231,19 +5043,19 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
 
          should_resume = follow_fork ();
 
-         parent = ecs->ptid;
-         child = ecs->ws.value.related_pid;
+         thread_info *parent = ecs->event_thread;
+         thread_info *child = find_thread_ptid (ecs->ws.value.related_pid);
 
          /* At this point, the parent is marked running, and the
             child is marked stopped.  */
 
          /* If not resuming the parent, mark it stopped.  */
          if (follow_child && !detach_fork && !non_stop && !sched_multi)
-           set_running (parent, 0);
+           parent->set_running (false);
 
          /* If resuming the child, mark it running.  */
          if (follow_child || (!detach_fork && (non_stop || sched_multi)))
-           set_running (child, 1);
+           child->set_running (true);
 
          /* In non-stop mode, also resume the other branch.  */
          if (!detach_fork && (non_stop
@@ -5280,12 +5092,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       /* Done with the shared memory region.  Re-insert breakpoints in
         the parent, and keep going.  */
 
-      if (debug_infrun)
-       fprintf_unfiltered (gdb_stdlog,
-                           "infrun: TARGET_WAITKIND_VFORK_DONE\n");
-
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
+      context_switch (ecs);
 
       current_inferior ()->waiting_for_vfork_done = 0;
       current_inferior ()->pspace->breakpoints_not_allowed = 0;
@@ -5299,14 +5106,11 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       return;
 
     case TARGET_WAITKIND_EXECD:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
 
       /* Note we can't read registers yet (the stop_pc), because we
         don't yet know the inferior's post-exec architecture.
         'stop_pc' is explicitly read below instead.  */
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       switch_to_thread_no_regs (ecs->event_thread);
+      switch_to_thread_no_regs (ecs->event_thread);
 
       /* Do whatever is necessary to the parent branch of the vfork.  */
       handle_vfork_child_exec_or_exit (1);
@@ -5316,16 +5120,18 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          stop.  */
       follow_exec (inferior_ptid, ecs->ws.value.execd_pathname);
 
-      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
-
       /* In follow_exec we may have deleted the original thread and
         created a new one.  Make sure that the event thread is the
         execd thread for that case (this is a nop otherwise).  */
       ecs->event_thread = inferior_thread ();
 
+      ecs->event_thread->suspend.stop_pc
+       = regcache_read_pc (get_thread_regcache (ecs->event_thread));
+
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_current_regcache ()->aspace (),
-                             stop_pc, ecs->ptid, &ecs->ws);
+                             ecs->event_thread->suspend.stop_pc,
+                             ecs->event_thread, &ecs->ws);
 
       /* Note that this may be referenced from inside
         bpstat_stop_status above, through inferior_has_execd.  */
@@ -5348,9 +5154,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
       /* Be careful not to try to gather much state about a thread
          that's in a syscall.  It's frequently a losing proposition.  */
     case TARGET_WAITKIND_SYSCALL_ENTRY:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n");
       /* Getting the current syscall number.  */
       if (handle_syscall_event (ecs) == 0)
        process_event_stop_test (ecs);
@@ -5362,32 +5165,25 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
          syscall.  Stepping one instruction seems to get it back
          into user code.)  */
     case TARGET_WAITKIND_SYSCALL_RETURN:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                           "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
       if (handle_syscall_event (ecs) == 0)
        process_event_stop_test (ecs);
       return;
 
     case TARGET_WAITKIND_STOPPED:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
       handle_signal_stop (ecs);
       return;
 
     case TARGET_WAITKIND_NO_HISTORY:
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
       /* Reverse execution: target ran out of history info.  */
 
       /* Switch to the stopped thread.  */
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
+      context_switch (ecs);
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
 
       delete_just_stopped_threads_single_step_breakpoints ();
-      stop_pc = regcache_read_pc (get_thread_regcache (inferior_ptid));
+      ecs->event_thread->suspend.stop_pc
+       = regcache_read_pc (get_thread_regcache (inferior_thread ()));
 
       if (handle_stop_requested (ecs))
        return;
@@ -5398,22 +5194,6 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
     }
 }
 
-/* A wrapper around handle_inferior_event_1, which also makes sure
-   that all temporary struct value objects that were created during
-   the handling of the event get deleted at the end.  */
-
-static void
-handle_inferior_event (struct execution_control_state *ecs)
-{
-  struct value *mark = value_mark ();
-
-  handle_inferior_event_1 (ecs);
-  /* Purge all temporary values created during the event handling,
-     as it could be a long time before we return to the command level
-     where such values would otherwise be purged.  */
-  value_free_to_mark (mark);
-}
-
 /* Restart threads back to what they were trying to do back when we
    paused them for an in-line step-over.  The EVENT_THREAD thread is
    ignored.  */
@@ -5421,12 +5201,10 @@ handle_inferior_event (struct execution_control_state *ecs)
 static void
 restart_threads (struct thread_info *event_thread)
 {
-  struct thread_info *tp;
-
   /* In case the instruction just stepped spawned a new thread.  */
   update_thread_list ();
 
-  ALL_NON_EXITED_THREADS (tp)
+  for (thread_info *tp : all_non_exited_threads ())
     {
       if (tp == event_thread)
        {
@@ -5434,7 +5212,7 @@ restart_threads (struct thread_info *event_thread)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] is event thread\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          continue;
        }
 
@@ -5444,7 +5222,7 @@ restart_threads (struct thread_info *event_thread)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] not meant to be running\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          continue;
        }
 
@@ -5453,7 +5231,7 @@ restart_threads (struct thread_info *event_thread)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] resumed\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
          continue;
        }
@@ -5464,7 +5242,7 @@ restart_threads (struct thread_info *event_thread)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] needs step-over\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          gdb_assert (!tp->resumed);
          continue;
        }
@@ -5476,7 +5254,7 @@ restart_threads (struct thread_info *event_thread)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: "
                                "[%s] has pending status\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          tp->resumed = 1;
          continue;
        }
@@ -5491,7 +5269,7 @@ restart_threads (struct thread_info *event_thread)
          internal_error (__FILE__, __LINE__,
                          "thread [%s] needs a step-over, but not in "
                          "step-over queue\n",
-                         target_pid_to_str (tp->ptid));
+                         target_pid_to_str (tp->ptid).c_str ());
        }
 
       if (currently_stepping (tp))
@@ -5499,7 +5277,7 @@ restart_threads (struct thread_info *event_thread)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] was stepping\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          keep_going_stepped_thread (tp);
        }
       else
@@ -5510,9 +5288,9 @@ restart_threads (struct thread_info *event_thread)
          if (debug_infrun)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: restart threads: [%s] continuing\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          reset_ecs (ecs, tp);
-         switch_to_thread (tp->ptid);
+         switch_to_thread (tp);
          keep_going_pass_signal (ecs);
        }
     }
@@ -5540,7 +5318,7 @@ finish_step_over (struct execution_control_state *ecs)
 {
   int had_step_over_info;
 
-  displaced_step_fixup (ecs->ptid,
+  displaced_step_fixup (ecs->event_thread,
                        ecs->event_thread->suspend.stop_signal);
 
   had_step_over_info = step_over_info_valid_p ();
@@ -5578,7 +5356,7 @@ finish_step_over (struct execution_control_state *ecs)
         another thread has a pending event for this breakpoint too,
         we'd discard its event (because the breakpoint that
         originally caused the event was no longer inserted).  */
-      context_switch (ecs->ptid);
+      context_switch (ecs);
       insert_breakpoints ();
 
       restart_threads (ecs->event_thread);
@@ -5621,7 +5399,7 @@ finish_step_over (struct execution_control_state *ecs)
 
          gdb_assert (!tp->executing);
 
-         regcache = get_thread_regcache (tp->ptid);
+         regcache = get_thread_regcache (tp);
          tp->suspend.stop_pc = regcache_read_pc (regcache);
 
          if (debug_infrun)
@@ -5631,7 +5409,7 @@ finish_step_over (struct execution_control_state *ecs)
                                  "(currently_stepping=%d)\n",
                                  paddress (target_gdbarch (),
                                            tp->suspend.stop_pc),
-                                 target_pid_to_str (tp->ptid),
+                                 target_pid_to_str (tp->ptid).c_str (),
                                  currently_stepping (tp));
            }
 
@@ -5679,28 +5457,30 @@ handle_signal_stop (struct execution_control_state *ecs)
       && ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
     ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
 
-  stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
+  ecs->event_thread->suspend.stop_pc
+    = regcache_read_pc (get_thread_regcache (ecs->event_thread));
 
   if (debug_infrun)
     {
-      struct regcache *regcache = get_thread_regcache (ecs->ptid);
-      struct gdbarch *gdbarch = regcache->arch ();
+      struct regcache *regcache = get_thread_regcache (ecs->event_thread);
+      struct gdbarch *reg_gdbarch = regcache->arch ();
       scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
       inferior_ptid = ecs->ptid;
 
       fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
-                          paddress (gdbarch, stop_pc));
+                         paddress (reg_gdbarch,
+                                   ecs->event_thread->suspend.stop_pc));
       if (target_stopped_by_watchpoint ())
        {
           CORE_ADDR addr;
 
          fprintf_unfiltered (gdb_stdlog, "infrun: stopped by watchpoint\n");
 
-          if (target_stopped_data_address (&current_target, &addr))
+         if (target_stopped_data_address (current_top_target (), &addr))
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: stopped data address = %s\n",
-                                paddress (gdbarch, addr));
+                                paddress (reg_gdbarch, addr));
           else
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: (no data address available)\n");
@@ -5709,11 +5489,10 @@ handle_signal_stop (struct execution_control_state *ecs)
 
   /* This is originated from start_remote(), start_inferior() and
      shared libraries hook functions.  */
-  stop_soon = get_inferior_stop_soon (ecs->ptid);
+  stop_soon = get_inferior_stop_soon (ecs);
   if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
     {
-      if (!ptid_equal (ecs->ptid, inferior_ptid))
-       context_switch (ecs->ptid);
+      context_switch (ecs);
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: quietly stopped\n");
       stop_print_frame = 1;
@@ -5754,15 +5533,15 @@ handle_signal_stop (struct execution_control_state *ecs)
 
   /* See if something interesting happened to the non-current thread.  If
      so, then switch to that thread.  */
-  if (!ptid_equal (ecs->ptid, inferior_ptid))
+  if (ecs->ptid != inferior_ptid)
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog, "infrun: context switch\n");
 
-      context_switch (ecs->ptid);
+      context_switch (ecs);
 
       if (deprecated_context_hook)
-       deprecated_context_hook (ptid_to_global_thread_id (ecs->ptid));
+       deprecated_context_hook (ecs->event_thread->global_num);
     }
 
   /* At this point, get hold of the now-current thread's frame.  */
@@ -5775,7 +5554,7 @@ handle_signal_stop (struct execution_control_state *ecs)
       struct regcache *regcache;
       CORE_ADDR pc;
 
-      regcache = get_thread_regcache (ecs->ptid);
+      regcache = get_thread_regcache (ecs->event_thread);
       const address_space *aspace = regcache->aspace ();
 
       pc = regcache_read_pc (regcache);
@@ -5793,7 +5572,7 @@ handle_signal_stop (struct execution_control_state *ecs)
                  fprintf_unfiltered (gdb_stdlog,
                                      "infrun: [%s] hit another thread's "
                                      "single-step breakpoint\n",
-                                     target_pid_to_str (ecs->ptid));
+                                     target_pid_to_str (ecs->ptid).c_str ());
                }
              ecs->hit_singlestep_breakpoint = 1;
            }
@@ -5805,7 +5584,7 @@ handle_signal_stop (struct execution_control_state *ecs)
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: [%s] hit its "
                                  "single-step breakpoint\n",
-                                 target_pid_to_str (ecs->ptid));
+                                 target_pid_to_str (ecs->ptid).c_str ());
            }
        }
     }
@@ -5862,14 +5641,15 @@ handle_signal_stop (struct execution_control_state *ecs)
   ecs->event_thread->control.stop_step = 0;
   stop_print_frame = 1;
   stopped_by_random_signal = 0;
+  bpstat stop_chain = NULL;
 
   /* Hide inlined functions starting here, unless we just performed stepi or
      nexti.  After stepi and nexti, always show the innermost frame (not any
      inline function call sites).  */
   if (ecs->event_thread->control.step_range_end != 1)
     {
-      const address_space *aspace =
-       get_thread_regcache (ecs->ptid)->aspace ();
+      const address_space *aspace
+       = get_thread_regcache (ecs->event_thread)->aspace ();
 
       /* skip_inline_frames is expensive, so we avoid it if we can
         determine that the address is one where functions cannot have
@@ -5886,14 +5666,19 @@ handle_signal_stop (struct execution_control_state *ecs)
         user had set a breakpoint on that inlined code, the missing
         skip_inline_frames call would break things.  Fortunately
         that's an extremely unlikely scenario.  */
-      if (!pc_at_non_inline_function (aspace, stop_pc, &ecs->ws)
+      if (!pc_at_non_inline_function (aspace,
+                                     ecs->event_thread->suspend.stop_pc,
+                                     &ecs->ws)
          && !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
               && ecs->event_thread->control.trap_expected
               && pc_at_non_inline_function (aspace,
                                             ecs->event_thread->prev_pc,
                                             &ecs->ws)))
        {
-         skip_inline_frames (ecs->ptid);
+         stop_chain = build_bpstat_chain (aspace,
+                                          ecs->event_thread->suspend.stop_pc,
+                                          &ecs->ws);
+         skip_inline_frames (ecs->event_thread, stop_chain);
 
          /* Re-fetch current thread's frame in case that invalidated
             the frame cache.  */
@@ -5942,7 +5727,8 @@ handle_signal_stop (struct execution_control_state *ecs)
      handles this event.  */
   ecs->event_thread->control.stop_bpstat
     = bpstat_stop_status (get_current_regcache ()->aspace (),
-                         stop_pc, ecs->ptid, &ecs->ws);
+                         ecs->event_thread->suspend.stop_pc,
+                         ecs->event_thread, &ecs->ws, stop_chain);
 
   /* Following in case break condition called a
      function.  */
@@ -5994,14 +5780,15 @@ handle_signal_stop (struct execution_control_state *ecs)
      been removed.  */
   if (random_signal && target_stopped_by_sw_breakpoint ())
     {
-      if (program_breakpoint_here_p (gdbarch, stop_pc))
+      if (program_breakpoint_here_p (gdbarch,
+                                    ecs->event_thread->suspend.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);
+         regcache = get_thread_regcache (ecs->event_thread);
          decr_pc = gdbarch_decr_pc_after_break (gdbarch);
          if (decr_pc != 0)
            {
@@ -6012,7 +5799,8 @@ handle_signal_stop (struct execution_control_state *ecs)
                restore_operation_disable.emplace
                  (record_full_gdb_operation_disable_set ());
 
-             regcache_write_pc (regcache, stop_pc + decr_pc);
+             regcache_write_pc (regcache,
+                                ecs->event_thread->suspend.stop_pc + decr_pc);
            }
        }
       else
@@ -6104,7 +5892,7 @@ handle_signal_stop (struct execution_control_state *ecs)
       if (signal_program[ecs->event_thread->suspend.stop_signal] == 0)
        ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
 
-      if (ecs->event_thread->prev_pc == stop_pc
+      if (ecs->event_thread->prev_pc == ecs->event_thread->suspend.stop_pc
          && ecs->event_thread->control.trap_expected
          && ecs->event_thread->control.step_resume_breakpoint == NULL)
        {
@@ -6136,7 +5924,8 @@ handle_signal_stop (struct execution_control_state *ecs)
        }
 
       if (ecs->event_thread->suspend.stop_signal != GDB_SIGNAL_0
-         && (pc_in_thread_step_range (stop_pc, ecs->event_thread)
+         && (pc_in_thread_step_range (ecs->event_thread->suspend.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)
@@ -6165,7 +5954,7 @@ handle_signal_stop (struct execution_control_state *ecs)
          return;
        }
 
-      /* Note: step_resume_breakpoint may be non-NULL.  This occures
+      /* Note: step_resume_breakpoint may be non-NULL.  This occurs
         when either there's a nested signal, or when there's a
         pending signal enabled just as the signal handler returns
         (leaving the inferior at the step-resume-breakpoint without
@@ -6366,7 +6155,7 @@ process_event_stop_test (struct execution_control_state *ecs)
          return;
        }
       fill_in_stop_func (gdbarch, ecs);
-      if (stop_pc == ecs->stop_func_start
+      if (ecs->event_thread->suspend.stop_pc == ecs->stop_func_start
          && execution_direction == EXEC_REVERSE)
        {
          /* We are stepping over a function call in reverse, and just
@@ -6499,7 +6288,8 @@ process_event_stop_test (struct execution_control_state *ecs)
      through a function epilogue and therefore must detect when
      the current-frame changes in the middle of a line.  */
 
-  if (pc_in_thread_step_range (stop_pc, ecs->event_thread)
+  if (pc_in_thread_step_range (ecs->event_thread->suspend.stop_pc,
+                              ecs->event_thread)
       && (execution_direction != EXEC_REVERSE
          || frame_id_eq (get_frame_id (frame),
                          ecs->event_thread->control.step_frame_id)))
@@ -6518,6 +6308,7 @@ process_event_stop_test (struct execution_control_state *ecs)
       /* When stepping backward, stop at beginning of line range
         (unless it's the function entry point, in which case
         keep going back to the call point).  */
+      CORE_ADDR stop_pc = ecs->event_thread->suspend.stop_pc;
       if (stop_pc == ecs->event_thread->control.step_range_start
          && stop_pc != ecs->stop_func_start
          && execution_direction == EXEC_REVERSE)
@@ -6544,10 +6335,11 @@ process_event_stop_test (struct execution_control_state *ecs)
 
   if (execution_direction != EXEC_REVERSE
       && ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
-      && in_solib_dynsym_resolve_code (stop_pc))
+      && in_solib_dynsym_resolve_code (ecs->event_thread->suspend.stop_pc))
     {
       CORE_ADDR pc_after_resolver =
-       gdbarch_skip_solib_resolver (gdbarch, stop_pc);
+       gdbarch_skip_solib_resolver (gdbarch,
+                                    ecs->event_thread->suspend.stop_pc);
 
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog,
@@ -6571,7 +6363,8 @@ process_event_stop_test (struct execution_control_state *ecs)
 
   /* Step through an indirect branch thunk.  */
   if (ecs->event_thread->control.step_over_calls != STEP_OVER_NONE
-      && gdbarch_in_indirect_branch_thunk (gdbarch, stop_pc))
+      && gdbarch_in_indirect_branch_thunk (gdbarch,
+                                          ecs->event_thread->suspend.stop_pc))
     {
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog,
@@ -6603,13 +6396,14 @@ process_event_stop_test (struct execution_control_state *ecs)
      call check below as on some targets return trampolines look
      like subroutine calls (MIPS16 return thunks).  */
   if (gdbarch_in_solib_return_trampoline (gdbarch,
-                                         stop_pc, ecs->stop_func_name)
+                                         ecs->event_thread->suspend.stop_pc,
+                                         ecs->stop_func_name)
       && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE)
     {
       /* Determine where this trampoline returns.  */
-      CORE_ADDR real_stop_pc;
-
-      real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
+      CORE_ADDR stop_pc = ecs->event_thread->suspend.stop_pc;
+      CORE_ADDR real_stop_pc
+       = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
 
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog,
@@ -6661,8 +6455,9 @@ process_event_stop_test (struct execution_control_state *ecs)
          && (!frame_id_eq (ecs->event_thread->control.step_stack_frame_id,
                            outer_frame_id)
              || (ecs->event_thread->control.step_start_function
-                 != find_pc_function (stop_pc)))))
+                 != find_pc_function (ecs->event_thread->suspend.stop_pc)))))
     {
+      CORE_ADDR stop_pc = ecs->event_thread->suspend.stop_pc;
       CORE_ADDR real_stop_pc;
 
       if (debug_infrun)
@@ -6768,7 +6563,8 @@ process_event_stop_test (struct execution_control_state *ecs)
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
        if (tmp_sal.line != 0
            && !function_name_is_marked_for_skip (ecs->stop_func_name,
-                                                 tmp_sal))
+                                                 tmp_sal)
+           && !inline_frame_is_marked_for_skip (true, ecs->event_thread))
          {
            if (execution_direction == EXEC_REVERSE)
              handle_step_into_function_backward (gdbarch, ecs);
@@ -6820,6 +6616,8 @@ process_event_stop_test (struct execution_control_state *ecs)
   if (execution_direction == EXEC_REVERSE
       && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE)
     {
+      CORE_ADDR stop_pc = ecs->event_thread->suspend.stop_pc;
+
       if (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
          || (ecs->stop_func_start == 0
              && in_solib_dynsym_resolve_code (stop_pc)))
@@ -6847,7 +6645,7 @@ process_event_stop_test (struct execution_control_state *ecs)
        }
     }
 
-  stop_pc_sal = find_pc_line (stop_pc, 0);
+  stop_pc_sal = find_pc_line (ecs->event_thread->suspend.stop_pc, 0);
 
   /* NOTE: tausq/2004-05-24: This if block used to be done before all
      the trampoline processing logic, however, there are some trampolines 
@@ -6915,7 +6713,7 @@ process_event_stop_test (struct execution_control_state *ecs)
 
   if (frame_id_eq (get_frame_id (get_current_frame ()),
                   ecs->event_thread->control.step_frame_id)
-      && inline_skipped_frames (ecs->ptid))
+      && inline_skipped_frames (ecs->event_thread))
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
@@ -6932,7 +6730,14 @@ process_event_stop_test (struct execution_control_state *ecs)
 
          if (call_sal.line == ecs->event_thread->current_line
              && call_sal.symtab == ecs->event_thread->current_symtab)
-           step_into_inline_frame (ecs->ptid);
+           {
+             step_into_inline_frame (ecs->event_thread);
+             if (inline_frame_is_marked_for_skip (false, ecs->event_thread))
+               {
+                 keep_going (ecs);
+                 return;
+               }
+           }
 
          end_stepping_range (ecs);
          return;
@@ -6966,14 +6771,15 @@ process_event_stop_test (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: stepping through inlined function\n");
 
-      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL
+         || inline_frame_is_marked_for_skip (false, ecs->event_thread))
        keep_going (ecs);
       else
        end_stepping_range (ecs);
       return;
     }
 
-  if ((stop_pc == stop_pc_sal.pc)
+  if ((ecs->event_thread->suspend.stop_pc == stop_pc_sal.pc)
       && (ecs->event_thread->current_line != stop_pc_sal.line
          || ecs->event_thread->current_symtab != stop_pc_sal.symtab))
     {
@@ -7015,7 +6821,6 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
 {
   if (!target_is_non_stop_p ())
     {
-      struct thread_info *tp;
       struct thread_info *stepping_thread;
 
       /* If any thread is blocked on some internal breakpoint, and we
@@ -7038,7 +6843,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
            {
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: need to finish step-over of [%s]\n",
-                                 target_pid_to_str (ecs->event_thread->ptid));
+                                 target_pid_to_str (ecs->event_thread->ptid).c_str ());
            }
          keep_going (ecs);
          return 1;
@@ -7053,7 +6858,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: need to step [%s] over single-step "
                                 "breakpoint\n",
-                                target_pid_to_str (ecs->ptid));
+                                target_pid_to_str (ecs->ptid).c_str ());
           }
         keep_going (ecs);
         return 1;
@@ -7068,7 +6873,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
            {
              fprintf_unfiltered (gdb_stdlog,
                                  "infrun: thread [%s] still needs step-over\n",
-                                 target_pid_to_str (ecs->event_thread->ptid));
+                                 target_pid_to_str (ecs->event_thread->ptid).c_str ());
            }
          keep_going (ecs);
          return 1;
@@ -7102,12 +6907,12 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
       /* Look for the stepping/nexting thread.  */
       stepping_thread = NULL;
 
-      ALL_NON_EXITED_THREADS (tp)
+      for (thread_info *tp : all_non_exited_threads ())
         {
          /* Ignore threads of processes the caller is not
             resuming.  */
          if (!sched_multi
-             && ptid_get_pid (tp->ptid) != ptid_get_pid (ecs->ptid))
+             && tp->ptid.pid () != ecs->ptid.pid ())
            continue;
 
          /* When stepping over a breakpoint, we lock all threads
@@ -7119,7 +6924,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs)
              internal_error (__FILE__, __LINE__,
                              "[%s] has inconsistent state: "
                              "trap_expected=%d\n",
-                             target_pid_to_str (tp->ptid),
+                             target_pid_to_str (tp->ptid).c_str (),
                              tp->control.trap_expected);
            }
 
@@ -7189,15 +6994,14 @@ keep_going_stepped_thread (struct thread_info *tp)
        stepping thread is still alive.  For that reason, we need to
        synchronously query the target now.  */
 
-  if (is_exited (tp->ptid)
-      || !target_thread_alive (tp->ptid))
+  if (tp->state == THREAD_EXITED || !target_thread_alive (tp->ptid))
     {
       if (debug_infrun)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: not resuming previously  "
                            "stepped thread, it has vanished\n");
 
-      delete_thread (tp->ptid);
+      delete_thread (tp);
       return 0;
     }
 
@@ -7206,9 +7010,9 @@ keep_going_stepped_thread (struct thread_info *tp)
                        "infrun: resuming previously stepped thread\n");
 
   reset_ecs (ecs, tp);
-  switch_to_thread (tp->ptid);
+  switch_to_thread (tp);
 
-  stop_pc = regcache_read_pc (get_thread_regcache (tp->ptid));
+  tp->suspend.stop_pc = regcache_read_pc (get_thread_regcache (tp));
   frame = get_current_frame ();
 
   /* If the PC of the thread we were trying to single-step has
@@ -7224,7 +7028,7 @@ keep_going_stepped_thread (struct thread_info *tp)
      This prevents us continuously moving the single-step breakpoint
      forward, one instruction at a time, overstepping.  */
 
-  if (stop_pc != tp->prev_pc)
+  if (tp->suspend.stop_pc != tp->prev_pc)
     {
       ptid_t resume_ptid;
 
@@ -7232,7 +7036,7 @@ keep_going_stepped_thread (struct thread_info *tp)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: expected thread advanced also (%s -> %s)\n",
                            paddress (target_gdbarch (), tp->prev_pc),
-                           paddress (target_gdbarch (), stop_pc));
+                           paddress (target_gdbarch (), tp->suspend.stop_pc));
 
       /* Clear the info of the previous step-over, as it's no longer
         valid (if the thread was trying to step over a breakpoint, it
@@ -7246,7 +7050,7 @@ keep_going_stepped_thread (struct thread_info *tp)
 
       insert_single_step_breakpoint (get_frame_arch (frame),
                                     get_frame_address_space (frame),
-                                    stop_pc);
+                                    tp->suspend.stop_pc);
 
       tp->resumed = 1;
       resume_ptid = internal_resume_ptid (tp->control.stepping_command);
@@ -7287,7 +7091,8 @@ handle_step_into_function (struct gdbarch *gdbarch,
 {
   fill_in_stop_func (gdbarch, ecs);
 
-  compunit_symtab *cust = find_pc_compunit_symtab (stop_pc);
+  compunit_symtab *cust
+    = find_pc_compunit_symtab (ecs->event_thread->suspend.stop_pc);
   if (cust != NULL && compunit_language (cust) != language_asm)
     ecs->stop_func_start
       = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start);
@@ -7327,7 +7132,7 @@ handle_step_into_function (struct gdbarch *gdbarch,
                                             ecs->stop_func_start);
     }
 
-  if (ecs->stop_func_start == stop_pc)
+  if (ecs->stop_func_start == ecs->event_thread->suspend.stop_pc)
     {
       /* We are already there: stop now.  */
       end_stepping_range (ecs);
@@ -7366,15 +7171,15 @@ handle_step_into_function_backward (struct gdbarch *gdbarch,
 
   fill_in_stop_func (gdbarch, ecs);
 
-  cust = find_pc_compunit_symtab (stop_pc);
+  cust = find_pc_compunit_symtab (ecs->event_thread->suspend.stop_pc);
   if (cust != NULL && compunit_language (cust) != language_asm)
     ecs->stop_func_start
       = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start);
 
-  stop_func_sal = find_pc_line (stop_pc, 0);
+  stop_func_sal = find_pc_line (ecs->event_thread->suspend.stop_pc, 0);
 
   /* OK, we're just going to keep stepping here.  */
-  if (stop_func_sal.pc == stop_pc)
+  if (stop_func_sal.pc == ecs->event_thread->suspend.stop_pc)
     {
       /* We're there already.  Just stop stepping now.  */
       end_stepping_range (ecs);
@@ -7516,14 +7321,14 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
                                    struct frame_info *frame,
                                    struct symbol *sym)
 {
-  TRY
+  try
     {
       struct block_symbol vsym;
       struct value *value;
       CORE_ADDR handler;
       struct breakpoint *bp;
 
-      vsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+      vsym = lookup_symbol_search_name (sym->search_name (),
                                        b, VAR_DOMAIN);
       value = read_var_value (vsym.symbol, vsym.block, frame);
       /* If the value was optimized out, revert to the old behavior.  */
@@ -7547,11 +7352,10 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
          inferior_thread ()->control.exception_resume_breakpoint = bp;
        }
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
       /* We want to ignore errors here.  */
     }
-  END_CATCH
 }
 
 /* A helper for check_exception_resume that sets an
@@ -7610,7 +7414,7 @@ check_exception_resume (struct execution_control_state *ecs,
   if (!func)
     return;
 
-  TRY
+  try
     {
       const struct block *b;
       struct block_iterator iter;
@@ -7647,10 +7451,9 @@ check_exception_resume (struct execution_control_state *ecs,
            }
        }
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
     }
-  END_CATCH
 }
 
 static void
@@ -7674,12 +7477,12 @@ stop_waiting (struct execution_control_state *ecs)
 static void
 keep_going_pass_signal (struct execution_control_state *ecs)
 {
-  gdb_assert (ptid_equal (ecs->event_thread->ptid, inferior_ptid));
+  gdb_assert (ecs->event_thread->ptid == inferior_ptid);
   gdb_assert (!ecs->event_thread->resumed);
 
   /* Save the pc before execution, to compare with pc after stop.  */
   ecs->event_thread->prev_pc
-    = regcache_read_pc (get_thread_regcache (ecs->ptid));
+    = regcache_read_pc (get_thread_regcache (ecs->event_thread));
 
   if (ecs->event_thread->control.trap_expected)
     {
@@ -7689,7 +7492,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: %s has trap_expected set, "
                            "resuming to collect trap\n",
-                           target_pid_to_str (tp->ptid));
+                           target_pid_to_str (tp->ptid).c_str ());
 
       /* We haven't yet gotten our trap, and either: intercepted a
         non-signal event (e.g., a fork); or took a signal which we
@@ -7711,7 +7514,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: step-over already in progress: "
                                "step-over for %s deferred\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
          thread_step_over_chain_enqueue (tp);
        }
       else
@@ -7720,7 +7523,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
            fprintf_unfiltered (gdb_stdlog,
                                "infrun: step-over in progress: "
                                "resume of %s deferred\n",
-                               target_pid_to_str (tp->ptid));
+                               target_pid_to_str (tp->ptid).c_str ());
        }
     }
   else
@@ -7777,18 +7580,17 @@ keep_going_pass_signal (struct execution_control_state *ecs)
        stop_all_threads ();
 
       /* Stop stepping if inserting breakpoints fails.  */
-      TRY
+      try
        {
          insert_breakpoints ();
        }
-      CATCH (e, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &e)
        {
          exception_print (gdb_stderr, e);
          stop_waiting (ecs);
          clear_step_over_info ();
          return;
        }
-      END_CATCH
 
       ecs->event_thread->control.trap_expected = (remove_bp || remove_wps);
 
@@ -7888,31 +7690,26 @@ 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));
+  std::string pidstr = target_pid_to_str (ptid_t (inf->pid));
 
   annotate_exited (exitstatus);
   if (exitstatus)
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED));
-      uiout->text ("[Inferior ");
-      uiout->text (plongest (inf->num));
-      uiout->text (" (");
-      uiout->text (pidstr);
-      uiout->text (") exited with code ");
-      uiout->field_fmt ("exit-code", "0%o", (unsigned int) exitstatus);
-      uiout->text ("]\n");
+      std::string exit_code_str
+       = string_printf ("0%o", (unsigned int) exitstatus);
+      uiout->message ("[Inferior %s (%s) exited with code %pF]\n",
+                     plongest (inf->num), pidstr.c_str (),
+                     string_field ("exit-code", exit_code_str.c_str ()));
     }
   else
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string
          ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
-      uiout->text ("[Inferior ");
-      uiout->text (plongest (inf->num));
-      uiout->text (" (");
-      uiout->text (pidstr);
-      uiout->text (") exited normally]\n");
+      uiout->message ("[Inferior %s (%s) exited normally]\n",
+                     plongest (inf->num), pidstr.c_str ());
     }
 }
 
@@ -7944,13 +7741,13 @@ print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
       const char *name;
 
       uiout->text ("\nThread ");
-      uiout->field_fmt ("thread-id", "%s", print_thread_id (thr));
+      uiout->field_string ("thread-id", print_thread_id (thr));
 
       name = thr->name != NULL ? thr->name : target_thread_name (thr);
       if (name != NULL)
        {
          uiout->text (" \"");
-         uiout->field_fmt ("name", "%s", name);
+         uiout->field_string ("name", name);
          uiout->text ("\"");
        }
     }
@@ -8009,7 +7806,8 @@ print_stop_location (struct target_waitstatus *ws)
       if (tp->control.stop_step
          && frame_id_eq (tp->control.step_frame_id,
                          get_frame_id (get_current_frame ()))
-         && tp->control.step_start_function == find_pc_function (stop_pc))
+         && (tp->control.step_start_function
+             == find_pc_function (tp->suspend.stop_pc)))
        {
          /* Finished step, just print source line.  */
          source_flag = SRC_LINE;
@@ -8048,7 +7846,7 @@ print_stop_location (struct target_waitstatus *ws)
 /* See infrun.h.  */
 
 void
-print_stop_event (struct ui_out *uiout)
+print_stop_event (struct ui_out *uiout, bool displays)
 {
   struct target_waitstatus last;
   ptid_t last_ptid;
@@ -8062,16 +7860,17 @@ print_stop_event (struct ui_out *uiout)
     print_stop_location (&last);
 
     /* Display the auto-display expressions.  */
-    do_displays ();
+    if (displays)
+      do_displays ();
   }
 
   tp = inferior_thread ();
   if (tp->thread_fsm != NULL
-      && thread_fsm_finished_p (tp->thread_fsm))
+      && tp->thread_fsm->finished_p ())
     {
       struct return_value_info *rv;
 
-      rv = thread_fsm_return_value (tp->thread_fsm);
+      rv = tp->thread_fsm->return_value ();
       if (rv != NULL)
        print_return_value (uiout, rv);
     }
@@ -8098,6 +7897,13 @@ maybe_remove_breakpoints (void)
 
 struct stop_context
 {
+  stop_context ();
+  ~stop_context ();
+
+  DISABLE_COPY_AND_ASSIGN (stop_context);
+
+  bool changed () const;
+
   /* The stop ID.  */
   ULONGEST stop_id;
 
@@ -8113,59 +7919,50 @@ struct stop_context
   int inf_num;
 };
 
-/* Returns a new stop context.  If stopped for a thread event, this
+/* Initializes a new stop context.  If stopped for a thread event, this
    takes a strong reference to the thread.  */
 
-static struct stop_context *
-save_stop_context (void)
+stop_context::stop_context ()
 {
-  struct stop_context *sc = XNEW (struct stop_context);
-
-  sc->stop_id = get_stop_id ();
-  sc->ptid = inferior_ptid;
-  sc->inf_num = current_inferior ()->num;
+  stop_id = get_stop_id ();
+  ptid = inferior_ptid;
+  inf_num = current_inferior ()->num;
 
-  if (!ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid != null_ptid)
     {
       /* Take a strong reference so that the thread can't be deleted
         yet.  */
-      sc->thread = inferior_thread ();
-      sc->thread->incref ();
+      thread = inferior_thread ();
+      thread->incref ();
     }
   else
-    sc->thread = NULL;
-
-  return sc;
+    thread = NULL;
 }
 
 /* Release a stop context previously created with save_stop_context.
    Releases the strong reference to the thread as well. */
 
-static void
-release_stop_context_cleanup (void *arg)
+stop_context::~stop_context ()
 {
-  struct stop_context *sc = (struct stop_context *) arg;
-
-  if (sc->thread != NULL)
-    sc->thread->decref ();
-  xfree (sc);
+  if (thread != NULL)
+    thread->decref ();
 }
 
 /* Return true if the current context no longer matches the saved stop
    context.  */
 
-static int
-stop_context_changed (struct stop_context *prev)
-{
-  if (!ptid_equal (prev->ptid, inferior_ptid))
-    return 1;
-  if (prev->inf_num != current_inferior ()->num)
-    return 1;
-  if (prev->thread != NULL && prev->thread->state != THREAD_STOPPED)
-    return 1;
-  if (get_stop_id () != prev->stop_id)
-    return 1;
-  return 0;
+bool
+stop_context::changed () const
+{
+  if (ptid != inferior_ptid)
+    return true;
+  if (inf_num != current_inferior ()->num)
+    return true;
+  if (thread != NULL && thread->state != THREAD_STOPPED)
+    return true;
+  if (get_stop_id () != stop_id)
+    return true;
+  return false;
 }
 
 /* See infrun.h.  */
@@ -8243,7 +8040,7 @@ normal_stop (void)
        {
          target_terminal::ours_for_output ();
          printf_filtered (_("[Switching to %s]\n"),
-                          target_pid_to_str (inferior_ptid));
+                          target_pid_to_str (inferior_ptid).c_str ());
          annotate_thread_changed ();
        }
       previous_inferior_ptid = inferior_ptid;
@@ -8308,37 +8105,30 @@ normal_stop (void)
      of stop_command's pre-hook not existing).  */
   if (stop_command != NULL)
     {
-      struct stop_context *saved_context = save_stop_context ();
-      struct cleanup *old_chain
-       = make_cleanup (release_stop_context_cleanup, saved_context);
+      stop_context saved_context;
 
-      TRY
+      try
        {
          execute_cmd_pre_hook (stop_command);
        }
-      CATCH (ex, RETURN_MASK_ALL)
+      catch (const gdb_exception &ex)
        {
          exception_fprintf (gdb_stderr, ex,
                             "Error while running hook_stop:\n");
        }
-      END_CATCH
 
       /* If the stop hook resumes the target, then there's no point in
         trying to notify about the previous stop; its context is
         gone.  Likewise if the command switches thread or inferior --
         the observers would print a stop for the wrong
         thread/inferior.  */
-      if (stop_context_changed (saved_context))
-       {
-         do_cleanups (old_chain);
-         return 1;
-       }
-      do_cleanups (old_chain);
+      if (saved_context.changed ())
+       return 1;
     }
 
   /* Notify observers about the stop.  This is where the interpreters
      print the stop event.  */
-  if (!ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid != null_ptid)
     gdb::observers::normal_stop.notify (inferior_thread ()->control.stop_bpstat,
                                 stop_print_frame);
   else
@@ -8349,7 +8139,8 @@ normal_stop (void)
   if (target_has_execution)
     {
       if (last.kind != TARGET_WAITKIND_SIGNALLED
-         && last.kind != TARGET_WAITKIND_EXITED)
+         && last.kind != TARGET_WAITKIND_EXITED
+         && last.kind != TARGET_WAITKIND_NO_RESUMED)
        /* Delete the breakpoint we stopped at, if it wants to be deleted.
           Delete any breakpoint that is to be deleted at the next stop.  */
        breakpoint_auto_delete (inferior_thread ()->control.stop_bpstat);
@@ -8439,7 +8230,7 @@ signal_catch_update (const unsigned int *info)
   for (i = 0; i < GDB_SIGNAL_LAST; ++i)
     signal_catch[i] = info[i] > 0;
   signal_cache_update (-1);
-  target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+  target_pass_signals (signal_pass);
 }
 
 static void
@@ -8472,11 +8263,9 @@ static void
 handle_command (const char *args, int from_tty)
 {
   int digits, wordlen;
-  int sigfirst, signum, siglast;
+  int sigfirst, siglast;
   enum gdb_signal oursig;
   int allsigs;
-  int nsigs;
-  unsigned char *sigs;
 
   if (args == NULL)
     {
@@ -8485,9 +8274,8 @@ handle_command (const char *args, int from_tty)
 
   /* Allocate and zero an array of flags for which signals to handle.  */
 
-  nsigs = (int) GDB_SIGNAL_LAST;
-  sigs = (unsigned char *) alloca (nsigs);
-  memset (sigs, 0, nsigs);
+  const size_t nsigs = GDB_SIGNAL_LAST;
+  unsigned char sigs[nsigs] {};
 
   /* Break the command line up into args.  */
 
@@ -8567,9 +8355,7 @@ handle_command (const char *args, int from_tty)
          if (sigfirst > siglast)
            {
              /* Bet he didn't figure we'd think of this case...  */
-             signum = sigfirst;
-             sigfirst = siglast;
-             siglast = signum;
+             std::swap (sigfirst, siglast);
            }
        }
       else
@@ -8589,7 +8375,7 @@ handle_command (const char *args, int from_tty)
       /* If any signal numbers or symbol names were found, set flags for
          which signals to apply actions to.  */
 
-      for (signum = sigfirst; signum >= 0 && signum <= siglast; signum++)
+      for (int signum = sigfirst; signum >= 0 && signum <= siglast; signum++)
        {
          switch ((enum gdb_signal) signum)
            {
@@ -8604,10 +8390,7 @@ Are you sure you want to change it? "),
                      sigs[signum] = 1;
                    }
                  else
-                   {
-                     printf_unfiltered (_("Not confirmed, unchanged.\n"));
-                     gdb_flush (gdb_stdout);
-                   }
+                   printf_unfiltered (_("Not confirmed, unchanged.\n"));
                }
              break;
            case GDB_SIGNAL_0:
@@ -8622,12 +8405,12 @@ Are you sure you want to change it? "),
        }
     }
 
-  for (signum = 0; signum < nsigs; signum++)
+  for (int signum = 0; signum < nsigs; signum++)
     if (sigs[signum])
       {
        signal_cache_update (-1);
-       target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
-       target_program_signals ((int) GDB_SIGNAL_LAST, signal_program);
+       target_pass_signals (signal_pass);
+       target_program_signals (signal_program);
 
        if (from_tty)
          {
@@ -8742,7 +8525,7 @@ siginfo_value_read (struct value *v)
   validate_registers_access ();
 
   transferred =
-    target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO,
+    target_read (current_top_target (), TARGET_OBJECT_SIGNAL_INFO,
                 NULL,
                 value_contents_all_raw (v),
                 value_offset (v),
@@ -8764,7 +8547,7 @@ siginfo_value_write (struct value *v, struct value *fromval)
      vice versa.  */
   validate_registers_access ();
 
-  transferred = target_write (&current_target,
+  transferred = target_write (current_top_target (),
                              TARGET_OBJECT_SIGNAL_INFO,
                              NULL,
                              value_contents_all_raw (fromval),
@@ -8790,7 +8573,7 @@ siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
                    void *ignore)
 {
   if (target_has_stack
-      && !ptid_equal (inferior_ptid, null_ptid)
+      && inferior_ptid != null_ptid
       && gdbarch_get_siginfo_type_p (gdbarch))
     {
       struct type *type = gdbarch_get_siginfo_type (gdbarch);
@@ -8808,70 +8591,105 @@ siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
    ends (either successfully, or after it hits a breakpoint or signal)
    if the program is to properly continue where it left off.  */
 
-struct infcall_suspend_state
+class infcall_suspend_state
 {
-  struct thread_suspend_state thread_suspend;
+public:
+  /* Capture state from GDBARCH, TP, and REGCACHE that must be restored
+     once the inferior function call has finished.  */
+  infcall_suspend_state (struct gdbarch *gdbarch,
+                         const struct thread_info *tp,
+                         struct regcache *regcache)
+    : m_thread_suspend (tp->suspend),
+      m_registers (new readonly_detached_regcache (*regcache))
+  {
+    gdb::unique_xmalloc_ptr<gdb_byte> siginfo_data;
 
-  /* Other fields:  */
-  CORE_ADDR stop_pc;
-  readonly_detached_regcache *registers;
+    if (gdbarch_get_siginfo_type_p (gdbarch))
+      {
+        struct type *type = gdbarch_get_siginfo_type (gdbarch);
+        size_t len = TYPE_LENGTH (type);
+
+        siginfo_data.reset ((gdb_byte *) xmalloc (len));
+
+        if (target_read (current_top_target (), TARGET_OBJECT_SIGNAL_INFO, NULL,
+                         siginfo_data.get (), 0, len) != len)
+          {
+            /* Errors ignored.  */
+            siginfo_data.reset (nullptr);
+          }
+      }
+
+    if (siginfo_data)
+      {
+        m_siginfo_gdbarch = gdbarch;
+        m_siginfo_data = std::move (siginfo_data);
+      }
+  }
+
+  /* Return a pointer to the stored register state.  */
+
+  readonly_detached_regcache *registers () const
+  {
+    return m_registers.get ();
+  }
+
+  /* Restores the stored state into GDBARCH, TP, and REGCACHE.  */
+
+  void restore (struct gdbarch *gdbarch,
+                struct thread_info *tp,
+                struct regcache *regcache) const
+  {
+    tp->suspend = m_thread_suspend;
+
+    if (m_siginfo_gdbarch == gdbarch)
+      {
+        struct type *type = gdbarch_get_siginfo_type (gdbarch);
+
+        /* Errors ignored.  */
+        target_write (current_top_target (), TARGET_OBJECT_SIGNAL_INFO, NULL,
+                      m_siginfo_data.get (), 0, TYPE_LENGTH (type));
+      }
+
+    /* The inferior can be gone if the user types "print exit(0)"
+       (and perhaps other times).  */
+    if (target_has_execution)
+      /* NB: The register write goes through to the target.  */
+      regcache->restore (registers ());
+  }
+
+private:
+  /* How the current thread stopped before the inferior function call was
+     executed.  */
+  struct thread_suspend_state m_thread_suspend;
+
+  /* The registers before the inferior function call was executed.  */
+  std::unique_ptr<readonly_detached_regcache> m_registers;
 
   /* Format of SIGINFO_DATA or NULL if it is not present.  */
-  struct gdbarch *siginfo_gdbarch;
+  struct gdbarch *m_siginfo_gdbarch = nullptr;
 
   /* The inferior format depends on SIGINFO_GDBARCH and it has a length of
      TYPE_LENGTH (gdbarch_get_siginfo_type ()).  For different gdbarch the
      content would be invalid.  */
-  gdb_byte *siginfo_data;
+  gdb::unique_xmalloc_ptr<gdb_byte> m_siginfo_data;
 };
 
-struct infcall_suspend_state *
-save_infcall_suspend_state (void)
+infcall_suspend_state_up
+save_infcall_suspend_state ()
 {
-  struct infcall_suspend_state *inf_state;
   struct thread_info *tp = inferior_thread ();
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = regcache->arch ();
-  gdb_byte *siginfo_data = NULL;
-
-  if (gdbarch_get_siginfo_type_p (gdbarch))
-    {
-      struct type *type = gdbarch_get_siginfo_type (gdbarch);
-      size_t len = TYPE_LENGTH (type);
-      struct cleanup *back_to;
-
-      siginfo_data = (gdb_byte *) xmalloc (len);
-      back_to = make_cleanup (xfree, siginfo_data);
 
-      if (target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
-                      siginfo_data, 0, len) == len)
-       discard_cleanups (back_to);
-      else
-       {
-         /* Errors ignored.  */
-         do_cleanups (back_to);
-         siginfo_data = NULL;
-       }
-    }
-
-  inf_state = XCNEW (struct infcall_suspend_state);
-
-  if (siginfo_data)
-    {
-      inf_state->siginfo_gdbarch = gdbarch;
-      inf_state->siginfo_data = siginfo_data;
-    }
-
-  inf_state->thread_suspend = tp->suspend;
+  infcall_suspend_state_up inf_state
+    (new struct infcall_suspend_state (gdbarch, tp, regcache));
 
-  /* run_inferior_call will not use the signal due to its `proceed' call with
-     GDB_SIGNAL_0 anyway.  */
+  /* Having saved the current state, adjust the thread state, discarding
+     any stop signal information.  The stop signal is not useful when
+     starting an inferior function call, and run_inferior_call will not use
+     the signal due to its `proceed' call with GDB_SIGNAL_0.  */
   tp->suspend.stop_signal = GDB_SIGNAL_0;
 
-  inf_state->stop_pc = stop_pc;
-
-  inf_state->registers = new readonly_detached_regcache (*regcache);
-
   return inf_state;
 }
 
@@ -8884,53 +8702,20 @@ restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = regcache->arch ();
 
-  tp->suspend = inf_state->thread_suspend;
-
-  stop_pc = inf_state->stop_pc;
-
-  if (inf_state->siginfo_gdbarch == gdbarch)
-    {
-      struct type *type = gdbarch_get_siginfo_type (gdbarch);
-
-      /* Errors ignored.  */
-      target_write (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
-                   inf_state->siginfo_data, 0, TYPE_LENGTH (type));
-    }
-
-  /* The inferior can be gone if the user types "print exit(0)"
-     (and perhaps other times).  */
-  if (target_has_execution)
-    /* NB: The register write goes through to the target.  */
-    regcache->restore (inf_state->registers);
-
+  inf_state->restore (gdbarch, tp, regcache);
   discard_infcall_suspend_state (inf_state);
 }
 
-static void
-do_restore_infcall_suspend_state_cleanup (void *state)
-{
-  restore_infcall_suspend_state ((struct infcall_suspend_state *) state);
-}
-
-struct cleanup *
-make_cleanup_restore_infcall_suspend_state
-  (struct infcall_suspend_state *inf_state)
-{
-  return make_cleanup (do_restore_infcall_suspend_state_cleanup, inf_state);
-}
-
 void
 discard_infcall_suspend_state (struct infcall_suspend_state *inf_state)
 {
-  delete inf_state->registers;
-  xfree (inf_state->siginfo_data);
-  xfree (inf_state);
+  delete inf_state;
 }
 
 readonly_detached_regcache *
 get_infcall_suspend_state_regcache (struct infcall_suspend_state *inf_state)
 {
-  return inf_state->registers;
+  return inf_state->registers ();
 }
 
 /* infcall_control_state contains state regarding gdb's control of the
@@ -8943,21 +8728,20 @@ struct infcall_control_state
   struct inferior_control_state inferior_control;
 
   /* Other fields:  */
-  enum stop_stack_kind stop_stack_dummy;
-  int stopped_by_random_signal;
+  enum stop_stack_kind stop_stack_dummy = STOP_NONE;
+  int stopped_by_random_signal = 0;
 
   /* ID if the selected frame when the inferior function call was made.  */
-  struct frame_id selected_frame_id;
+  struct frame_id selected_frame_id {};
 };
 
 /* Save all of the information associated with the inferior<==>gdb
    connection.  */
 
-struct infcall_control_state *
-save_infcall_control_state (void)
+infcall_control_state_up
+save_infcall_control_state ()
 {
-  struct infcall_control_state *inf_status =
-    XNEW (struct infcall_control_state);
+  infcall_control_state_up inf_status (new struct infcall_control_state);
   struct thread_info *tp = inferior_thread ();
   struct inferior *inf = current_inferior ();
 
@@ -9028,11 +8812,11 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
       /* The point of the try/catch is that if the stack is clobbered,
          walking the stack might encounter a garbage pointer and
          error() trying to dereference it.  */
-      TRY
+      try
        {
          restore_selected_frame (inf_status->selected_frame_id);
        }
-      CATCH (ex, RETURN_MASK_ERROR)
+      catch (const gdb_exception_error &ex)
        {
          exception_fprintf (gdb_stderr, ex,
                             "Unable to restore previously selected frame:\n");
@@ -9040,23 +8824,9 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
             innermost frame.  */
          select_frame (get_current_frame ());
        }
-      END_CATCH
     }
 
-  xfree (inf_status);
-}
-
-static void
-do_restore_infcall_control_state_cleanup (void *sts)
-{
-  restore_infcall_control_state ((struct infcall_control_state *) sts);
-}
-
-struct cleanup *
-make_cleanup_restore_infcall_control_state
-  (struct infcall_control_state *inf_status)
-{
-  return make_cleanup (do_restore_infcall_control_state_cleanup, inf_status);
+  delete inf_status;
 }
 
 void
@@ -9073,7 +8843,7 @@ discard_infcall_control_state (struct infcall_control_state *inf_status)
   /* See save_infcall_control_state for info on stop_bpstat.  */
   bpstat_clear (&inf_status->thread_control.stop_bpstat);
 
-  xfree (inf_status);
+  delete inf_status;
 }
 \f
 /* See infrun.h.  */
@@ -9165,8 +8935,6 @@ infrun_async_inferior_event_handler (gdb_client_data data)
 void
 _initialize_infrun (void)
 {
-  int i;
-  int numsigs;
   struct cmd_list_element *c;
 
   /* Register extra event sources in the event loop.  */
@@ -9248,13 +9016,7 @@ leave it stopped or free to run as needed."),
                           &setlist,
                           &showlist);
 
-  numsigs = (int) GDB_SIGNAL_LAST;
-  signal_stop = XNEWVEC (unsigned char, numsigs);
-  signal_print = XNEWVEC (unsigned char, numsigs);
-  signal_program = XNEWVEC (unsigned char, numsigs);
-  signal_catch = XNEWVEC (unsigned char, numsigs);
-  signal_pass = XNEWVEC (unsigned char, numsigs);
-  for (i = 0; i < numsigs; i++)
+  for (size_t i = 0; i < GDB_SIGNAL_LAST; i++)
     {
       signal_stop[i] = 1;
       signal_print[i] = 1;
This page took 0.08356 seconds and 4 git commands to generate.