Multi-target support
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 2b5eebbbee8fde239e7a8978485ada7a0c9b6767..5b734abf1c161b41001b428782a0f27d19f13edb 100644 (file)
@@ -1,6 +1,6 @@
 /* Everything about breakpoints, for GDB.
 
-   Copyright (C) 1986-2018 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -49,7 +49,7 @@
 #include "block.h"
 #include "solib.h"
 #include "solist.h"
-#include "observer.h"
+#include "observable.h"
 #include "memattr.h"
 #include "ada-lang.h"
 #include "top.h"
 #include "gdb_regex.h"
 #include "probe.h"
 #include "cli/cli-utils.h"
-#include "continuations.h"
 #include "stack.h"
-#include "skip.h"
 #include "ax-gdb.h"
 #include "dummy-frame.h"
 #include "interps.h"
-#include "format.h"
+#include "gdbsupport/format.h"
 #include "thread-fsm.h"
 #include "tid-parse.h"
+#include "cli/cli-style.h"
 
 /* readline include files */
-#include "readline/readline.h"
-#include "readline/history.h"
+#include "readline/tilde.h"
 
 /* readline defines this.  */
 #undef savestring
 #include "extension.h"
 #include <algorithm>
 #include "progspace-and-thread.h"
-#include "common/array-view.h"
-#include "common/gdb_optional.h"
-
-/* Enums for exception-handling support.  */
-enum exception_event_kind
-{
-  EX_EVENT_THROW,
-  EX_EVENT_RETHROW,
-  EX_EVENT_CATCH
-};
+#include "gdbsupport/array-view.h"
+#include "gdbsupport/gdb_optional.h"
 
 /* Prototypes for local functions.  */
 
@@ -117,7 +107,8 @@ static std::vector<symtab_and_line> decode_location_default
   (struct breakpoint *b, const struct event_location *location,
    struct program_space *search_pspace);
 
-static int can_use_hardware_watchpoint (struct value *);
+static int can_use_hardware_watchpoint
+    (const std::vector<value_ref_ptr> &vals);
 
 static void mention (struct breakpoint *);
 
@@ -222,15 +213,13 @@ static void update_global_location_list (enum ugll_insert_mode);
 
 static void update_global_location_list_nothrow (enum ugll_insert_mode);
 
-static int is_hardware_watchpoint (const struct breakpoint *bpt);
-
 static void insert_breakpoint_locations (void);
 
 static void trace_pass_command (const char *, int);
 
 static void set_tracepoint_count (int num);
 
-static int is_masked_watchpoint (const struct breakpoint *b);
+static bool is_masked_watchpoint (const struct breakpoint *b);
 
 static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address);
 
@@ -257,6 +246,9 @@ struct breakpoint_ops bkpt_breakpoint_ops;
 /* Breakpoints set on probes.  */
 static struct breakpoint_ops bkpt_probe_breakpoint_ops;
 
+/* Tracepoints set on probes.  */
+static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
+
 /* Dynamic printf class type.  */
 struct breakpoint_ops dprintf_breakpoint_ops;
 
@@ -297,7 +289,7 @@ static char *dprintf_channel;
 
 /* True if dprintf commands should continue to operate even if GDB
    has disconnected.  */
-static int disconnected_dprintf = 1;
+static bool disconnected_dprintf = true;
 
 struct command_line *
 breakpoint_commands (struct breakpoint *b)
@@ -308,7 +300,7 @@ breakpoint_commands (struct breakpoint *b)
 /* Flag indicating that a command has proceeded the inferior past the
    current breakpoint.  */
 
-static int breakpoint_proceeded;
+static bool breakpoint_proceeded;
 
 const char *
 bpdisp_text (enum bpdisp disp)
@@ -353,11 +345,11 @@ show_pending_break_support (struct ui_file *file, int from_tty,
                    value);
 }
 
-/* If 1, gdb will automatically use hardware breakpoints for breakpoints
+/* If true, gdb will automatically use hardware breakpoints for breakpoints
    set with "break" but falling in read-only memory.
-   If 0, gdb will warn about such breakpoints, but won't automatically
+   If false, gdb will warn about such breakpoints, but won't automatically
    use hardware breakpoints.  */
-static int automatic_hardware_breakpoints;
+static bool automatic_hardware_breakpoints;
 static void
 show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
                                     struct cmd_list_element *c,
@@ -375,7 +367,7 @@ show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
    breakpoints until the next resume, and removes them again when the
    target fully stops.  This is a bit safer in case GDB crashes while
    processing user input.  */
-static int always_inserted_mode = 0;
+static bool always_inserted_mode = false;
 
 static void
 show_always_inserted_mode (struct ui_file *file, int from_tty,
@@ -397,10 +389,8 @@ breakpoints_should_be_inserted_now (void)
         no threads under GDB's control yet.  */
       return 1;
     }
