2011-06-22 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 70931045b3eb5e54fbae7b6c3c8964f3550d216d..a3e89c2039b9e9ddb8d77fcaa745e4080c9a08d1 100644 (file)
@@ -64,6 +64,7 @@
 #include "xml-syscall.h"
 #include "parser-defs.h"
 #include "cli/cli-utils.h"
+#include "continuations.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -176,7 +177,7 @@ static void hbreak_command (char *, int);
 
 static void thbreak_command (char *, int);
 
-static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
+static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp);
 
 static void stop_command (char *arg, int from_tty);
 
@@ -2015,20 +2016,6 @@ remove_breakpoints_pid (int pid)
   return 0;
 }
 
-int
-remove_hw_watchpoints (void)
-{
-  struct bp_location *bl, **blp_tmp;
-  int val = 0;
-
-  ALL_BP_LOCATIONS (bl, blp_tmp)
-  {
-    if (bl->inserted && bl->loc_type == bp_loc_hardware_watchpoint)
-      val |= remove_breakpoint (bl, mark_uninserted);
-  }
-  return val;
-}
-
 int
 reattach_breakpoints (int pid)
 {
@@ -2429,7 +2416,7 @@ update_breakpoints_after_exec (void)
       }
 
     /* Step-resume breakpoints are meaningless after an exec().  */
-    if (b->type == bp_step_resume)
+    if (b->type == bp_step_resume || b->type == bp_hp_step_resume)
       {
        delete_breakpoint (b);
        continue;
@@ -3517,6 +3504,7 @@ print_it_typical (bpstat bs)
     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:
@@ -3880,6 +3868,8 @@ watchpoint_check (void *p)
                   " 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->commands);
       watchpoint_del_at_next_stop (b);
 
       return WP_DELETED;
@@ -4501,6 +4491,15 @@ bpstat_what (bpstat bs_head)
              this_action = BPSTAT_WHAT_SINGLE;
            }
          break;
+       case bp_hp_step_resume:
+         if (bs->stop)
+           this_action = BPSTAT_WHAT_HP_STEP_RESUME;
+         else
+           {
+             /* It is for the wrong frame.  */
+             this_action = BPSTAT_WHAT_SINGLE;
+           }
+         break;
        case bp_watchpoint_scope:
        case bp_thread_event:
        case bp_overlay_event:
@@ -4769,6 +4768,7 @@ bptype_string (enum bptype type)
     {bp_exception, "exception"},
     {bp_exception_resume, "exception resume"},
     {bp_step_resume, "step resume"},
+    {bp_hp_step_resume, "high-priority step resume"},
     {bp_watchpoint_scope, "watchpoint scope"},
     {bp_call_dummy, "call dummy"},
     {bp_std_terminate, "std::terminate"},
@@ -4904,6 +4904,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       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:
@@ -5713,6 +5714,7 @@ allocate_bp_location (struct breakpoint *bpt)
     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:
@@ -5783,18 +5785,34 @@ decref_bp_location (struct bp_location **blp)
   *blp = NULL;
 }
 
-/* Helper to set_raw_breakpoint below.  Creates a breakpoint that has
-   type BPTYPE and has no locations as yet.  */
-/* This function is used in gdbtk sources and thus can not be made
-   static.  */
+/* Add breakpoint B at the end of the global breakpoint chain.  */
 
-static struct breakpoint *
-set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
-                                    enum bptype bptype)
+static void
+add_to_breakpoint_chain (struct breakpoint *b)
 {
-  struct breakpoint *b, *b1;
+  struct breakpoint *b1;
 
-  b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
+  /* Add this breakpoint to the end of the chain so that a list of
+     breakpoints will come out in order of increasing numbers.  */
+
+  b1 = breakpoint_chain;
+  if (b1 == 0)
+    breakpoint_chain = b;
+  else
+    {
+      while (b1->next)
+       b1 = b1->next;
+      b1->next = b;
+    }
+}
+
+/* Initializes breakpoint B with type BPTYPE and no locations yet.  */
+
+static void
+init_raw_breakpoint_without_location (struct breakpoint *b,
+                                     struct gdbarch *gdbarch,
+                                     enum bptype bptype)
+{
   memset (b, 0, sizeof (*b));
 
   b->type = bptype;
@@ -5808,26 +5826,25 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
   b->ignore_count = 0;
   b->commands = NULL;
   b->frame_id = null_frame_id;
-  b->forked_inferior_pid = null_ptid;
-  b->exec_pathname = NULL;
-  b->syscalls_to_be_caught = NULL;
   b->ops = NULL;
   b->condition_not_parsed = 0;
   b->py_bp_object = NULL;
   b->related_breakpoint = b;
+}
 
