Fix dwarf2_string_attr for -gsplit-dwarf
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 1fe4eb08c5d78cd5109f70c601d605a2a88fe852..3dc9112690251774b12062f5c304078ca02962b3 100644 (file)
@@ -80,6 +80,7 @@
 #include "mi/mi-common.h"
 #include "extension.h"
 #include <algorithm>
+#include "progspace-and-thread.h"
 
 /* Enums for exception-handling support.  */
 enum exception_event_kind
@@ -119,7 +120,9 @@ static void
 
 static void create_breakpoints_sal_default (struct gdbarch *,
                                            struct linespec_result *,
-                                           char *, char *, enum bptype,
+                                           gdb::unique_xmalloc_ptr<char>,
+                                           gdb::unique_xmalloc_ptr<char>,
+                                           enum bptype,
                                            enum bpdisp, int, int,
                                            int,
                                            const struct breakpoint_ops *,
@@ -308,9 +311,6 @@ static struct breakpoint_ops internal_breakpoint_ops;
 /* Momentary breakpoints class type.  */
 static struct breakpoint_ops momentary_breakpoint_ops;
 
-/* Momentary breakpoints for bp_longjmp and bp_exception class type.  */
-static struct breakpoint_ops longjmp_breakpoint_ops;
-
 /* The breakpoint_ops structure to be used in regular user created
    breakpoints.  */
 struct breakpoint_ops bkpt_breakpoint_ops;
@@ -947,7 +947,6 @@ get_first_locp_gte_addr (CORE_ADDR address)
   struct bp_location **locp_found = NULL;
 
   /* Initialize the dummy location's address field.  */
-  memset (&dummy_loc, 0, sizeof (struct bp_location));
   dummy_loc.address = address;
 
   /* Find a close match to the first location at ADDRESS.  */
@@ -1043,8 +1042,9 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
 
 /* Completion for the "condition" command.  */
 
-static VEC (char_ptr) *
+static void
 condition_completer (struct cmd_list_element *cmd,
+                    completion_tracker &tracker,
                     const char *text, const char *word)
 {
   const char *space;
@@ -1060,9 +1060,9 @@ condition_completer (struct cmd_list_element *cmd,
       if (text[0] == '$')
        {
          /* We don't support completion of history indices.  */
-         if (isdigit (text[1]))
-           return NULL;
-         return complete_internalvar (&text[1]);
+         if (!isdigit (text[1]))
+           complete_internalvar (tracker, &text[1]);
+         return;
        }
 
       /* We're completing the breakpoint number.  */
@@ -1075,15 +1075,18 @@ condition_completer (struct cmd_list_element *cmd,
          xsnprintf (number, sizeof (number), "%d", b->number);
 
          if (strncmp (number, text, len) == 0)
-           VEC_safe_push (char_ptr, result, xstrdup (number));
+           {
+             gdb::unique_xmalloc_ptr<char> copy (xstrdup (number));
+             tracker.add_completion (std::move (copy));
+           }
        }
 
-      return result;
+      return;
     }
 
   /* We're completing the expression part.  */
   text = skip_spaces_const (space);
-  return expression_completer (cmd, text, word);
+  expression_completer (cmd, tracker, text, word);
 }
 
 /* condition N EXP -- set break condition of breakpoint N to EXP.  */
@@ -1160,22 +1163,51 @@ check_no_tracepoint_commands (struct command_line *commands)
     }
 }
 
+struct longjmp_breakpoint : public breakpoint
+{
+  ~longjmp_breakpoint () override;
+};
+
 /* Encapsulate tests for different types of tracepoints.  */
 
-static int
-is_tracepoint_type (enum bptype type)
+static bool
+is_tracepoint_type (bptype type)
 {
   return (type == bp_tracepoint
          || type == bp_fast_tracepoint
          || type == bp_static_tracepoint);
 }
 
+static bool
+is_longjmp_type (bptype type)
+{
+  return type == bp_longjmp || type == bp_exception;
+}
+
 int
 is_tracepoint (const struct breakpoint *b)
 {
   return is_tracepoint_type (b->type);
 }
 
+/* Factory function to create an appropriate instance of breakpoint given
+   TYPE.  */
+
+static std::unique_ptr<breakpoint>
+new_breakpoint_from_type (bptype type)
+{
+  breakpoint *b;
+
+  if (is_tracepoint_type (type))
+    b = new tracepoint ();
+  else if (is_longjmp_type (type))
+    b = new longjmp_breakpoint ();
+  else
+    b = new breakpoint ();
+
+  return std::unique_ptr<breakpoint> (b);
+}
+
 /* A helper function that validates that COMMANDS are valid for a
    breakpoint.  This function will throw an exception if a problem is
    found.  */