-  else if (target_has_execution)
+  else
     {
-      struct thread_info *tp;
-
       if (always_inserted_mode)
        {
          /* The user wants breakpoints inserted even if all threads
@@ -408,12 +398,14 @@ breakpoints_should_be_inserted_now (void)
          return 1;
        }
 
-      if (threads_are_executing ())
-       return 1;
+      for (inferior *inf : all_inferiors ())
+       if (inf->has_execution ()
+           && threads_are_executing (inf->process_target ()))
+         return 1;
 
       /* Don't remove breakpoints yet if, even though all threads are
         stopped, we still have events to process.  */
-      ALL_NON_EXITED_THREADS (tp)
+      for (thread_info *tp : all_non_exited_threads ())
        if (tp->resumed
            && tp->suspend.waitstatus_pending_p)
          return 1;
@@ -486,7 +478,7 @@ static int executing_breakpoint_commands;
 static int overlay_events_enabled;
 
 /* See description in breakpoint.h. */
-int target_exact_watchpoints = 0;
+bool target_exact_watchpoints = false;
 
 /* Walk the following statement or block through all breakpoints.
    ALL_BREAKPOINTS_SAFE does so even if the statement deletes the
@@ -530,9 +522,9 @@ int target_exact_watchpoints = 0;
 
 /* Chains of all breakpoints defined.  */
 
-struct breakpoint *breakpoint_chain;
+static struct breakpoint *breakpoint_chain;
 
-/* Array is sorted by bp_locations_compare - primarily by the ADDRESS.  */
+/* Array is sorted by bp_location_is_less_than - primarily by the ADDRESS.  */
 
 static struct bp_location **bp_locations;
 
@@ -559,7 +551,7 @@ static CORE_ADDR bp_locations_shadow_len_after_address_max;
 /* The locations that no longer correspond to any breakpoint, unlinked
    from the bp_locations array, but for which a hit may still be
    reported by a target.  */
-VEC(bp_location_p) *moribund_locations = NULL;
+static std::vector<bp_location *> moribund_locations;
 
 /* Number of last breakpoint made.  */
 
@@ -786,7 +778,7 @@ show_condition_evaluation_mode (struct ui_file *file, int from_tty,
 
 /* A comparison function for bp_location AP and BP that is used by
    bsearch.  This comparison function only cares about addresses, unlike
-   the more general bp_locations_compare function.  */
+   the more general bp_location_is_less_than function.  */
 
 static int
 bp_locations_compare_addrs (const void *ap, const void *bp)
@@ -879,12 +871,12 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
        {
          struct watchpoint *w = (struct watchpoint *) b;
 
-         innermost_block = NULL;
+         innermost_block_tracker tracker;
          arg = exp;
-         w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
+         w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
          if (*arg)
            error (_("Junk at end of expression"));
-         w->cond_exp_valid_block = innermost_block;
+         w->cond_exp_valid_block = tracker.block ();
        }
       else
        {
@@ -903,7 +895,7 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
     }
   mark_breakpoint_modified (b);
 
-  observer_notify_breakpoint_modified (b);
+  gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Completion for the "condition" command.  */
@@ -940,10 +932,7 @@ condition_completer (struct cmd_list_element *cmd,
          xsnprintf (number, sizeof (number), "%d", b->number);
 
          if (strncmp (number, text, len) == 0)
-           {
-             gdb::unique_xmalloc_ptr<char> copy (xstrdup (number));
-             tracker.add_completion (std::move (copy));
-           }
+           tracker.add_completion (make_unique_xstrdup (number));
        }
 
       return;
@@ -1008,14 +997,12 @@ check_no_tracepoint_commands (struct command_line *commands)
 
   for (c = commands; c; c = c->next)
     {
-      int i;
-
       if (c->control_type == while_stepping_control)
        error (_("The 'while-stepping' command can "
                 "only be used for tracepoints"));
 
-      for (i = 0; i < c->body_count; ++i)
-       check_no_tracepoint_commands ((c->body_list)[i]);
+      check_no_tracepoint_commands (c->body_list_0.get ());
+      check_no_tracepoint_commands (c->body_list_1.get ());
 
       /* Not that command parsing removes leading whitespace and comment
         lines and also empty lines.  So, we only need to check for
@@ -1049,7 +1036,9 @@ is_longjmp_type (bptype type)
   return type == bp_longjmp || type == bp_exception;
 }
 
-int
+/* See breakpoint.h.  */
+
+bool
 is_tracepoint (const struct breakpoint *b)
 {
   return is_tracepoint_type (b->type);
@@ -1126,8 +1115,8 @@ validate_commands_for_breakpoint (struct breakpoint *b,
        {
          struct command_line *c2;
 
-         gdb_assert (while_stepping->body_count == 1);
-         c2 = while_stepping->body_list[0];
+         gdb_assert (while_stepping->body_list_1 == nullptr);
+         c2 = while_stepping->body_list_0.get ();
          for (; c2; c2 = c2->next)
            {
              if (c2->control_type == while_stepping_control)
@@ -1144,11 +1133,11 @@ validate_commands_for_breakpoint (struct breakpoint *b,
 /* Return a vector of all the static tracepoints set at ADDR.  The
    caller is responsible for releasing the vector.  */
 
-VEC(breakpoint_p) *
+std::vector<breakpoint *>
 static_tracepoints_here (CORE_ADDR addr)
 {
   struct breakpoint *b;
-  VEC(breakpoint_p) *found = 0;
+  std::vector<breakpoint *> found;
   struct bp_location *loc;
 
   ALL_BREAKPOINTS (b)
@@ -1156,7 +1145,7 @@ static_tracepoints_here (CORE_ADDR addr)
       {
        for (loc = b->loc; loc; loc = loc->next)
          if (loc->address == addr)
-           VEC_safe_push(breakpoint_p, found, b);
+           found.push_back (b);
       }
 
   return found;
@@ -1167,12 +1156,12 @@ static_tracepoints_here (CORE_ADDR addr)
 
 void
 breakpoint_set_commands (struct breakpoint *b, 
-                        command_line_up &&commands)
+                        counted_command_line &&commands)
 {
   validate_commands_for_breakpoint (b, commands.get ());
 
   b->commands = std::move (commands);
-  observer_notify_breakpoint_modified (b);
+  gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Set the internal `silent' flag on the breakpoint.  Note that this
@@ -1186,7 +1175,7 @@ breakpoint_set_silent (struct breakpoint *b, int silent)
 
   b->silent = silent;
   if (old_silent != silent)
-    observer_notify_breakpoint_modified (b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Set the thread for this breakpoint.  If THREAD is -1, make the
@@ -1199,7 +1188,7 @@ breakpoint_set_thread (struct breakpoint *b, int thread)
 
   b->thread = thread;
   if (old_thread != thread)
-    observer_notify_breakpoint_modified (b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Set the task for this breakpoint.  If TASK is 0, make the
@@ -1212,15 +1201,7 @@ breakpoint_set_task (struct breakpoint *b, int task)
 
   b->task = task;
   if (old_task != task)
-    observer_notify_breakpoint_modified (b);
-}
-
-void
-check_tracepoint_command (char *line, void *closure)
-{
-  struct breakpoint *b = (struct breakpoint *) closure;
-
-  validate_actionline (line, b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 static void
@@ -1228,6 +1209,10 @@ commands_command_1 (const char *arg, int from_tty,
                    struct command_line *control)
 {
   counted_command_line cmd;
+  /* cmd_read will be true once we have read cmd.  Note that cmd might still be
+     NULL after the call to read_command_lines if the user provides an empty
+     list of command by just typing "end".  */
+  bool cmd_read = false;
 
   std::string new_arg;
 
@@ -1244,10 +1229,11 @@ commands_command_1 (const char *arg, int from_tty,
   map_breakpoint_numbers
     (arg, [&] (breakpoint *b)
      {
-       if (cmd == NULL)
+       if (!cmd_read)
         {
+          gdb_assert (cmd == NULL);
           if (control != NULL)
-            cmd = copy_command_lines (control->body_list[0]);
+            cmd = control->body_list_0;
           else
             {
               std::string str
@@ -1255,12 +1241,17 @@ commands_command_1 (const char *arg, int from_tty,
                                    "%s, one per line."),
                                  arg);
 
-              cmd = read_command_lines (&str[0],
-                                        from_tty, 1,
-                                        (is_tracepoint (b)
-                                         ? check_tracepoint_command : 0),
-                                        b);
+              auto do_validate = [=] (const char *line)
+                                 {
+                                   validate_actionline (line, b);
+                                 };
+              gdb::function_view<void (const char *)> validator;
+              if (is_tracepoint (b))
+                validator = do_validate;
+
+              cmd = read_command_lines (str.c_str (), from_tty, 1, validator);
             }
+          cmd_read = true;
         }
 
        /* If a breakpoint was on the list more than once, we don't need to
@@ -1269,7 +1260,7 @@ commands_command_1 (const char *arg, int from_tty,
         {
           validate_commands_for_breakpoint (b, cmd.get ());
           b->commands = cmd;
-          observer_notify_breakpoint_modified (b);
+          gdb::observers::breakpoint_modified.notify (b);
         }
      });
 }
@@ -1503,12 +1494,9 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
   }
 }
 
-\f
-
-/* Return true if BPT is either a software breakpoint or a hardware
-   breakpoint.  */
+/* See breakpoint.h.  */
 
-int
+bool
 is_breakpoint (const struct breakpoint *bpt)
 {
   return (bpt->type == bp_breakpoint
@@ -1518,7 +1506,7 @@ is_breakpoint (const struct breakpoint *bpt)
 
 /* Return true if BPT is of any hardware watchpoint kind.  */
 
-static int
+static bool
 is_hardware_watchpoint (const struct breakpoint *bpt)
 {
   return (bpt->type == bp_hardware_watchpoint
@@ -1526,10 +1514,9 @@ is_hardware_watchpoint (const struct breakpoint *bpt)
          || bpt->type == bp_access_watchpoint);
 }
 
-/* Return true if BPT is of any watchpoint kind, hardware or
-   software.  */
+/* See breakpoint.h.  */
 
-int
+bool
 is_watchpoint (const struct breakpoint *bpt)
 {
   return (is_hardware_watchpoint (bpt)
@@ -1549,9 +1536,9 @@ static int
 watchpoint_in_thread_scope (struct watchpoint *b)
 {
   return (b->pspace == current_program_space
-         && (ptid_equal (b->watchpoint_thread, null_ptid)
-             || (ptid_equal (inferior_ptid, b->watchpoint_thread)
-                 && !is_executing (inferior_ptid))));
+         && (b->watchpoint_thread == null_ptid
+             || (inferior_ptid == b->watchpoint_thread
+                 && !inferior_thread ()->executing)));
 }
 
 /* Set watchpoint B to disp_del_at_next_stop, even including its possible
@@ -1614,7 +1601,7 @@ software_watchpoint_add_no_memory_location (struct breakpoint *b,
 /* Returns true if B is a software watchpoint that is not watching any
    memory (e.g., "watch $pc").  */
 
-static int
+static bool
 is_no_memory_software_watchpoint (struct breakpoint *b)
 {
   return (b->type == bp_watchpoint
@@ -1740,9 +1727,8 @@ update_watchpoint (struct watchpoint *b, int reparse)
         no longer relevant.  We don't want to report a watchpoint hit
         to the user when the old value and the new value may actually
         be completely different objects.  */
-      value_free (b->val);
       b->val = NULL;
-      b->val_valid = 0;
+      b->val_valid = false;
 
       /* Note that unlike with breakpoints, the watchpoint's condition
         expression is stored in the breakpoint object, not in the
@@ -1778,7 +1764,8 @@ update_watchpoint (struct watchpoint *b, int reparse)
   else if (within_current_scope && b->exp)
     {
       int pc = 0;
-      struct value *val_chain, *v, *result, *next;
+      std::vector<value_ref_ptr> val_chain;
+      struct value *v, *result;
       struct program_space *frame_pspace;
 
       fetch_subexp_value (b->exp.get (), &pc, &v, &result, &val_chain, 0);
@@ -1792,27 +1779,26 @@ update_watchpoint (struct watchpoint *b, int reparse)
       if (!b->val_valid && !is_masked_watchpoint (b))
        {
          if (b->val_bitsize != 0)
-           {
-             v = extract_bitfield_from_watchpoint_value (b, v);
-             if (v != NULL)
-               release_value (v);
-           }
-         b->val = v;
-         b->val_valid = 1;
+           v = extract_bitfield_from_watchpoint_value (b, v);
+         b->val = release_value (v);
+         b->val_valid = true;
        }
 
       frame_pspace = get_frame_program_space (get_selected_frame (NULL));
 
       /* Look at each value on the value chain.  */
-      for (v = val_chain; v; v = value_next (v))
+      gdb_assert (!val_chain.empty ());
+      for (const value_ref_ptr &iter : val_chain)
        {
+         v = iter.get ();
+
          /* If it's a memory location, and GDB actually needed
             its contents to evaluate the expression, then we
             must watch it.  If the first value returned is
             still lazy, that means an error occurred reading it;
             watch it anyway in case it becomes readable.  */
          if (VALUE_LVAL (v) == lval_memory
-             && (v == val_chain || ! value_lazy (v)))
+             && (v == val_chain[0] || ! value_lazy (v)))
            {
              struct type *vtype = check_typedef (value_type (v));
 
@@ -1967,13 +1953,6 @@ update_watchpoint (struct watchpoint *b, int reparse)
            bl->loc_type = loc_type;
        }
 
-      for (v = val_chain; v; v = next)
-       {
-         next = value_next (v);
-         if (v != b->val)
-           value_free (v);
-       }
-
       /* If a software watchpoint is not watching any memory, then the
         above left it without any location set up.  But,
         bpstat_stop_status requires a location to be able to report
@@ -2104,18 +2083,17 @@ parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
 
   /* We don't want to stop processing, so catch any errors
      that may show up.  */
-  TRY
+  try
     {
       aexpr = gen_eval_for_expr (scope, cond);
     }
 
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       /* If we got here, it means the condition could not be parsed to a valid
         bytecode expression and thus can't be evaluated on the target's side.
         It's no use iterating through the conditions.  */
     }
-  END_CATCH
 
   /* We have a valid agent expression.  */
   return aexpr;
@@ -2279,19 +2257,18 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
 
   /* We don't want to stop processing, so catch any errors
      that may show up.  */
-  TRY
+  try
     {
       aexpr = gen_printf (scope, gdbarch, 0, 0,
                          format_start, format_end - format_start,
                          argvec.size (), argvec.data ());
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       /* If we got here, it means the command could not be parsed to a valid
         bytecode expression and thus can't be evaluated on the target's side.
         It's no use iterating through the other commands.  */
     }
-  END_CATCH
 
   /* We have a valid agent expression, return it.  */
   return aexpr;
@@ -2419,7 +2396,7 @@ breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr)
       struct thread_info *thr = find_thread_global_id (bl->owner->thread);
       struct regcache *regcache;
 
-      regcache = get_thread_regcache (thr->ptid);
+      regcache = get_thread_regcache (thr);
 
       return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
                                                         regcache, addr);
@@ -2443,7 +2420,7 @@ insert_bp_location (struct bp_location *bl,
                    int *hw_breakpoint_error,
                    int *hw_bp_error_explained_already)
 {
-  gdb_exception bp_excpt = exception_none;
+  gdb_exception bp_excpt;
 
   if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
     return 0;
@@ -2546,7 +2523,7 @@ insert_bp_location (struct bp_location *bl,
          || !(section_is_overlay (bl->section)))
        {
          /* No overlay handling: just set the breakpoint.  */
-         TRY
+         try
            {
              int val;
 
@@ -2554,11 +2531,10 @@ insert_bp_location (struct bp_location *bl,
              if (val)
                bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
            }
-         CATCH (e, RETURN_MASK_ALL)
+         catch (gdb_exception &e)
            {
-             bp_excpt = e;
+             bp_excpt = std::move (e);
            }
-         END_CATCH
        }
       else
        {
@@ -2581,7 +2557,7 @@ insert_bp_location (struct bp_location *bl,
                  bl->overlay_target_info.reqstd_address = addr;
 
                  /* No overlay handling: just set the breakpoint.  */
-                 TRY
+                 try
                    {
                      int val;
 
@@ -2594,11 +2570,10 @@ insert_bp_location (struct bp_location *bl,
                        bp_excpt
                          = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
                    }
-                 CATCH (e, RETURN_MASK_ALL)
+                 catch (gdb_exception &e)
                    {
-                     bp_excpt = e;
+                     bp_excpt = std::move (e);
                    }
-                 END_CATCH
 
                  if (bp_excpt.reason != 0)
                    fprintf_unfiltered (tmp_error_stream,
@@ -2611,7 +2586,7 @@ insert_bp_location (struct bp_location *bl,
          if (section_is_mapped (bl->section))
            {
              /* Yes.  This overlay section is mapped into memory.  */
-             TRY
+             try
                {
                  int val;
 
@@ -2619,11 +2594,10 @@ insert_bp_location (struct bp_location *bl,
                  if (val)
                    bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
                }
-             CATCH (e, RETURN_MASK_ALL)
+             catch (gdb_exception &e)
                {
-                 bp_excpt = e;
+                 bp_excpt = std::move (e);
                }
-             END_CATCH
            }
          else
            {
@@ -2655,7 +2629,7 @@ insert_bp_location (struct bp_location *bl,
            {
              /* See also: disable_breakpoints_in_shlibs.  */
              bl->shlib_disabled = 1;
-             observer_notify_breakpoint_modified (bl->owner);
+             gdb::observers::breakpoint_modified.notify (bl->owner);
              if (!*disabled_breaks)
                {
                  fprintf_unfiltered (tmp_error_stream, 
@@ -2682,7 +2656,7 @@ insert_bp_location (struct bp_location *bl,
                                      bp_excpt.message ? ":" : ".\n");
                   if (bp_excpt.message != NULL)
                     fprintf_unfiltered (tmp_error_stream, "%s.\n",
-                                       bp_excpt.message);
+                                       bp_excpt.what ());
                }
              else
                {
@@ -2702,7 +2676,7 @@ insert_bp_location (struct bp_location *bl,
                      fprintf_unfiltered (tmp_error_stream,
                                          "Cannot insert breakpoint %d: %s\n",
                                          bl->owner->number,
-                                         bp_excpt.message);
+                                         bp_excpt.what ());
                    }
                }
              return 1;
@@ -2905,7 +2879,7 @@ update_inserted_breakpoint_locations (void)
       /* We only want to update locations that are already inserted
         and need updating.  This is to avoid unwanted insertion during
         deletion of breakpoints.  */
-      if (!bl->inserted || (bl->inserted && !bl->needs_update))
+      if (!bl->inserted || !bl->needs_update)
        continue;
 
       switch_to_program_space_and_thread (bl->pspace);
@@ -2915,7 +2889,7 @@ update_inserted_breakpoint_locations (void)
         if we aren't attached to any process yet, we should still
         insert breakpoints.  */
       if (!gdbarch_has_global_breakpoints (target_gdbarch ())
-         && ptid_equal (inferior_ptid, null_ptid))
+         && (inferior_ptid == null_ptid || !target_has_execution))
        continue;
 
       val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
@@ -2971,7 +2945,7 @@ insert_breakpoint_locations (void)
         if we aren't attached to any process yet, we should still
         insert breakpoints.  */
       if (!gdbarch_has_global_breakpoints (target_gdbarch ())
-         && ptid_equal (inferior_ptid, null_ptid))
+         && (inferior_ptid == null_ptid || !target_has_execution))
        continue;
 
       val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
@@ -3072,14 +3046,13 @@ Thread-specific breakpoint %d deleted - thread %s no longer in the thread list.\
     }
 }
 
-/* Remove breakpoints of process PID.  */
+/* See breakpoint.h.  */
 
-int
-remove_breakpoints_pid (int pid)
+void
+remove_breakpoints_inf (inferior *inf)
 {
   struct bp_location *bl, **blp_tmp;
   int val;
-  struct inferior *inf = find_inferior_pid (pid);
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
   {
@@ -3090,10 +3063,9 @@ remove_breakpoints_pid (int pid)
       {
        val = remove_breakpoint (bl);
        if (val != 0)
-         return val;
+         return;
       }
   }
-  return 0;
 }
 
 static int internal_breakpoint_number = -1;
@@ -3169,7 +3141,8 @@ struct breakpoint_objfile_data
   std::vector<probe *> exception_probes;
 };
 
-static const struct objfile_data *breakpoint_objfile_key;
+static const struct objfile_key<breakpoint_objfile_data>
+  breakpoint_objfile_key;
 
 /* Minimal symbol not found sentinel.  */
 static struct minimal_symbol msym_not_found;
@@ -3190,32 +3163,18 @@ get_breakpoint_objfile_data (struct objfile *objfile)
 {
   struct breakpoint_objfile_data *bp_objfile_data;
 
-  bp_objfile_data = ((struct breakpoint_objfile_data *)
-                    objfile_data (objfile, breakpoint_objfile_key));
+  bp_objfile_data = breakpoint_objfile_key.get (objfile);
   if (bp_objfile_data == NULL)
-    {
-      bp_objfile_data = new breakpoint_objfile_data ();
-      set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
-    }
+    bp_objfile_data = breakpoint_objfile_key.emplace (objfile);
   return bp_objfile_data;
 }
 
-static void
-free_breakpoint_objfile_data (struct objfile *obj, void *data)
-{
-  struct breakpoint_objfile_data *bp_objfile_data
-    = (struct breakpoint_objfile_data *) data;
-
-  delete bp_objfile_data;
-}
-
 static void
 create_overlay_event_breakpoint (void)
 {
-  struct objfile *objfile;
   const char *const func_name = "_ovly_debug_event";
 
-  ALL_OBJFILES (objfile)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       struct breakpoint *b;
       struct breakpoint_objfile_data *bp_objfile_data;
@@ -3271,97 +3230,93 @@ create_longjmp_master_breakpoint (void)
 
   ALL_PSPACES (pspace)
   {
-    struct objfile *objfile;
-
     set_current_program_space (pspace);
 
-    ALL_OBJFILES (objfile)
-    {
-      int i;
-      struct gdbarch *gdbarch;
-      struct breakpoint_objfile_data *bp_objfile_data;
-
-      gdbarch = get_objfile_arch (objfile);
+    for (objfile *objfile : current_program_space->objfiles ())
+      {
+       int i;
+       struct gdbarch *gdbarch;
+       struct breakpoint_objfile_data *bp_objfile_data;
 
-      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+       gdbarch = get_objfile_arch (objfile);
 
-      if (!bp_objfile_data->longjmp_searched)
-       {
-         std::vector<probe *> ret
-           = find_probes_in_objfile (objfile, "libc", "longjmp");
+       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-         if (!ret.empty ())
-           {
-             /* We are only interested in checking one element.  */
-             probe *p = ret[0];
+       if (!bp_objfile_data->longjmp_searched)
+         {
+           std::vector<probe *> ret
+             = find_probes_in_objfile (objfile, "libc", "longjmp");
 
-             if (!p->can_evaluate_arguments ())
-               {
-                 /* We cannot use the probe interface here, because it does
-                    not know how to evaluate arguments.  */
-                 ret.clear ();
-               }
-           }
-         bp_objfile_data->longjmp_probes = ret;
-         bp_objfile_data->longjmp_searched = 1;
-       }
+           if (!ret.empty ())
+             {
+               /* We are only interested in checking one element.  */
+               probe *p = ret[0];
 
-      if (!bp_objfile_data->longjmp_probes.empty ())
-       {
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+               if (!p->can_evaluate_arguments ())
+                 {
+                   /* We cannot use the probe interface here, because it does
+                      not know how to evaluate arguments.  */
+                   ret.clear ();
+                 }
+             }
+           bp_objfile_data->longjmp_probes = ret;
+           bp_objfile_data->longjmp_searched = 1;
+         }
 
-         for (probe *p : bp_objfile_data->longjmp_probes)
-           {
-             struct breakpoint *b;
+       if (!bp_objfile_data->longjmp_probes.empty ())
+         {
+           for (probe *p : bp_objfile_data->longjmp_probes)
+             {
+               struct breakpoint *b;
+
+               b = create_internal_breakpoint (gdbarch,
+                                               p->get_relocated_address (objfile),
+                                               bp_longjmp_master,
+                                               &internal_breakpoint_ops);
+               b->location = new_probe_location ("-probe-stap libc:longjmp");
+               b->enable_state = bp_disabled;
+             }
 
-             b = create_internal_breakpoint (gdbarch,
-                                             p->get_relocated_address (objfile),
-                                             bp_longjmp_master,
-                                             &internal_breakpoint_ops);
-             b->location = new_probe_location ("-probe-stap libc:longjmp");
-             b->enable_state = bp_disabled;
-           }
+           continue;
+         }
 
+       if (!gdbarch_get_longjmp_target_p (gdbarch))
          continue;
-       }
 
-      if (!gdbarch_get_longjmp_target_p (gdbarch))
-       continue;
-
-      for (i = 0; i < NUM_LONGJMP_NAMES; i++)
-       {
-         struct breakpoint *b;
-         const char *func_name;
-         CORE_ADDR addr;
-         struct explicit_location explicit_loc;
+       for (i = 0; i < NUM_LONGJMP_NAMES; i++)
+         {
+           struct breakpoint *b;
+           const char *func_name;
+           CORE_ADDR addr;
+           struct explicit_location explicit_loc;
 
-         if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
-           continue;
+           if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
+             continue;
 
-         func_name = longjmp_names[i];
-         if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
-           {
-             struct bound_minimal_symbol m;
+           func_name = longjmp_names[i];
+           if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
+             {
+               struct bound_minimal_symbol m;
 
-             m = lookup_minimal_symbol_text (func_name, objfile);
-             if (m.minsym == NULL)
-               {
-                 /* Prevent future lookups in this objfile.  */
-                 bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
-                 continue;
-               }
-             bp_objfile_data->longjmp_msym[i] = m;
-           }
+               m = lookup_minimal_symbol_text (func_name, objfile);
+               if (m.minsym == NULL)
+                 {
+                   /* Prevent future lookups in this objfile.  */
+                   bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
+                   continue;
+                 }
+               bp_objfile_data->longjmp_msym[i] = m;
+             }
 
-         addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
-         b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
-                                         &internal_breakpoint_ops);
-         initialize_explicit_location (&explicit_loc);
-         explicit_loc.function_name = ASTRDUP (func_name);
-         b->location = new_explicit_location (&explicit_loc);
-         b->enable_state = bp_disabled;
-       }
-    }
+           addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
+           b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
+                                           &internal_breakpoint_ops);
+           initialize_explicit_location (&explicit_loc);
+           explicit_loc.function_name = ASTRDUP (func_name);
+           b->location = new_explicit_location (&explicit_loc);
+           b->enable_state = bp_disabled;
+         }
+      }
   }
 }
 
@@ -3376,46 +3331,45 @@ create_std_terminate_master_breakpoint (void)
 
   ALL_PSPACES (pspace)
   {
-    struct objfile *objfile;
     CORE_ADDR addr;
 
     set_current_program_space (pspace);
 
-    ALL_OBJFILES (objfile)
-    {
-      struct breakpoint *b;
-      struct breakpoint_objfile_data *bp_objfile_data;
-      struct explicit_location explicit_loc;
+    for (objfile *objfile : current_program_space->objfiles ())
+      {
+       struct breakpoint *b;
+       struct breakpoint_objfile_data *bp_objfile_data;
+       struct explicit_location explicit_loc;
 
-      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-      if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
-       continue;
+       if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
+         continue;
 
-      if (bp_objfile_data->terminate_msym.minsym == NULL)
-       {
-         struct bound_minimal_symbol m;
+       if (bp_objfile_data->terminate_msym.minsym == NULL)
+         {
+           struct bound_minimal_symbol m;
 
-         m = lookup_minimal_symbol (func_name, NULL, objfile);
-         if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
-                                  && MSYMBOL_TYPE (m.minsym) != mst_file_text))
-           {
-             /* Prevent future lookups in this objfile.  */
-             bp_objfile_data->terminate_msym.minsym = &msym_not_found;
-             continue;
-           }
-         bp_objfile_data->terminate_msym = m;
-       }
+           m = lookup_minimal_symbol (func_name, NULL, objfile);
+           if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
+                                    && MSYMBOL_TYPE (m.minsym) != mst_file_text))
+             {
+               /* Prevent future lookups in this objfile.  */
+               bp_objfile_data->terminate_msym.minsym = &msym_not_found;
+               continue;
+             }
+           bp_objfile_data->terminate_msym = m;
+         }
 
-      addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
-      b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
-                                      bp_std_terminate_master,
-                                     &internal_breakpoint_ops);
-      initialize_explicit_location (&explicit_loc);
-      explicit_loc.function_name = ASTRDUP (func_name);
-      b->location = new_explicit_location (&explicit_loc);
-      b->enable_state = bp_disabled;
-    }
+       addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
+       b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
+                                       bp_std_terminate_master,
+                                       &internal_breakpoint_ops);
+       initialize_explicit_location (&explicit_loc);
+       explicit_loc.function_name = ASTRDUP (func_name);
+       b->location = new_explicit_location (&explicit_loc);
+       b->enable_state = bp_disabled;
+      }
   }
 }
 
@@ -3424,10 +3378,9 @@ create_std_terminate_master_breakpoint (void)
 static void
 create_exception_master_breakpoint (void)
 {
-  struct objfile *objfile;
   const char *const func_name = "_Unwind_DebugHook";
 
-  ALL_OBJFILES (objfile)
+  for (objfile *objfile : current_program_space->objfiles ())
     {
       struct breakpoint *b;
       struct gdbarch *gdbarch;
@@ -3461,12 +3414,10 @@ create_exception_master_breakpoint (void)
 
       if (!bp_objfile_data->exception_probes.empty ())
        {
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         gdbarch = get_objfile_arch (objfile);
 
          for (probe *p : bp_objfile_data->exception_probes)
            {
-             struct breakpoint *b;
-
              b = create_internal_breakpoint (gdbarch,
                                              p->get_relocated_address (objfile),
                                              bp_exception_master,
@@ -3501,7 +3452,7 @@ create_exception_master_breakpoint (void)
 
       addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
       addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-                                                &current_target);
+                                                current_top_target ());
       b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
                                      &internal_breakpoint_ops);
       initialize_explicit_location (&explicit_loc);
@@ -3649,7 +3600,7 @@ detach_breakpoints (ptid_t ptid)
   scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
   struct inferior *inf = current_inferior ();
 
-  if (ptid_get_pid (ptid) == ptid_get_pid (inferior_ptid))
+  if (ptid.pid () == inferior_ptid.pid ())
     error (_("Cannot detach breakpoints of inferior_ptid"));
 
   /* Set inferior_ptid; remove_breakpoint_1 uses this global.  */
@@ -3872,8 +3823,6 @@ void
 breakpoint_init_inferior (enum inf_context context)
 {
   struct breakpoint *b, *b_tmp;
-  struct bp_location *bl;
-  int ix;
   struct program_space *pspace = current_program_space;
 
   /* If breakpoint locations are shared across processes, then there's
@@ -3951,10 +3900,8 @@ breakpoint_init_inferior (enum inf_context context)
                {
                  /* Reset val field to force reread of starting value in
                     insert_breakpoints.  */
-                 if (w->val)
-                   value_free (w->val);
-                 w->val = NULL;
-                 w->val_valid = 0;
+                 w->val.reset (nullptr);
+                 w->val_valid = false;
                }
            }
        }
@@ -3965,9 +3912,9 @@ breakpoint_init_inferior (enum inf_context context)
   }
 
   /* Get rid of the moribund locations.  */
-  for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, bl); ++ix)
+  for (bp_location *bl : moribund_locations)
     decref_bp_location (&bl);
-  VEC_free (bp_location_p, moribund_locations);
+  moribund_locations.clear ();
 }
 
 /* These functions concern about actual breakpoints inserted in the
@@ -4055,10 +4002,7 @@ breakpoint_in_range_p (const address_space *aspace,
 int
 moribund_breakpoint_here_p (const address_space *aspace, CORE_ADDR pc)
 {
-  struct bp_location *loc;
-  int ix;
-
-  for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+  for (bp_location *loc : moribund_locations)
     if (breakpoint_location_address_match (loc, aspace, pc))
       return 1;
 
@@ -4183,15 +4127,13 @@ hardware_watchpoint_inserted_in_range (const address_space *aspace,
     }
   return 0;
 }
-\f
 
-/* bpstat stuff.  External routines' interfaces are documented
-   in breakpoint.h.  */
+/* See breakpoint.h.  */
 
-int
-is_catchpoint (struct breakpoint *ep)
+bool
+is_catchpoint (struct breakpoint *b)
 {
-  return (ep->type == bp_catchpoint);
+  return (b->type == bp_catchpoint);
 }
 
 /* Frees any storage that is part of a bpstat.  Does not walk the
@@ -4199,8 +4141,6 @@ is_catchpoint (struct breakpoint *ep)
 
 bpstats::~bpstats ()
 {
-  if (old_val != NULL)
-    value_free (old_val);
   if (bp_location_at != NULL)
     decref_bp_location (&bp_location_at);
 }
@@ -4231,16 +4171,12 @@ bpstats::bpstats (const bpstats &other)
     bp_location_at (other.bp_location_at),
     breakpoint_at (other.breakpoint_at),
     commands (other.commands),
-    old_val (other.old_val),
     print (other.print),
     stop (other.stop),
     print_it (other.print_it)
 {
-  if (old_val != NULL)
-    {
-      old_val = value_copy (old_val);
-      release_value (old_val);
-    }
+  if (other.old_val != NULL)
+    old_val = release_value (value_copy (other.old_val.get ()));
   incref_bp_location (bp_location_at);
 }
 
@@ -4290,7 +4226,7 @@ bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
 
 /* See breakpoint.h.  */
 
-int
+bool
 bpstat_explains_signal (bpstat bsp, enum gdb_signal sig)
 {
   for (; bsp != NULL; bsp = bsp->next)
@@ -4300,17 +4236,17 @@ bpstat_explains_signal (bpstat bsp, enum gdb_signal sig)
          /* A moribund location can never explain a signal other than
             GDB_SIGNAL_TRAP.  */
          if (sig == GDB_SIGNAL_TRAP)
-           return 1;
+           return true;
        }
       else
        {
          if (bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at,
                                                        sig))
-           return 1;
+           return true;
        }
     }
 
-  return 0;
+  return false;
 }
 
 /* Put in *NUM the breakpoint number of the first breakpoint we are
@@ -4348,25 +4284,16 @@ bpstat_num (bpstat *bsp, int *num)
 void
 bpstat_clear_actions (void)
 {
-  struct thread_info *tp;
   bpstat bs;
 
-  if (ptid_equal (inferior_ptid, null_ptid))
-    return;
-
-  tp = find_thread_ptid (inferior_ptid);
-  if (tp == NULL)
+  if (inferior_ptid == null_ptid)
     return;
 
+  thread_info *tp = inferior_thread ();
   for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
     {
       bs->commands = NULL;
-
-      if (bs->old_val != NULL)
-       {
-         value_free (bs->old_val);
-         bs->old_val = NULL;
-       }
+      bs->old_val.reset (nullptr);
     }
 }
 
@@ -4375,7 +4302,7 @@ bpstat_clear_actions (void)
 static void
 breakpoint_about_to_proceed (void)
 {
-  if (!ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid != null_ptid)
     {
       struct thread_info *tp = inferior_thread ();
 
@@ -4490,24 +4417,39 @@ bpstat_do_actions_1 (bpstat *bsp)
   return again;
 }
 
+/* Helper for bpstat_do_actions.  Get the current thread, if there's
+   one, is alive and has execution.  Return NULL otherwise.  */
+
+static thread_info *
+get_bpstat_thread ()
+{
+  if (inferior_ptid == null_ptid || !target_has_execution)
+    return NULL;
+
+  thread_info *tp = inferior_thread ();
+  if (tp->state == THREAD_EXITED || tp->executing)
+    return NULL;
+  return tp;
+}
+
 void
 bpstat_do_actions (void)
 {
-  struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
+  auto cleanup_if_error = make_scope_exit (bpstat_clear_actions);
+  thread_info *tp;
 
   /* Do any commands attached to breakpoint we are stopped at.  */
-  while (!ptid_equal (inferior_ptid, null_ptid)
-        && target_has_execution
-        && !is_exited (inferior_ptid)
-        && !is_executing (inferior_ptid))
-    /* Since in sync mode, bpstat_do_actions may resume the inferior,
-       and only return when it is stopped at the next breakpoint, we
-       keep doing breakpoint actions until it returns false to
-       indicate the inferior was not resumed.  */
-    if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
-      break;
+  while ((tp = get_bpstat_thread ()) != NULL)
+    {
+      /* Since in sync mode, bpstat_do_actions may resume the
+        inferior, and only return when it is stopped at the next
+        breakpoint, we keep doing breakpoint actions until it returns
+        false to indicate the inferior was not resumed.  */
+      if (!bpstat_do_actions_1 (&tp->control.stop_bpstat))
+       break;
+    }
 
-  discard_cleanups (cleanup_if_error);
+  cleanup_if_error.release ();
 }
 
 /* Print out the (old or new) value associated with a watchpoint.  */
@@ -4516,7 +4458,7 @@ static void
 watchpoint_value_print (struct value *val, struct ui_file *stream)
 {
   if (val == NULL)
-    fprintf_unfiltered (stream, _("<unreadable>"));
+    fprintf_styled (stream, metadata_style.style (), _("<unreadable>"));
   else
     {
       struct value_print_options opts;
@@ -4542,13 +4484,13 @@ maybe_print_thread_hit_breakpoint (struct ui_out *uiout)
       struct thread_info *thr = inferior_thread ();
 
       uiout->text ("Thread ");
-      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 ("\"");
        }
 
@@ -4604,10 +4546,8 @@ print_bp_stop_message (bpstat bs)
 static void
 print_solib_event (int is_catchpoint)
 {
-  int any_deleted
-    = !VEC_empty (char_ptr, current_program_space->deleted_solibs);
-  int any_added
-    = !VEC_empty (so_list_ptr, current_program_space->added_solibs);
+  bool any_deleted = !current_program_space->deleted_solibs.empty ();
+  bool any_added = !current_program_space->added_solibs.empty ();
 
   if (!is_catchpoint)
     {
@@ -4624,16 +4564,12 @@ print_solib_event (int is_catchpoint)
 
   if (any_deleted)
     {
-      char *name;
-      int ix;
-
       current_uiout->text (_("  Inferior unloaded "));
       ui_out_emit_list list_emitter (current_uiout, "removed");
-      for (ix = 0;
-          VEC_iterate (char_ptr, current_program_space->deleted_solibs,
-                       ix, name);
-          ++ix)
+      for (int ix = 0; ix < current_program_space->deleted_solibs.size (); ix++)
        {
+         const std::string &name = current_program_space->deleted_solibs[ix];
+
          if (ix > 0)
            current_uiout->text ("    ");
          current_uiout->field_string ("library", name);
@@ -4643,18 +4579,14 @@ print_solib_event (int is_catchpoint)
 
   if (any_added)
     {
-      struct so_list *iter;
-      int ix;
-
       current_uiout->text (_("  Inferior loaded "));
       ui_out_emit_list list_emitter (current_uiout, "added");
-      for (ix = 0;
-          VEC_iterate (so_list_ptr, current_program_space->added_solibs,
-                       ix, iter);
-          ++ix)
+      bool first = true;
+      for (so_list *iter : current_program_space->added_solibs)
        {
-         if (ix > 0)
+         if (!first)
            current_uiout->text ("    ");
+         first = false;
          current_uiout->field_string ("library", iter->so_name);
          current_uiout->text ("\n");
        }
@@ -4733,7 +4665,6 @@ bpstats::bpstats (struct bp_location *bl, bpstat **bs_link_pointer)
     bp_location_at (bl),
     breakpoint_at (bl->owner),
     commands (NULL),
-    old_val (NULL),
     print (0),
     stop (0),
     print_it (print_it_normal)
@@ -4748,7 +4679,6 @@ bpstats::bpstats ()
     bp_location_at (NULL),
     breakpoint_at (NULL),
     commands (NULL),
-    old_val (NULL),
     print (0),
     stop (0),
     print_it (print_it_normal)
@@ -4761,7 +4691,7 @@ bpstats::bpstats ()
 int
 watchpoints_triggered (struct target_waitstatus *ws)
 {
-  int stopped_by_watchpoint = target_stopped_by_watchpoint ();
+  bool stopped_by_watchpoint = target_stopped_by_watchpoint ();
   CORE_ADDR addr;
   struct breakpoint *b;
 
@@ -4780,7 +4710,7 @@ watchpoints_triggered (struct target_waitstatus *ws)
       return 0;
     }
 
-  if (!target_stopped_data_address (&current_target, &addr))
+  if (!target_stopped_data_address (current_top_target (), &addr))
     {
       /* We were stopped by a watchpoint, but we don't know where.
         Mark all watchpoints as unknown.  */
@@ -4820,7 +4750,7 @@ watchpoints_triggered (struct target_waitstatus *ws)
                  }
              }
            /* Exact match not required.  Within range is sufficient.  */
-           else if (target_watchpoint_addr_within_range (&current_target,
+           else if (target_watchpoint_addr_within_range (current_top_target (),
                                                         addr, loc->address,
                                                         loc->length))
              {
@@ -4943,16 +4873,14 @@ watchpoint_check (bpstat bs)
         the address of the array instead of its contents.  This is
         not what we want.  */
       if ((b->val != NULL) != (new_val != NULL)
-         || (b->val != NULL && !value_equal_contents (b->val, new_val)))
+         || (b->val != NULL && !value_equal_contents (b->val.get (),
+                                                      new_val)))
        {
-         if (new_val != NULL)
-           {
-             release_value (new_val);
-             value_free_to_mark (mark);
-           }
          bs->old_val = b->val;
-         b->val = new_val;
-         b->val_valid = 1;
+         b->val = release_value (new_val);
+         b->val_valid = true;
+         if (new_val != NULL)
+           value_free_to_mark (mark);
          return WP_VALUE_CHANGED;
        }
       else
@@ -4985,10 +4913,10 @@ watchpoint_check (bpstat bs)
          if (uiout->is_mi_like_p ())
            uiout->field_string
              ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
-         uiout->text ("\nWatchpoint ");
-         uiout->field_int ("wpnum", b->number);
-         uiout->text (" deleted because the program has left the block in\n"
-                      "which its expression is valid.\n");
+         uiout->message ("\nWatchpoint %pF deleted because the program has "
+                         "left the block in\n"
+                         "which its expression is valid.\n",
+                         signed_field ("wpnum", b->number));
        }
 
       /* Make sure the watchpoint's commands aren't executed.  */
@@ -5055,11 +4983,11 @@ bpstat_check_watchpoint (bpstat bs)
        {
          wp_check_result e;
 
-         TRY
+         try
            {
              e = watchpoint_check (bs);
            }
-         CATCH (ex, RETURN_MASK_ALL)
+         catch (const gdb_exception &ex)
            {
              exception_fprintf (gdb_stderr, ex,
                                 "Error evaluating expression "
@@ -5074,7 +5002,6 @@ bpstat_check_watchpoint (bpstat bs)
              watchpoint_del_at_next_stop (b);
              e = WP_DELETED;
            }
-         END_CATCH
 
          switch (e)
            {
@@ -5192,7 +5119,7 @@ bpstat_check_watchpoint (bpstat bs)
    breakpoint, set BS->stop to 0.  */
 
 static void
-bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
+bpstat_check_breakpoint_conditions (bpstat bs, thread_info *thread)
 {
   const struct bp_location *bl;
   struct breakpoint *b;
@@ -5222,9 +5149,8 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
   /* If this is a thread/task-specific breakpoint, don't waste cpu
      evaluating the condition if this isn't the specified
      thread/task.  */
-  if ((b->thread != -1 && b->thread != ptid_to_global_thread_id (ptid))
-      || (b->task != 0 && b->task != ada_get_task_number (ptid)))
-
+  if ((b->thread != -1 && b->thread != thread->global_num)
+      || (b->task != 0 && b->task != ada_get_task_number (thread)))
     {
       bs->stop = 0;
       return;
@@ -5294,16 +5220,15 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
        }
       if (within_current_scope)
        {
-         TRY
+         try
            {
              condition_result = breakpoint_cond_eval (cond);
            }
-         CATCH (ex, RETURN_MASK_ALL)
+         catch (const gdb_exception &ex)
            {
              exception_fprintf (gdb_stderr, ex,
                                 "Error in testing breakpoint condition:\n");
            }
-         END_CATCH
        }
       else
        {
@@ -5326,7 +5251,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
       bs->stop = 0;
       /* Increase the hit count even though we don't stop.  */
       ++(b->hit_count);
-      observer_notify_breakpoint_modified (b);
+      gdb::observers::breakpoint_modified.notify (b);
     }  
 }
 
@@ -5342,54 +5267,21 @@ need_moribund_for_location_type (struct bp_location *loc)
              && !target_supports_stopped_by_hw_breakpoint ()));
 }
 
-
-/* Get a bpstat associated with having just stopped at address
-   BP_ADDR in thread PTID.
-
-   Determine whether we stopped at a breakpoint, etc, or whether we
-   don't understand this stop.  Result is a chain of bpstat's such
-   that:
-
-   if we don't understand the stop, the result is a null pointer.
-
-   if we understand why we stopped, the result is not null.
-
-   Each element of the chain refers to a particular breakpoint or
-   watchpoint at which we have stopped.  (We may have stopped for
-   several reasons concurrently.)
-
-   Each element of the chain has valid next, breakpoint_at,
-   commands, FIXME??? fields.  */
+/* See breakpoint.h.  */
 
 bpstat
-bpstat_stop_status (const address_space *aspace,
-                   CORE_ADDR bp_addr, ptid_t ptid,
+build_bpstat_chain (const address_space *aspace, CORE_ADDR bp_addr,
                    const struct target_waitstatus *ws)
 {
-  struct breakpoint *b = NULL;
-  struct bp_location *bl;
-  struct bp_location *loc;
-  /* First item of allocated bpstat's.  */
+  struct breakpoint *b;
   bpstat bs_head = NULL, *bs_link = &bs_head;
-  /* Pointer to the last thing in the chain currently.  */
-  bpstat bs;
-  int ix;
-  int need_remove_insert;
-  int removed_any;
-
-  /* First, build the bpstat chain with locations that explain a
-     target stop, while being careful to not set the target running,
-     as that may invalidate locations (in particular watchpoint
-     locations are recreated).  Resuming will happen here with
-     breakpoint conditions or watchpoint expressions that include
-     inferior function calls.  */
 
   ALL_BREAKPOINTS (b)
     {
       if (!breakpoint_enabled (b))
        continue;
 
-      for (bl = b->loc; bl != NULL; bl = bl->next)
+      for (bp_location *bl = b->loc; bl != NULL; bl = bl->next)
        {
          /* For hardware watchpoints, we look only at the first
             location.  The watchpoint_check function will work on the
@@ -5408,8 +5300,8 @@ bpstat_stop_status (const address_space *aspace,
          /* Come here if it's a watchpoint, or if the break address
             matches.  */
 
-         bs = new bpstats (bl, &bs_link);      /* Alloc a bpstat to
-                                                  explain stop.  */
+         bpstat bs = new bpstats (bl, &bs_link);       /* Alloc a bpstat to
+                                                          explain stop.  */
 
          /* Assume we stop.  Should we find a watchpoint that is not
             actually triggered, or if the condition of the breakpoint
@@ -5434,12 +5326,12 @@ bpstat_stop_status (const address_space *aspace,
   if (!target_supports_stopped_by_sw_breakpoint ()
       || !target_supports_stopped_by_hw_breakpoint ())
     {
-      for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+      for (bp_location *loc : moribund_locations)
        {
          if (breakpoint_location_address_match (loc, aspace, bp_addr)
              && need_moribund_for_location_type (loc))
            {
-             bs = new bpstats (loc, &bs_link);
+             bpstat bs = new bpstats (loc, &bs_link);
              /* For hits of moribund locations, we should just proceed.  */
              bs->stop = 0;
              bs->print = 0;
@@ -5448,6 +5340,33 @@ bpstat_stop_status (const address_space *aspace,
        }
     }
 
+  return bs_head;
+}
+
+/* See breakpoint.h.  */
+
+bpstat
+bpstat_stop_status (const address_space *aspace,
+                   CORE_ADDR bp_addr, thread_info *thread,
+                   const struct target_waitstatus *ws,
+                   bpstat stop_chain)
+{
+  struct breakpoint *b = NULL;
+  /* First item of allocated bpstat's.  */
+  bpstat bs_head = stop_chain;
+  bpstat bs;
+  int need_remove_insert;
+  int removed_any;
+
+  /* First, build the bpstat chain with locations that explain a
+     target stop, while being careful to not set the target running,
+     as that may invalidate locations (in particular watchpoint
+     locations are recreated).  Resuming will happen here with
+     breakpoint conditions or watchpoint expressions that include
+     inferior function calls.  */
+  if (bs_head == NULL)
+    bs_head = build_bpstat_chain (aspace, bp_addr, ws);
+
   /* A bit of special processing for shlib breakpoints.  We need to
      process solib loading here, so that the lists of loaded and
      unloaded libraries are correct before we handle "catch load" and
@@ -5476,12 +5395,12 @@ bpstat_stop_status (const address_space *aspace,
       b->ops->check_status (bs);
       if (bs->stop)
        {
-         bpstat_check_breakpoint_conditions (bs, ptid);
+         bpstat_check_breakpoint_conditions (bs, thread);
 
          if (bs->stop)
            {
              ++(b->hit_count);
-             observer_notify_breakpoint_modified (b);
+             gdb::observers::breakpoint_modified.notify (b);
 
              /* We will stop here.  */
              if (b->disposition == disp_disable)
@@ -5567,7 +5486,7 @@ bpstat_what (bpstat bs_head)
 
   retval.main_action = BPSTAT_WHAT_KEEP_CHECKING;
   retval.call_dummy = STOP_NONE;
-  retval.is_longjmp = 0;
+  retval.is_longjmp = false;
 
   for (bs = bs_head; bs != NULL; bs = bs->next)
     {
@@ -5679,8 +5598,10 @@ bpstat_what (bpstat bs_head)
            }
          else
            {
-             /* There was a catchpoint, but we're not stopping.
-                This requires no further action.  */
+             /* Some catchpoints are implemented with breakpoints.
+                For those, we need to step over the breakpoint.  */
+             if (bs->bp_location_at->loc_type != bp_loc_other)
+               this_action = BPSTAT_WHAT_SINGLE;
            }
          break;
        case bp_jit_event:
@@ -5761,29 +5682,29 @@ bpstat_run_callbacks (bpstat bs_head)
     }
 }
 
-/* Nonzero if we should step constantly (e.g. watchpoints on machines
-   without hardware support).  This isn't related to a specific bpstat,
-   just to things like whether watchpoints are set.  */
+/* See breakpoint.h.  */
 
-int
-bpstat_should_step (void)
+bool
+bpstat_should_step ()
 {
   struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
     if (breakpoint_enabled (b) && b->type == bp_watchpoint && b->loc != NULL)
-      return 1;
-  return 0;
+      return true;
+  return false;
 }
 
-int
+/* See breakpoint.h.  */
+
+bool
 bpstat_causes_stop (bpstat bs)
 {
   for (; bs != NULL; bs = bs->next)
     if (bs->stop)
-      return 1;
+      return true;
 
-  return 0;
+  return false;
 }
 
 \f
@@ -5899,25 +5820,24 @@ print_breakpoint_location (struct breakpoint *b,
     {
       const struct symbol *sym = loc->symbol;
 
-      if (sym == NULL)
-       sym = find_pc_sect_function (loc->address, loc->section);
-
       if (sym)
        {
          uiout->text ("in ");
-         uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+         uiout->field_string ("func", sym->print_name (),
+                              function_name_style.style ());
          uiout->text (" ");
          uiout->wrap_hint (wrap_indent_at_field (uiout, "what"));
          uiout->text ("at ");
        }
       uiout->field_string ("file",
-                          symtab_to_filename_for_display (loc->symtab));
+                          symtab_to_filename_for_display (loc->symtab),
+                          file_name_style.style ());
       uiout->text (":");
 
       if (uiout->is_mi_like_p ())
        uiout->field_string ("fullname", symtab_to_fullname (loc->symtab));
       
-      uiout->field_int ("line", loc->line_number);
+      uiout->field_signed ("line", loc->line_number);
     }
   else if (loc)
     {
@@ -6049,14 +5969,18 @@ output_thread_groups (struct ui_out *uiout,
     }
 }
 
-/* Print B to gdb_stdout.  */
+/* Print B to gdb_stdout.  If RAW_LOC, print raw breakpoint locations
+   instead of going via breakpoint_ops::print_one.  This makes "maint
+   info breakpoints" show the software breakpoint locations of
+   catchpoints, which are considered internal implementation
+   detail.  */
 
 static void
 print_one_breakpoint_location (struct breakpoint *b,
                               struct bp_location *loc,
                               int loc_number,
                               struct bp_location **last_loc,
-                              int allflag)
+                              int allflag, bool raw_loc)
 {
   struct command_line *l;
   static char bpenables[] = "nynny";
@@ -6083,16 +6007,9 @@ print_one_breakpoint_location (struct breakpoint *b,
   /* 1 */
   annotate_field (0);
   if (part_of_multiple)
-    {
-      char *formatted;
-      formatted = xstrprintf ("%d.%d", b->number, loc_number);
-      uiout->field_string ("number", formatted);
-      xfree (formatted);
-    }
+    uiout->field_fmt ("number", "%d.%d", b->number, loc_number);
   else
-    {
-      uiout->field_int ("number", b->number);
-    }
+    uiout->field_signed ("number", b->number);
 
   /* 2 */
   annotate_field (1);
@@ -6108,37 +6025,19 @@ print_one_breakpoint_location (struct breakpoint *b,
   else
     uiout->field_string ("disp", bpdisp_text (b->disposition));
 
-
   /* 4 */
   annotate_field (3);
   if (part_of_multiple)
     uiout->field_string ("enabled", loc->enabled ? "y" : "n");
   else
     uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]);
-  uiout->spaces (2);
 
-  
   /* 5 and 6 */
-  if (b->ops != NULL && b->ops->print_one != NULL)
-    {
-      /* Although the print_one can possibly print all locations,
-        calling it here is not likely to get any nice result.  So,
-        make sure there's just one location.  */
-      gdb_assert (b->loc == NULL || b->loc->next == NULL);
-      b->ops->print_one (b, last_loc);
-    }
+  if (!raw_loc && b->ops != NULL && b->ops->print_one != NULL)
+    b->ops->print_one (b, last_loc);
   else
-    switch (b->type)
-      {
-      case bp_none:
-       internal_error (__FILE__, __LINE__,
-                       _("print_one_breakpoint: bp_none encountered\n"));
-       break;
-
-      case bp_watchpoint:
-      case bp_hardware_watchpoint:
-      case bp_read_watchpoint:
-      case bp_access_watchpoint:
+    {
+      if (is_watchpoint (b))
        {
          struct watchpoint *w = (struct watchpoint *) b;
 
@@ -6150,63 +6049,36 @@ print_one_breakpoint_location (struct breakpoint *b,
          annotate_field (5);
          uiout->field_string ("what", w->exp_string);
        }
-       break;
-
-      case bp_breakpoint:
-      case bp_hardware_breakpoint:
-      case bp_single_step:
-      case bp_until:
-      case bp_finish:
-      case bp_longjmp:
-      case bp_longjmp_resume:
-      case bp_longjmp_call_dummy:
-      case bp_exception:
-      case bp_exception_resume:
-      case bp_step_resume:
-      case bp_hp_step_resume:
-      case bp_watchpoint_scope:
-      case bp_call_dummy:
-      case bp_std_terminate:
-      case bp_shlib_event:
-      case bp_thread_event:
-      case bp_overlay_event:
-      case bp_longjmp_master:
-      case bp_std_terminate_master:
-      case bp_exception_master:
-      case bp_tracepoint:
-      case bp_fast_tracepoint:
-      case bp_static_tracepoint:
-      case bp_dprintf:
-      case bp_jit_event:
-      case bp_gnu_ifunc_resolver:
-      case bp_gnu_ifunc_resolver_return:
-       if (opts.addressprint)
-         {
-           annotate_field (4);
-           if (header_of_multiple)
-             uiout->field_string ("addr", "<MULTIPLE>");
-           else if (b->loc == NULL || loc->shlib_disabled)
-             uiout->field_string ("addr", "<PENDING>");
-           else
-             uiout->field_core_addr ("addr",
-                                     loc->gdbarch, loc->address);
-         }
-       annotate_field (5);
-       if (!header_of_multiple)
-         print_breakpoint_location (b, loc);
-       if (b->loc)
-         *last_loc = b->loc;
-       break;
-      }
-
+      else if (!is_catchpoint (b) || is_exception_catchpoint (b)
+              || is_ada_exception_catchpoint (b))
+       {
+         if (opts.addressprint)
+           {
+             annotate_field (4);
+             if (header_of_multiple)
+               uiout->field_string ("addr", "<MULTIPLE>",
+                                    metadata_style.style ());
+             else if (b->loc == NULL || loc->shlib_disabled)
+               uiout->field_string ("addr", "<PENDING>",
+                                    metadata_style.style ());
+             else
+               uiout->field_core_addr ("addr",
+                                       loc->gdbarch, loc->address);
+           }
+         annotate_field (5);
+         if (!header_of_multiple)
+           print_breakpoint_location (b, loc);
+         if (b->loc)
+           *last_loc = b->loc;
+       }
+    }
 
   if (loc != NULL && !header_of_multiple)
     {
-      struct inferior *inf;
       std::vector<int> inf_nums;
       int mi_only = 1;
 
-      ALL_INFERIORS (inf)
+      for (inferior *inf : all_inferiors ())
        {
          if (inf->pspace == loc->pspace)
            inf_nums.push_back (inf->num);
@@ -6232,12 +6104,12 @@ print_one_breakpoint_location (struct breakpoint *b,
          /* FIXME: This seems to be redundant and lost here; see the
             "stop only in" line a little further down.  */
          uiout->text (" thread ");
-         uiout->field_int ("thread", b->thread);
+         uiout->field_signed ("thread", b->thread);
        }
       else if (b->task != 0)
        {
          uiout->text (" task ");
-         uiout->field_int ("task", b->task);
+         uiout->field_signed ("task", b->task);
        }
     }
 
@@ -6272,10 +6144,9 @@ print_one_breakpoint_location (struct breakpoint *b,
          && breakpoint_condition_evaluation_mode ()
          == condition_evaluation_target)
        {
-         uiout->text (" (");
-         uiout->field_string ("evaluated-by",
-                              bp_condition_evaluator (b));
-         uiout->text (" evals)");
+         uiout->message (" (%pF evals)",
+                         string_field ("evaluated-by",
+                                       bp_condition_evaluator (b)));
        }
       uiout->text ("\n");
     }
@@ -6285,7 +6156,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       /* FIXME should make an annotation for this.  */
       uiout->text ("\tstop only in thread ");
       if (uiout->is_mi_like_p ())
-       uiout->field_int ("thread", b->thread);
+       uiout->field_signed ("thread", b->thread);
       else
        {
          struct thread_info *thr = find_thread_global_id (b->thread);
@@ -6307,7 +6178,7 @@ print_one_breakpoint_location (struct breakpoint *b,
          else
            uiout->text ("\tbreakpoint");
          uiout->text (" already hit ");
-         uiout->field_int ("times", b->hit_count);
+         uiout->field_signed ("times", b->hit_count);
          if (b->hit_count == 1)
            uiout->text (" time\n");
          else
@@ -6317,16 +6188,15 @@ print_one_breakpoint_location (struct breakpoint *b,
        {
          /* Output the count also if it is zero, but only if this is mi.  */
          if (uiout->is_mi_like_p ())
-           uiout->field_int ("times", b->hit_count);
+           uiout->field_signed ("times", b->hit_count);
        }
     }
 
   if (!part_of_multiple && b->ignore_count)
     {
       annotate_field (8);
-      uiout->text ("\tignore next ");
-      uiout->field_int ("ignore", b->ignore_count);
-      uiout->text (" hits\n");
+      uiout->message ("\tignore next %pF hits\n",
+                     signed_field ("ignore", b->ignore_count));
     }
 
   /* Note that an enable count of 1 corresponds to "enable once"
@@ -6342,7 +6212,7 @@ print_one_breakpoint_location (struct breakpoint *b,
        uiout->text ("additional ");
       else
        uiout->text ("next ");
-      uiout->field_int ("enable", b->enable_count);
+      uiout->field_signed ("enable", b->enable_count);
       uiout->text (" hits\n");
     }
 
@@ -6353,7 +6223,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       if (tp->traceframe_usage)
        {
          uiout->text ("\ttrace buffer usage ");
-         uiout->field_int ("traceframe-usage", tp->traceframe_usage);
+         uiout->field_signed ("traceframe-usage", tp->traceframe_usage);
          uiout->text (" bytes\n");
        }
     }
@@ -6374,7 +6244,7 @@ print_one_breakpoint_location (struct breakpoint *b,
        {
          annotate_field (10);
          uiout->text ("\tpass count ");
-         uiout->field_int ("pass", t->pass_count);
+         uiout->field_signed ("pass", t->pass_count);
          uiout->text (" \n");
        }
 
@@ -6413,23 +6283,34 @@ print_one_breakpoint_location (struct breakpoint *b,
     }
 }
 
+/* See breakpoint.h. */
+
+bool fix_multi_location_breakpoint_output_globally = false;
+
 static void
 print_one_breakpoint (struct breakpoint *b,
                      struct bp_location **last_loc, 
                      int allflag)
 {
   struct ui_out *uiout = current_uiout;
+  bool use_fixed_output
+    = (uiout->test_flags (fix_multi_location_breakpoint_output)
+       || fix_multi_location_breakpoint_output_globally);
 
-  {
-    ui_out_emit_tuple tuple_emitter (uiout, "bkpt");
+  gdb::optional<ui_out_emit_tuple> bkpt_tuple_emitter (gdb::in_place, uiout, "bkpt");
+  print_one_breakpoint_location (b, NULL, 0, last_loc, allflag, false);
 
-    print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
-  }
+  /* The mi2 broken format: the main breakpoint tuple ends here, the locations
+     are outside.  */
+  if (!use_fixed_output)
+    bkpt_tuple_emitter.reset ();
 
   /* If this breakpoint has custom print function,
      it's already printed.  Otherwise, print individual
      locations, if any.  */
-  if (b->ops == NULL || b->ops->print_one == NULL)
+  if (b->ops == NULL
+      || b->ops->print_one == NULL
+      || allflag)
     {
       /* If breakpoint has a single location that is disabled, we
         print it as if it had several locations, since otherwise it's
@@ -6437,18 +6318,32 @@ print_one_breakpoint (struct breakpoint *b,
         situation.
 
         Note that while hardware watchpoints have several locations
-        internally, that's not a property exposed to user.  */
-      if (b->loc 
-         && !is_hardware_watchpoint (b)
-         && (b->loc->next || !b->loc->enabled))
-       {
-         struct bp_location *loc;
-         int n = 1;
+        internally, that's not a property exposed to users.
+
+        Likewise, while catchpoints may be implemented with
+        breakpoints (e.g., catch throw), that's not a property
+        exposed to users.  We do however display the internal
+        breakpoint locations with "maint info breakpoints".  */
+      if (!is_hardware_watchpoint (b)
+         && (!is_catchpoint (b) || is_exception_catchpoint (b)
+             || is_ada_exception_catchpoint (b))
+         && (allflag
+             || (b->loc && (b->loc->next || !b->loc->enabled))))
+       {
+         gdb::optional<ui_out_emit_list> locations_list;
+
+         /* For MI version <= 2, keep the behavior where GDB outputs an invalid
+            MI record.  For later versions, place breakpoint locations in a
+            list.  */
+         if (uiout->is_mi_like_p () && use_fixed_output)
+           locations_list.emplace (uiout, "locations");
 
-         for (loc = b->loc; loc; loc = loc->next, ++n)
+         int n = 1;
+         for (bp_location *loc = b->loc; loc != NULL; loc = loc->next, ++n)
            {
-             ui_out_emit_tuple tuple_emitter (uiout, NULL);
-             print_one_breakpoint_location (b, loc, n, last_loc, allflag);
+             ui_out_emit_tuple loc_tuple_emitter (uiout, NULL);
+             print_one_breakpoint_location (b, loc, n, last_loc,
+                                            allflag, allflag);
            }
        }
     }
@@ -6503,16 +6398,22 @@ pending_breakpoint_p (struct breakpoint *b)
   return b->loc == NULL;
 }
 
-/* Print information on user settable breakpoint (watchpoint, etc)
-   number BNUM.  If BNUM is -1 print all user-settable breakpoints.
-   If ALLFLAG is non-zero, include non-user-settable breakpoints.  If
-   FILTER is non-NULL, call it on each breakpoint and only include the
-   ones for which it returns non-zero.  Return the total number of
-   breakpoints listed.  */
+/* Print information on breakpoints (including watchpoints and tracepoints).
+
+   If non-NULL, BP_NUM_LIST is a list of numbers and number ranges as
+   understood by number_or_range_parser.  Only breakpoints included in this
+   list are then printed.
+
+   If SHOW_INTERNAL is true, print internal breakpoints.
+
+   If FILTER is non-NULL, call it on each breakpoint and only include the
+   ones for which it returns true.
+
+   Return the total number of breakpoints listed.  */
 
 static int
-breakpoint_1 (const char *args, int allflag, 
-             int (*filter) (const struct breakpoint *))
+breakpoint_1 (const char *bp_num_list, bool show_internal,
+             bool (*filter) (const struct breakpoint *))
 {
   struct breakpoint *b;
   struct bp_location *last_loc = NULL;
@@ -6533,17 +6434,17 @@ breakpoint_1 (const char *args, int allflag,
       if (filter && !filter (b))
        continue;
 
-      /* If we have an "args" string, it is a list of breakpoints to 
+      /* If we have a BP_NUM_LIST string, it is a list of breakpoints to
         accept.  Skip the others.  */
-      if (args != NULL && *args != '\0')
+      if (bp_num_list != NULL && *bp_num_list != '\0')
        {
-         if (allflag && parse_and_eval_long (args) != b->number)
+         if (show_internal && parse_and_eval_long (bp_num_list) != b->number)
            continue;
-         if (!allflag && !number_is_in_list (args, b->number))
+         if (!show_internal && !number_is_in_list (bp_num_list, b->number))
            continue;
        }
 
-      if (allflag || user_breakpoint_p (b))
+      if (show_internal || user_breakpoint_p (b))
        {
          int addr_bit, type_len;
 
@@ -6602,26 +6503,26 @@ breakpoint_1 (const char *args, int allflag,
        if (filter && !filter (b))
          continue;
 
-       /* If we have an "args" string, it is a list of breakpoints to 
+       /* If we have a BP_NUM_LIST string, it is a list of breakpoints to
           accept.  Skip the others.  */
 
-       if (args != NULL && *args != '\0')
+       if (bp_num_list != NULL && *bp_num_list != '\0')
          {
-           if (allflag)        /* maintenance info breakpoint */
+           if (show_internal)  /* maintenance info breakpoint */
              {
-               if (parse_and_eval_long (args) != b->number)
+               if (parse_and_eval_long (bp_num_list) != b->number)
                  continue;
              }
            else                /* all others */
              {
-               if (!number_is_in_list (args, b->number))
+               if (!number_is_in_list (bp_num_list, b->number))
                  continue;
              }
          }
        /* We only print out user settable breakpoints unless the
-          allflag is set.  */
-       if (allflag || user_breakpoint_p (b))
-         print_one_breakpoint (b, &last_loc, allflag);
+          show_internal is set.  */
+       if (show_internal || user_breakpoint_p (b))
+         print_one_breakpoint (b, &last_loc, show_internal);
       }
   }
 
@@ -6631,11 +6532,11 @@ breakpoint_1 (const char *args, int allflag,
         empty list.  */
       if (!filter)
        {
-         if (args == NULL || *args == '\0')
+         if (bp_num_list == NULL || *bp_num_list == '\0')
            uiout->message ("No breakpoints or watchpoints.\n");
          else
            uiout->message ("No breakpoint or watchpoint matching '%s'.\n",
-                           args);
+                           bp_num_list);
        }
     }
   else
@@ -6675,7 +6576,7 @@ default_collect_info (void)
 static void
 info_breakpoints_command (const char *args, int from_tty)
 {
-  breakpoint_1 (args, 0, NULL);
+  breakpoint_1 (args, false, NULL);
 
   default_collect_info ();
 }
@@ -6683,7 +6584,7 @@ info_breakpoints_command (const char *args, int from_tty)
 static void
 info_watchpoints_command (const char *args, int from_tty)
 {
-  int num_printed = breakpoint_1 (args, 0, is_watchpoint);
+  int num_printed = breakpoint_1 (args, false, is_watchpoint);
   struct ui_out *uiout = current_uiout;
 
   if (num_printed == 0)
@@ -6698,7 +6599,7 @@ info_watchpoints_command (const char *args, int from_tty)
 static void
 maintenance_info_breakpoints (const char *args, int from_tty)
 {
-  breakpoint_1 (args, 1, NULL);
+  breakpoint_1 (args, true, NULL);
 
   default_collect_info ();
 }
@@ -6758,34 +6659,28 @@ describe_other_breakpoints (struct gdbarch *gdbarch,
                             (others > 1) ? "," 
                             : ((others == 1) ? " and" : ""));
          }
-      printf_filtered (_("also set at pc "));
-      fputs_filtered (paddress (gdbarch, pc), gdb_stdout);
-      printf_filtered (".\n");
+      current_uiout->message (_("also set at pc %ps.\n"),
+                             styled_string (address_style.style (),
+                                            paddress (gdbarch, pc)));
     }
 }
 \f
 
-/* Return true iff it is meaningful to use the address member of
-   BPT locations.  For some breakpoint types, the locations' address members
-   are irrelevant and it makes no sense to attempt to compare them to other
-   addresses (or use them for any other purpose either).
+/* Return true iff it is meaningful to use the address member of LOC.
+   For some breakpoint types, the locations' address members are
+   irrelevant and it makes no sense to attempt to compare them to
+   other addresses (or use them for any other purpose either).
 
-   More specifically, each of the following breakpoint types will
-   always have a zero valued location address and we don't want to mark
-   breakpoints of any of these types to be a duplicate of an actual
-   breakpoint location at address zero:
+   More specifically, software watchpoints and catchpoints that are
+   not backed by breakpoints always have a zero valued location
+   address and we don't want to mark breakpoints of any of these types
+   to be a duplicate of an actual breakpoint location at address
+   zero.  */
 
-      bp_watchpoint
-      bp_catchpoint
-
-*/
-
-static int
-breakpoint_address_is_meaningful (struct breakpoint *bpt)
+static bool
+bl_address_is_meaningful (bp_location *loc)
 {
-  enum bptype type = bpt->type;
-
-  return (type != bp_watchpoint && type != bp_catchpoint);
+  return loc->loc_type != bp_loc_other;
 }
 
 /* Assuming LOC1 and LOC2's owners are hardware watchpoints, returns
@@ -6917,8 +6812,8 @@ tracepoint_locations_match (struct bp_location *loc1,
 }
 
 /* Assuming LOC1 and LOC2's types' have meaningful target addresses
-   (breakpoint_address_is_meaningful), returns true if LOC1 and LOC2
-   represent the same location.  */
+   (bl_address_is_meaningful), returns true if LOC1 and LOC2 represent
+   the same location.  */
 
 static int
 breakpoint_locations_match (struct bp_location *loc1, 
@@ -7016,19 +6911,10 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
     }
 }
 
-bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner)
+static bp_loc_type
+bp_location_from_bp_type (bptype type)
 {
-  bp_location *loc = this;
-
-  gdb_assert (ops != NULL);
-
-  loc->ops = ops;
-  loc->owner = owner;
-  loc->cond_bytecode = NULL;
-  loc->shlib_disabled = 0;
-  loc->enabled = 1;
-
-  switch (owner->type)
+  switch (type)
     {
     case bp_breakpoint:
     case bp_single_step:
@@ -7054,30 +6940,44 @@ bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner)
     case bp_gnu_ifunc_resolver:
     case bp_gnu_ifunc_resolver_return:
     case bp_dprintf:
-      loc->loc_type = bp_loc_software_breakpoint;
-      mark_breakpoint_location_modified (loc);
-      break;
+      return bp_loc_software_breakpoint;
     case bp_hardware_breakpoint:
-      loc->loc_type = bp_loc_hardware_breakpoint;
-      mark_breakpoint_location_modified (loc);
-      break;
+      return bp_loc_hardware_breakpoint;
     case bp_hardware_watchpoint:
     case bp_read_watchpoint:
     case bp_access_watchpoint:
-      loc->loc_type = bp_loc_hardware_watchpoint;
-      break;
+      return bp_loc_hardware_watchpoint;
     case bp_watchpoint:
     case bp_catchpoint:
     case bp_tracepoint:
     case bp_fast_tracepoint:
     case bp_static_tracepoint:
-      loc->loc_type = bp_loc_other;
-      break;
+      return bp_loc_other;
     default:
       internal_error (__FILE__, __LINE__, _("unknown breakpoint type"));
     }
+}
+
+bp_location::bp_location (breakpoint *owner, bp_loc_type type)
+{
+  this->owner = owner;
+  this->cond_bytecode = NULL;
+  this->shlib_disabled = 0;
+  this->enabled = 1;
+
+  this->loc_type = type;
+
+  if (this->loc_type == bp_loc_software_breakpoint
+      || this->loc_type == bp_loc_hardware_breakpoint)
+    mark_breakpoint_location_modified (this);
+
+  this->refc = 1;
+}
 
-  loc->refc = 1;
+bp_location::bp_location (breakpoint *owner)
+  : bp_location::bp_location (owner,
+                             bp_location_from_bp_type (owner->type))
+{
 }
 
 /* Allocate a struct bp_location.  */
@@ -7091,7 +6991,6 @@ allocate_bp_location (struct breakpoint *bpt)
 static void
 free_bp_location (struct bp_location *loc)
 {
-  loc->ops->dtor (loc);
   delete loc;
 }
 
@@ -7172,12 +7071,10 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
   return add_to_breakpoint_chain (std::move (b));
 }
 
-/* Initialize loc->function_name.  EXPLICIT_LOC says no indirect function
-   resolutions should be made as the user specified the location explicitly
-   enough.  */
+/* Initialize loc->function_name.  */
 
 static void
-set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
+set_breakpoint_location_function (struct bp_location *loc)
 {
   gdb_assert (loc->owner != NULL);
 
@@ -7185,37 +7082,29 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
       || loc->owner->type == bp_hardware_breakpoint
       || is_tracepoint (loc->owner))
     {
-      int is_gnu_ifunc;
       const char *function_name;
-      CORE_ADDR func_addr;
-
-      find_pc_partial_function_gnu_ifunc (loc->address, &function_name,
-                                         &func_addr, NULL, &is_gnu_ifunc);
 
-      if (is_gnu_ifunc && !explicit_loc)
+      if (loc->msymbol != NULL
+         && (MSYMBOL_TYPE (loc->msymbol) == mst_text_gnu_ifunc
+             || MSYMBOL_TYPE (loc->msymbol) == mst_data_gnu_ifunc))
        {
          struct breakpoint *b = loc->owner;
 
-         gdb_assert (loc->pspace == current_program_space);
-         if (gnu_ifunc_resolve_name (function_name,
-                                     &loc->requested_address))
-           {
-             /* Recalculate ADDRESS based on new REQUESTED_ADDRESS.  */
-             loc->address = adjust_breakpoint_address (loc->gdbarch,
-                                                       loc->requested_address,
-                                                       b->type);
-           }
-         else if (b->type == bp_breakpoint && b->loc == loc
-                  && loc->next == NULL && b->related_breakpoint == b)
+         function_name = loc->msymbol->linkage_name ();
+
+         if (b->type == bp_breakpoint && b->loc == loc
+             && loc->next == NULL && b->related_breakpoint == b)
            {
              /* Create only the whole new breakpoint of this type but do not
                 mess more complicated breakpoints with multiple locations.  */
              b->type = bp_gnu_ifunc_resolver;
              /* Remember the resolver's address for use by the return
                 breakpoint.  */
-             loc->related_address = func_addr;
+             loc->related_address = loc->address;
            }
        }
+      else
+       find_pc_partial_function (loc->address, &function_name, NULL, NULL);
 
       if (function_name)
        loc->function_name = xstrdup (function_name);
@@ -7364,7 +7253,7 @@ set_longjmp_breakpoint_for_call_dummy (void)
        new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
                                                  &momentary_breakpoint_ops,
                                                  1);
-       new_b->thread = ptid_to_global_thread_id (inferior_ptid);
+       new_b->thread = inferior_thread ()->global_num;
 
        /* Link NEW_B into the chain of RETVAL breakpoints.  */
 
@@ -7404,7 +7293,7 @@ check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp)
            || frame_find_by_id (dummy_b->frame_id) != NULL)
          continue;
        
-       dummy_frame_discard (dummy_b->frame_id, tp->ptid);
+       dummy_frame_discard (dummy_b->frame_id, tp);
 
        while (b->related_breakpoint != b)
          {
@@ -7644,7 +7533,7 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
        loc->inserted = 0;
 
        /* This may cause duplicate notifications for the same breakpoint.  */
-       observer_notify_breakpoint_modified (b);
+       gdb::observers::breakpoint_modified.notify (b);
 
        if (!disabled_shlib_breaks)
          {
@@ -7727,7 +7616,7 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile)
        }
 
       if (bp_modified)
-       observer_notify_breakpoint_modified (b);
+       gdb::observers::breakpoint_modified.notify (b);
     }
 }
 
@@ -7751,7 +7640,7 @@ struct fork_catchpoint : public breakpoint
 static int
 insert_catch_fork (struct bp_location *bl)
 {
-  return target_insert_fork_catchpoint (ptid_get_pid (inferior_ptid));
+  return target_insert_fork_catchpoint (inferior_ptid.pid ());
 }
 
 /* Implement the "remove" breakpoint_ops method for fork
@@ -7760,7 +7649,7 @@ insert_catch_fork (struct bp_location *bl)
 static int
 remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason)
 {
-  return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
+  return target_remove_fork_catchpoint (inferior_ptid.pid ());
 }
 
 /* Implement the "breakpoint_hit" breakpoint_ops method for fork
@@ -7801,9 +7690,9 @@ print_it_catch_fork (bpstat bs)
       uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_FORK));
       uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  uiout->field_int ("bkptno", b->number);
+  uiout->field_signed ("bkptno", b->number);
   uiout->text (" (forked process ");
-  uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+  uiout->field_signed ("newpid", c->forked_inferior_pid.pid ());
   uiout->text ("), ");
   return PRINT_SRC_AND_LOC;
 }
@@ -7827,10 +7716,10 @@ print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc)
     uiout->field_skip ("addr");
   annotate_field (5);
   uiout->text ("fork");
-  if (!ptid_equal (c->forked_inferior_pid, null_ptid))
+  if (c->forked_inferior_pid != null_ptid)
     {
       uiout->text (", process ");
-      uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+      uiout->field_signed ("what", c->forked_inferior_pid.pid ());
       uiout->spaces (1);
     }
 
@@ -7867,7 +7756,7 @@ static struct breakpoint_ops catch_fork_breakpoint_ops;
 static int
 insert_catch_vfork (struct bp_location *bl)
 {
-  return target_insert_vfork_catchpoint (ptid_get_pid (inferior_ptid));
+  return target_insert_vfork_catchpoint (inferior_ptid.pid ());
 }
 
 /* Implement the "remove" breakpoint_ops method for vfork
@@ -7876,7 +7765,7 @@ insert_catch_vfork (struct bp_location *bl)
 static int
 remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason)
 {
-  return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
+  return target_remove_vfork_catchpoint (inferior_ptid.pid ());
 }
 
 /* Implement the "breakpoint_hit" breakpoint_ops method for vfork
@@ -7917,9 +7806,9 @@ print_it_catch_vfork (bpstat bs)
       uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_VFORK));
       uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  uiout->field_int ("bkptno", b->number);
+  uiout->field_signed ("bkptno", b->number);
   uiout->text (" (vforked process ");
-  uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+  uiout->field_signed ("newpid", c->forked_inferior_pid.pid ());
   uiout->text ("), ");
   return PRINT_SRC_AND_LOC;
 }
@@ -7942,10 +7831,10 @@ print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc)
     uiout->field_skip ("addr");
   annotate_field (5);
   uiout->text ("vfork");
-  if (!ptid_equal (c->forked_inferior_pid, null_ptid))
+  if (c->forked_inferior_pid != null_ptid)
     {
       uiout->text (", process ");
-      uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+      uiout->field_signed ("what", c->forked_inferior_pid.pid ());
       uiout->spaces (1);
     }
 
@@ -8050,16 +7939,10 @@ check_status_catch_solib (struct bpstats *bs)
 {
   struct solib_catchpoint *self
     = (struct solib_catchpoint *) bs->breakpoint_at;
-  int ix;
 
   if (self->is_load)
     {
-      struct so_list *iter;
-
-      for (ix = 0;
-          VEC_iterate (so_list_ptr, current_program_space->added_solibs,
-                       ix, iter);
-          ++ix)
+      for (so_list *iter : current_program_space->added_solibs)
        {
          if (!self->regex
              || self->compiled->exec (iter->so_name, 0, NULL, 0) == 0)
@@ -8068,15 +7951,10 @@ check_status_catch_solib (struct bpstats *bs)
     }
   else
     {
-      char *iter;
-
-      for (ix = 0;
-          VEC_iterate (char_ptr, current_program_space->deleted_solibs,
-                       ix, iter);
-          ++ix)
+      for (const std::string &iter : current_program_space->deleted_solibs)
        {
          if (!self->regex
-             || self->compiled->exec (iter, 0, NULL, 0) == 0)
+             || self->compiled->exec (iter.c_str (), 0, NULL, 0) == 0)
            return;
        }
     }
@@ -8097,7 +7975,7 @@ print_it_catch_solib (bpstat bs)
     uiout->text ("Temporary catchpoint ");
   else
     uiout->text ("Catchpoint ");
-  uiout->field_int ("bkptno", b->number);
+  uiout->field_signed ("bkptno", b->number);
   uiout->text ("\n");
   if (uiout->is_mi_like_p ())
     uiout->field_string ("disp", bpdisp_text (b->disposition));
@@ -8111,7 +7989,6 @@ print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
   struct solib_catchpoint *self = (struct solib_catchpoint *) b;
   struct value_print_options opts;
   struct ui_out *uiout = current_uiout;
-  char *msg;
 
   get_user_print_options (&opts);
   /* Field 4, the address, is omitted (which makes the columns not
@@ -8123,23 +8000,23 @@ print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
       uiout->field_skip ("addr");
     }
 
+  std::string msg;
   annotate_field (5);
   if (self->is_load)
     {
       if (self->regex)
-       msg = xstrprintf (_("load of library matching %s"), self->regex);
+       msg = string_printf (_("load of library matching %s"), self->regex);
       else
-       msg = xstrdup (_("load of library"));
+       msg = _("load of library");
     }
   else
     {
       if (self->regex)
-       msg = xstrprintf (_("unload of library matching %s"), self->regex);
+       msg = string_printf (_("unload of library matching %s"), self->regex);
       else
-       msg = xstrdup (_("unload of library"));
+       msg = _("unload of library");
     }
   uiout->field_string ("what", msg);
-  xfree (msg);
 
   if (uiout->is_mi_like_p ())
     uiout->field_string ("catch-type", self->is_load ? "load" : "unload");
@@ -8261,7 +8138,7 @@ install_breakpoint (int internal, std::unique_ptr<breakpoint> &&arg, int update_
     set_tracepoint_count (breakpoint_count);
   if (!internal)
     mention (b);
-  observer_notify_breakpoint_created (b);
+  gdb::observers::breakpoint_created.notify (b);
 
   if (update_gll)
     update_global_location_list (UGLL_MAY_INSERT);
@@ -8307,13 +8184,13 @@ exec_catchpoint::~exec_catchpoint ()
 static int
 insert_catch_exec (struct bp_location *bl)
 {
-  return target_insert_exec_catchpoint (ptid_get_pid (inferior_ptid));
+  return target_insert_exec_catchpoint (inferior_ptid.pid ());
 }
 
 static int
 remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason)
 {
-  return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
+  return target_remove_exec_catchpoint (inferior_ptid.pid ());
 }
 
 static int
@@ -8348,7 +8225,7 @@ print_it_catch_exec (bpstat bs)
       uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXEC));
       uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  uiout->field_int ("bkptno", b->number);
+  uiout->field_signed ("bkptno", b->number);
   uiout->text (" (exec'd ");
   uiout->field_string ("new-exec", c->exec_pathname);
   uiout->text ("), ");
@@ -8556,11 +8433,7 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
   b->disposition = disp_donttouch;
   b->frame_id = frame_id;
 
-  /* If we're debugging a multi-threaded program, then we want
-     momentary breakpoints to be active in only a single thread of
-     control.  */
-  if (in_thread_list (inferior_ptid))
-    b->thread = ptid_to_global_thread_id (inferior_ptid);
+  b->thread = inferior_thread ()->global_num;
 
   update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
@@ -8581,7 +8454,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig,
 
   copy = set_raw_breakpoint_without_location (orig->gdbarch, type, ops);
   copy->loc = allocate_bp_location (copy);
-  set_breakpoint_location_function (copy->loc, 1);
+  set_breakpoint_location_function (copy->loc);
 
   copy->loc->gdbarch = orig->loc->gdbarch;
   copy->loc->requested_address = orig->loc->requested_address;
@@ -8638,9 +8511,7 @@ static void
 mention (struct breakpoint *b)
 {
   b->ops->print_mention (b);
-  if (current_uiout->is_mi_like_p ())
-    return;
-  printf_filtered ("\n");
+  current_uiout->text ("\n");
 }
 \f
 
@@ -8685,9 +8556,10 @@ add_location_to_breakpoint (struct breakpoint *b,
   loc->line_number = sal->line;
   loc->symtab = sal->symtab;
   loc->symbol = sal->symbol;
+  loc->msymbol = sal->msymbol;
+  loc->objfile = sal->objfile;
 
-  set_breakpoint_location_function (loc,
-                                   sal->explicit_pc || sal->explicit_line);
+  set_breakpoint_location_function (loc);
 
   /* While by definition, permanent breakpoints are already present in the
      code, we don't mark the location as inserted.  Normally one would expect
@@ -8749,11 +8621,12 @@ bp_loc_is_permanent (struct bp_location *loc)
 {
   gdb_assert (loc != NULL);
 
-  /* If we have a catchpoint or a watchpoint, just return 0.  We should not
-     attempt to read from the addresses the locations of these breakpoint types
-     point to.  program_breakpoint_here_p, below, will attempt to read
+  /* If we have a non-breakpoint-backed catchpoint or a software
+     watchpoint, just return 0.  We should not attempt to read from
+     the addresses the locations of these breakpoint types point to.
+     program_breakpoint_here_p, below, will attempt to read
      memory.  */
-  if (!breakpoint_address_is_meaningful (loc->owner))
+  if (!bl_address_is_meaningful (loc))
     return 0;
 
   scoped_restore_current_pspace_and_thread restore_pspace_thread;
@@ -8816,18 +8689,12 @@ update_dprintf_command_list (struct breakpoint *b)
                    _("Invalid dprintf style."));
 
   gdb_assert (printf_line != NULL);
-  /* Manufacture a printf sequence.  */
-  {
-    struct command_line *printf_cmd_line = XNEW (struct command_line);
-
-    printf_cmd_line->control_type = simple_control;
-    printf_cmd_line->body_count = 0;
-    printf_cmd_line->body_list = NULL;
-    printf_cmd_line->next = NULL;
-    printf_cmd_line->line = printf_line;
 
-    breakpoint_set_commands (b, command_line_up (printf_cmd_line));
-  }
+  /* Manufacture a printf sequence.  */
+  struct command_line *printf_cmd_line
+    = new struct command_line (simple_control, printf_line);
+  breakpoint_set_commands (b, counted_command_line (printf_cmd_line,
+                                                   command_lines_deleter ()));
 }
 
 /* Update all dprintf commands, making their command lists reflect
@@ -8923,27 +8790,24 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                  const char *p
                    = &event_location_to_string (b->location.get ())[3];
                  const char *endp;
-                 char *marker_str;
 
                  p = skip_spaces (p);
 
                  endp = skip_to_space (p);
 
-                 marker_str = savestring (p, endp - p);
-                 t->static_trace_marker_id = marker_str;
+                 t->static_trace_marker_id.assign (p, endp - p);
 
                  printf_filtered (_("Probed static tracepoint "
                                     "marker \"%s\"\n"),
-                                  t->static_trace_marker_id);
+                                  t->static_trace_marker_id.c_str ());
                }
              else if (target_static_tracepoint_marker_at (sal.pc, &marker))
                {
-                 t->static_trace_marker_id = xstrdup (marker.str_id);
-                 release_static_tracepoint_marker (&marker);
+                 t->static_trace_marker_id = std::move (marker.str_id);
 
                  printf_filtered (_("Probed static tracepoint "
                                     "marker \"%s\"\n"),
-                                  t->static_trace_marker_id);
+                                  t->static_trace_marker_id.c_str ());
                }
              else
                warning (_("Couldn't determine the static "
@@ -8987,7 +8851,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
     b->location = std::move (location);
   else
     b->location = new_address_location (b->loc->address, NULL, 0);
-  b->filter = filter.release ();
+  b->filter = std::move (filter);
 }
 
 static void
@@ -9177,10 +9041,6 @@ static void
 check_fast_tracepoint_sals (struct gdbarch *gdbarch,
                            gdb::array_view<const symtab_and_line> sals)
 {
-  int rslt;
-  char *msg;
-  struct cleanup *old_chain;
-
   for (const auto &sal : sals)
     {
       struct gdbarch *sarch;
@@ -9190,14 +9050,10 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch,
         associated with SAL.  */
       if (sarch == NULL)
        sarch = gdbarch;
-      rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal.pc, &msg);
-      old_chain = make_cleanup (xfree, msg);
-
-      if (!rslt)
+      std::string msg;
+      if (!gdbarch_fast_tracepoint_valid_at (sarch, sal.pc, &msg))
        error (_("May not have a fast tracepoint at %s%s"),
-              paddress (sarch, sal.pc), (msg ? msg : ""));
-
-      do_cleanups (old_chain);
+              paddress (sarch, sal.pc), msg.c_str ());
     }
 }
 
@@ -9283,10 +9139,8 @@ find_condition_and_thread (const char *tok, CORE_ADDR pc,
 static std::vector<symtab_and_line>
 decode_static_tracepoint_spec (const char **arg_p)
 {
-  VEC(static_tracepoint_marker_p) *markers = NULL;
   const char *p = &(*arg_p)[3];
   const char *endp;
-  int i;
 
   p = skip_spaces (p);
 
@@ -9294,29 +9148,59 @@ decode_static_tracepoint_spec (const char **arg_p)
 
   std::string marker_str (p, endp - p);
 
-  markers = target_static_tracepoint_markers_by_strid (marker_str.c_str ());
-  if (VEC_empty(static_tracepoint_marker_p, markers))
+  std::vector<static_tracepoint_marker> markers
+    = target_static_tracepoint_markers_by_strid (marker_str.c_str ());
+  if (markers.empty ())
     error (_("No known static tracepoint marker named %s"),
           marker_str.c_str ());
 
   std::vector<symtab_and_line> sals;
-  sals.reserve (VEC_length(static_tracepoint_marker_p, markers));
+  sals.reserve (markers.size ());
 
-  for (i = 0; i < VEC_length(static_tracepoint_marker_p, markers); i++)
+  for (const static_tracepoint_marker &marker : markers)
     {
-      struct static_tracepoint_marker *marker;
+      symtab_and_line sal = find_pc_line (marker.address, 0);
+      sal.pc = marker.address;
+      sals.push_back (sal);
+   }
 
-      marker = VEC_index (static_tracepoint_marker_p, markers, i);
+  *arg_p = endp;
+  return sals;
+}
 
-      symtab_and_line sal = find_pc_line (marker->address, 0);
-      sal.pc = marker->address;
-      sals.push_back (sal);
+/* Returns the breakpoint ops appropriate for use with with LOCATION_TYPE and
+   according to IS_TRACEPOINT.  */
 
-      release_static_tracepoint_marker (marker);
+static const struct breakpoint_ops *
+breakpoint_ops_for_event_location_type (enum event_location_type location_type,
+                                       bool is_tracepoint)
+{
+  if (is_tracepoint)
+    {
+      if (location_type == PROBE_LOCATION)
+       return &tracepoint_probe_breakpoint_ops;
+      else
+       return &tracepoint_breakpoint_ops;
     }
+  else
+    {
+      if (location_type == PROBE_LOCATION)
+       return &bkpt_probe_breakpoint_ops;
+      else
+       return &bkpt_breakpoint_ops;
+    }
+}
 
-  *arg_p = endp;
-  return sals;
+/* See breakpoint.h.  */
+
+const struct breakpoint_ops *
+breakpoint_ops_for_event_location (const struct event_location *location,
+                                  bool is_tracepoint)
+{
+  if (location != nullptr)
+    return breakpoint_ops_for_event_location_type
+      (event_location_type (location), is_tracepoint);
+  return is_tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
 }
 
 /* See breakpoint.h.  */
@@ -9335,7 +9219,6 @@ create_breakpoint (struct gdbarch *gdbarch,
                   unsigned flags)
 {
   struct linespec_result canonical;
-  struct cleanup *bkpt_chain = NULL;
   int pending = 0;
   int task = 0;
   int prev_bkpt_count = breakpoint_count;
@@ -9346,11 +9229,11 @@ create_breakpoint (struct gdbarch *gdbarch,
   if (extra_string != NULL && *extra_string == '\0')
     extra_string = NULL;
 
-  TRY
+  try
     {
       ops->create_sals_from_location (location, &canonical, type_wanted);
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
       /* If caller is interested in rc value from parse, set
         value.  */
@@ -9360,7 +9243,7 @@ create_breakpoint (struct gdbarch *gdbarch,
             error.  */
 
          if (pending_break_support == AUTO_BOOLEAN_FALSE)
-           throw_exception (e);
+           throw;
 
          exception_print (gdb_stderr, e);
 
@@ -9378,19 +9261,12 @@ create_breakpoint (struct gdbarch *gdbarch,
          pending = 1;
        }
       else
-       throw_exception (e);
+       throw;
     }
-  END_CATCH
 
   if (!pending && canonical.lsals.empty ())
     return 0;
 
-  /* ----------------------------- SNIP -----------------------------
-     Anything added to the cleanup chain beyond this point is assumed
-     to be part of a breakpoint.  If the breakpoint create succeeds
-     then the memory is not reclaimed.  */
-  bkpt_chain = make_cleanup (null_cleanup, 0);
-
   /* Resolve all line numbers to PC's and verify that the addresses
      are ok for the target.  */
   if (!pending)
@@ -9489,11 +9365,6 @@ create_breakpoint (struct gdbarch *gdbarch,
       prev_breakpoint_count = prev_bkpt_count;
     }
 
-  /* That's it.  Discard the cleanups for data inserted into the
-     breakpoint.  */
-  discard_cleanups (bkpt_chain);
-
-  /* error call may happen here - have BKPT_CHAIN already discarded.  */
   update_global_location_list (UGLL_MAY_INSERT);
 
   return 1;
@@ -9513,16 +9384,10 @@ break_command_1 (const char *arg, int flag, int from_tty)
   enum bptype type_wanted = (flag & BP_HARDWAREFLAG
                             ? bp_hardware_breakpoint
                             : bp_breakpoint);
-  struct breakpoint_ops *ops;
 
   event_location_up location = string_to_event_location (&arg, current_language);
-
-  /* Matching breakpoints on probes.  */
-  if (location != NULL
-      && event_location_type (location.get ()) == PROBE_LOCATION)
-    ops = &bkpt_probe_breakpoint_ops;
-  else
-    ops = &bkpt_breakpoint_ops;
+  const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
+    (location.get (), false /* is_tracepoint */);
 
   create_breakpoint (get_current_arch (),
                     location.get (),
@@ -9629,7 +9494,7 @@ stopin_command (const char *arg, int from_tty)
 {
   int badInput = 0;
 
-  if (arg == (char *) NULL)
+  if (arg == NULL)
     badInput = 1;
   else if (*arg != '*')
     {
@@ -9662,7 +9527,7 @@ stopat_command (const char *arg, int from_tty)
 {
   int badInput = 0;
 
-  if (arg == (char *) NULL || *arg == '*')     /* no line number */
+  if (arg == NULL || *arg == '*')      /* no line number */
     badInput = 1;
   else
     {
@@ -9684,7 +9549,7 @@ stopat_command (const char *arg, int from_tty)
     }
 
   if (badInput)
-    printf_filtered (_("Usage: stop at <line>\n"));
+    printf_filtered (_("Usage: stop at LINE\n"));
   else
     break_command_1 (arg, 0, from_tty);
 }
@@ -9786,7 +9651,7 @@ print_it_ranged_breakpoint (bpstat bs)
                      async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
       uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  uiout->field_int ("bkptno", b->number);
+  uiout->field_signed ("bkptno", b->number);
   uiout->text (", ");
 
   return PRINT_SRC_AND_LOC;
@@ -9853,12 +9718,9 @@ print_mention_ranged_breakpoint (struct breakpoint *b)
   gdb_assert (bl);
   gdb_assert (b->type == bp_hardware_breakpoint);
 
-  if (uiout->is_mi_like_p ())
-    return;
-
-  printf_filtered (_("Hardware assisted ranged breakpoint %d from %s to %s."),
-                  b->number, paddress (bl->gdbarch, bl->address),
-                  paddress (bl->gdbarch, bl->address + bl->length - 1));
+  uiout->message (_("Hardware assisted ranged breakpoint %d from %s to %s."),
+                 b->number, paddress (bl->gdbarch, bl->address),
+                 paddress (bl->gdbarch, bl->address + bl->length - 1));
 }
 
 /* Implement the "print_recreate" breakpoint_ops method for
@@ -10008,7 +9870,7 @@ break_range_command (const char *arg, int from_tty)
   b->loc->length = length;
 
   mention (b);
-  observer_notify_breakpoint_created (b);
+  gdb::observers::breakpoint_created.notify (b);
   update_global_location_list (UGLL_MAY_INSERT);
 }
 
@@ -10131,7 +9993,6 @@ watchpoint::~watchpoint ()
 {
   xfree (this->exp_string);
   xfree (this->exp_string_reparse);
-  value_free (this->val);
 }
 
 /* Implement the "re_set" breakpoint_ops method for watchpoints.  */
@@ -10273,10 +10134,10 @@ print_it_watchpoint (bpstat bs)
       mention (b);
       tuple_emitter.emplace (uiout, "value");
       uiout->text ("\nOld value = ");
-      watchpoint_value_print (bs->old_val, &stb);
+      watchpoint_value_print (bs->old_val.get (), &stb);
       uiout->field_stream ("old", stb);
       uiout->text ("\nNew value = ");
-      watchpoint_value_print (w->val, &stb);
+      watchpoint_value_print (w->val.get (), &stb);
       uiout->field_stream ("new", stb);
       uiout->text ("\n");
       /* More than one watchpoint may have been triggered.  */
@@ -10290,7 +10151,7 @@ print_it_watchpoint (bpstat bs)
       mention (b);
       tuple_emitter.emplace (uiout, "value");
       uiout->text ("\nValue = ");
-      watchpoint_value_print (w->val, &stb);
+      watchpoint_value_print (w->val.get (), &stb);
       uiout->field_stream ("value", stb);
       uiout->text ("\n");
       result = PRINT_UNKNOWN;
@@ -10306,7 +10167,7 @@ print_it_watchpoint (bpstat bs)
          mention (b);
          tuple_emitter.emplace (uiout, "value");
          uiout->text ("\nOld value = ");
-         watchpoint_value_print (bs->old_val, &stb);
+         watchpoint_value_print (bs->old_val.get (), &stb);
          uiout->field_stream ("old", stb);
          uiout->text ("\nNew value = ");
        }
@@ -10320,7 +10181,7 @@ print_it_watchpoint (bpstat bs)
          tuple_emitter.emplace (uiout, "value");
          uiout->text ("\nValue = ");
        }
-      watchpoint_value_print (w->val, &stb);
+      watchpoint_value_print (w->val.get (), &stb);
       uiout->field_stream ("new", stb);
       uiout->text ("\n");
       result = PRINT_UNKNOWN;
@@ -10366,7 +10227,7 @@ print_mention_watchpoint (struct breakpoint *b)
     }
 
   ui_out_emit_tuple tuple_emitter (uiout, tuple_name);
-  uiout->field_int ("number", b->number);
+  uiout->field_signed ("number", b->number);
   uiout->text (": ");
   uiout->field_string ("exp", w->exp_string);
 }
@@ -10559,7 +10420,7 @@ print_mention_masked_watchpoint (struct breakpoint *b)
     }
 
   ui_out_emit_tuple tuple_emitter (uiout, tuple_name);
-  uiout->field_int ("number", b->number);
+  uiout->field_signed ("number", b->number);
   uiout->text (": ");
   uiout->field_string ("exp", w->exp_string);
 }
@@ -10600,7 +10461,7 @@ static struct breakpoint_ops masked_watchpoint_breakpoint_ops;
 
 /* Tell whether the given watchpoint is a masked hardware watchpoint.  */
 
-static int
+static bool
 is_masked_watchpoint (const struct breakpoint *b)
 {
   return b->ops == &masked_watchpoint_breakpoint_ops;
@@ -10615,7 +10476,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
 {
   struct breakpoint *scope_breakpoint = NULL;
   const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
-  struct value *val, *mark, *result;
+  struct value *result;
   int saved_bitpos = 0, saved_bitsize = 0;
   const char *exp_start = NULL;
   const char *exp_end = NULL;
@@ -10717,10 +10578,10 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   /* Parse the rest of the arguments.  From here on out, everything
      is in terms of a newly allocated string instead of the original
      ARG.  */
-  innermost_block = NULL;
   std::string expression (arg, exp_end - arg);
   exp_start = arg = expression.c_str ();
-  expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
+  innermost_block_tracker tracker;
+  expression_up exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
   exp_end = arg;
   /* Remove trailing whitespace from the expression before saving it.
      This makes the eventual display of the expression string a bit
@@ -10739,28 +10600,30 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
       error (_("Cannot watch constant value `%.*s'."), len, exp_start);
     }
 
-  exp_valid_block = innermost_block;
-  mark = value_mark ();
-  fetch_subexp_value (exp.get (), &pc, &val, &result, NULL, just_location);
+  exp_valid_block = tracker.block ();
+  struct value *mark = value_mark ();
+  struct value *val_as_value = nullptr;
+  fetch_subexp_value (exp.get (), &pc, &val_as_value, &result, NULL,
+                     just_location);
 
-  if (val != NULL && just_location)
+  if (val_as_value != NULL && just_location)
     {
-      saved_bitpos = value_bitpos (val);
-      saved_bitsize = value_bitsize (val);
+      saved_bitpos = value_bitpos (val_as_value);
+      saved_bitsize = value_bitsize (val_as_value);
     }
 
+  value_ref_ptr val;
   if (just_location)
     {
       int ret;
 
       exp_valid_block = NULL;
-      val = value_addr (result);
-      release_value (val);
+      val = release_value (value_addr (result));
       value_free_to_mark (mark);
 
       if (use_mask)
        {
-         ret = target_masked_watch_num_registers (value_as_address (val),
+         ret = target_masked_watch_num_registers (value_as_address (val.get ()),
                                                   mask);
          if (ret == -1)
            error (_("This target does not support masked watchpoints."));
@@ -10768,8 +10631,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
            error (_("Invalid mask or memory region."));
        }
     }
-  else if (val != NULL)
-    release_value (val);
+  else if (val_as_value != NULL)
+    val = release_value (val_as_value);
 
   tok = skip_spaces (arg);
   end_tok = skip_to_space (tok);
@@ -10777,13 +10640,13 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   toklen = end_tok - tok;
   if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
     {
-      innermost_block = NULL;
       tok = cond_start = end_tok + 1;
-      parse_exp_1 (&tok, 0, 0, 0);
+      innermost_block_tracker if_tracker;
+      parse_exp_1 (&tok, 0, 0, 0, &if_tracker);
 
       /* The watchpoint expression may not be local, but the condition
         may still be.  E.g.: `watch global if local > 0'.  */
-      cond_exp_valid_block = innermost_block;
+      cond_exp_valid_block = if_tracker.block ();
 
       cond_end = tok;
     }
@@ -10863,8 +10726,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   w->cond_exp_valid_block = cond_exp_valid_block;
   if (just_location)
     {
-      struct type *t = value_type (val);
-      CORE_ADDR addr = value_as_address (val);
+      struct type *t = value_type (val.get ());
+      CORE_ADDR addr = value_as_address (val.get ());
 
       w->exp_string_reparse
        = current_language->la_watch_location_expression (t, addr).release ();
@@ -10884,7 +10747,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
       w->val = val;
       w->val_bitpos = saved_bitpos;
       w->val_bitsize = saved_bitsize;
-      w->val_valid = 1;
+      w->val_valid = true;
     }
 
   if (cond_start)
@@ -10925,15 +10788,17 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
    If the watchpoint cannot be handled in hardware return zero.  */
 
 static int
-can_use_hardware_watchpoint (struct value *v)
+can_use_hardware_watchpoint (const std::vector<value_ref_ptr> &vals)
 {
   int found_memory_cnt = 0;
-  struct value *head = v;
 
   /* Did the user specifically forbid us to use hardware watchpoints? */
   if (!can_use_hw_watchpoints)
     return 0;
 
+  gdb_assert (!vals.empty ());
+  struct value *head = vals[0].get ();
+
   /* Make sure that the value of the expression depends only upon
      memory contents, and values computed from them within GDB.  If we
      find any register references or function calls, we can't use a
@@ -10953,8 +10818,10 @@ can_use_hardware_watchpoint (struct value *v)
      function calls are special in any way.  So this function may not
      notice that an expression involving an inferior function call
      can't be watched with hardware watchpoints.  FIXME.  */
-  for (; v; v = value_next (v))
+  for (const value_ref_ptr &iter : vals)
     {
+      struct value *v = iter.get ();
+
       if (VALUE_LVAL (v) == lval_memory)
        {
          if (v != head && value_lazy (v))
@@ -11022,10 +10889,7 @@ watch_maybe_just_location (const char *arg, int accessflag, int from_tty)
   if (arg
       && (check_for_argument (&arg, "-location", sizeof ("-location") - 1)
          || check_for_argument (&arg, "-l", sizeof ("-l") - 1)))
-    {
-      arg = skip_spaces (arg);
-      just_location = 1;
-    }
+    just_location = 1;
 
   watch_command_1 (arg, accessflag, from_tty, just_location, 0);
 }
@@ -11065,106 +10929,66 @@ awatch_command (const char *arg, int from_tty)
    in infcmd.c.  Here because it uses the mechanisms of
    breakpoints.  */
 
-struct until_break_fsm
+struct until_break_fsm : public thread_fsm
 {
-  /* The base class.  */
-  struct thread_fsm thread_fsm;
-
-  /* The thread that as current when the command was executed.  */
+  /* The thread that was current when the command was executed.  */
   int thread;
 
   /* The breakpoint set at the destination location.  */
-  struct breakpoint *location_breakpoint;
+  breakpoint_up location_breakpoint;
 
   /* Breakpoint set at the return address in the caller frame.  May be
      NULL.  */
-  struct breakpoint *caller_breakpoint;
-};
-
-static void until_break_fsm_clean_up (struct thread_fsm *self,
-                                     struct thread_info *thread);
-static int until_break_fsm_should_stop (struct thread_fsm *self,
-                                       struct thread_info *thread);
-static enum async_reply_reason
-  until_break_fsm_async_reply_reason (struct thread_fsm *self);
+  breakpoint_up caller_breakpoint;
 
-/* until_break_fsm's vtable.  */
+  until_break_fsm (struct interp *cmd_interp, int thread,
+                  breakpoint_up &&location_breakpoint,
+                  breakpoint_up &&caller_breakpoint)
+    : thread_fsm (cmd_interp),
+      thread (thread),
+      location_breakpoint (std::move (location_breakpoint)),
+      caller_breakpoint (std::move (caller_breakpoint))
+  {
+  }
 
-static struct thread_fsm_ops until_break_fsm_ops =
-{
-  NULL, /* dtor */
-  until_break_fsm_clean_up,
-  until_break_fsm_should_stop,
-  NULL, /* return_value */
-  until_break_fsm_async_reply_reason,
+  void clean_up (struct thread_info *thread) override;
+  bool should_stop (struct thread_info *thread) override;
+  enum async_reply_reason do_async_reply_reason () override;
 };
 
-/* Allocate a new until_break_command_fsm.  */
-
-static struct until_break_fsm *
-new_until_break_fsm (struct interp *cmd_interp, int thread,
-                    breakpoint_up &&location_breakpoint,
-                    breakpoint_up &&caller_breakpoint)
-{
-  struct until_break_fsm *sm;
-
-  sm = XCNEW (struct until_break_fsm);
-  thread_fsm_ctor (&sm->thread_fsm, &until_break_fsm_ops, cmd_interp);
-
-  sm->thread = thread;
-  sm->location_breakpoint = location_breakpoint.release ();
-  sm->caller_breakpoint = caller_breakpoint.release ();
-
-  return sm;
-}
-
 /* Implementation of the 'should_stop' FSM method for the
    until(location)/advance commands.  */
 
-static int
-until_break_fsm_should_stop (struct thread_fsm *self,
-                            struct thread_info *tp)
+bool
+until_break_fsm::should_stop (struct thread_info *tp)
 {
-  struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
   if (bpstat_find_breakpoint (tp->control.stop_bpstat,
-                             sm->location_breakpoint) != NULL
-      || (sm->caller_breakpoint != NULL
+                             location_breakpoint.get ()) != NULL
+      || (caller_breakpoint != NULL
          && bpstat_find_breakpoint (tp->control.stop_bpstat,
-                                    sm->caller_breakpoint) != NULL))
-    thread_fsm_set_finished (self);
+                                    caller_breakpoint.get ()) != NULL))
+    set_finished ();
 
-  return 1;
+  return true;
 }
 
 /* Implementation of the 'clean_up' FSM method for the
    until(location)/advance commands.  */
 
-static void
-until_break_fsm_clean_up (struct thread_fsm *self,
-                         struct thread_info *thread)
+void
+until_break_fsm::clean_up (struct thread_info *)
 {
-  struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
   /* Clean up our temporary breakpoints.  */
-  if (sm->location_breakpoint != NULL)
-    {
-      delete_breakpoint (sm->location_breakpoint);
-      sm->location_breakpoint = NULL;
-    }
-  if (sm->caller_breakpoint != NULL)
-    {
-      delete_breakpoint (sm->caller_breakpoint);
-      sm->caller_breakpoint = NULL;
-    }
-  delete_longjmp_breakpoint (sm->thread);
+  location_breakpoint.reset ();
+  caller_breakpoint.reset ();
+  delete_longjmp_breakpoint (thread);
 }
 
 /* Implementation of the 'async_reply_reason' FSM method for the
    until(location)/advance commands.  */
 
-static enum async_reply_reason
-until_break_fsm_async_reply_reason (struct thread_fsm *self)
+enum async_reply_reason
+until_break_fsm::do_async_reply_reason ()
 {
   return EXEC_ASYNC_LOCATION_REACHED;
 }
@@ -11176,10 +11000,8 @@ until_break_command (const char *arg, int from_tty, int anywhere)
   struct gdbarch *frame_gdbarch;
   struct frame_id stack_frame_id;
   struct frame_id caller_frame_id;
-  struct cleanup *old_chain;
   int thread;
   struct thread_info *tp;
-  struct until_break_fsm *sm;
 
   clear_proceed_status (0);
 
@@ -11194,7 +11016,7 @@ until_break_command (const char *arg, int from_tty, int anywhere)
                        get_last_displayed_symtab (),
                        get_last_displayed_line ())
        : decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE,
-                       NULL, (struct symtab *) NULL, 0));
+                       NULL, NULL, 0));
 
   if (sals.size () != 1)
     error (_("Couldn't get information on specified line."));
@@ -11209,8 +11031,6 @@ until_break_command (const char *arg, int from_tty, int anywhere)
   tp = inferior_thread ();
   thread = tp->global_num;
 
-  old_chain = make_cleanup (null_cleanup, NULL);
-
   /* Note linespec handling above invalidates the frame chain.
      Installing a breakpoint also invalidates the frame chain (as it
      may need to switch threads), so do any frame handling before
@@ -11225,6 +11045,9 @@ until_break_command (const char *arg, int from_tty, int anywhere)
      one.  */
 
   breakpoint_up caller_breakpoint;
+
+  gdb::optional<delete_longjmp_breakpoint_cleanup> lj_deleter;
+
   if (frame_id_p (caller_frame_id))
     {
       struct symtab_and_line sal2;
@@ -11239,7 +11062,7 @@ until_break_command (const char *arg, int from_tty, int anywhere)
                                                    bp_until);
 
       set_longjmp_breakpoint (tp, caller_frame_id);
-      make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
+      lj_deleter.emplace (thread);
     }
 
   /* set_momentary_breakpoint could invalidate FRAME.  */
@@ -11257,12 +11080,12 @@ until_break_command (const char *arg, int from_tty, int anywhere)
     location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
                                                    stack_frame_id, bp_until);
 
-  sm = new_until_break_fsm (command_interp (), tp->global_num,
-                           std::move (location_breakpoint),
-                           std::move (caller_breakpoint));
-  tp->thread_fsm = &sm->thread_fsm;
+  tp->thread_fsm = new until_break_fsm (command_interp (), tp->global_num,
+                                       std::move (location_breakpoint),
+                                       std::move (caller_breakpoint));
 
-  discard_cleanups (old_chain);
+  if (lj_deleter)
+    lj_deleter->release ();
 
   proceed (-1, GDB_SIGNAL_DEFAULT);
 }
@@ -11415,7 +11238,7 @@ init_ada_exception_breakpoint (struct breakpoint *b,
          enough for now, though.  */
     }
 
-  init_raw_breakpoint (b, gdbarch, sal, bp_breakpoint, ops);
+  init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops);
 
   b->enable_state = enabled ? bp_enabled : bp_disabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