-  /* Add this breakpoint to the end of the chain so that a list of
-     breakpoints will come out in order of increasing numbers.  */
+/* Helper to set_raw_breakpoint below.  Creates a breakpoint
+   that has type BPTYPE and has no locations as yet.  */
+/* This function is used in gdbtk sources and thus can not be made
+   static.  */
 
-  b1 = breakpoint_chain;
-  if (b1 == 0)
-    breakpoint_chain = b;
-  else
-    {
-      while (b1->next)
-       b1 = b1->next;
-      b1->next = b;
-    }
+static struct breakpoint *
+set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
+                                    enum bptype bptype)
+{
+  struct breakpoint *b = XNEW (struct breakpoint);
+
+  init_raw_breakpoint_without_location (b, gdbarch, bptype);
+  add_to_breakpoint_chain (b);
   return b;
 }
 
@@ -5888,30 +5905,23 @@ get_sal_arch (struct symtab_and_line sal)
   return NULL;
 }
 
-/* set_raw_breakpoint is a low level routine for allocating and
-   partially initializing a breakpoint of type BPTYPE.  The newly
-   created breakpoint's address, section, source file name, and line
-   number are provided by SAL.  The newly created and partially
-   initialized breakpoint is added to the breakpoint chain and
-   is also returned as the value of this function.
+/* Low level routine for partially initializing a breakpoint of type
+   BPTYPE.  The newly created breakpoint's address, section, source
+   file name, and line number are provided by SAL.
 
    It is expected that the caller will complete the initialization of
    the newly created breakpoint struct as well as output any status
-   information regarding the creation of a new breakpoint.  In
-   particular, set_raw_breakpoint does NOT set the breakpoint
-   number!  Care should be taken to not allow an error to occur
-   prior to completing the initialization of the breakpoint.  If this
-   should happen, a bogus breakpoint will be left on the chain.  */
+   information regarding the creation of a new breakpoint.  */
 
-struct breakpoint *
-set_raw_breakpoint (struct gdbarch *gdbarch,
-                   struct symtab_and_line sal, enum bptype bptype)
+static void
+init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
+                    struct symtab_and_line sal, enum bptype bptype)
 {
-  struct breakpoint *b = set_raw_breakpoint_without_location (gdbarch, 
-                                                             bptype);
   CORE_ADDR adjusted_address;
   struct gdbarch *loc_gdbarch;
 
+  init_raw_breakpoint_without_location (b, gdbarch, bptype);
+
   loc_gdbarch = get_sal_arch (sal);
   if (!loc_gdbarch)
     loc_gdbarch = b->gdbarch;
@@ -5949,7 +5959,31 @@ set_raw_breakpoint (struct gdbarch *gdbarch,
                                    sal.explicit_pc || sal.explicit_line);
 
   breakpoints_changed ();
+}
 
+/* set_raw_breakpoint is a low level routine for allocating and
+   partially initializing a breakpoint of type BPTYPE.  The newly
+   created breakpoint's address, section, source file name, and line
+   number are provided by SAL.  The newly created and partially
+   initialized breakpoint is added to the breakpoint chain and
+   is also returned as the value of this function.
+
+   It is expected that the caller will complete the initialization of
+   the newly created breakpoint struct as well as output any status
+   information regarding the creation of a new breakpoint.  In
+   particular, set_raw_breakpoint does NOT set the breakpoint
+   number!  Care should be taken to not allow an error to occur
+   prior to completing the initialization of the breakpoint.  If this
+   should happen, a bogus breakpoint will be left on the chain.  */
+
+struct breakpoint *
+set_raw_breakpoint (struct gdbarch *gdbarch,
+                   struct symtab_and_line sal, enum bptype bptype)
+{
+  struct breakpoint *b = XNEW (struct breakpoint);
+
+  init_raw_breakpoint (b, gdbarch, sal, bptype);
+  add_to_breakpoint_chain (b);
   return b;
 }
 
@@ -6240,6 +6274,23 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
 
 /* 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.  */
+
+struct fork_catchpoint
+{
+  /* 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.  */
+  ptid_t forked_inferior_pid;
+};
+
 /* Implement the "insert" breakpoint_ops method for fork
    catchpoints.  */
 