@@ -1707,7 +1739,7 @@ is_watchpoint (const struct breakpoint *bpt)
 static int
 watchpoint_in_thread_scope (struct watchpoint *b)
 {
-  return (b->base.pspace == current_program_space
+  return (b->pspace == current_program_space
          && (ptid_equal (b->watchpoint_thread, null_ptid)
              || (ptid_equal (inferior_ptid, b->watchpoint_thread)
                  && !is_executing (inferior_ptid))));
@@ -1719,17 +1751,15 @@ watchpoint_in_thread_scope (struct watchpoint *b)
 static void
 watchpoint_del_at_next_stop (struct watchpoint *w)
 {
-  struct breakpoint *b = &w->base;
-
-  if (b->related_breakpoint != b)
+  if (w->related_breakpoint != w)
     {
-      gdb_assert (b->related_breakpoint->type == bp_watchpoint_scope);
-      gdb_assert (b->related_breakpoint->related_breakpoint == b);
-      b->related_breakpoint->disposition = disp_del_at_next_stop;
-      b->related_breakpoint->related_breakpoint = b->related_breakpoint;
-      b->related_breakpoint = b;
+      gdb_assert (w->related_breakpoint->type == bp_watchpoint_scope);
+      gdb_assert (w->related_breakpoint->related_breakpoint == w);
+      w->related_breakpoint->disposition = disp_del_at_next_stop;
+      w->related_breakpoint->related_breakpoint = w->related_breakpoint;
+      w->related_breakpoint = w;
     }
-  b->disposition = disp_del_at_next_stop;
+  w->disposition = disp_del_at_next_stop;
 }
 
 /* Extract a bitfield value from value VAL using the bit parameters contained in
@@ -1850,7 +1880,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
   if (!watchpoint_in_thread_scope (b))
     return;
 
-  if (b->base.disposition == disp_del_at_next_stop)
+  if (b->disposition == disp_del_at_next_stop)
     return;
  
   frame_saved = 0;
@@ -1888,7 +1918,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
   /* We don't free locations.  They are stored in the bp_location array
      and update_global_location_list will eventually delete them and
      remove breakpoints if needed.  */
-  b->base.loc = NULL;
+  b->loc = NULL;
 
   if (within_current_scope && reparse)
     {
@@ -1908,11 +1938,11 @@ update_watchpoint (struct watchpoint *b, int reparse)
       /* Note that unlike with breakpoints, the watchpoint's condition
         expression is stored in the breakpoint object, not in the
         locations (re)created below.  */
-      if (b->base.cond_string != NULL)
+      if (b->cond_string != NULL)
        {
          b->cond_exp.reset ();
 
-         s = b->base.cond_string;
+         s = b->cond_string;
          b->cond_exp = parse_exp_1 (&s, 0, b->cond_exp_valid_block, 0);
        }
     }
@@ -1929,8 +1959,8 @@ update_watchpoint (struct watchpoint *b, int reparse)
         the target gains execution, through breakpoint_re_set.  */
       if (!can_use_hw_watchpoints)
        {
-         if (b->base.ops->works_in_software_mode (&b->base))
-           b->base.type = bp_watchpoint;
+         if (b->ops->works_in_software_mode (b))
+           b->type = bp_watchpoint;
          else
            error (_("Can't set read/access watchpoint when "
                     "hardware watchpoints are disabled."));
@@ -1950,7 +1980,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
         happens, the code that reports it updates b->val directly.
         We don't keep track of the memory value for masked
         watchpoints.  */
-      if (!b->val_valid && !is_masked_watchpoint (&b->base))
+      if (!b->val_valid && !is_masked_watchpoint (b))
        {
          if (b->val_bitsize != 0)
            {
@@ -2013,13 +2043,13 @@ update_watchpoint (struct watchpoint *b, int reparse)
                    }
 
                  type = hw_write;
-                 if (b->base.type == bp_read_watchpoint)
+                 if (b->type == bp_read_watchpoint)
                    type = hw_read;
-                 else if (b->base.type == bp_access_watchpoint)
+                 else if (b->type == bp_access_watchpoint)
                    type = hw_access;
 
-                 loc = allocate_bp_location (&b->base);
-                 for (tmp = &(b->base.loc); *tmp != NULL; tmp = &((*tmp)->next))
+                 loc = allocate_bp_location (b);
+                 for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
                    ;
                  *tmp = loc;
                  loc->gdbarch = get_type_arch (value_type (v));
@@ -2069,7 +2099,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
              /* If this is a software watchpoint, we try to turn it
                 to a hardware one -- count resources as if B was of
                 hardware watchpoint type.  */
-             type = b->base.type;
+             type = b->type;
              if (type == bp_watchpoint)
                type = bp_hardware_watchpoint;
 
@@ -2080,16 +2110,16 @@ update_watchpoint (struct watchpoint *b, int reparse)
                 manually.  */
 
              /* Count resources used by all watchpoints except B.  */
-             i = hw_watchpoint_used_count_others (&b->base, type, &other_type_used);
+             i = hw_watchpoint_used_count_others (b, type, &other_type_used);
 
              /* Add in the resources needed for B.  */
-             i += hw_watchpoint_use_count (&b->base);
+             i += hw_watchpoint_use_count (b);
 
              target_resources_ok
                = target_can_use_hardware_watchpoint (type, i, other_type_used);
              if (target_resources_ok <= 0)
                {
-                 int sw_mode = b->base.ops->works_in_software_mode (&b->base);
+                 int sw_mode = b->ops->works_in_software_mode (b);
 
                  if (target_resources_ok == 0 && !sw_mode)
                    error (_("Target does not support this type of "
@@ -2099,7 +2129,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
                             "resources for this watchpoint."));
 
                  /* Downgrade to software watchpoint.  */
-                 b->base.type = bp_watchpoint;
+                 b->type = bp_watchpoint;
                }
              else
                {
@@ -2107,10 +2137,10 @@ update_watchpoint (struct watchpoint *b, int reparse)
                     found we have enough resources to turn it to a
                     hardware watchpoint.  Otherwise, this is a
                     nop.  */
-                 b->base.type = type;
+                 b->type = type;
                }
            }
-         else if (!b->base.ops->works_in_software_mode (&b->base))
+         else if (!b->ops->works_in_software_mode (b))
            {
              if (!can_use_hw_watchpoints)
                error (_("Can't set read/access watchpoint when "
@@ -2120,11 +2150,11 @@ update_watchpoint (struct watchpoint *b, int reparse)
                         "read/access watchpoint."));
            }
          else
-           b->base.type = bp_watchpoint;
+           b->type = bp_watchpoint;
 
-         loc_type = (b->base.type == bp_watchpoint? bp_loc_other
+         loc_type = (b->type == bp_watchpoint? bp_loc_other
                      : bp_loc_hardware_watchpoint);
-         for (bl = b->base.loc; bl; bl = bl->next)
+         for (bl = b->loc; bl; bl = bl->next)
            bl->loc_type = loc_type;
        }
 
@@ -2139,15 +2169,15 @@ update_watchpoint (struct watchpoint *b, int reparse)
         above left it without any location set up.  But,
         bpstat_stop_status requires a location to be able to report
         stops, so make sure there's at least a dummy one.  */
-      if (b->base.type == bp_watchpoint && b->base.loc == NULL)
-       software_watchpoint_add_no_memory_location (&b->base, frame_pspace);
+      if (b->type == bp_watchpoint && b->loc == NULL)
+       software_watchpoint_add_no_memory_location (b, frame_pspace);
     }
   else if (!within_current_scope)
     {
       printf_filtered (_("\
 Watchpoint %d deleted because the program has left the block\n\
 in which its expression is valid.\n"),
-                      b->base.number);
+                      b->number);
       watchpoint_del_at_next_stop (b);
     }
 
@@ -3066,7 +3096,7 @@ update_inserted_breakpoint_locations (void)
      there was an error.  */
   tmp_error_stream.puts ("Warning:\n");
 
-  struct cleanup *cleanups = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
     {
@@ -3102,8 +3132,6 @@ update_inserted_breakpoint_locations (void)
       target_terminal_ours_for_output ();
       error_stream (tmp_error_stream);
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Used when starting or continuing the program.  */
@@ -3125,7 +3153,7 @@ insert_breakpoint_locations (void)
      there was an error.  */
   tmp_error_stream.puts ("Warning:\n");
 
-  struct cleanup *cleanups = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
     {
@@ -3203,8 +3231,6 @@ You may have requested too many hardware breakpoints/watchpoints.\n");
       target_terminal_ours_for_output ();
       error_stream (tmp_error_stream);
     }
-
-  do_cleanups (cleanups);
 }
 
 /* Used when the program stops.
@@ -3490,9 +3516,8 @@ static void
 create_longjmp_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct cleanup *old_chain;
 
-  old_chain = save_current_program_space ();
+  scoped_restore_current_program_space restore_pspace;
 
   ALL_PSPACES (pspace)
   {
@@ -3596,8 +3621,6 @@ create_longjmp_master_breakpoint (void)
        }
     }
   }
-
-  do_cleanups (old_chain);
 }
 
 /* Create a master std::terminate breakpoint.  */
@@ -3605,10 +3628,9 @@ static void
 create_std_terminate_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct cleanup *old_chain;
   const char *const func_name = "std::terminate()";
 
-  old_chain = save_current_program_space ();
+  scoped_restore_current_program_space restore_pspace;
 
   ALL_PSPACES (pspace)
   {
@@ -3653,8 +3675,6 @@ create_std_terminate_master_breakpoint (void)
       b->enable_state = bp_disabled;
     }
   }
-
-  do_cleanups (old_chain);
 }
 
 /* Install a master breakpoint on the unwinder's debug hook.  */
@@ -4078,9 +4098,6 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 static int
 remove_breakpoint (struct bp_location *bl)
 {
-  int ret;
-  struct cleanup *old_chain;
-
   /* BL is never in moribund_locations by our callers.  */
   gdb_assert (bl->owner != NULL);
 
@@ -4088,14 +4105,11 @@ remove_breakpoint (struct bp_location *bl)
      This should not ever happen.  */
   gdb_assert (bl->owner->type != bp_none);
 
-  old_chain = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   switch_to_program_space_and_thread (bl->pspace);
 
-  ret = remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
-
-  do_cleanups (old_chain);
-  return ret;
+  return remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
 }
 
 /* Clear the "inserted" flag in all breakpoints.  */
@@ -4885,13 +4899,11 @@ print_solib_event (int is_catchpoint)
 
   if (any_deleted)
     {
-      struct cleanup *cleanup;
       char *name;
       int ix;
 
       current_uiout->text (_("  Inferior unloaded "));
-      cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
-                                                   "removed");
+      ui_out_emit_list list_emitter (current_uiout, "removed");
       for (ix = 0;
           VEC_iterate (char_ptr, current_program_space->deleted_solibs,
                        ix, name);
@@ -4902,19 +4914,15 @@ print_solib_event (int is_catchpoint)
          current_uiout->field_string ("library", name);
          current_uiout->text ("\n");
        }
-
-      do_cleanups (cleanup);
     }
 
   if (any_added)
     {
       struct so_list *iter;
       int ix;
-      struct cleanup *cleanup;
 
       current_uiout->text (_("  Inferior loaded "));
-      cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
-                                                   "added");
+      ui_out_emit_list list_emitter (current_uiout, "added");
       for (ix = 0;
           VEC_iterate (so_list_ptr, current_program_space->added_solibs,
                        ix, iter);
@@ -4925,8 +4933,6 @@ print_solib_event (int is_catchpoint)
          current_uiout->field_string ("library", iter->so_name);
          current_uiout->text ("\n");
        }
-
-      do_cleanups (cleanup);
     }
 }
 
@@ -5191,7 +5197,7 @@ watchpoint_check (void *p)
       struct value *mark;
       struct value *new_val;
 
-      if (is_masked_watchpoint (&b->base))
+      if (is_masked_watchpoint (b))
        /* Since we don't know the exact trigger address (from
           stopped_data_address), just tell the user we've triggered
           a mask watchpoint.  */
@@ -5251,13 +5257,13 @@ watchpoint_check (void *p)
            uiout->field_string
              ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
          uiout->text ("\nWatchpoint ");
-         uiout->field_int ("wpnum", b->base.number);
+         uiout->field_int ("wpnum", b->number);
          uiout->text (" deleted because the program has left the block in\n"
                       "which its expression is valid.\n");
        }
 
       /* Make sure the watchpoint's commands aren't executed.  */
-      decref_counted_command_line (&b->base.commands);
+      decref_counted_command_line (&b->commands);
       watchpoint_del_at_next_stop (b);
 
       return WP_DELETED;