@@ -11585,14 +11408,14 @@ clear_command (const char *arg, int from_tty)
 
   /* Remove duplicates from the vec.  */
   std::sort (found.begin (), found.end (),
-            [] (const breakpoint *a, const breakpoint *b)
+            [] (const breakpoint *bp_a, const breakpoint *bp_b)
             {
-              return compare_breakpoints (a, b) < 0;
+              return compare_breakpoints (bp_a, bp_b) < 0;
             });
   found.erase (std::unique (found.begin (), found.end (),
-                           [] (const breakpoint *a, const breakpoint *b)
+                           [] (const breakpoint *bp_a, const breakpoint *bp_b)
                            {
-                             return compare_breakpoints (a, b) == 0;
+                             return compare_breakpoints (bp_a, bp_b) == 0;
                            }),
               found.end ());
 
@@ -11639,42 +11462,36 @@ breakpoint_auto_delete (bpstat bs)
 }
 
 /* A comparison function for bp_location AP and BP being interfaced to
-   qsort.  Sort elements primarily by their ADDRESS (no matter what
-   does breakpoint_address_is_meaningful say for its OWNER),
-   secondarily by ordering first permanent elements and
-   terciarily just ensuring the array is sorted stable way despite
-   qsort being an unstable algorithm.  */
+   std::sort.  Sort elements primarily by their ADDRESS (no matter what
+   bl_address_is_meaningful says), secondarily by ordering first
+   permanent elements and terciarily just ensuring the array is sorted
+   stable way despite std::sort being an unstable algorithm.  */
 
 static int