@@ -6265,7 +6316,9 @@ static int
 breakpoint_hit_catch_fork (const struct bp_location *bl,
                           struct address_space *aspace, CORE_ADDR bp_addr)
 {
-  return inferior_has_forked (inferior_ptid, &bl->owner->forked_inferior_pid);
+  struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
+
+  return inferior_has_forked (inferior_ptid, &c->forked_inferior_pid);
 }
 
 /* Implement the "print_it" breakpoint_ops method for fork
@@ -6274,9 +6327,11 @@ breakpoint_hit_catch_fork (const struct bp_location *bl,
 static enum print_stop_action
 print_it_catch_fork (struct breakpoint *b)
 {
+  struct fork_catchpoint *c = (struct fork_catchpoint *) b;
+
   annotate_catchpoint (b->number);
   printf_filtered (_("\nCatchpoint %d (forked process %d), "),
-                  b->number, ptid_get_pid (b->forked_inferior_pid));
+                  b->number, ptid_get_pid (c->forked_inferior_pid));
   return PRINT_SRC_AND_LOC;
 }
 
@@ -6286,6 +6341,7 @@ print_it_catch_fork (struct breakpoint *b)
 static void
 print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc)
 {
+  struct fork_catchpoint *c = (struct fork_catchpoint *) b;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -6297,11 +6353,11 @@ print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc)
     ui_out_field_skip (uiout, "addr");
   annotate_field (5);
   ui_out_text (uiout, "fork");
-  if (!ptid_equal (b->forked_inferior_pid, null_ptid))
+  if (!ptid_equal (c->forked_inferior_pid, null_ptid))
     {
       ui_out_text (uiout, ", process ");
       ui_out_field_int (uiout, "what",
-                        ptid_get_pid (b->forked_inferior_pid));
+                        ptid_get_pid (c->forked_inferior_pid));
       ui_out_spaces (uiout, 1);
     }
 }
@@ -6328,6 +6384,7 @@ print_recreate_catch_fork (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_fork_breakpoint_ops =
 {
+  NULL, /* dtor */
   insert_catch_fork,
   remove_catch_fork,
   breakpoint_hit_catch_fork,
@@ -6365,7 +6422,9 @@ static int
 breakpoint_hit_catch_vfork (const struct bp_location *bl,
                            struct address_space *aspace, CORE_ADDR bp_addr)
 {
-  return inferior_has_vforked (inferior_ptid, &bl->owner->forked_inferior_pid);
+  struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
+
+  return inferior_has_vforked (inferior_ptid, &c->forked_inferior_pid);
 }
 
 /* Implement the "print_it" breakpoint_ops method for vfork
@@ -6374,9 +6433,11 @@ breakpoint_hit_catch_vfork (const struct bp_location *bl,
 static enum print_stop_action
 print_it_catch_vfork (struct breakpoint *b)
 {
+  struct fork_catchpoint *c = (struct fork_catchpoint *) b;
+
   annotate_catchpoint (b->number);
   printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
-                  b->number, ptid_get_pid (b->forked_inferior_pid));
+                  b->number, ptid_get_pid (c->forked_inferior_pid));
   return PRINT_SRC_AND_LOC;
 }
 
@@ -6386,6 +6447,7 @@ print_it_catch_vfork (struct breakpoint *b)
 static void
 print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc)
 {
+  struct fork_catchpoint *c = (struct fork_catchpoint *) b;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -6396,11 +6458,11 @@ print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc)
     ui_out_field_skip (uiout, "addr");
   annotate_field (5);
   ui_out_text (uiout, "vfork");
-  if (!ptid_equal (b->forked_inferior_pid, null_ptid))
+  if (!ptid_equal (c->forked_inferior_pid, null_ptid))
     {
       ui_out_text (uiout, ", process ");
       ui_out_field_int (uiout, "what",
-                        ptid_get_pid (b->forked_inferior_pid));
+                        ptid_get_pid (c->forked_inferior_pid));
       ui_out_spaces (uiout, 1);
     }
 }
@@ -6427,6 +6489,7 @@ print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_vfork_breakpoint_ops =
 {
+  NULL, /* dtor */
   insert_catch_vfork,
   remove_catch_vfork,
   breakpoint_hit_catch_vfork,
@@ -6439,23 +6502,53 @@ static struct breakpoint_ops catch_vfork_breakpoint_ops =
   print_recreate_catch_vfork
 };
 