@@ -5299,7 +5305,7 @@ bpstat_check_watchpoint (bpstat bs)
     {
       int must_check_value = 0;
       
-      if (b->base.type == bp_watchpoint)
+      if (b->type == bp_watchpoint)
        /* For a software watchpoint, we must always check the
           watched value.  */
        must_check_value = 1;
@@ -5309,7 +5315,7 @@ bpstat_check_watchpoint (bpstat bs)
           this watchpoint.  */
        must_check_value = 1;
       else if (b->watchpoint_triggered == watch_triggered_unknown
-              && b->base.type == bp_hardware_watchpoint)
+              && b->type == bp_hardware_watchpoint)
        /* We were stopped by a hardware watchpoint, but the target could
           not report the data address.  We must check the watchpoint's
           value.  Access and read watchpoints are out of luck; without
@@ -5320,7 +5326,7 @@ bpstat_check_watchpoint (bpstat bs)
        {
          char *message
            = xstrprintf ("Error evaluating expression for watchpoint %d\n",
-                         b->base.number);
+                         b->number);
          struct cleanup *cleanups = make_cleanup (xfree, message);
          int e = catch_errors (watchpoint_check, bs, message,
                                RETURN_MASK_ALL);
@@ -5337,7 +5343,7 @@ bpstat_check_watchpoint (bpstat bs)
              bs->stop = 0;
              break;
            case WP_VALUE_CHANGED:
-             if (b->base.type == bp_read_watchpoint)
+             if (b->type == bp_read_watchpoint)
                {
                  /* There are two cases to consider here:
 
@@ -5408,8 +5414,8 @@ bpstat_check_watchpoint (bpstat bs)
                }
              break;
            case WP_VALUE_NOT_CHANGED:
-             if (b->base.type == bp_hardware_watchpoint
-                 || b->base.type == bp_watchpoint)
+             if (b->type == bp_hardware_watchpoint
+                 || b->type == bp_watchpoint)
                {
                  /* Don't stop: write watchpoints shouldn't fire if
                     the value hasn't changed.  */
@@ -5426,7 +5432,7 @@ bpstat_check_watchpoint (bpstat bs)
                SWITCH_THRU_ALL_UIS ()
                  {
                    printf_filtered (_("Watchpoint %d deleted.\n"),
-                                    b->base.number);
+                                    b->number);
                  }
                watchpoint_del_at_next_stop (b);
                /* We've already printed what needs to be printed.  */
@@ -6138,7 +6144,8 @@ print_breakpoint_location (struct breakpoint *b,
                           struct bp_location *loc)
 {
   struct ui_out *uiout = current_uiout;
-  struct cleanup *old_chain = save_current_program_space ();
+
+  scoped_restore_current_program_space restore_pspace;
 
   if (loc != NULL && loc->shlib_disabled)
     loc = NULL;
@@ -6203,8 +6210,6 @@ print_breakpoint_location (struct breakpoint *b,
                           bp_location_condition_evaluator (loc));
       uiout->text (")");
     }
-
-  do_cleanups (old_chain);
 }
 
 static const char *