-bp_locations_compare (const void *ap, const void *bp)
+bp_location_is_less_than (const bp_location *a, const bp_location *b)
 {
-  const struct bp_location *a = *(const struct bp_location **) ap;
-  const struct bp_location *b = *(const struct bp_location **) bp;
-
   if (a->address != b->address)
-    return (a->address > b->address) - (a->address < b->address);
+    return a->address < b->address;
 
   /* Sort locations at the same address by their pspace number, keeping
      locations of the same inferior (in a multi-inferior environment)
      grouped.  */
 
   if (a->pspace->num != b->pspace->num)
-    return ((a->pspace->num > b->pspace->num)
-           - (a->pspace->num < b->pspace->num));
+    return a->pspace->num < b->pspace->num;
 
   /* Sort permanent breakpoints first.  */
   if (a->permanent != b->permanent)
-    return (a->permanent < b->permanent) - (a->permanent > b->permanent);
+    return a->permanent > b->permanent;
 
   /* Make the internal GDB representation stable across GDB runs
      where A and B memory inside GDB can differ.  Breakpoint locations of
      the same type at the same address can be sorted in arbitrary order.  */
 
   if (a->owner->number != b->owner->number)
-    return ((a->owner->number > b->owner->number)
-           - (a->owner->number < b->owner->number));
+    return a->owner->number < b->owner->number;
 
-  return (a > b) - (a < b);
+  return a < b;
 }
 
 /* Set bp_locations_placed_address_before_address_max and
@@ -11763,7 +11580,7 @@ download_tracepoint_locations (void)
       t = (struct tracepoint *) b;
       t->number_on_target = b->number;
       if (bp_location_downloaded)
-       observer_notify_breakpoint_modified (b);
+       gdb::observers::breakpoint_modified.notify (b);
     }
 }
 
@@ -11889,8 +11706,8 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
   ALL_BREAKPOINTS (b)
     for (loc = b->loc; loc; loc = loc->next)
       *locp++ = loc;
-  qsort (bp_locations, bp_locations_count, sizeof (*bp_locations),
-        bp_locations_compare);
+  std::sort (bp_locations, bp_locations + bp_locations_count,
+            bp_location_is_less_than);
 
   bp_locations_target_extensions_update ();
 
@@ -11983,7 +11800,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
                 this one from the target.  */
 
              /* OLD_LOC comes from existing struct breakpoint.  */