+/* An instance of this type is used to represent a syscall 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_SYSCALL_BREAKPOINT_OPS.  */
+
+struct syscall_catchpoint
+{
+  /* The base class.  */
+  struct breakpoint base;
+
+  /* Syscall numbers used for the 'catch syscall' feature.  If no
+     syscall has been specified for filtering, its value is NULL.
+     Otherwise, it holds a list of all syscalls to be caught.  The
+     list elements are allocated with xmalloc.  */
+  VEC(int) *syscalls_to_be_caught;
+};
+
+/* Implement the "dtor" breakpoint_ops method for syscall
+   catchpoints.  */
+
+static void
+dtor_catch_syscall (struct breakpoint *b)
+{
+  struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+
+  VEC_free (int, c->syscalls_to_be_caught);
+}
+
 /* Implement the "insert" breakpoint_ops method for syscall
    catchpoints.  */
 
 static int
 insert_catch_syscall (struct bp_location *bl)
 {
+  struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
 
   ++inf->total_syscalls_count;
-  if (!bl->owner->syscalls_to_be_caught)
+  if (!c->syscalls_to_be_caught)
     ++inf->any_syscall_count;
   else
     {
       int i, iter;
 
       for (i = 0;
-           VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
            i++)
        {
           int elem;
@@ -6490,17 +6583,18 @@ insert_catch_syscall (struct bp_location *bl)
 static int
 remove_catch_syscall (struct bp_location *bl)
 {
+  struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
 
   --inf->total_syscalls_count;
-  if (!bl->owner->syscalls_to_be_caught)
+  if (!c->syscalls_to_be_caught)
     --inf->any_syscall_count;
   else
     {
       int i, iter;
 
       for (i = 0;
-           VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
            i++)
        {
           int elem;
@@ -6531,18 +6625,19 @@ breakpoint_hit_catch_syscall (const struct bp_location *bl,
      breakpoint.  If we are, then we must guarantee that the called
      syscall is the same syscall we are catching.  */
   int syscall_number = 0;
-  const struct breakpoint *b = bl->owner;
+  const struct syscall_catchpoint *c
+    = (const struct syscall_catchpoint *) bl->owner;
 
   if (!inferior_has_called_syscall (inferior_ptid, &syscall_number))
     return 0;
 
   /* Now, checking if the syscall is the same.  */
-  if (b->syscalls_to_be_caught)
+  if (c->syscalls_to_be_caught)
     {
       int i, iter;
 
       for (i = 0;
-           VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
            i++)
        if (syscall_number == iter)
          break;
@@ -6602,6 +6697,7 @@ static void
 print_one_catch_syscall (struct breakpoint *b,
                         struct bp_location **last_loc)
 {
+  struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -6612,19 +6708,19 @@ print_one_catch_syscall (struct breakpoint *b,
     ui_out_field_skip (uiout, "addr");
   annotate_field (5);
 
-  if (b->syscalls_to_be_caught
-      && VEC_length (int, b->syscalls_to_be_caught) > 1)
+  if (c->syscalls_to_be_caught
+      && VEC_length (int, c->syscalls_to_be_caught) > 1)
     ui_out_text (uiout, "syscalls \"");
   else
     ui_out_text (uiout, "syscall \"");
 
-  if (b->syscalls_to_be_caught)
+  if (c->syscalls_to_be_caught)
     {
       int i, iter;
       char *text = xstrprintf ("%s", "");
 
       for (i = 0;
-           VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
            i++)
         {
           char *x = text;
@@ -6656,17 +6752,19 @@ print_one_catch_syscall (struct breakpoint *b,
 static void
 print_mention_catch_syscall (struct breakpoint *b)
 {
-  if (b->syscalls_to_be_caught)
+  struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+
+  if (c->syscalls_to_be_caught)
     {
       int i, iter;
 
-      if (VEC_length (int, b->syscalls_to_be_caught) > 1)
+      if (VEC_length (int, c->syscalls_to_be_caught) > 1)
         printf_filtered (_("Catchpoint %d (syscalls"), b->number);
       else
         printf_filtered (_("Catchpoint %d (syscall"), b->number);
 
       for (i = 0;
-           VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
            i++)
         {
           struct syscall s;
@@ -6690,14 +6788,16 @@ print_mention_catch_syscall (struct breakpoint *b)
 static void
 print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
 {
+  struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
+
   fprintf_unfiltered (fp, "catch syscall");
 
-  if (b->syscalls_to_be_caught)
+  if (c->syscalls_to_be_caught)
     {
       int i, iter;
 
       for (i = 0;
-           VEC_iterate (int, b->syscalls_to_be_caught, i, iter);
+           VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
            i++)
         {
           struct syscall s;
@@ -6715,6 +6815,7 @@ print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_syscall_breakpoint_ops =
 {
+  dtor_catch_syscall,
   insert_catch_syscall,
   remove_catch_syscall,
   breakpoint_hit_catch_syscall,
@@ -6735,30 +6836,25 @@ syscall_catchpoint_p (struct breakpoint *b)
   return (b->ops == &catch_syscall_breakpoint_ops);
 }
 
-/* Create a new breakpoint of the bp_catchpoint kind and return it,
-   but does NOT mention it nor update the global location list.
-   This is useful if you need to fill more fields in the
-   struct breakpoint before calling mention.
-   If TEMPFLAG is non-zero, then make the breakpoint temporary.
-   If COND_STRING is not NULL, then store it in the breakpoint.
-   OPS, if not NULL, is the breakpoint_ops structure associated
-   to the catchpoint.  */
+/* Initialize a new breakpoint of the bp_catchpoint kind.  If TEMPFLAG
+   is non-zero, then make the breakpoint temporary.  If COND_STRING is
+   not NULL, then store it in the breakpoint.  OPS, if not NULL, is
+   the breakpoint_ops structure associated to the catchpoint.  */
 
-static struct breakpoint *
-create_catchpoint_without_mention (struct gdbarch *gdbarch, int tempflag,
-                                  char *cond_string,
-                                  struct breakpoint_ops *ops)
+static void
+init_catchpoint (struct breakpoint *b,
+                struct gdbarch *gdbarch, int tempflag,
+                char *cond_string,
+                struct breakpoint_ops *ops)
 {
   struct symtab_and_line sal;
-  struct breakpoint *b;
+
+  memset (b, 0, sizeof (*b));
 
   init_sal (&sal);
   sal.pspace = current_program_space;
 
-  b = set_raw_breakpoint (gdbarch, sal, bp_catchpoint);
-  set_breakpoint_count (breakpoint_count + 1);
-  b->number = breakpoint_count;
+  init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint);
 
   b->cond_string = (cond_string == NULL) ? NULL : xstrdup (cond_string);
   b->thread = -1;
@@ -6766,29 +6862,20 @@ create_catchpoint_without_mention (struct gdbarch *gdbarch, int tempflag,
   b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
   b->ops = ops;
-
-  return b;
 }
 
-/* Create a new breakpoint of the bp_catchpoint kind and return it.
-   If TEMPFLAG is non-zero, then make the breakpoint temporary.
-   If COND_STRING is not NULL, then store it in the breakpoint.
-   OPS, if not NULL, is the breakpoint_ops structure associated
-   to the catchpoint.  */
+/* Add breakpoint B on the breakpoint list, and notify the user, the
+   target and breakpoint_created observers of its existence.  */
 
-static struct breakpoint *
-create_catchpoint (struct gdbarch *gdbarch, int tempflag,
-                  char *cond_string, struct breakpoint_ops *ops)
+static void
+install_catchpoint (struct breakpoint *b)
 {
-  struct breakpoint *b =
-    create_catchpoint_without_mention (gdbarch, tempflag, cond_string, ops);
-
+  add_to_breakpoint_chain (b);
+  set_breakpoint_count (breakpoint_count + 1);
+  b->number = breakpoint_count;
   mention (b);
   observer_notify_breakpoint_created (b);
   update_global_location_list (1);
-
-  return b;
 }
 
 static void
@@ -6796,16 +6883,45 @@ create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
                                    int tempflag, char *cond_string,
                                     struct breakpoint_ops *ops)
 {
-  struct breakpoint *b
-    = create_catchpoint (gdbarch, tempflag, cond_string, ops);
+  struct fork_catchpoint *c = XNEW (struct fork_catchpoint);
 
-  /* FIXME: We should put this information in a breakpoint private data
-     area.  */
-  b->forked_inferior_pid = null_ptid;
+  init_catchpoint (&c->base, gdbarch, tempflag, cond_string, ops);
+
+  c->forked_inferior_pid = null_ptid;
+
+  install_catchpoint (&c->base);
 }
 
 /* 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
+   CATCH_EXEC_BREAKPOINT_OPS.  */
+
+struct exec_catchpoint
+{
+  /* The base class.  */
+  struct breakpoint base;
+
+  /* Filename of a program whose exec triggered this catchpoint.
+     This field is only valid immediately after this catchpoint has
+     triggered.  */
+  char *exec_pathname;
+};
+
+/* Implement the "dtor" breakpoint_ops method for exec
+   catchpoints.  */
+
+static void
+dtor_catch_exec (struct breakpoint *b)
+{
+  struct exec_catchpoint *c = (struct exec_catchpoint *) b;
+
+  xfree (c->exec_pathname);
+}
+
 static int
 insert_catch_exec (struct bp_location *bl)
 {
@@ -6822,21 +6938,26 @@ static int
 breakpoint_hit_catch_exec (const struct bp_location *bl,
                           struct address_space *aspace, CORE_ADDR bp_addr)
 {
-  return inferior_has_execd (inferior_ptid, &bl->owner->exec_pathname);
+  struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner;
+
+  return inferior_has_execd (inferior_ptid, &c->exec_pathname);
 }
 
 static enum print_stop_action
 print_it_catch_exec (struct breakpoint *b)
 {
+  struct exec_catchpoint *c = (struct exec_catchpoint *) b;
+
   annotate_catchpoint (b->number);
   printf_filtered (_("\nCatchpoint %d (exec'd %s), "), b->number,
-                  b->exec_pathname);
+                  c->exec_pathname);
   return PRINT_SRC_AND_LOC;
 }
 
 static void
 print_one_catch_exec (struct breakpoint *b, struct bp_location **last_loc)
 {
+  struct exec_catchpoint *c = (struct exec_catchpoint *) b;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
@@ -6848,10 +6969,10 @@ print_one_catch_exec (struct breakpoint *b, struct bp_location **last_loc)
     ui_out_field_skip (uiout, "addr");
   annotate_field (5);
   ui_out_text (uiout, "exec");
-  if (b->exec_pathname != NULL)
+  if (c->exec_pathname != NULL)
     {
       ui_out_text (uiout, ", program \"");
-      ui_out_field_string (uiout, "what", b->exec_pathname);
+      ui_out_field_string (uiout, "what", c->exec_pathname);
       ui_out_text (uiout, "\" ");
     }
 }
@@ -6873,6 +6994,7 @@ print_recreate_catch_exec (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_exec_breakpoint_ops =
 {
+  dtor_catch_exec,
   insert_catch_exec,
   remove_catch_exec,
   breakpoint_hit_catch_exec,
@@ -6889,17 +7011,14 @@ static void
 create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
                                  struct breakpoint_ops *ops)
 {
+  struct syscall_catchpoint *c;
   struct gdbarch *gdbarch = get_current_arch ();
-  struct breakpoint *b =
-    create_catchpoint_without_mention (gdbarch, tempflag, NULL, ops);
 
-  b->syscalls_to_be_caught = filter;
+  c = XNEW (struct syscall_catchpoint);
+  init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
+  c->syscalls_to_be_caught = filter;
 
-  /* Now, we have to mention the breakpoint and update the global
-     location list.  */
-  mention (b);
-  observer_notify_breakpoint_created (b);
-  update_global_location_list (1);
+  install_catchpoint (&c->base);
 }
 
 static int
@@ -7239,6 +7358,7 @@ mention (struct breakpoint *b)
       case bp_exception:
       case bp_exception_resume:
       case bp_step_resume:
+      case bp_hp_step_resume:
       case bp_call_dummy:
       case bp_std_terminate:
       case bp_watchpoint_scope:
@@ -8499,6 +8619,7 @@ print_recreate_ranged_breakpoint (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops ranged_breakpoint_ops =
 {
+  NULL, /* dtor */
   NULL, /* insert */
   NULL, /* remove */
   breakpoint_hit_ranged_breakpoint,
@@ -8824,6 +8945,7 @@ works_in_software_mode_watchpoint (const struct breakpoint *b)
 
 static struct breakpoint_ops watchpoint_breakpoint_ops =
 {
+  NULL, /* dtor */
   insert_watchpoint,
   remove_watchpoint,
   NULL, /* breakpoint_hit */
@@ -9002,6 +9124,7 @@ print_recreate_masked_watchpoint (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops masked_watchpoint_breakpoint_ops =
 {
+  NULL, /* dtor */
   insert_masked_watchpoint,
   remove_masked_watchpoint,
   NULL, /* breakpoint_hit */
@@ -9505,7 +9628,7 @@ struct until_break_command_continuation_args
    care of cleaning up the temporary breakpoints set up by the until
    command.  */
 static void
-until_break_command_continuation (void *arg)
+until_break_command_continuation (void *arg, int err)
 {
   struct until_break_command_continuation_args *a = arg;
 
@@ -9700,6 +9823,7 @@ static void
 catch_exec_command_1 (char *arg, int from_tty, 
                      struct cmd_list_element *command)
 {
+  struct exec_catchpoint *c;
   struct gdbarch *gdbarch = get_current_arch ();
   int tempflag;
   char *cond_string = NULL;
@@ -9720,10 +9844,12 @@ catch_exec_command_1 (char *arg, int from_tty,
   if ((*arg != '\0') && !isspace (*arg))
     error (_("Junk at end of arguments."));
 
-  /* If this target supports it, create an exec catchpoint
-     and enable reporting of such events.  */
-  create_catchpoint (gdbarch, tempflag, cond_string,
-                    &catch_exec_breakpoint_ops);
+  c = XNEW (struct exec_catchpoint);
+  init_catchpoint (&c->base, gdbarch, tempflag, cond_string,
+                  &catch_exec_breakpoint_ops);
+  c->exec_pathname = NULL;
+
+  install_catchpoint (&c->base);
 }
 
 static enum print_stop_action
@@ -9814,6 +9940,7 @@ print_recreate_exception_catchpoint (struct breakpoint *b,
 }
 
 static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
+  NULL, /* dtor */
   NULL, /* insert */
   NULL, /* remove */
   NULL, /* breakpoint_hit */
@@ -10770,6 +10897,9 @@ delete_breakpoint (struct breakpoint *bpt)
       break;
     }
 
+  if (bpt->ops != NULL && bpt->ops->dtor != NULL)
+    bpt->ops->dtor (bpt);
+
   decref_counted_command_line (&bpt->commands);
   xfree (bpt->cond_string);
   xfree (bpt->cond_exp);
@@ -10780,8 +10910,6 @@ delete_breakpoint (struct breakpoint *bpt)
   xfree (bpt->exp_string_reparse);
   value_free (bpt->val);
   xfree (bpt->source_file);
-  xfree (bpt->exec_pathname);
-  clean_up_filters (&bpt->syscalls_to_be_caught);
 
 
   /* Be sure no bpstat's are pointing at the breakpoint after it's
@@ -10824,8 +10952,42 @@ make_cleanup_delete_breakpoint (struct breakpoint *b)
   return make_cleanup (do_delete_breakpoint_cleanup, b);
 }
 
-/* A callback for map_breakpoint_numbers that calls
-   delete_breakpoint.  */
+/* Iterator function to call a user-provided callback function once
+   for each of B and its related breakpoints.  */
+
+static void
+iterate_over_related_breakpoints (struct breakpoint *b,
+                                 void (*function) (struct breakpoint *,
+                                                   void *),
+                                 void *data)
+{
+  struct breakpoint *related;
+
+  related = b;
+  do
+    {
+      struct breakpoint *next;
+
+      /* FUNCTION may delete RELATED.  */
+      next = related->related_breakpoint;
+
+      if (next == related)
+       {
+         /* RELATED is the last ring entry.  */
+         function (related, data);
+
+         /* FUNCTION may have deleted it, so we'd never reach back to
+            B.  There's nothing left to do anyway, so just break
+            out.  */
+         break;
+       }
+      else
+       function (related, data);
+
+      related = next;
+    }
+  while (related != b);
+}
 
 static void
 do_delete_breakpoint (struct breakpoint *b, void *ignore)
@@ -10833,6 +10995,15 @@ do_delete_breakpoint (struct breakpoint *b, void *ignore)
   delete_breakpoint (b);
 }
 
+/* A callback for map_breakpoint_numbers that calls
+   delete_breakpoint.  */
+
+static void
+do_map_delete_breakpoint (struct breakpoint *b, void *ignore)
+{
+  iterate_over_related_breakpoints (b, do_delete_breakpoint, NULL);
+}
+
 void
 delete_command (char *arg, int from_tty)
 {
@@ -10864,7 +11035,7 @@ delete_command (char *arg, int from_tty)
        }
     }
   else
-    map_breakpoint_numbers (arg, do_delete_breakpoint, NULL);
+    map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
 }
 
 static int
@@ -11428,6 +11599,7 @@ breakpoint_re_set_one (void *bint)
     case bp_call_dummy:
     case bp_std_terminate:
     case bp_step_resume:
+    case bp_hp_step_resume:
     case bp_longjmp:
     case bp_longjmp_resume:
     case bp_exception:
@@ -11599,25 +11771,8 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *,
          ALL_BREAKPOINTS_SAFE (b, tmp)
            if (b->number == num)
              {
-               struct breakpoint *related_breakpoint;
-
                match = 1;
-               related_breakpoint = b;
-               do
-                 {
-                   struct breakpoint *next_related_b;
-
-                   /* FUNCTION can be also delete_breakpoint.  */
-                   next_related_b = related_breakpoint->related_breakpoint;
-                   function (related_breakpoint, data);
-
-                   /* For delete_breakpoint of the last entry of the ring we
-                      were traversing we would never get back to B.  */
-                   if (next_related_b == related_breakpoint)
-                     break;
-                   related_breakpoint = next_related_b;
-                 }
-               while (related_breakpoint != b);
+               function (b, data);
                break;
              }
          if (match == 0)
@@ -11701,13 +11856,21 @@ disable_breakpoint (struct breakpoint *bpt)
   observer_notify_breakpoint_modified (bpt);
 }
 
+/* A callback for iterate_over_related_breakpoints.  */
+
+static void
+do_disable_breakpoint (struct breakpoint *b, void *ignore)
+{
+  disable_breakpoint (b);
+}
+
 /* A callback for map_breakpoint_numbers that calls
    disable_breakpoint.  */
 
 static void
 do_map_disable_breakpoint (struct breakpoint *b, void *ignore)
 {
-  disable_breakpoint (b);
+  iterate_over_related_breakpoints (b, do_disable_breakpoint, NULL);
 }
 
 static void
@@ -11739,7 +11902,7 @@ disable_command (char *args, int from_tty)
 }
 
 static void
-do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
+enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition)
 {
   int target_resources_ok;
 
@@ -11800,7 +11963,13 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
 void
 enable_breakpoint (struct breakpoint *bpt)
 {
-  do_enable_breakpoint (bpt, bpt->disposition);
+  enable_breakpoint_disp (bpt, bpt->disposition);
+}
+
+static void
+do_enable_breakpoint (struct breakpoint *bpt, void *arg)
+{
+  enable_breakpoint (bpt);
 }
 
 /* A callback for map_breakpoint_numbers that calls
@@ -11809,7 +11978,7 @@ enable_breakpoint (struct breakpoint *bpt)
 static void
 do_map_enable_breakpoint (struct breakpoint *b, void *ignore)
 {
-  enable_breakpoint (b);
+  iterate_over_related_breakpoints (b, do_enable_breakpoint, NULL);
 }
 
 /* The enable command enables the specified breakpoints (or all defined
@@ -11845,27 +12014,39 @@ enable_command (char *args, int from_tty)
 }
 
 static void
-enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
+do_enable_breakpoint_disp (struct breakpoint *bpt, void *arg)
 {
-  do_enable_breakpoint (bpt, disp_disable);
+  enum bpdisp disp = *(enum bpdisp *) arg;
+
+  enable_breakpoint_disp (bpt, disp);
+}
+
+static void
+do_map_enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
+{
+  enum bpdisp disp = disp_disable;
+
+  iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
 }
 
 static void
 enable_once_command (char *args, int from_tty)
 {
-  map_breakpoint_numbers (args, enable_once_breakpoint, NULL);
+  map_breakpoint_numbers (args, do_map_enable_once_breakpoint, NULL);
 }
 
 static void
-enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
+do_map_enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
 {
-  do_enable_breakpoint (bpt, disp_del);
+  enum bpdisp disp = disp_del;
+
+  iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
 }
 
 static void
 enable_delete_command (char *args, int from_tty)
 {
-  map_breakpoint_numbers (args, enable_delete_breakpoint, NULL);
+  map_breakpoint_numbers (args, do_map_enable_delete_breakpoint, NULL);
 }
 \f
 static void
@@ -12128,11 +12309,13 @@ catching_syscall_number (int syscall_number)
   ALL_BREAKPOINTS (bp)
     if (is_syscall_catchpoint_enabled (bp))
       {
-       if (bp->syscalls_to_be_caught)
+       struct syscall_catchpoint *c = (struct syscall_catchpoint *) bp;
+
+       if (c->syscalls_to_be_caught)
          {
             int i, iter;
             for (i = 0;
-                 VEC_iterate (int, bp->syscalls_to_be_caught, i, iter);
+                 VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
                  i++)
              if (syscall_number == iter)
                return 1;
@@ -12391,7 +12574,7 @@ delete_trace_command (char *arg, int from_tty)
        }
     }
   else
-    map_breakpoint_numbers (arg, do_delete_breakpoint, NULL);
+    map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
 }
 
 /* Helper function for trace_pass_command.  */
@@ -12941,7 +13124,7 @@ If a breakpoint is hit while enabled in this fashion, it becomes disabled."),
 Disable some breakpoints.\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 reenabled."),
+A disabled breakpoint is not forgotten, but has no effect until re-enabled."),
                  &disablelist, "disable ", 1, &cmdlist);
   add_com_alias ("dis", "disable", class_breakpoint, 1);
   add_com_alias ("disa", "disable", class_breakpoint, 1);
@@ -12950,13 +13133,13 @@ A disabled breakpoint is not forgotten, but has no effect until reenabled."),
 Disable some breakpoints.\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 reenabled."));
+A disabled breakpoint is not forgotten, but has no effect until re-enabled."));
 
   add_cmd ("breakpoints", class_alias, disable_command, _("\
 Disable some breakpoints.\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 reenabled.\n\
+A disabled breakpoint is not forgotten, but has no effect until re-enabled.\n\
 This command may be abbreviated \"disable\"."),
           &disablelist);
 
This page took 0.044684 seconds and 4 git commands to generate.