@@ -6271,7 +6276,6 @@ output_thread_groups (struct ui_out *uiout,
                      VEC(int) *inf_num,
                      int mi_only)
 {
-  struct cleanup *back_to;
   int is_mi = uiout->is_mi_like_p ();
   int inf;
   int i;
@@ -6281,7 +6285,7 @@ output_thread_groups (struct ui_out *uiout,
   if (!is_mi && mi_only)
     return;
 
-  back_to = make_cleanup_ui_out_list_begin_end (uiout, field_name);
+  ui_out_emit_list list_emitter (uiout, field_name);
 
   for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
     {
@@ -6302,8 +6306,6 @@ output_thread_groups (struct ui_out *uiout,
          uiout->text (plongest (inf));
        }
     }
-
-  do_cleanups (back_to);
 }
 
 /* Print B to gdb_stdout.  */
@@ -6619,12 +6621,9 @@ print_one_breakpoint_location (struct breakpoint *b,
   l = b->commands ? b->commands->commands : NULL;
   if (!part_of_multiple && l)
     {
-      struct cleanup *script_chain;
-
       annotate_field (9);
-      script_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "script");
+      ui_out_emit_tuple tuple_emitter (uiout, "script");
       print_command_lines (uiout, l, 4);
-      do_cleanups (script_chain);
     }
 
   if (is_tracepoint (b))
@@ -6679,13 +6678,13 @@ print_one_breakpoint (struct breakpoint *b,
                      struct bp_location **last_loc, 
                      int allflag)
 {
-  struct cleanup *bkpt_chain;
   struct ui_out *uiout = current_uiout;
 
-  bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt");
+  {
+    ui_out_emit_tuple tuple_emitter (uiout, "bkpt");
 
-  print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
-  do_cleanups (bkpt_chain);
+    print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
+  }
 
   /* If this breakpoint has custom print function,
      it's already printed.  Otherwise, print individual
@@ -6708,10 +6707,8 @@ print_one_breakpoint (struct breakpoint *b,
 
          for (loc = b->loc; loc; loc = loc->next, ++n)
            {
-             struct cleanup *inner2 =
-               make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+             ui_out_emit_tuple tuple_emitter (uiout, NULL);
              print_one_breakpoint_location (b, loc, n, last_loc, allflag);
-             do_cleanups (inner2);
            }
        }
     }
@@ -6811,7 +6808,6 @@ breakpoint_1 (char *args, int allflag,
   struct breakpoint *b;
   struct bp_location *last_loc = NULL;
   int nr_printable_breakpoints;
-  struct cleanup *bkpttbl_chain;
   struct value_print_options opts;
   int print_address_bits = 0;
   int print_type_col_width = 14;
@@ -6854,77 +6850,71 @@ breakpoint_1 (char *args, int allflag,
        }
     }
 
-  if (opts.addressprint)
-    bkpttbl_chain 
-      = make_cleanup_ui_out_table_begin_end (uiout, 6,
-                                            nr_printable_breakpoints,
-                                             "BreakpointTable");
-  else
-    bkpttbl_chain 
-      = make_cleanup_ui_out_table_begin_end (uiout, 5,
-                                            nr_printable_breakpoints,
-                                             "BreakpointTable");
-
-  if (nr_printable_breakpoints > 0)
-    annotate_breakpoints_headers ();
-  if (nr_printable_breakpoints > 0)
-    annotate_field (0);
-  uiout->table_header (7, ui_left, "number", "Num"); /* 1 */
-  if (nr_printable_breakpoints > 0)
-    annotate_field (1);
-  uiout->table_header (print_type_col_width, ui_left, "type", "Type"); /* 2 */
-  if (nr_printable_breakpoints > 0)
-    annotate_field (2);
-  uiout->table_header (4, ui_left, "disp", "Disp"); /* 3 */
-  if (nr_printable_breakpoints > 0)
-    annotate_field (3);
-  uiout->table_header (3, ui_left, "enabled", "Enb"); /* 4 */
-  if (opts.addressprint)
-    {
-      if (nr_printable_breakpoints > 0)
-       annotate_field (4);
-      if (print_address_bits <= 32)
-       uiout->table_header (10, ui_left, "addr", "Address"); /* 5 */
-      else
-       uiout->table_header (18, ui_left, "addr", "Address"); /* 5 */
-    }
-  if (nr_printable_breakpoints > 0)
-    annotate_field (5);
-  uiout->table_header (40, ui_noalign, "what", "What"); /* 6 */
-  uiout->table_body ();
-  if (nr_printable_breakpoints > 0)
-    annotate_breakpoints_table ();
-
-  ALL_BREAKPOINTS (b)
-    {
-      QUIT;
-      /* If we have a filter, only list the breakpoints it accepts.  */
-      if (filter && !filter (b))
-       continue;
+  {
+    ui_out_emit_table table_emitter (uiout,
+                                    opts.addressprint ? 6 : 5,
+                                    nr_printable_breakpoints,
+                                    "BreakpointTable");
+
+    if (nr_printable_breakpoints > 0)
+      annotate_breakpoints_headers ();
+    if (nr_printable_breakpoints > 0)
+      annotate_field (0);
+    uiout->table_header (7, ui_left, "number", "Num"); /* 1 */
+    if (nr_printable_breakpoints > 0)
+      annotate_field (1);
+    uiout->table_header (print_type_col_width, ui_left, "type", "Type"); /* 2 */
+    if (nr_printable_breakpoints > 0)
+      annotate_field (2);
+    uiout->table_header (4, ui_left, "disp", "Disp"); /* 3 */
+    if (nr_printable_breakpoints > 0)
+      annotate_field (3);
+    uiout->table_header (3, ui_left, "enabled", "Enb"); /* 4 */
+    if (opts.addressprint)
+      {
+       if (nr_printable_breakpoints > 0)
+         annotate_field (4);
+       if (print_address_bits <= 32)
+         uiout->table_header (10, ui_left, "addr", "Address"); /* 5 */
+       else
+         uiout->table_header (18, ui_left, "addr", "Address"); /* 5 */
+      }
+    if (nr_printable_breakpoints > 0)
+      annotate_field (5);
+    uiout->table_header (40, ui_noalign, "what", "What"); /* 6 */
+    uiout->table_body ();
+    if (nr_printable_breakpoints > 0)
+      annotate_breakpoints_table ();
+
+    ALL_BREAKPOINTS (b)
+      {
+       QUIT;
+       /* If we have a filter, only list the breakpoints it accepts.  */
+       if (filter && !filter (b))
+         continue;
 
-      /* If we have an "args" string, it is a list of breakpoints to 
-        accept.  Skip the others.  */
+       /* If we have an "args" string, it is a list of breakpoints to 
+          accept.  Skip the others.  */
 
-      if (args != NULL && *args != '\0')
-       {
-         if (allflag)  /* maintenance info breakpoint */
-           {
-             if (parse_and_eval_long (args) != b->number)
-               continue;
-           }
-         else          /* all others */
-           {
-             if (!number_is_in_list (args, 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);
-    }
-
-  do_cleanups (bkpttbl_chain);
+       if (args != NULL && *args != '\0')
+         {
+           if (allflag)        /* maintenance info breakpoint */
+             {
+               if (parse_and_eval_long (args) != b->number)
+                 continue;
+             }
+           else                /* all others */
+             {
+               if (!number_is_in_list (args, 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);
+      }
+  }
 
   if (nr_printable_breakpoints == 0)
     {
@@ -7316,11 +7306,9 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
     }
 }
 
-void
-init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
-                 struct breakpoint *owner)
+bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner)
 {
-  memset (loc, 0, sizeof (*loc));
+  bp_location *loc = this;
 
   gdb_assert (ops != NULL);
 
@@ -7447,8 +7435,6 @@ init_raw_breakpoint_without_location (struct breakpoint *b,
                                      enum bptype bptype,
                                      const struct breakpoint_ops *ops)
 {
-  memset (b, 0, sizeof (*b));
-
   gdb_assert (ops != NULL);
 
   b->ops = ops;
@@ -7456,17 +7442,7 @@ init_raw_breakpoint_without_location (struct breakpoint *b,
   b->gdbarch = gdbarch;
   b->language = current_language->la_language;
   b->input_radix = input_radix;
-  b->thread = -1;
-  b->enable_state = bp_enabled;
-  b->next = 0;
-  b->silent = 0;
-  b->ignore_count = 0;
-  b->commands = NULL;
-  b->frame_id = null_frame_id;
-  b->condition_not_parsed = 0;
-  b->py_bp_object = NULL;
   b->related_breakpoint = b;
-  b->location = NULL;
 }
 
 /* Helper to set_raw_breakpoint below.  Creates a breakpoint
@@ -7477,11 +7453,12 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
                                     enum bptype bptype,
                                     const struct breakpoint_ops *ops)
 {
-  struct breakpoint *b = new breakpoint ();
+  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (bptype);
 
-  init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
-  add_to_breakpoint_chain (b);
-  return b;
+  init_raw_breakpoint_without_location (b.get (), gdbarch, bptype, ops);
+  add_to_breakpoint_chain (b.get ());
+
+  return b.release ();
 }
 
 /* Initialize loc->function_name.  EXPLICIT_LOC says no indirect function
@@ -7593,11 +7570,12 @@ set_raw_breakpoint (struct gdbarch *gdbarch,
                    struct symtab_and_line sal, enum bptype bptype,
                    const struct breakpoint_ops *ops)
 {
-  struct breakpoint *b = new breakpoint ();
+  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (bptype);
 
-  init_raw_breakpoint (b, gdbarch, sal, bptype, ops);
-  add_to_breakpoint_chain (b);
-  return b;
+  init_raw_breakpoint (b.get (), gdbarch, sal, bptype, ops);
+  add_to_breakpoint_chain (b.get ());
+
+  return b.release ();
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
@@ -7625,7 +7603,7 @@ set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
        /* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
           after their removal.  */
        clone = momentary_breakpoint_from_master (b, type,
-                                                 &longjmp_breakpoint_ops, 1);
+                                                 &momentary_breakpoint_ops, 1);
        clone->thread = thread;
       }
 
@@ -8047,16 +8025,11 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile)
 /* FORK & VFORK catchpoints.  */
 
 /* An instance of this type is used to represent a fork or vfork
-   catchpoint.  It includes a "struct breakpoint" as a kind of base
-   class; users downcast to "struct breakpoint *" when needed.  A
-   breakpoint is really of this type iff its ops pointer points to
-   CATCH_FORK_BREAKPOINT_OPS.  */
+   catchpoint.  A breakpoint is really of this type iff its ops pointer points
+   to CATCH_FORK_BREAKPOINT_OPS.  */
 
-struct fork_catchpoint
+struct fork_catchpoint : public breakpoint
 {
-  /* The base class.  */
-  struct breakpoint base;
-
   /* Process id of a child process whose forking triggered this
      catchpoint.  This field is only valid immediately after this
      catchpoint has triggered.  */
@@ -8295,15 +8268,12 @@ print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
 static struct breakpoint_ops catch_vfork_breakpoint_ops;
 
 /* An instance of this type is used to represent an solib catchpoint.
-   It includes a "struct breakpoint" as a kind of base class; users
-   downcast to "struct breakpoint *" when needed.  A breakpoint is
-   really of this type iff its ops pointer points to
+   A breakpoint is really of this type iff its ops pointer points to
    CATCH_SOLIB_BREAKPOINT_OPS.  */
 
-struct solib_catchpoint
+struct solib_catchpoint : public breakpoint
 {
-  /* The base class.  */
-  struct breakpoint base;
+  ~solib_catchpoint () override;
 
   /* True for "catch load", false for "catch unload".  */
   unsigned char is_load;
@@ -8311,19 +8281,12 @@ struct solib_catchpoint
   /* Regular expression to match, if any.  COMPILED is only valid when
      REGEX is non-NULL.  */
   char *regex;
-  regex_t compiled;
+  std::unique_ptr<compiled_regex> compiled;
 };
 
-static void
-dtor_catch_solib (struct breakpoint *b)
+solib_catchpoint::~solib_catchpoint ()
 {
-  struct solib_catchpoint *self = (struct solib_catchpoint *) b;
-
-  if (self->regex)
-    regfree (&self->compiled);
-  xfree (self->regex);
-
-  base_breakpoint_ops.dtor (b);
+  xfree (this->regex);
 }
 
 static int
@@ -8360,7 +8323,7 @@ breakpoint_hit_catch_solib (const struct bp_location *bl,
     if (other->type != bp_shlib_event)
       continue;
 
-    if (self->base.pspace != NULL && other->pspace != self->base.pspace)
+    if (self->pspace != NULL && other->pspace != self->pspace)
       continue;
 
     for (other_bl = other->loc; other_bl != NULL; other_bl = other_bl->next)
@@ -8390,7 +8353,7 @@ check_status_catch_solib (struct bpstats *bs)
           ++ix)
        {
          if (!self->regex
-             || regexec (&self->compiled, iter->so_name, 0, NULL, 0) == 0)
+             || self->compiled->exec (iter->so_name, 0, NULL, 0) == 0)
            return;
        }
     }
@@ -8404,7 +8367,7 @@ check_status_catch_solib (struct bpstats *bs)
           ++ix)
        {
          if (!self->regex
-             || regexec (&self->compiled, iter, 0, NULL, 0) == 0)
+             || self->compiled->exec (iter, 0, NULL, 0) == 0)
            return;
        }
     }
@@ -8520,27 +8483,19 @@ add_solib_catchpoint (const char *arg, int is_load, int is_temp, int enabled)
 
   if (*arg != '\0')
     {
-      int errcode;
-
-      errcode = regcomp (&c->compiled, arg, REG_NOSUB);
-      if (errcode != 0)
-       {
-         char *err = get_regcomp_error (errcode, &c->compiled);
-
-         make_cleanup (xfree, err);
-         error (_("Invalid regexp (%s): %s"), err, arg);
-       }
+      c->compiled.reset (new compiled_regex (arg, REG_NOSUB,
+                                            _("Invalid regexp")));
       c->regex = xstrdup (arg);
     }
 
   c->is_load = is_load;
-  init_catchpoint (&c->base, gdbarch, is_temp, NULL,
+  init_catchpoint (c, gdbarch, is_temp, NULL,
                   &catch_solib_breakpoint_ops);
 
-  c->base.enable_state = enabled ? bp_enabled : bp_disabled;
+  c->enable_state = enabled ? bp_enabled : bp_disabled;
 
   discard_cleanups (cleanup);
-  install_breakpoint (0, &c->base, 1);
+  install_breakpoint (0, c, 1);
 }
 
 /* A helper function that does all the work for "catch load" and
@@ -8616,25 +8571,22 @@ create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
 {
   struct fork_catchpoint *c = new fork_catchpoint ();
 
-  init_catchpoint (&c->base, gdbarch, tempflag, cond_string, ops);
+  init_catchpoint (c, gdbarch, tempflag, cond_string, ops);
 
   c->forked_inferior_pid = null_ptid;
 
-  install_breakpoint (0, &c->base, 1);
+  install_breakpoint (0, c, 1);
 }
 
 /* Exec catchpoints.  */
 
 /* An instance of this type is used to represent an exec catchpoint.
-   It includes a "struct breakpoint" as a kind of base class; users
-   downcast to "struct breakpoint *" when needed.  A breakpoint is
-   really of this type iff its ops pointer points to
+   A breakpoint is really of this type iff its ops pointer points to
    CATCH_EXEC_BREAKPOINT_OPS.  */
 