-             if (breakpoint_address_is_meaningful (old_loc->owner))
+             if (bl_address_is_meaningful (old_loc))
                {
                  for (loc2p = locp;
                       (loc2p < bp_locations + bp_locations_count
@@ -12088,10 +11905,21 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
                 around.  We simply always ignore hardware watchpoint
                 traps we can no longer explain.  */
 
-             old_loc->events_till_retirement = 3 * (thread_count () + 1);
+             process_stratum_target *proc_target = nullptr;
+             for (inferior *inf : all_inferiors ())
+               if (inf->pspace == old_loc->pspace)
+                 {
+                   proc_target = inf->process_target ();
+                   break;
+                 }
+             if (proc_target != nullptr)
+               old_loc->events_till_retirement
+                 = 3 * (thread_count (proc_target) + 1);
+             else
+               old_loc->events_till_retirement = 1;
              old_loc->owner = NULL;
 
-             VEC_safe_push (bp_location_p, moribund_locations, old_loc);
+             moribund_locations.push_back (old_loc);
            }
          else
            {
@@ -12123,7 +11951,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
       b = loc->owner;
 
       if (!unduplicated_should_be_inserted (loc)
-         || !breakpoint_address_is_meaningful (b)
+         || !bl_address_is_meaningful (loc)
          /* Don't detect duplicate for tracepoint locations because they are
           never duplicated.  See the comments in field `duplicate' of
           `struct bp_location'.  */
@@ -12194,30 +12022,29 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
 void
 breakpoint_retire_moribund (void)
 {
-  struct bp_location *loc;
-  int ix;
-
-  for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
-    if (--(loc->events_till_retirement) == 0)
-      {
-       decref_bp_location (&loc);
-       VEC_unordered_remove (bp_location_p, moribund_locations, ix);
-       --ix;
-      }
+  for (int ix = 0; ix < moribund_locations.size (); ++ix)
+    {
+      struct bp_location *loc = moribund_locations[ix];
+      if (--(loc->events_till_retirement) == 0)
+       {
+         decref_bp_location (&loc);
+         unordered_remove (moribund_locations, ix);
+         --ix;
+       }
+    }
 }
 
 static void
 update_global_location_list_nothrow (enum ugll_insert_mode insert_mode)
 {
 
-  TRY
+  try
     {
       update_global_location_list (insert_mode);
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &e)
     {
     }
-  END_CATCH
 }
 
 /* Clear BKP from a BPS.  */
@@ -12284,19 +12111,23 @@ say_where (struct breakpoint *b)
   else
     {
       if (opts.addressprint || b->loc->symtab == NULL)
-       {
-         printf_filtered (" at ");
-         fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
-                         gdb_stdout);
-       }
+       printf_filtered (" at %ps",
+                        styled_string (address_style.style (),
+                                       paddress (b->loc->gdbarch,
+                                                 b->loc->address)));
       if (b->loc->symtab != NULL)
        {
          /* If there is a single location, we can print the location
             more nicely.  */
          if (b->loc->next == NULL)
-           printf_filtered (": file %s, line %d.",
-                            symtab_to_filename_for_display (b->loc->symtab),
-                            b->loc->line_number);
+           {
+             const char *filename
+               = symtab_to_filename_for_display (b->loc->symtab);
+             printf_filtered (": file %ps, line %d.",
+                              styled_string (file_name_style.style (),
+                                             filename),
+                              b->loc->line_number);
+           }
          else
            /* This is not ideal, but each location may have a
               different file name, and this at least reflects the
@@ -12316,32 +12147,23 @@ say_where (struct breakpoint *b)
     }
 }
 
-/* Default bp_location_ops methods.  */
-
-static void
-bp_location_dtor (struct bp_location *self)
+bp_location::~bp_location ()
 {
-  xfree (self->function_name);
+  xfree (function_name);
 }
 
-static const struct bp_location_ops bp_location_ops =
-{
-  bp_location_dtor
-};
-
 /* Destructor for the breakpoint base class.  */
 
 breakpoint::~breakpoint ()
 {
   xfree (this->cond_string);
   xfree (this->extra_string);
-  xfree (this->filter);
 }
 
 static struct bp_location *
 base_breakpoint_allocate_location (struct breakpoint *self)
 {
-  return new bp_location (&bp_location_ops, self);
+  return new bp_location (self);
 }
 
 static void
@@ -12601,18 +12423,18 @@ bkpt_print_it (bpstat bs)
   annotate_breakpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
 
-  if (bp_temp)
-    uiout->text ("Temporary breakpoint ");
-  else
-    uiout->text ("Breakpoint ");
   if (uiout->is_mi_like_p ())
     {
       uiout->field_string ("reason",
                           async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
       uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  uiout->field_int ("bkptno", b->number);
-  uiout->text (", ");
+  if (bp_temp)
+    uiout->message ("Temporary breakpoint %pF, ",
+                   signed_field ("bkptno", b->number));
+  else
+    uiout->message ("Breakpoint %pF, ",
+                   signed_field ("bkptno", b->number));
 
   return PRINT_SRC_AND_LOC;
 }
@@ -12924,14 +12746,13 @@ tracepoint_print_one_detail (const struct breakpoint *self,
                             struct ui_out *uiout)
 {
   struct tracepoint *tp = (struct tracepoint *) self;
-  if (tp->static_trace_marker_id)
+  if (!tp->static_trace_marker_id.empty ())
     {
       gdb_assert (self->type == bp_static_tracepoint);
 
-      uiout->text ("\tmarker id is ");
-      uiout->field_string ("static-tracepoint-marker-string-id",
-                          tp->static_trace_marker_id);
-      uiout->text ("\n");
+      uiout->message ("\tmarker id is %pF\n",
+                     string_field ("static-tracepoint-marker-string-id",
+                                   tp->static_trace_marker_id.c_str ()));
     }
 }
 
@@ -13026,8 +12847,7 @@ tracepoint_decode_location (struct breakpoint *b,
 
 struct breakpoint_ops tracepoint_breakpoint_ops;
 
-/* The breakpoint_ops structure to be use on tracepoints placed in a
-   static probe.  */
+/* Virtual table for tracepoints on static probes.  */
 
 static void
 tracepoint_probe_create_sals_from_location
@@ -13048,8 +12868,6 @@ tracepoint_probe_decode_location (struct breakpoint *b,
   return bkpt_probe_decode_location (b, location, search_pspace);
 }
 
-static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
-
 /* Dprintf breakpoint_ops methods.  */
 
 static void
@@ -13208,7 +13026,7 @@ strace_marker_decode_location (struct breakpoint *b,
       return sals;
     }
   else
-    error (_("marker %s not found"), tp->static_trace_marker_id);
+    error (_("marker %s not found"), tp->static_trace_marker_id.c_str ());
 }
 
 static struct breakpoint_ops strace_marker_breakpoint_ops;
@@ -13276,7 +13094,7 @@ delete_breakpoint (struct breakpoint *bpt)
      a problem in that process, we'll be asked to delete the half-created
      watchpoint.  In that case, don't announce the deletion.  */
   if (bpt->number)
-    observer_notify_breakpoint_deleted (bpt);
+    gdb::observers::breakpoint_deleted.notify (bpt);
 
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
@@ -13381,9 +13199,9 @@ delete_command (const char *arg, int from_tty)
     }
   else
     map_breakpoint_numbers
-      (arg, [&] (breakpoint *b)
+      (arg, [&] (breakpoint *br)
        {
-        iterate_over_related_breakpoints (b, delete_breakpoint);
+        iterate_over_related_breakpoints (br, delete_breakpoint);
        });
 }
 
@@ -13413,10 +13231,8 @@ static int
 ambiguous_names_p (struct bp_location *loc)
 {
   struct bp_location *l;
-  htab_t htab = htab_create_alloc (13, htab_hash_string,
-                                  (int (*) (const void *, 
-                                            const void *)) streq,
-                                  NULL, xcalloc, xfree);
+  htab_t htab = htab_create_alloc (13, htab_hash_string, streq_hash, NULL,
+                                  xcalloc, xfree);
 
   for (l = loc; l != NULL; l = l->next)
     {
@@ -13489,14 +13305,12 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
 
   if (target_static_tracepoint_marker_at (pc, &marker))
     {
-      if (strcmp (tp->static_trace_marker_id, marker.str_id) != 0)
+      if (tp->static_trace_marker_id != marker.str_id)
        warning (_("static tracepoint %d changed probed marker from %s to %s"),
-                b->number,
-                tp->static_trace_marker_id, marker.str_id);
+                b->number, tp->static_trace_marker_id.c_str (),
+                marker.str_id.c_str ());
 
-      xfree (tp->static_trace_marker_id);
-      tp->static_trace_marker_id = xstrdup (marker.str_id);
-      release_static_tracepoint_marker (&marker);
+      tp->static_trace_marker_id = std::move (marker.str_id);
 
       return sal;
     }
@@ -13506,39 +13320,39 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
   if (!sal.explicit_pc
       && sal.line != 0
       && sal.symtab != NULL
-      && tp->static_trace_marker_id != NULL)
+      && !tp->static_trace_marker_id.empty ())
     {
-      VEC(static_tracepoint_marker_p) *markers;
-
-      markers
-       = target_static_tracepoint_markers_by_strid (tp->static_trace_marker_id);
+      std::vector<static_tracepoint_marker> markers
+       = target_static_tracepoint_markers_by_strid
+           (tp->static_trace_marker_id.c_str ());
 
-      if (!VEC_empty(static_tracepoint_marker_p, markers))
+      if (!markers.empty ())
        {
          struct symbol *sym;
          struct static_tracepoint_marker *tpmarker;
          struct ui_out *uiout = current_uiout;
          struct explicit_location explicit_loc;
 
-         tpmarker = VEC_index (static_tracepoint_marker_p, markers, 0);
+         tpmarker = &markers[0];
 
-         xfree (tp->static_trace_marker_id);
-         tp->static_trace_marker_id = xstrdup (tpmarker->str_id);
+         tp->static_trace_marker_id = std::move (tpmarker->str_id);
 
          warning (_("marker for static tracepoint %d (%s) not "
                     "found at previous line number"),
-                  b->number, tp->static_trace_marker_id);
+                  b->number, tp->static_trace_marker_id.c_str ());
 
          symtab_and_line sal2 = find_pc_line (tpmarker->address, 0);
          sym = find_pc_sect_function (tpmarker->address, NULL);
          uiout->text ("Now in ");
          if (sym)
            {
-             uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+             uiout->field_string ("func", sym->print_name (),
+                                  function_name_style.style ());
              uiout->text (" at ");
            }
          uiout->field_string ("file",
-                              symtab_to_filename_for_display (sal2.symtab));
+                              symtab_to_filename_for_display (sal2.symtab),
+                              file_name_style.style ());
          uiout->text (":");
 
          if (uiout->is_mi_like_p ())
@@ -13548,7 +13362,7 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
              uiout->field_string ("fullname", fullname);
            }
 
-         uiout->field_int ("line", sal2.line);
+         uiout->field_signed ("line", sal2.line);
          uiout->text ("\n");
 
          b->loc->line_number = sal2.line;
@@ -13564,8 +13378,6 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
 
          /* Might be nice to check if function changed, and warn if
             so.  */
-
-         release_static_tracepoint_marker (tpmarker);
        }
     }
   return sal;
@@ -13687,20 +13499,19 @@ update_breakpoint_locations (struct breakpoint *b,
          const char *s;
 
          s = b->cond_string;
-         TRY
+         try
            {
              new_loc->cond = parse_exp_1 (&s, sal.pc,
                                           block_for_pc (sal.pc),
                                           0);
            }
-         CATCH (e, RETURN_MASK_ERROR)
+         catch (const gdb_exception_error &e)
            {
              warning (_("failed to reevaluate condition "
                         "for breakpoint %d: %s"), 
-                      b->number, e.message);
+                      b->number, e.what ());
              new_loc->enabled = 0;
            }
-         END_CATCH
        }
 
       if (!sals_end.empty ())
@@ -13751,7 +13562,7 @@ update_breakpoint_locations (struct breakpoint *b,
   }
 
   if (!locations_are_equal (existing_locations, b->loc))
-    observer_notify_breakpoint_modified (b);
+    gdb::observers::breakpoint_modified.notify (b);
 }
 
 /* Find the SaL locations corresponding to the given LOCATION.
@@ -13761,22 +13572,20 @@ static std::vector<symtab_and_line>
 location_to_sals (struct breakpoint *b, struct event_location *location,
                  struct program_space *search_pspace, int *found)
 {
-  struct gdb_exception exception = exception_none;
+  struct gdb_exception exception;
 
   gdb_assert (b->ops != NULL);
 
   std::vector<symtab_and_line> sals;
 
-  TRY
+  try
     {
       sals = b->ops->decode_location (b, location, search_pspace);
     }
-  CATCH (e, RETURN_MASK_ERROR)
+  catch (gdb_exception_error &e)
     {
       int not_found_and_ok = 0;
 
-      exception = e;
-
       /* For pending breakpoints, it's expected that parsing will
         fail until the right shared library is loaded.  User has
         already told to create pending breakpoints and don't need
@@ -13803,10 +13612,11 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
             happens only when a binary has changed, I don't know
             which approach is better.  */
          b->enable_state = bp_disabled;