-struct exec_catchpoint
+struct exec_catchpoint : public breakpoint
 {
-  /* The base class.  */
-  struct breakpoint base;
+  ~exec_catchpoint () override;
 
   /* Filename of a program whose exec triggered this catchpoint.
      This field is only valid immediately after this catchpoint has
@@ -8642,17 +8594,11 @@ struct exec_catchpoint
   char *exec_pathname;
 };
 
-/* Implement the "dtor" breakpoint_ops method for exec
-   catchpoints.  */
+/* Exec catchpoint destructor.  */
 
-static void
-dtor_catch_exec (struct breakpoint *b)
+exec_catchpoint::~exec_catchpoint ()
 {
-  struct exec_catchpoint *c = (struct exec_catchpoint *) b;
-
-  xfree (c->exec_pathname);
-
-  base_breakpoint_ops.dtor (b);
+  xfree (this->exec_pathname);
 }
 
 static int
@@ -9102,9 +9048,6 @@ program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address)
 static int
 bp_loc_is_permanent (struct bp_location *loc)
 {
-  struct cleanup *cleanup;
-  int retval;
-
   gdb_assert (loc != NULL);
 
   /* If we have a catchpoint or a watchpoint, just return 0.  We should not
@@ -9114,14 +9057,9 @@ bp_loc_is_permanent (struct bp_location *loc)
   if (!breakpoint_address_is_meaningful (loc->owner))
     return 0;
 
-  cleanup = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
   switch_to_program_space_and_thread (loc->pspace);
-
-  retval = program_breakpoint_here_p (loc->gdbarch, loc->address);
-
-  do_cleanups (cleanup);
-
-  return retval;
+  return program_breakpoint_here_p (loc->gdbarch, loc->address);
 }
 
 /* Build a command list for the dprintf corresponding to the current
@@ -9218,8 +9156,9 @@ static void
 init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
                     struct symtabs_and_lines sals,
                     event_location_up &&location,
-                    char *filter, char *cond_string,
-                    char *extra_string,
+                    gdb::unique_xmalloc_ptr<char> filter,
+                    gdb::unique_xmalloc_ptr<char> cond_string,
+                    gdb::unique_xmalloc_ptr<char> extra_string,
                     enum bptype type, enum bpdisp disposition,
                     int thread, int task, int ignore_count,
                     const struct breakpoint_ops *ops, int from_tty,
@@ -9265,8 +9204,8 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
          b->thread = thread;
          b->task = task;
 
-         b->cond_string = cond_string;
-         b->extra_string = extra_string;
+         b->cond_string = cond_string.release ();
+         b->extra_string = extra_string.release ();
          b->ignore_count = ignore_count;
          b->enable_state = enabled ? bp_enabled : bp_disabled;
          b->disposition = disposition;
@@ -9350,47 +9289,36 @@ 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;
+  b->filter = filter.release ();
 }
 
 static void
 create_breakpoint_sal (struct gdbarch *gdbarch,
                       struct symtabs_and_lines sals,
                       event_location_up &&location,
-                      char *filter, char *cond_string,
-                      char *extra_string,
+                      gdb::unique_xmalloc_ptr<char> filter,
+                      gdb::unique_xmalloc_ptr<char> cond_string,
+                      gdb::unique_xmalloc_ptr<char> extra_string,
                       enum bptype type, enum bpdisp disposition,
                       int thread, int task, int ignore_count,
                       const struct breakpoint_ops *ops, int from_tty,
                       int enabled, int internal, unsigned flags,
                       int display_canonical)
 {
-  struct breakpoint *b;
-  struct cleanup *old_chain;
+  std::unique_ptr<breakpoint> b = new_breakpoint_from_type (type);
 
-  if (is_tracepoint_type (type))
-    {
-      struct tracepoint *t;
-
-      t = new tracepoint ();
-      b = &t->base;
-    }
-  else
-    b = new breakpoint ();
-
-  old_chain = make_cleanup (xfree, b);
-
-  init_breakpoint_sal (b, gdbarch,
+  init_breakpoint_sal (b.get (), gdbarch,
                       sals, std::move (location),
-                      filter, cond_string, extra_string,
+                      std::move (filter),
+                      std::move (cond_string),
+                      std::move (extra_string),
                       type, disposition,
                       thread, task, ignore_count,
                       ops, from_tty,
                       enabled, internal, flags,
                       display_canonical);
-  discard_cleanups (old_chain);
 
-  install_breakpoint (internal, b, 0);
+  install_breakpoint (internal, b.release (), 0);
 }
 
 /* Add SALS.nelts breakpoints to the breakpoint table.  For each
@@ -9411,7 +9339,8 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
 static void
 create_breakpoints_sal (struct gdbarch *gdbarch,
                        struct linespec_result *canonical,
-                       char *cond_string, char *extra_string,
+                       gdb::unique_xmalloc_ptr<char> cond_string,
+                       gdb::unique_xmalloc_ptr<char> extra_string,
                        enum bptype type, enum bpdisp disposition,
                        int thread, int task, int ignore_count,
                        const struct breakpoint_ops *ops, int from_tty,
@@ -9430,13 +9359,14 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
       event_location_up location
        = (canonical->location != NULL
           ? copy_event_location (canonical->location.get ()) : NULL);
-      char *filter_string = lsal->canonical ? xstrdup (lsal->canonical) : NULL;
+      gdb::unique_xmalloc_ptr<char> filter_string
+       (lsal->canonical != NULL ? xstrdup (lsal->canonical) : NULL);
 
-      make_cleanup (xfree, filter_string);
       create_breakpoint_sal (gdbarch, lsal->sals,
                             std::move (location),
-                            filter_string,
-                            cond_string, extra_string,
+                            std::move (filter_string),
+                            std::move (cond_string),
+                            std::move (extra_string),
                             type, disposition,
                             thread, task, ignore_count, ops,
                             from_tty, enabled, internal, flags,
@@ -9715,8 +9645,9 @@ decode_static_tracepoint_spec (const char **arg_p)
 
 int
 create_breakpoint (struct gdbarch *gdbarch,
-                  const struct event_location *location, char *cond_string,
-                  int thread, char *extra_string,
+                  const struct event_location *location,
+                  const char *cond_string,
+                  int thread, const char *extra_string,
                   int parse_extra,
                   int tempflag, enum bptype type_wanted,
                   int ignore_count,
@@ -9808,9 +9739,13 @@ create_breakpoint (struct gdbarch *gdbarch,
      breakpoint.  */
   if (!pending)
     {
+      gdb::unique_xmalloc_ptr<char> cond_string_copy;
+      gdb::unique_xmalloc_ptr<char> extra_string_copy;
+
       if (parse_extra)
         {
          char *rest;
+         char *cond;
          struct linespec_sals *lsal;
 
          lsal = VEC_index (linespec_sals, canonical.sals, 0);
@@ -9821,15 +9756,9 @@ create_breakpoint (struct gdbarch *gdbarch,
             re-parse it in context of each sal.  */
 
          find_condition_and_thread (extra_string, lsal->sals.sals[0].pc,
-                                    &cond_string, &thread, &task, &rest);
-         if (cond_string)
-           make_cleanup (xfree, cond_string);
-         if (rest)
-           make_cleanup (xfree, rest);
-         if (rest)
-           extra_string = rest;
-         else
-           extra_string = NULL;
+                                    &cond, &thread, &task, &rest);
+         cond_string_copy.reset (cond);
+         extra_string_copy.reset (rest);
         }
       else
         {
@@ -9839,39 +9768,25 @@ create_breakpoint (struct gdbarch *gdbarch,
 
          /* Create a private copy of condition string.  */
          if (cond_string)
-           {
-             cond_string = xstrdup (cond_string);
-             make_cleanup (xfree, cond_string);
-           }
+           cond_string_copy.reset (xstrdup (cond_string));
          /* Create a private copy of any extra string.  */
          if (extra_string)
-           {
-             extra_string = xstrdup (extra_string);
-             make_cleanup (xfree, extra_string);
-           }
+           extra_string_copy.reset (xstrdup (extra_string));
         }
 
       ops->create_breakpoints_sal (gdbarch, &canonical,
-                                  cond_string, extra_string, type_wanted,
+                                  std::move (cond_string_copy),
+                                  std::move (extra_string_copy),
+                                  type_wanted,
                                   tempflag ? disp_del : disp_donttouch,
                                   thread, task, ignore_count, ops,
                                   from_tty, enabled, internal, flags);
     }
   else
     {
-      struct breakpoint *b;
+      std::unique_ptr <breakpoint> b = new_breakpoint_from_type (type_wanted);
 
-      if (is_tracepoint_type (type_wanted))
-       {
-         struct tracepoint *t;
-
-         t = new tracepoint ();
-         b = &t->base;
-       }
-      else
-       b = new breakpoint ();
-
-      init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
+      init_raw_breakpoint_without_location (b.get (), gdbarch, type_wanted, ops);
       b->location = copy_event_location (location);
 
       if (parse_extra)
@@ -9879,22 +9794,12 @@ create_breakpoint (struct gdbarch *gdbarch,
       else
        {
          /* Create a private copy of condition string.  */
-         if (cond_string)
-           {
-             cond_string = xstrdup (cond_string);
-             make_cleanup (xfree, cond_string);
-           }
-         b->cond_string = cond_string;
+         b->cond_string = cond_string != NULL ? xstrdup (cond_string) : NULL;
          b->thread = thread;
        }
 
       /* Create a private copy of any extra string.  */
-      if (extra_string != NULL)
-       {
-         extra_string = xstrdup (extra_string);
-         make_cleanup (xfree, extra_string);
-       }
-      b->extra_string = extra_string;
+      b->extra_string = extra_string != NULL ? xstrdup (extra_string) : NULL;
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
@@ -9903,7 +9808,7 @@ create_breakpoint (struct gdbarch *gdbarch,
            && type_wanted != bp_hardware_breakpoint) || thread != -1)
        b->pspace = current_program_space;
 
-      install_breakpoint (internal, b, 0);
+      install_breakpoint (internal, b.release (), 0);
     }
   
   if (VEC_length (linespec_sals, canonical.sals) > 1)
@@ -10005,16 +9910,12 @@ resolve_sal_pc (struct symtab_and_line *sal)
                 if we have line numbers but no functions (as can
                 happen in assembly source).  */
 
-             struct bound_minimal_symbol msym;
-             struct cleanup *old_chain = save_current_space_and_thread ();
-
+             scoped_restore_current_pspace_and_thread restore_pspace_thread;
              switch_to_program_space_and_thread (sal->pspace);
 
-             msym = lookup_minimal_symbol_by_pc (sal->pc);
+             bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (sal->pc);
              if (msym.minsym)
                sal->section = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym);
-
-             do_cleanups (old_chain);
            }
        }
     }