-         throw_exception (e);
+         throw;
        }
+
+      exception = std::move (e);
     }
-  END_CATCH
 
   if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR)
     {
@@ -13919,9 +13729,8 @@ decode_location_default (struct breakpoint *b,
   struct linespec_result canonical;
 
   decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace,
-                   (struct symtab *) NULL, 0,
-                   &canonical, multiple_symbols_all,
-                   b->filter);
+                   NULL, 0, &canonical, multiple_symbols_all,
+                   b->filter.get ());
 
   /* We should get 0 or 1 resulting SALs.  */
   gdb_assert (canonical.lsals.size () < 2);
@@ -13958,6 +13767,19 @@ breakpoint_re_set (void)
     scoped_restore save_input_radix = make_scoped_restore (&input_radix);
     scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
+    /* breakpoint_re_set_one sets the current_language to the language
+       of the breakpoint it is resetting (see prepare_re_set_context)
+       before re-evaluating the breakpoint's location.  This change can
+       unfortunately get undone by accident if the language_mode is set
+       to auto, and we either switch frames, or more likely in this context,
+       we select the current frame.
+
+       We prevent this by temporarily turning the language_mode to
+       language_mode_manual.  We restore it once all breakpoints
+       have been reset.  */
+    scoped_restore save_language_mode = make_scoped_restore (&language_mode);
+    language_mode = language_mode_manual;
+
     /* Note: we must not try to insert locations until after all
        breakpoints have been re-set.  Otherwise, e.g., when re-setting
        breakpoint 1, we'd insert the locations of breakpoint 2, which
@@ -13965,17 +13787,16 @@ breakpoint_re_set (void)
 
     ALL_BREAKPOINTS_SAFE (b, b_tmp)
       {
-       TRY
+       try
          {
            breakpoint_re_set_one (b);
          }
-       CATCH (ex, RETURN_MASK_ALL)
+       catch (const gdb_exception &ex)
          {
            exception_fprintf (gdb_stderr, ex,
                               "Error in re-setting breakpoint %d: ",
                               b->number);
          }
-       END_CATCH
       }
 
     jit_breakpoint_re_set ();
@@ -13999,8 +13820,7 @@ breakpoint_re_set_thread (struct breakpoint *b)
 {
   if (b->thread != -1)
     {
-      if (in_thread_list (inferior_ptid))
-       b->thread = ptid_to_global_thread_id (inferior_ptid);
+      b->thread = inferior_thread ()->global_num;
 
       /* We're being called after following a fork.  The new fork is
         selected as current, and unless this was a vfork will have a
@@ -14048,7 +13868,7 @@ set_ignore_count (int bptnum, int count, int from_tty)
                               "crossings of breakpoint %d."),
                             count, bptnum);
        }
-      observer_notify_breakpoint_modified (b);
+      gdb::observers::breakpoint_modified.notify (b);
       return;
     }
 
@@ -14305,6 +14125,8 @@ enable_disable_bp_num_loc (int bp_num, int loc_num, bool enable)
        target_disable_tracepoint (loc);
     }
   update_global_location_list (UGLL_DONT_INSERT);
+
+  gdb::observers::breakpoint_modified.notify (loc->owner);
 }
 
 /* Enable or disable a range of breakpoint locations.  BP_NUM is the
@@ -14351,7 +14173,7 @@ disable_breakpoint (struct breakpoint *bpt)
 
   update_global_location_list (UGLL_DONT_INSERT);
 
-  observer_notify_breakpoint_modified (bpt);
+  gdb::observers::breakpoint_modified.notify (bpt);
 }
 
 /* Enable or disable the breakpoint(s) or breakpoint location(s)
@@ -14441,7 +14263,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
       /* Initialize it just to avoid a GCC false warning.  */
       enum enable_state orig_enable_state = bp_disabled;
 