@@ -10562,18 +10463,13 @@ watchpoint_exp_is_const (const struct expression *exp)
   return 1;
 }
 
-/* Implement the "dtor" breakpoint_ops method for watchpoints.  */
+/* Watchpoint destructor.  */
 
-static void
-dtor_watchpoint (struct breakpoint *self)
+watchpoint::~watchpoint ()
 {
-  struct watchpoint *w = (struct watchpoint *) self;
-
-  xfree (w->exp_string);
-  xfree (w->exp_string_reparse);
-  value_free (w->val);
-
-  base_breakpoint_ops.dtor (self);
+  xfree (this->exp_string);
+  xfree (this->exp_string_reparse);
+  value_free (this->val);
 }
 
 /* Implement the "re_set" breakpoint_ops method for watchpoints.  */
@@ -10783,37 +10679,37 @@ print_it_watchpoint (bpstat bs)
 static void
 print_mention_watchpoint (struct breakpoint *b)
 {
-  struct cleanup *ui_out_chain;
   struct watchpoint *w = (struct watchpoint *) b;
   struct ui_out *uiout = current_uiout;
+  const char *tuple_name;
 
   switch (b->type)
     {
     case bp_watchpoint:
       uiout->text ("Watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+      tuple_name = "wpt";
       break;
     case bp_hardware_watchpoint:
       uiout->text ("Hardware watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+      tuple_name = "wpt";
       break;
     case bp_read_watchpoint:
       uiout->text ("Hardware read watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
+      tuple_name = "hw-rwpt";
       break;
     case bp_access_watchpoint:
       uiout->text ("Hardware access (read/write) watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
+      tuple_name = "hw-awpt";
       break;
     default:
       internal_error (__FILE__, __LINE__,
                      _("Invalid hardware watchpoint type."));
     }
 
+  ui_out_emit_tuple tuple_emitter (uiout, tuple_name);
   uiout->field_int ("number", b->number);
   uiout->text (": ");
   uiout->field_string ("exp", w->exp_string);
-  do_cleanups (ui_out_chain);
 }
 
 /* Implement the "print_recreate" breakpoint_ops method for
@@ -10982,31 +10878,31 @@ print_mention_masked_watchpoint (struct breakpoint *b)
 {
   struct watchpoint *w = (struct watchpoint *) b;
   struct ui_out *uiout = current_uiout;
-  struct cleanup *ui_out_chain;
+  const char *tuple_name;
 
   switch (b->type)
     {
     case bp_hardware_watchpoint:
       uiout->text ("Masked hardware watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+      tuple_name = "wpt";
       break;
     case bp_read_watchpoint:
       uiout->text ("Masked hardware read watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
+      tuple_name = "hw-rwpt";
       break;
     case bp_access_watchpoint:
       uiout->text ("Masked hardware access (read/write) watchpoint ");
-      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
+      tuple_name = "hw-awpt";
       break;
     default:
       internal_error (__FILE__, __LINE__,
                      _("Invalid hardware watchpoint type."));
     }
 
+  ui_out_emit_tuple tuple_emitter (uiout, tuple_name);
   uiout->field_int ("number", b->number);
   uiout->text (": ");
   uiout->field_string ("exp", w->exp_string);
-  do_cleanups (ui_out_chain);
 }
 
 /* Implement the "print_recreate" breakpoint_ops method for
@@ -11058,11 +10954,10 @@ static void
 watch_command_1 (const char *arg, int accessflag, int from_tty,
                 int just_location, int internal)
 {
-  struct breakpoint *b, *scope_breakpoint = NULL;
+  struct breakpoint *scope_breakpoint = NULL;
   const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
   struct value *val, *mark, *result;
   int saved_bitpos = 0, saved_bitsize = 0;
-  struct frame_info *frame;
   const char *exp_start = NULL;
   const char *exp_end = NULL;
   const char *tok, *end_tok;
@@ -11240,35 +11135,44 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   if (*tok)
     error (_("Junk at end of command."));
 
-  frame = block_innermost_frame (exp_valid_block);
+  frame_info *wp_frame = block_innermost_frame (exp_valid_block);
+
+  /* Save this because create_internal_breakpoint below invalidates
+     'wp_frame'.  */
+  frame_id watchpoint_frame = get_frame_id (wp_frame);
 
   /* If the expression is "local", then set up a "watchpoint scope"
      breakpoint at the point where we've left the scope of the watchpoint
      expression.  Create the scope breakpoint before the watchpoint, so
      that we will encounter it first in bpstat_stop_status.  */
-  if (exp_valid_block && frame)
+  if (exp_valid_block != NULL && wp_frame != NULL)
     {
-      if (frame_id_p (frame_unwind_caller_id (frame)))
+      frame_id caller_frame_id = frame_unwind_caller_id (wp_frame);
+
+      if (frame_id_p (caller_frame_id))
        {
+         gdbarch *caller_arch = frame_unwind_caller_arch (wp_frame);
+         CORE_ADDR caller_pc = frame_unwind_caller_pc (wp_frame);
+
          scope_breakpoint
-           = create_internal_breakpoint (frame_unwind_caller_arch (frame),
-                                         frame_unwind_caller_pc (frame),
+           = create_internal_breakpoint (caller_arch, caller_pc,
                                          bp_watchpoint_scope,
                                          &momentary_breakpoint_ops);
 
+         /* create_internal_breakpoint could invalidate WP_FRAME.  */
+         wp_frame = NULL;
+
          scope_breakpoint->enable_state = bp_enabled;
 
          /* Automatically delete the breakpoint when it hits.  */
          scope_breakpoint->disposition = disp_del;
 
          /* Only break in the proper frame (help with recursion).  */
-         scope_breakpoint->frame_id = frame_unwind_caller_id (frame);
+         scope_breakpoint->frame_id = caller_frame_id;
 
          /* Set the address at which we will stop.  */
-         scope_breakpoint->loc->gdbarch
-           = frame_unwind_caller_arch (frame);
-         scope_breakpoint->loc->requested_address
-           = frame_unwind_caller_pc (frame);
+         scope_breakpoint->loc->gdbarch = caller_arch;
+         scope_breakpoint->loc->requested_address = caller_pc;
          scope_breakpoint->loc->address
            = adjust_breakpoint_address (scope_breakpoint->loc->gdbarch,
                                         scope_breakpoint->loc->requested_address,
@@ -11289,16 +11193,16 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
     bp_type = bp_hardware_watchpoint;
 
   w = new watchpoint ();
-  b = &w->base;
+
   if (use_mask)
-    init_raw_breakpoint_without_location (b, NULL, bp_type,
+    init_raw_breakpoint_without_location (w, NULL, bp_type,
                                          &masked_watchpoint_breakpoint_ops);
   else
-    init_raw_breakpoint_without_location (b, NULL, bp_type,
+    init_raw_breakpoint_without_location (w, NULL, bp_type,
                                          &watchpoint_breakpoint_ops);
-  b->thread = thread;
-  b->disposition = disp_donttouch;
-  b->pspace = current_program_space;
+  w->thread = thread;
+  w->disposition = disp_donttouch;
+  w->pspace = current_program_space;
   w->exp = std::move (exp);
   w->exp_valid_block = exp_valid_block;
   w->cond_exp_valid_block = cond_exp_valid_block;
@@ -11307,18 +11211,11 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
       struct type *t = value_type (val);
       CORE_ADDR addr = value_as_address (val);
 
-      t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
-
-      std::string name = type_to_string (t);
-
-      w->exp_string_reparse = xstrprintf ("* (%s *) %s", name.c_str (),
-                                         core_addr_to_string (addr));
+      w->exp_string_reparse
+       = current_language->la_watch_location_expression (t, addr).release ();
 
       w->exp_string = xstrprintf ("-location %.*s",
                                  (int) (exp_end - exp_start), exp_start);
-
-      /* The above expression is in C.  */
-      b->language = language_c;
     }
   else
     w->exp_string = savestring (exp_start, exp_end - exp_start);
@@ -11336,13 +11233,13 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
     }
 
   if (cond_start)
-    b->cond_string = savestring (cond_start, cond_end - cond_start);
+    w->cond_string = savestring (cond_start, cond_end - cond_start);
   else
-    b->cond_string = 0;
+    w->cond_string = 0;
 
-  if (frame)
+  if (frame_id_p (watchpoint_frame))
     {
-      w->watchpoint_frame = get_frame_id (frame);
+      w->watchpoint_frame = watchpoint_frame;
       w->watchpoint_thread = inferior_ptid;
     }
   else
@@ -11355,8 +11252,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
     {
       /* The scope breakpoint is related to the watchpoint.  We will
         need to act on them together.  */
-      b->related_breakpoint = scope_breakpoint;
-      scope_breakpoint->related_breakpoint = b;
+      w->related_breakpoint = scope_breakpoint;
+      scope_breakpoint->related_breakpoint = w;
     }
 
   if (!just_location)
@@ -11370,12 +11267,12 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
     }
   CATCH (e, RETURN_MASK_ALL)
     {
-      delete_breakpoint (b);
+      delete_breakpoint (w);
       throw_exception (e);
     }
   END_CATCH
 
-  install_breakpoint (internal, b, 1);
+  install_breakpoint (internal, w, 1);
   do_cleanups (back_to);
 }
 
@@ -11845,11 +11742,11 @@ catch_exec_command_1 (char *arg_entry, int from_tty,
     error (_("Junk at end of arguments."));
 
   c = new exec_catchpoint ();
-  init_catchpoint (&c->base, gdbarch, tempflag, cond_string,
+  init_catchpoint (c, gdbarch, tempflag, cond_string,
                   &catch_exec_breakpoint_ops);
   c->exec_pathname = NULL;
 
-  install_breakpoint (0, &c->base, 1);
+  install_breakpoint (0, c, 1);
 }
 
 void
@@ -12200,10 +12097,9 @@ static void
 download_tracepoint_locations (void)
 {
   struct breakpoint *b;
-  struct cleanup *old_chain;
   enum tribool can_download_tracepoint = TRIBOOL_UNKNOWN;
 
-  old_chain = save_current_space_and_thread ();
+  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
   ALL_TRACEPOINTS (b)
     {
@@ -12247,8 +12143,6 @@ download_tracepoint_locations (void)
       if (bp_location_downloaded)
        observer_notify_breakpoint_modified (b);
     }
-
-  do_cleanups (old_chain);
 }
 
 /* Swap the insertion/duplication state between two locations.  */
@@ -12817,26 +12711,20 @@ static const struct bp_location_ops bp_location_ops =
   bp_location_dtor
 };
 
-/* Default breakpoint_ops methods all breakpoint_ops ultimately
-   inherit from.  */
+/* Destructor for the breakpoint base class.  */
 
-static void
-base_breakpoint_dtor (struct breakpoint *self)
+breakpoint::~breakpoint ()
 {
-  decref_counted_command_line (&self->commands);
-  xfree (self->cond_string);
-  xfree (self->extra_string);
-  xfree (self->filter);
+  decref_counted_command_line (&this->commands);
+  xfree (this->cond_string);
+  xfree (this->extra_string);
+  xfree (this->filter);
 }
 
 static struct bp_location *
 base_breakpoint_allocate_location (struct breakpoint *self)
 {
-  struct bp_location *loc;
-
-  loc = new struct bp_location ();
-  init_bp_location (loc, &bp_location_ops, self);
-  return loc;
+  return new bp_location (&bp_location_ops, self);
 }
 
 static void
@@ -12931,8 +12819,8 @@ base_breakpoint_create_sals_from_location
 static void
 base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                        struct linespec_result *c,
-                                       char *cond_string,
-                                       char *extra_string,
+                                       gdb::unique_xmalloc_ptr<char> cond_string,
+                                       gdb::unique_xmalloc_ptr<char> extra_string,
                                        enum bptype type_wanted,
                                        enum bpdisp disposition,
                                        int thread,
@@ -12971,7 +12859,6 @@ base_breakpoint_after_condition_true (struct bpstats *bs)
 
 struct breakpoint_ops base_breakpoint_ops =
 {
-  base_breakpoint_dtor,
   base_breakpoint_allocate_location,
   base_breakpoint_re_set,
   base_breakpoint_insert_location,
@@ -13181,8 +13068,8 @@ bkpt_create_sals_from_location (const struct event_location *location,
 static void
 bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             struct linespec_result *canonical,
-                            char *cond_string,
-                            char *extra_string,
+                            gdb::unique_xmalloc_ptr<char> cond_string,
+                            gdb::unique_xmalloc_ptr<char> extra_string,
                             enum bptype type_wanted,
                             enum bpdisp disposition,
                             int thread,
@@ -13192,7 +13079,8 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
                             int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical,
-                                 cond_string, extra_string,
+                                 std::move (cond_string),
+                                 std::move (extra_string),
                                  type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
@@ -13339,15 +13227,12 @@ momentary_bkpt_print_mention (struct breakpoint *b)
    It gets cleared already on the removal of the first one of such placed
    breakpoints.  This is OK as they get all removed altogether.  */
 
-static void
-longjmp_bkpt_dtor (struct breakpoint *self)
+longjmp_breakpoint::~longjmp_breakpoint ()
 {
-  struct thread_info *tp = find_thread_global_id (self->thread);
+  thread_info *tp = find_thread_global_id (this->thread);
 
-  if (tp)
+  if (tp != NULL)
     tp->initiating_frame = null_frame_id;
-
-  momentary_breakpoint_ops.dtor (self);
 }
 
 /* Specific methods for probe breakpoints.  */
@@ -13503,8 +13388,8 @@ tracepoint_create_sals_from_location (const struct event_location *location,
 static void
 tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   struct linespec_result *canonical,
-                                  char *cond_string,
-                                  char *extra_string,
+                                  gdb::unique_xmalloc_ptr<char> cond_string,
+                                  gdb::unique_xmalloc_ptr<char> extra_string,
                                   enum bptype type_wanted,
                                   enum bpdisp disposition,
                                   int thread,
@@ -13514,7 +13399,8 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
                                   int internal, unsigned flags)
 {
   create_breakpoints_sal_default (gdbarch, canonical,
-                                 cond_string, extra_string,
+                                 std::move (cond_string),
+                                 std::move (extra_string),
                                  type_wanted,
                                  disposition, thread, task,
                                  ignore_count, ops, from_tty,
@@ -13659,8 +13545,8 @@ strace_marker_create_sals_from_location (const struct event_location *location,
 static void
 strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
                                      struct linespec_result *canonical,
-                                     char *cond_string,
-                                     char *extra_string,
+                                     gdb::unique_xmalloc_ptr<char> cond_string,
+                                     gdb::unique_xmalloc_ptr<char> extra_string,
                                      enum bptype type_wanted,
                                      enum bpdisp disposition,
                                      int thread,
@@ -13692,9 +13578,10 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
       location = copy_event_location (canonical->location.get ());
 
       tp = new tracepoint ();
-      init_breakpoint_sal (&tp->base, gdbarch, expanded,
+      init_breakpoint_sal (tp, gdbarch, expanded,
                           std::move (location), NULL,
-                          cond_string, extra_string,
+                          std::move (cond_string),
+                          std::move (extra_string),
                           type_wanted, disposition,
                           thread, task, ignore_count, ops,
                           from_tty, enabled, internal, flags,
@@ -13707,7 +13594,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
         corresponds to this one  */
       tp->static_trace_marker_id_idx = i;
 
-      install_breakpoint (internal, &tp->base, 0);
+      install_breakpoint (internal, tp, 0);
     }
 }
 
@@ -13827,7 +13714,6 @@ delete_breakpoint (struct breakpoint *bpt)
      self-contained, but it's not the case now.  */
   update_global_location_list (UGLL_DONT_INSERT);
 
-  bpt->ops->dtor (bpt);
   /* On the chance that someone will soon try again to delete this
      same bp, we mark it as deleted before freeing its storage.  */
   bpt->type = bp_none;
@@ -14448,8 +14334,8 @@ create_sals_from_location_default (const struct event_location *location,
 static void
 create_breakpoints_sal_default (struct gdbarch *gdbarch,
                                struct linespec_result *canonical,
-                               char *cond_string,
-                               char *extra_string,
+                               gdb::unique_xmalloc_ptr<char> cond_string,
+                               gdb::unique_xmalloc_ptr<char> extra_string,
                                enum bptype type_wanted,
                                enum bpdisp disposition,
                                int thread,
@@ -14458,8 +14344,9 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch,
                                int from_tty, int enabled,
                                int internal, unsigned flags)
 {
-  create_breakpoints_sal (gdbarch, canonical, cond_string,
-                         extra_string,
+  create_breakpoints_sal (gdbarch, canonical,
+                         std::move (cond_string),
+                         std::move (extra_string),
                          type_wanted, disposition,
                          thread, task, ignore_count, ops, from_tty,
                          enabled, internal, flags);
@@ -14533,32 +14420,32 @@ breakpoint_re_set (void)
   struct breakpoint *b, *b_tmp;
   enum language save_language;
   int save_input_radix;
-  struct cleanup *old_chain;
 
   save_language = current_language->la_language;
   save_input_radix = input_radix;
-  old_chain = save_current_space_and_thread ();
-
-  /* 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
-     hadn't been re-set yet, and thus may have stale locations.  */
 
-  ALL_BREAKPOINTS_SAFE (b, b_tmp)
   {
-    /* Format possible error msg.  */
-    char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
-                               b->number);
-    struct cleanup *cleanups = make_cleanup (xfree, message);
-    catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
-    do_cleanups (cleanups);
-  }
-  set_language (save_language);
-  input_radix = save_input_radix;
+    scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
-  jit_breakpoint_re_set ();
+    /* 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
+       hadn't been re-set yet, and thus may have stale locations.  */
 
-  do_cleanups (old_chain);
+    ALL_BREAKPOINTS_SAFE (b, b_tmp)
+      {
+       /* Format possible error msg.  */
+       char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
+                                   b->number);
+       struct cleanup *cleanups = make_cleanup (xfree, message);
+       catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
+       do_cleanups (cleanups);
+      }
+    set_language (save_language);
+    input_radix = save_input_radix;
+
+    jit_breakpoint_re_set ();
+  }
 
   create_overlay_event_breakpoint ();
   create_longjmp_master_breakpoint ();
@@ -15106,22 +14993,18 @@ int
 insert_single_step_breakpoints (struct gdbarch *gdbarch)
 {
   struct regcache *regcache = get_current_regcache ();
-  VEC (CORE_ADDR) * next_pcs;
+  std::vector<CORE_ADDR> next_pcs;
 
   next_pcs = gdbarch_software_single_step (gdbarch, regcache);
 
-  if (next_pcs != NULL)
+  if (!next_pcs.empty ())
     {
-      int i;
-      CORE_ADDR pc;
       struct frame_info *frame = get_current_frame ();
       struct address_space *aspace = get_frame_address_space (frame);
 
-      for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
+      for (CORE_ADDR pc : next_pcs)
        insert_single_step_breakpoint (gdbarch, aspace, pc);
 
-      VEC_free (CORE_ADDR, next_pcs);
-
       return 1;
     }
   else
@@ -15327,7 +15210,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
   if (utp->pass > 0)
     {
       xsnprintf (small_buf, sizeof (small_buf), "%d %d", utp->pass,
-                tp->base.number);
+                tp->number);
 
       trace_pass_command (small_buf, 0);
     }
@@ -15345,7 +15228,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
 
       cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
 
-      breakpoint_set_commands (&tp->base, std::move (cmd_list));
+      breakpoint_set_commands (tp, std::move (cmd_list));
     }
   else if (!VEC_empty (char_ptr, utp->actions)
           || !VEC_empty (char_ptr, utp->step_actions))
@@ -15354,7 +15237,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
             utp->number);
 
   /* Copy any status information that might be available.  */
-  tp->base.hit_count = utp->hit_count;
+  tp->hit_count = utp->hit_count;
   tp->traceframe_usage = utp->traceframe_usage;
 
   return tp;
@@ -15440,10 +15323,10 @@ static void
 trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
 {
   tp->pass_count = count;
-  observer_notify_breakpoint_modified (&tp->base);
+  observer_notify_breakpoint_modified (tp);
   if (from_tty)
     printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
-                    tp->base.number, count);
+                    tp->number, count);
 }
 
 /* Set passcount for tracepoint.
@@ -15595,7 +15478,6 @@ save_breakpoints (char *filename, int from_tty,
 {
   struct breakpoint *tp;
   int any = 0;
-  struct cleanup *cleanup;
   int extra_trace_bits = 0;
 
   if (filename == 0 || *filename == 0)
@@ -15629,14 +15511,13 @@ save_breakpoints (char *filename, int from_tty,
       return;
     }
 
-  filename = tilde_expand (filename);
-  cleanup = make_cleanup (xfree, filename);
+  gdb::unique_xmalloc_ptr<char> expanded_filename (tilde_expand (filename));
 
   stdio_file fp;
 
-  if (!fp.open (filename, "w"))
+  if (!fp.open (expanded_filename.get (), "w"))
     error (_("Unable to open file '%s' for saving (%s)"),
-          filename, safe_strerror (errno));
+          expanded_filename.get (), safe_strerror (errno));
 
   if (extra_trace_bits)
     save_trace_state_variables (&fp);
@@ -15704,8 +15585,7 @@ save_breakpoints (char *filename, int from_tty,
     fp.printf ("set default-collect %s\n", default_collect);
 
   if (from_tty)
-    printf_filtered (_("Saved to file '%s'.\n"), filename);
-  do_cleanups (cleanup);
+    printf_filtered (_("Saved to file '%s'.\n"), expanded_filename.get ());
 }
 
 /* The `save breakpoints' command.  */
@@ -15949,11 +15829,6 @@ initialize_breakpoint_ops (void)
   ops->print_it = momentary_bkpt_print_it;
   ops->print_mention = momentary_bkpt_print_mention;
 
-  /* Momentary breakpoints for bp_longjmp and bp_exception.  */
-  ops = &longjmp_breakpoint_ops;
-  *ops = momentary_breakpoint_ops;
-  ops->dtor = longjmp_bkpt_dtor;
-
   /* Probe breakpoints.  */
   ops = &bkpt_probe_breakpoint_ops;
   *ops = bkpt_breakpoint_ops;
@@ -15965,7 +15840,6 @@ initialize_breakpoint_ops (void)
   /* Watchpoints.  */
   ops = &watchpoint_breakpoint_ops;
   *ops = base_breakpoint_ops;
-  ops->dtor = dtor_watchpoint;
   ops->re_set = re_set_watchpoint;
   ops->insert_location = insert_watchpoint;
   ops->remove_location = remove_watchpoint;
@@ -16040,7 +15914,6 @@ initialize_breakpoint_ops (void)
   /* Exec catchpoints.  */
   ops = &catch_exec_breakpoint_ops;
   *ops = base_breakpoint_ops;
-  ops->dtor = dtor_catch_exec;
   ops->insert_location = insert_catch_exec;
   ops->remove_location = remove_catch_exec;
   ops->breakpoint_hit = breakpoint_hit_catch_exec;
@@ -16052,7 +15925,6 @@ initialize_breakpoint_ops (void)
   /* Solib-related catchpoints.  */
   ops = &catch_solib_breakpoint_ops;
   *ops = base_breakpoint_ops;
-  ops->dtor = dtor_catch_solib;
   ops->insert_location = insert_catch_solib;
   ops->remove_location = remove_catch_solib;
   ops->breakpoint_hit = breakpoint_hit_catch_solib;
This page took 0.052374 seconds and 4 git commands to generate.