-      TRY
+      try
        {
          struct watchpoint *w = (struct watchpoint *) bpt;
 
@@ -14449,14 +14271,13 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
          bpt->enable_state = bp_enabled;
          update_watchpoint (w, 1 /* reparse */);
        }
-      CATCH (e, RETURN_MASK_ALL)
+      catch (const gdb_exception &e)
        {
          bpt->enable_state = orig_enable_state;
          exception_fprintf (gdb_stderr, e, _("Cannot enable watchpoint %d: "),
                             bpt->number);
          return;
        }
-      END_CATCH
     }
 
   bpt->enable_state = bp_enabled;
@@ -14477,7 +14298,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
   bpt->enable_count = count;
   update_global_location_list (UGLL_MAY_INSERT);
 
-  observer_notify_breakpoint_modified (bpt);
+  gdb::observers::breakpoint_modified.notify (bpt);
 }
 
 
@@ -14574,7 +14395,7 @@ invalidate_bp_value_on_memory_change (struct inferior *inferior,
       {
        struct watchpoint *wp = (struct watchpoint *) bp;
 
-       if (wp->val_valid && wp->val)
+       if (wp->val_valid && wp->val != nullptr)
          {
            struct bp_location *loc;
 
@@ -14583,9 +14404,8 @@ invalidate_bp_value_on_memory_change (struct inferior *inferior,
                  && loc->address + loc->length > addr
                  && addr + len > loc->address)
                {
-                 value_free (wp->val);
                  wp->val = NULL;
-                 wp->val_valid = 0;
+                 wp->val_valid = false;
                }
          }
       }
@@ -14689,15 +14509,10 @@ set_tracepoint_count (int num)
 static void
 trace_command (const char *arg, int from_tty)
 {
-  struct breakpoint_ops *ops;
-
   event_location_up location = string_to_event_location (&arg,
                                                         current_language);
-  if (location != NULL
-      && event_location_type (location.get ()) == PROBE_LOCATION)
-    ops = &tracepoint_probe_breakpoint_ops;
-  else
-    ops = &tracepoint_breakpoint_ops;
+  const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
+    (location.get (), true /* is_tracepoint */);
 
   create_breakpoint (get_current_arch (),
                     location.get (),
@@ -14773,11 +14588,13 @@ static int next_cmd;
 static char *
 read_uploaded_action (void)
 {
-  char *rslt;
-
-  VEC_iterate (char_ptr, this_utp->cmd_strings, next_cmd, rslt);
+  char *rslt = nullptr;
 
-  next_cmd++;
+  if (next_cmd < this_utp->cmd_strings.size ())
+    {
+      rslt = this_utp->cmd_strings[next_cmd].get ();
+      next_cmd++;
+    }
 
   return rslt;
 }
@@ -14796,7 +14613,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
   struct tracepoint *tp;
 
   if (utp->at_string)
-    addr_str = utp->at_string;
+    addr_str = utp->at_string.get ();
   else
     {
       /* In the absence of a source location, fall back to raw
@@ -14820,7 +14637,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
                                                         current_language);
   if (!create_breakpoint (get_current_arch (),
                          location.get (),
-                         utp->cond_string, -1, addr_str,
+                         utp->cond_string.get (), -1, addr_str,
                          0 /* parse cond/thread */,
                          0 /* tempflag */,
                          utp->type /* type_wanted */,
@@ -14849,19 +14666,19 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
      special-purpose "reader" function and call the usual command line
      reader, then pass the result to the breakpoint command-setting
      function.  */
-  if (!VEC_empty (char_ptr, utp->cmd_strings))
+  if (!utp->cmd_strings.empty ())
     {
-      command_line_up cmd_list;
+      counted_command_line cmd_list;
 
       this_utp = utp;
       next_cmd = 0;
 
-      cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
+      cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL);
 
       breakpoint_set_commands (tp, std::move (cmd_list));
     }
-  else if (!VEC_empty (char_ptr, utp->actions)
-          || !VEC_empty (char_ptr, utp->step_actions))
+  else if (!utp->actions.empty ()
+          || !utp->step_actions.empty ())
     warning (_("Uploaded tracepoint %d actions "
               "have no source form, ignoring them"),
             utp->number);
@@ -14882,7 +14699,7 @@ info_tracepoints_command (const char *args, int from_tty)
   struct ui_out *uiout = current_uiout;
   int num_printed;
 
-  num_printed = breakpoint_1 (args, 0, is_tracepoint);
+  num_printed = breakpoint_1 (args, false, is_tracepoint);
 
   if (num_printed == 0)
     {
@@ -14945,9 +14762,9 @@ delete_trace_command (const char *arg, int from_tty)
     }
   else
     map_breakpoint_numbers
-      (arg, [&] (breakpoint *b)
+      (arg, [&] (breakpoint *br)
        {
-        iterate_over_related_breakpoints (b, delete_breakpoint);
+        iterate_over_related_breakpoints (br, delete_breakpoint);
        });
 }
 
@@ -14957,7 +14774,7 @@ static void
 trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
 {
   tp->pass_count = count;
-  observer_notify_breakpoint_modified (tp);
+  gdb::observers::breakpoint_modified.notify (tp);
   if (from_tty)
     printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
                     tp->number, count);
@@ -15104,11 +14921,11 @@ print_recreate_thread (struct breakpoint *b, struct ui_file *fp)
 /* Save information on user settable breakpoints (watchpoints, etc) to
    a new script file named FILENAME.  If FILTER is non-NULL, call it
    on each breakpoint and only include the ones for which it returns
-   non-zero.  */
+   true.  */
 
 static void
 save_breakpoints (const char *filename, int from_tty,
-                 int (*filter) (const struct breakpoint *))
+                 bool (*filter) (const struct breakpoint *))
 {
   struct breakpoint *tp;
   int any = 0;
@@ -15183,16 +15000,15 @@ save_breakpoints (const char *filename, int from_tty,
        fp.puts ("  commands\n");
        
        current_uiout->redirect (&fp);
-       TRY
+       try
          {
            print_command_lines (current_uiout, tp->commands.get (), 2);
          }
-       CATCH (ex, RETURN_MASK_ALL)
+       catch (const gdb_exception &ex)
          {
          current_uiout->redirect (NULL);
-           throw_exception (ex);
+           throw;
          }
-       END_CATCH
 
        current_uiout->redirect (NULL);
        fp.puts ("  end\n");
@@ -15240,15 +15056,15 @@ save_tracepoints_command (const char *args, int from_tty)
 
 /* Create a vector of all tracepoints.  */
 
-VEC(breakpoint_p) *
+std::vector<breakpoint *>
 all_tracepoints (void)
 {
-  VEC(breakpoint_p) *tp_vec = 0;
+  std::vector<breakpoint *> tp_vec;
   struct breakpoint *tp;
 
   ALL_TRACEPOINTS (tp)
   {
-    VEC_safe_push (breakpoint_p, tp_vec, tp);
+    tp_vec.push_back (tp);
   }
 
   return tp_vec;
@@ -15280,7 +15096,7 @@ functions in all scopes.  For C++, this means in all namespaces and\n\
 classes.  For Ada, this means in all packages.  E.g., in C++,\n\
 \"func()\" matches \"A::func()\", \"A::B::func()\", etc.  The\n\
 \"-qualified\" flag overrides this behavior, making GDB interpret the\n\
-specified name as a complete fully-qualified name instead.\n"
+specified name as a complete fully-qualified name instead."
 
 /* This help string is used for the break, hbreak, tbreak and thbreak
    commands.  It is defined as a macro to prevent duplication.
@@ -15301,7 +15117,7 @@ stack frame.  This is useful for breaking on return to a stack frame.\n\
 \n\
 THREADNUM is the number from \"info threads\".\n\
 CONDITION is a boolean expression.\n\
-\n" LOCATION_HELP_STRING "\n\
+\n" LOCATION_HELP_STRING "\n\n\
 Multiple breakpoints at one place are permitted, and useful if their\n\
 conditions are different.\n\
 \n\
@@ -15344,14 +15160,13 @@ save_command (const char *arg, int from_tty)
 }
 
 struct breakpoint *
-iterate_over_breakpoints (int (*callback) (struct breakpoint *, void *),
-                         void *data)
+iterate_over_breakpoints (gdb::function_view<bool (breakpoint *)> callback)
 {
   struct breakpoint *b, *b_tmp;
 
   ALL_BREAKPOINTS_SAFE (b, b_tmp)
     {
-      if ((*callback) (b, data))
+      if (callback (b))
        return b;
     }
 
@@ -15590,6 +15405,10 @@ initialize_breakpoint_ops (void)
 
 static struct cmd_list_element *enablebreaklist = NULL;
 
+/* See breakpoint.h.  */
+
+cmd_list_element *commands_cmd_element = nullptr;
+
 void
 _initialize_breakpoint (void)
 {
@@ -15597,12 +15416,9 @@ _initialize_breakpoint (void)
 
   initialize_breakpoint_ops ();
 
-  observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
-  observer_attach_free_objfile (disable_breakpoints_in_freed_objfile);
-  observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
-
-  breakpoint_objfile_key
-    = register_objfile_data_with_cleanup (NULL, free_breakpoint_objfile_data);
+  gdb::observers::solib_unloaded.attach (disable_breakpoints_in_unloaded_shlib);
+  gdb::observers::free_objfile.attach (disable_breakpoints_in_freed_objfile);
+  gdb::observers::memory_changed.attach (invalidate_bp_value_on_memory_change);
 
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
@@ -15615,7 +15431,8 @@ _initialize_breakpoint (void)
 Set ignore-count of breakpoint number N to COUNT.\n\
 Usage is `ignore N COUNT'."));
 
-  add_com ("commands", class_breakpoint, commands_command, _("\
+  commands_cmd_element = add_com ("commands", class_breakpoint,
+                                 commands_command, _("\
 Set commands to be executed when the given breakpoints are hit.\n\
 Give a space-separated breakpoint list as argument after \"commands\".\n\
 A list element can be a breakpoint number (e.g. `5') or a range of numbers\n\
@@ -15658,7 +15475,8 @@ BREAK_ARGS_HELP ("thbreak")));
   set_cmd_completer (c, location_completer);
 
   add_prefix_cmd ("enable", class_breakpoint, enable_command, _("\
-Enable some breakpoints.\n\
+Enable all or some breakpoints.\n\
+Usage: enable [BREAKPOINTNUM]...\n\
 Give breakpoint numbers (separated by spaces) as arguments.\n\
 With no subcommand, breakpoints are enabled until you command otherwise.\n\
 This is used to cancel the effect of the \"disable\" command.\n\
@@ -15668,46 +15486,54 @@ With a subcommand you can enable temporarily."),
   add_com_alias ("en", "enable", class_breakpoint, 1);
 
   add_prefix_cmd ("breakpoints", class_breakpoint, enable_command, _("\
-Enable some breakpoints.\n\
+Enable all or some breakpoints.\n\
+Usage: enable breakpoints [BREAKPOINTNUM]...\n\
 Give breakpoint numbers (separated by spaces) as arguments.\n\
 This is used to cancel the effect of the \"disable\" command.\n\
-May be abbreviated to simply \"enable\".\n"),
+May be abbreviated to simply \"enable\"."),
                   &enablebreaklist, "enable breakpoints ", 1, &enablelist);
 
   add_cmd ("once", no_class, enable_once_command, _("\
-Enable breakpoints for one hit.  Give breakpoint numbers.\n\
+Enable some breakpoints for one hit.\n\
+Usage: enable breakpoints once BREAKPOINTNUM...\n\
 If a breakpoint is hit while enabled in this fashion, it becomes disabled."),
           &enablebreaklist);
 
   add_cmd ("delete", no_class, enable_delete_command, _("\
-Enable breakpoints and delete when hit.  Give breakpoint numbers.\n\
+Enable some breakpoints and delete when hit.\n\
+Usage: enable breakpoints delete BREAKPOINTNUM...\n\
 If a breakpoint is hit while enabled in this fashion, it is deleted."),
           &enablebreaklist);
 
   add_cmd ("count", no_class, enable_count_command, _("\
-Enable breakpoints for COUNT hits.  Give count and then breakpoint numbers.\n\
+Enable some breakpoints for COUNT hits.\n\
+Usage: enable breakpoints count COUNT BREAKPOINTNUM...\n\
 If a breakpoint is hit while enabled in this fashion,\n\
 the count is decremented; when it reaches zero, the breakpoint is disabled."),
           &enablebreaklist);
 
   add_cmd ("delete", no_class, enable_delete_command, _("\
-Enable breakpoints and delete when hit.  Give breakpoint numbers.\n\
+Enable some breakpoints and delete when hit.\n\
+Usage: enable delete BREAKPOINTNUM...\n\
 If a breakpoint is hit while enabled in this fashion, it is deleted."),
           &enablelist);
 
   add_cmd ("once", no_class, enable_once_command, _("\
-Enable breakpoints for one hit.  Give breakpoint numbers.\n\
+Enable some breakpoints for one hit.\n\
+Usage: enable once BREAKPOINTNUM...\n\
 If a breakpoint is hit while enabled in this fashion, it becomes disabled."),
           &enablelist);
 
   add_cmd ("count", no_class, enable_count_command, _("\
-Enable breakpoints for COUNT hits.  Give count and then breakpoint numbers.\n\
+Enable some breakpoints for COUNT hits.\n\
+Usage: enable count COUNT BREAKPOINTNUM...\n\
 If a breakpoint is hit while enabled in this fashion,\n\
 the count is decremented; when it reaches zero, the breakpoint is disabled."),
           &enablelist);
 
   add_prefix_cmd ("disable", class_breakpoint, disable_command, _("\
-Disable some breakpoints.\n\
+Disable all or some breakpoints.\n\
+Usage: disable [BREAKPOINTNUM]...\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To disable all breakpoints, give no argument.\n\
 A disabled breakpoint is not forgotten, but has no effect until re-enabled."),
@@ -15716,7 +15542,8 @@ A disabled breakpoint is not forgotten, but has no effect until re-enabled."),
   add_com_alias ("disa", "disable", class_breakpoint, 1);
 
   add_cmd ("breakpoints", class_alias, disable_command, _("\
-Disable some breakpoints.\n\
+Disable all or some breakpoints.\n\
+Usage: disable breakpoints [BREAKPOINTNUM]...\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To disable all breakpoints, give no argument.\n\
 A disabled breakpoint is not forgotten, but has no effect until re-enabled.\n\
@@ -15724,18 +15551,19 @@ This command may be abbreviated \"disable\"."),
           &disablelist);
 
   add_prefix_cmd ("delete", class_breakpoint, delete_command, _("\
-Delete some breakpoints or auto-display expressions.\n\
+Delete all or some breakpoints.\n\
+Usage: delete [BREAKPOINTNUM]...\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To delete all breakpoints, give no argument.\n\
 \n\
-Also a prefix command for deletion of other GDB objects.\n\
-The \"unset\" command is also an alias for \"delete\"."),
+Also a prefix command for deletion of other GDB objects."),
                  &deletelist, "delete ", 1, &cmdlist);
   add_com_alias ("d", "delete", class_breakpoint, 1);
   add_com_alias ("del", "delete", class_breakpoint, 1);
 
   add_cmd ("breakpoints", class_alias, delete_command, _("\
-Delete some breakpoints or auto-display expressions.\n\
+Delete all or some breakpoints or auto-display expressions.\n\
+Usage: delete breakpoints [BREAKPOINTNUM]...\n\
 Arguments are breakpoint numbers with spaces in between.\n\
 To delete all breakpoints, give no argument.\n\
 This command may be abbreviated \"delete\"."),
@@ -15747,7 +15575,7 @@ Argument may be a linespec, explicit, or address location as described below.\n\
 \n\
 With no argument, clears all breakpoints in the line that the selected frame\n\
 is executing in.\n"
-"\n" LOCATION_HELP_STRING "\n\
+"\n" LOCATION_HELP_STRING "\n\n\
 See also the \"delete\" command which clears breakpoints by number."));
   add_com_alias ("cl", "clear", class_breakpoint, 1);
 
@@ -15947,7 +15775,7 @@ tracing library.  You can inspect it when analyzing the trace buffer,\n\
 by printing the $_sdata variable like any other convenience variable.\n\
 \n\
 CONDITION is a boolean expression.\n\
-\n" LOCATION_HELP_STRING "\n\
+\n" LOCATION_HELP_STRING "\n\n\
 Multiple tracepoints at one place are permitted, and useful if their\n\
 conditions are different.\n\
 \n\
@@ -16012,15 +15840,15 @@ Use the 'source' command in another debug session to restore them."),
   deprecate_cmd (c, "save tracepoints");
 
   add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, _("\
-Breakpoint specific settings\n\
+Breakpoint specific settings.\n\
 Configure various breakpoint-specific variables such as\n\
-pending breakpoint behavior"),
+pending breakpoint behavior."),
                  &breakpoint_set_cmdlist, "set breakpoint ",
                  0/*allow-unknown*/, &setlist);
   add_prefix_cmd ("breakpoint", class_maintenance, show_breakpoint_cmd, _("\
-Breakpoint specific settings\n\
+Breakpoint specific settings.\n\
 Configure various breakpoint-specific variables such as\n\
-pending breakpoint behavior"),
+pending breakpoint behavior."),
                  &breakpoint_show_cmdlist, "show breakpoint ",
                  0/*allow-unknown*/, &showlist);
 
@@ -16121,16 +15949,16 @@ output stream by setting dprintf-function and dprintf-channel."),
   dprintf_function = xstrdup ("printf");
   add_setshow_string_cmd ("dprintf-function", class_support,
                          &dprintf_function, _("\
-Set the function to use for dynamic printf"), _("\
-Show the function to use for dynamic printf"), NULL,
+Set the function to use for dynamic printf."), _("\
+Show the function to use for dynamic printf."), NULL,
                          update_dprintf_commands, NULL,
                          &setlist, &showlist);
 
   dprintf_channel = xstrdup ("");
   add_setshow_string_cmd ("dprintf-channel", class_support,
                          &dprintf_channel, _("\
-Set the channel to use for dynamic printf"), _("\
-Show the channel to use for dynamic printf"), NULL,
+Set the channel to use for dynamic printf."), _("\
+Show the channel to use for dynamic printf."), NULL,
                          update_dprintf_commands, NULL,
                          &setlist, &showlist);
 
@@ -16145,11 +15973,13 @@ even if GDB disconnects or detaches from the target."),
                           &setlist, &showlist);
 
   add_com ("agent-printf", class_vars, agent_printf_command, _("\
-agent-printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
-(target agent only) This is useful for formatted output in user-defined commands."));
+Target agent only formatted printing, like the C \"printf\" function.\n\
+Usage: agent-printf \"format string\", ARG1, ARG2, ARG3, ..., ARGN\n\
+This supports most C printf format specifications, like %s, %d, etc.\n\
+This is useful for formatted output in user-defined commands."));
 
-  automatic_hardware_breakpoints = 1;
+  automatic_hardware_breakpoints = true;
 
-  observer_attach_about_to_proceed (breakpoint_about_to_proceed);
-  observer_attach_thread_exit (remove_threaded_breakpoints);
+  gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed);
+  gdb::observers::thread_exit.attach (remove_threaded_breakpoints);
 }
This page took 0.0932 seconds and 4 git commands to generate.