NEWS: Mention new sim --map-info flag.
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index f23f5181fc48f102a4bfcc9a19f0b943929f65c1..6a51a3b3f6a8566c8d4ef6326b213f73a35b317f 100644 (file)
@@ -133,8 +133,6 @@ static void watchpoints_info (char *, int);
 
 static int breakpoint_1 (int, int, int (*) (const struct breakpoint *));
 
-static bpstat bpstat_alloc (struct bp_location *, bpstat);
-
 static int breakpoint_cond_eval (void *);
 
 static void cleanup_executing_breakpoints (void *);
@@ -224,7 +222,7 @@ static void trace_pass_command (char *, int);
 /* Assuming we're creating a static tracepoint, does S look like a
    static tracepoint marker spec ("-m MARKER_ID")?  */
 #define is_marker_spec(s)                                              \
-  (strncmp (s, "-m", 2) == 0 && ((s)[2] == ' ' || (s)[2] == '\t'))
+  (s != NULL && strncmp (s, "-m", 2) == 0 && ((s)[2] == ' ' || (s)[2] == '\t'))
 
 /* A reference-counted struct command_line.  This lets multiple
    breakpoints share a single command list.  */
@@ -2070,6 +2068,24 @@ reattach_breakpoints (int pid)
 
 static int internal_breakpoint_number = -1;
 
+/* Set the breakpoint number of B, depending on the value of INTERNAL.
+   If INTERNAL is non-zero, the breakpoint number will be populated
+   from internal_breakpoint_number and that variable decremented.
+   Otherwis the breakpoint number will be populated from
+   breakpoint_count and that value incremented.  Internal breakpoints
+   do not set the internal var bpnum.  */
+static void
+set_breakpoint_number (int internal, struct breakpoint *b)
+{
+  if (internal)
+    b->number = internal_breakpoint_number--;
+  else
+    {
+      set_breakpoint_count (breakpoint_count + 1);
+      b->number = breakpoint_count;
+    }
+}
+
 static struct breakpoint *
 create_internal_breakpoint (struct gdbarch *gdbarch,
                            CORE_ADDR address, enum bptype type)
@@ -2193,6 +2209,35 @@ create_std_terminate_master_breakpoint (const char *func_name)
   do_cleanups (old_chain);
 }
 
+/* Install a master breakpoint on the unwinder's debug hook.  */
+
+void
+create_exception_master_breakpoint (void)
+{
+  struct objfile *objfile;
+
+  ALL_OBJFILES (objfile)
+    {
+      struct minimal_symbol *debug_hook;
+
+      debug_hook = lookup_minimal_symbol ("_Unwind_DebugHook", NULL, objfile);
+      if (debug_hook != NULL)
+       {
+         struct breakpoint *b;
+         CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (debug_hook);
+         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+         addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
+                                                    &current_target);
+         b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
+         b->addr_string = xstrdup ("_Unwind_DebugHook");
+         b->enable_state = bp_disabled;
+       }
+    }
+
+  update_global_location_list (1);
+}
+
 void
 update_breakpoints_after_exec (void)
 {
@@ -2234,7 +2279,8 @@ update_breakpoints_after_exec (void)
     /* Thread event breakpoints must be set anew after an exec(),
        as must overlay event and longjmp master breakpoints.  */
     if (b->type == bp_thread_event || b->type == bp_overlay_event
-       || b->type == bp_longjmp_master || b->type == bp_std_terminate_master)
+       || b->type == bp_longjmp_master || b->type == bp_std_terminate_master
+       || b->type == bp_exception_master)
       {
        delete_breakpoint (b);
        continue;
@@ -2249,7 +2295,8 @@ update_breakpoints_after_exec (void)
 
     /* Longjmp and longjmp-resume breakpoints are also meaningless
        after an exec.  */
-    if (b->type == bp_longjmp || b->type == bp_longjmp_resume)
+    if (b->type == bp_longjmp || b->type == bp_longjmp_resume
+       || b->type == bp_exception || b->type == bp_exception_resume)
       {
        delete_breakpoint (b);
        continue;
@@ -2311,6 +2358,7 @@ update_breakpoints_after_exec (void)
   create_longjmp_master_breakpoint ("siglongjmp");
   create_longjmp_master_breakpoint ("_siglongjmp");
   create_std_terminate_master_breakpoint ("std::terminate()");
+  create_exception_master_breakpoint ();
 }
 
 int
@@ -2992,7 +3040,7 @@ breakpoint_about_to_proceed (void)
         interrupt the command list.  When the call finishes
         successfully, the inferior will be standing at the same
         breakpoint as if nothing happened.  */
-      if (tp->in_infcall)
+      if (tp->control.in_infcall)
        return;
     }
 
@@ -3111,7 +3159,7 @@ bpstat_do_actions (void)
        and only return when it is stopped at the next breakpoint, we
        keep doing breakpoint actions until it returns false to
        indicate the inferior was not resumed.  */
-    if (!bpstat_do_actions_1 (&inferior_thread ()->stop_bpstat))
+    if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
       break;
 }
 
@@ -3232,6 +3280,12 @@ print_it_typical (bpstat bs)
       result = PRINT_NOTHING;
       break;
 
+    case bp_exception_master:
+      /* These should never be enabled.  */
+      printf_filtered (_("Exception Master Breakpoint: gdb should not stop!\n"));
+      result = PRINT_NOTHING;
+      break;
+
     case bp_watchpoint:
     case bp_hardware_watchpoint:
       annotate_watchpoint (b->number);
@@ -3319,6 +3373,8 @@ print_it_typical (bpstat bs)
     case bp_none:
     case bp_longjmp:
     case bp_longjmp_resume:
+    case bp_exception:
+    case bp_exception_resume:
     case bp_step_resume:
     case bp_watchpoint_scope:
     case bp_call_dummy:
@@ -3436,15 +3492,17 @@ breakpoint_cond_eval (void *exp)
   return i;
 }
 
-/* Allocate a new bpstat and chain it to the current one.  */
+/* Allocate a new bpstat.  Link it to the FIFO list by BS_LINK_POINTER.  */
 
 static bpstat
-bpstat_alloc (struct bp_location *bl, bpstat cbs /* Current "bs" value */ )
+bpstat_alloc (struct bp_location *bl, bpstat **bs_link_pointer)
 {
   bpstat bs;
 
   bs = (bpstat) xmalloc (sizeof (*bs));
-  cbs->next = bs;
+  bs->next = NULL;
+  **bs_link_pointer = bs;
+  *bs_link_pointer = &bs->next;
   bs->breakpoint_at = bl->owner;
   bs->bp_location_at = bl;
   incref_bp_location (bl);
@@ -4016,10 +4074,10 @@ bpstat_stop_status (struct address_space *aspace,
   struct breakpoint *b = NULL;
   struct bp_location *bl;
   struct bp_location *loc;
-  /* Root of the chain of bpstat's */
-  struct bpstats root_bs[1];
+  /* First item of allocated bpstat's.  */
+  bpstat bs_head = NULL, *bs_link = &bs_head;
   /* Pointer to the last thing in the chain currently.  */
-  bpstat bs = root_bs;
+  bpstat bs;
   int ix;
   int need_remove_insert;
   int removed_any;
@@ -4054,7 +4112,7 @@ bpstat_stop_status (struct address_space *aspace,
 
          /* Come here if it's a watchpoint, or if the break address matches */
 
-         bs = bpstat_alloc (bl, bs);   /* Alloc a bpstat to explain stop */
+         bs = bpstat_alloc (bl, &bs_link);     /* Alloc a bpstat to explain stop */
 
          /* Assume we stop.  Should we find a watchpoint that is not
             actually triggered, or if the condition of the breakpoint
@@ -4076,7 +4134,7 @@ bpstat_stop_status (struct address_space *aspace,
       if (breakpoint_address_match (loc->pspace->aspace, loc->address,
                                    aspace, bp_addr))
        {
-         bs = bpstat_alloc (loc, bs);
+         bs = bpstat_alloc (loc, &bs_link);
          /* For hits of moribund locations, we should just proceed.  */
          bs->stop = 0;
          bs->print = 0;
@@ -4084,16 +4142,13 @@ bpstat_stop_status (struct address_space *aspace,
        }
     }
 
-  /* Terminate the chain.  */
-  bs->next = NULL;
-
   /* Now go through the locations that caused the target to stop, and
      check whether we're interested in reporting this stop to higher
      layers, or whether we should resume the target transparently.  */
 
   removed_any = 0;
 
-  for (bs = root_bs->next; bs != NULL; bs = bs->next)
+  for (bs = bs_head; bs != NULL; bs = bs->next)
     {
       if (!bs->stop)
        continue;
@@ -4106,7 +4161,8 @@ bpstat_stop_status (struct address_space *aspace,
 
          if (b->type == bp_thread_event || b->type == bp_overlay_event
              || b->type == bp_longjmp_master
-             || b->type == bp_std_terminate_master)
+             || b->type == bp_std_terminate_master
+             || b->type == bp_exception_master)
            /* We do not stop for these.  */
            bs->stop = 0;
          else
@@ -4149,8 +4205,8 @@ bpstat_stop_status (struct address_space *aspace,
      watching may have.  Don't bother if we're stopping; this will get
      done later.  */
   need_remove_insert = 0;
-  if (! bpstat_causes_stop (root_bs->next))
-    for (bs = root_bs->next; bs != NULL; bs = bs->next)
+  if (! bpstat_causes_stop (bs_head))
+    for (bs = bs_head; bs != NULL; bs = bs->next)
       if (!bs->stop
          && bs->breakpoint_at
          && is_hardware_watchpoint (bs->breakpoint_at))
@@ -4164,7 +4220,7 @@ bpstat_stop_status (struct address_space *aspace,
   else if (removed_any)
     update_global_location_list (0);
 
-  return root_bs->next;
+  return bs_head;
 }
 
 static void
@@ -4201,6 +4257,7 @@ bpstat_what (bpstat bs)
 
   retval.main_action = BPSTAT_WHAT_KEEP_CHECKING;
   retval.call_dummy = STOP_NONE;
+  retval.is_longjmp = 0;
 
   for (; bs != NULL; bs = bs->next)
     {
@@ -4256,10 +4313,14 @@ bpstat_what (bpstat bs)
            }
          break;
        case bp_longjmp:
+       case bp_exception:
          this_action = BPSTAT_WHAT_SET_LONGJMP_RESUME;
+         retval.is_longjmp = bptype == bp_longjmp;
          break;
        case bp_longjmp_resume:
+       case bp_exception_resume:
          this_action = BPSTAT_WHAT_CLEAR_LONGJMP_RESUME;
+         retval.is_longjmp = bptype == bp_longjmp_resume;
          break;
        case bp_step_resume:
          if (bs->stop)
@@ -4275,6 +4336,7 @@ bpstat_what (bpstat bs)
        case bp_overlay_event:
        case bp_longjmp_master:
        case bp_std_terminate_master:
+       case bp_exception_master:
          this_action = BPSTAT_WHAT_SINGLE;
          break;
        case bp_catchpoint:
@@ -4468,6 +4530,8 @@ bptype_string (enum bptype type)
     {bp_access_watchpoint, "acc watchpoint"},
     {bp_longjmp, "longjmp"},
     {bp_longjmp_resume, "longjmp resume"},
+    {bp_exception, "exception"},
+    {bp_exception_resume, "exception resume"},
     {bp_step_resume, "step resume"},
     {bp_watchpoint_scope, "watchpoint scope"},
     {bp_call_dummy, "call dummy"},
@@ -4477,6 +4541,7 @@ bptype_string (enum bptype type)
     {bp_overlay_event, "overlay events"},
     {bp_longjmp_master, "longjmp master"},
     {bp_std_terminate_master, "std::terminate master"},
+    {bp_exception_master, "exception master"},
     {bp_catchpoint, "catchpoint"},
     {bp_tracepoint, "tracepoint"},
     {bp_fast_tracepoint, "fast tracepoint"},
@@ -4615,6 +4680,8 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_finish:
       case bp_longjmp:
       case bp_longjmp_resume:
+      case bp_exception:
+      case bp_exception_resume:
       case bp_step_resume:
       case bp_watchpoint_scope:
       case bp_call_dummy:
@@ -4624,6 +4691,7 @@ print_one_breakpoint_location (struct breakpoint *b,
       case bp_overlay_event:
       case bp_longjmp_master:
       case bp_std_terminate_master:
+      case bp_exception_master:
       case bp_tracepoint:
       case bp_fast_tracepoint:
       case bp_static_tracepoint:
@@ -4942,7 +5010,8 @@ breakpoint_1 (int bnum, int allflag, int (*filter) (const struct breakpoint *))
        if (filter && !filter (b))
          continue;
        
-       if (allflag || user_settable_breakpoint (b))
+       if (allflag || (user_settable_breakpoint (b)
+                       && b->number > 0))
          {
            int addr_bit, type_len;
 
@@ -5010,7 +5079,8 @@ breakpoint_1 (int bnum, int allflag, int (*filter) (const struct breakpoint *))
        
        /* We only print out user settable breakpoints unless the
           allflag is set. */
-       if (allflag || user_settable_breakpoint (b))
+       if (allflag || (user_settable_breakpoint (b)
+                       && b->number > 0))
          print_one_breakpoint (b, &last_loc, print_address_bits, allflag);
       }
   }
@@ -5362,6 +5432,8 @@ allocate_bp_location (struct breakpoint *bpt)
     case bp_finish:
     case bp_longjmp:
     case bp_longjmp_resume:
+    case bp_exception:
+    case bp_exception_resume:
     case bp_step_resume:
     case bp_watchpoint_scope:
     case bp_call_dummy:
@@ -5372,6 +5444,7 @@ allocate_bp_location (struct breakpoint *bpt)
     case bp_jit_event:
     case bp_longjmp_master:
     case bp_std_terminate_master:
+    case bp_exception_master:
       loc->loc_type = bp_loc_software_breakpoint;
       break;
     case bp_hardware_breakpoint:
@@ -5423,6 +5496,8 @@ incref_bp_location (struct bp_location *bl)
 static void
 decref_bp_location (struct bp_location **blp)
 {
+  gdb_assert ((*blp)->refc > 0);
+
   if (--(*blp)->refc == 0)
     free_bp_location (*blp);
   *blp = NULL;
@@ -5457,6 +5532,7 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
   b->syscalls_to_be_caught = NULL;
   b->ops = NULL;
   b->condition_not_parsed = 0;
+  b->py_bp_object = NULL;
 
   /* Add this breakpoint to the end of the chain
      so that a list of breakpoints will come out in order
@@ -5585,13 +5661,14 @@ make_breakpoint_permanent (struct breakpoint *b)
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
-   if we do a longjmp() in THREAD.  When we hit that breakpoint, call
-   set_longjmp_resume_breakpoint() to figure out where we are going. */
+   if we do a longjmp() or 'throw' in TP.  FRAME is the frame which
+   initiated the operation.  */
 
 void
-set_longjmp_breakpoint (int thread)
+set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
 {
   struct breakpoint *b, *temp;
+  int thread = tp->num;
 
   /* To avoid having to rescan all objfile symbols at every step,
      we maintain a list of continually-inserted but always disabled
@@ -5599,13 +5676,16 @@ set_longjmp_breakpoint (int thread)
      clones of those and enable them for the requested thread.  */
   ALL_BREAKPOINTS_SAFE (b, temp)
     if (b->pspace == current_program_space
-       && b->type == bp_longjmp_master)
+       && (b->type == bp_longjmp_master
+           || b->type == bp_exception_master))
       {
        struct breakpoint *clone = clone_momentary_breakpoint (b);
 
-       clone->type = bp_longjmp;
+       clone->type = b->type == bp_longjmp_master ? bp_longjmp : bp_exception;
        clone->thread = thread;
       }
+
+  tp->initiating_frame = frame;
 }
 
 /* Delete all longjmp breakpoints from THREAD.  */
@@ -5615,7 +5695,7 @@ delete_longjmp_breakpoint (int thread)
   struct breakpoint *b, *temp;
 
   ALL_BREAKPOINTS_SAFE (b, temp)
-    if (b->type == bp_longjmp)
+    if (b->type == bp_longjmp || b->type == bp_exception)
       {
        if (b->thread == thread)
          delete_breakpoint (b);
@@ -6787,6 +6867,8 @@ mention (struct breakpoint *b)
       case bp_finish:
       case bp_longjmp:
       case bp_longjmp_resume:
+      case bp_exception:
+      case bp_exception_resume:
       case bp_step_resume:
       case bp_call_dummy:
       case bp_std_terminate:
@@ -6797,6 +6879,7 @@ mention (struct breakpoint *b)
       case bp_jit_event:
       case bp_longjmp_master:
       case bp_std_terminate_master:
+      case bp_exception_master:
        break;
       }
 
@@ -6915,7 +6998,8 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
                       char *cond_string,
                       enum bptype type, enum bpdisp disposition,
                       int thread, int task, int ignore_count,
-                      struct breakpoint_ops *ops, int from_tty, int enabled)
+                      struct breakpoint_ops *ops, int from_tty,
+                      int enabled, int internal)
 {
   struct breakpoint *b = NULL;
   int i;
@@ -6952,8 +7036,7 @@ create_breakpoint_sal (struct gdbarch *gdbarch,
       if (i == 0)
        {
          b = set_raw_breakpoint (gdbarch, sal, type);
-         set_breakpoint_count (breakpoint_count + 1);
-         b->number = breakpoint_count;
+         set_breakpoint_number (internal, b);
          b->thread = thread;
          b->task = task;
   
@@ -7035,7 +7118,12 @@ Couldn't determine the static tracepoint marker to probe"));
       = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));
 
   b->ops = ops;
-  mention (b);
+  if (internal)
+    /* Do not mention breakpoints with a negative number, but do
+       notify observers.  */
+    observer_notify_breakpoint_created (b->number);
+  else
+    mention (b);
 }
 
 /* Remove element at INDEX_TO_REMOVE from SAL, shifting other
@@ -7191,7 +7279,7 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
                        enum bptype type, enum bpdisp disposition,
                        int thread, int task, int ignore_count,
                        struct breakpoint_ops *ops, int from_tty,
-                       int enabled)
+                       int enabled, int internal)
 {
   int i;
 
@@ -7202,7 +7290,8 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
 
       create_breakpoint_sal (gdbarch, expanded, addr_string[i],
                             cond_string, type, disposition,
-                            thread, task, ignore_count, ops, from_tty, enabled);
+                            thread, task, ignore_count, ops,
+                            from_tty, enabled, internal);
     }
 }
 
@@ -7471,8 +7560,10 @@ decode_static_tracepoint_spec (char **arg_p)
    parameter.  If non-zero, the function will parse arg, extracting
    breakpoint location, address and thread. Otherwise, ARG is just the
    location of breakpoint, with condition and thread specified by the
-   COND_STRING and THREAD parameters.  Returns true if any breakpoint
-   was created; false otherwise.  */
+   COND_STRING and THREAD parameters.  If INTERNAL is non-zero, the
+   breakpoint number will be allocated from the internal breakpoint
+   count.  Returns true if any breakpoint was created; false
+   otherwise.  */
 
 int
 create_breakpoint (struct gdbarch *gdbarch,
@@ -7482,8 +7573,7 @@ create_breakpoint (struct gdbarch *gdbarch,
                   int ignore_count,
                   enum auto_boolean pending_break_support,
                   struct breakpoint_ops *ops,
-                  int from_tty,
-                  int enabled)
+                  int from_tty, int enabled, int internal)
 {
   struct gdb_exception e;
   struct symtabs_and_lines sals;
@@ -7546,7 +7636,7 @@ create_breakpoint (struct gdbarch *gdbarch,
           /* If pending breakpoint support is auto query and the user
             selects no, then simply return the error code.  */
          if (pending_break_support == AUTO_BOOLEAN_AUTO
-             && !nquery ("Make breakpoint pending on future shared library load? "))
+             && !nquery (_("Make breakpoint pending on future shared library load? ")))
            return 0;
 
          /* At this point, either the user was queried about setting
@@ -7659,12 +7749,15 @@ create_breakpoint (struct gdbarch *gdbarch,
                                     cond_string, type_wanted,
                                     tempflag ? disp_del : disp_donttouch,
                                     thread, task, ignore_count, ops,
-                                    from_tty, enabled);
+                                    from_tty, enabled, internal);
 
              do_cleanups (old_chain);
 
              /* Get the tracepoint we just created.  */
-             tp = get_breakpoint (breakpoint_count);
+             if (internal)
+               tp = get_breakpoint (internal_breakpoint_number);
+             else
+               tp = get_breakpoint (breakpoint_count);
              gdb_assert (tp != NULL);
 
              /* Given that its possible to have multiple markers with
@@ -7680,7 +7773,7 @@ create_breakpoint (struct gdbarch *gdbarch,
        create_breakpoints_sal (gdbarch, sals, addr_string, cond_string,
                                type_wanted, tempflag ? disp_del : disp_donttouch,
                                thread, task, ignore_count, ops, from_tty,
-                               enabled);
+                               enabled, internal);
     }
   else
     {
@@ -7689,8 +7782,7 @@ create_breakpoint (struct gdbarch *gdbarch,
       make_cleanup (xfree, copy_arg);
 
       b = set_raw_breakpoint_without_location (gdbarch, type_wanted);
-      set_breakpoint_count (breakpoint_count + 1);
-      b->number = breakpoint_count;
+      set_breakpoint_number (internal, b);
       b->thread = -1;
       b->addr_string = addr_string[0];
       b->cond_string = NULL;
@@ -7700,13 +7792,19 @@ create_breakpoint (struct gdbarch *gdbarch,
       b->ops = ops;
       b->enable_state = enabled ? bp_enabled : bp_disabled;
       b->pspace = current_program_space;
+      b->py_bp_object = NULL;
 
       if (enabled && b->pspace->executing_startup
          && (b->type == bp_breakpoint
              || b->type == bp_hardware_breakpoint))
        b->enable_state = bp_startup_disabled;
 
-      mention (b);
+      if (internal)
+        /* Do not mention breakpoints with a negative number, 
+          but do notify observers.  */
+        observer_notify_breakpoint_created (b->number);
+      else
+        mention (b);
     }
   
   if (sals.nelts > 1)
@@ -7751,7 +7849,8 @@ break_command_1 (char *arg, int flag, int from_tty)
                     pending_break_support,
                     NULL /* breakpoint_ops */,
                     from_tty,
-                    1 /* enabled */);
+                    1 /* enabled */,
+                    0 /* internal */);
 }
 
 
@@ -8018,12 +8117,13 @@ watchpoint_exp_is_const (const struct expression *exp)
                 hw_read:   watch read, 
                hw_access: watch access (read or write) */
 static void
-watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
+watch_command_1 (char *arg, int accessflag, int from_tty,
+                int just_location, int internal)
 {
   struct breakpoint *b, *scope_breakpoint = NULL;
   struct expression *exp;
   struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
-  struct value *val, *mark;
+  struct value *val, *mark, *result;
   struct frame_info *frame;
   char *exp_start = NULL;
   char *exp_end = NULL;
@@ -8122,12 +8222,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
 
   exp_valid_block = innermost_block;
   mark = value_mark ();
-  fetch_subexp_value (exp, &pc, &val, NULL, NULL);
+  fetch_subexp_value (exp, &pc, &val, &result, NULL);
 
   if (just_location)
     {
       exp_valid_block = NULL;
-      val = value_addr (val);
+      val = value_addr (result);
       release_value (val);
       value_free_to_mark (mark);
     }
@@ -8226,8 +8326,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
 
   /* Now set up the breakpoint.  */
   b = set_raw_breakpoint_without_location (NULL, bp_type);
-  set_breakpoint_count (breakpoint_count + 1);
-  b->number = breakpoint_count;
+  set_breakpoint_number (internal, b);
   b->thread = thread;
   b->disposition = disp_donttouch;
   b->exp = exp;
@@ -8286,8 +8385,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
   /* Finally update the new watchpoint.  This creates the locations
      that should be inserted.  */
   update_watchpoint (b, 1);
-
-  mention (b);
+  if (internal)
+    /* Do not mention breakpoints with a negative number, but do
+       notify observers.  */
+    observer_notify_breakpoint_created (b->number);
+  else
+    mention (b);
   update_global_location_list (1);
 }
 
@@ -8328,10 +8431,12 @@ can_use_hardware_watchpoint (struct value *v)
     {
       if (VALUE_LVAL (v) == lval_memory)
        {
-         if (value_lazy (v))
-           /* A lazy memory lvalue is one that GDB never needed to fetch;
-              we either just used its address (e.g., `a' in `a.b') or
-              we never needed it at all (e.g., `a' in `a,b').  */
+         if (v != head && value_lazy (v))
+           /* A lazy memory lvalue in the chain is one that GDB never
+              needed to fetch; we either just used its address (e.g.,
+              `a' in `a.b') or we never needed it at all (e.g., `a'
+              in `a,b').  This doesn't apply to HEAD; if that is
+              lazy then it was not readable, but watch it anyway.  */
            ;
          else
            {
@@ -8369,9 +8474,9 @@ can_use_hardware_watchpoint (struct value *v)
 }
 
 void
-watch_command_wrapper (char *arg, int from_tty)
+watch_command_wrapper (char *arg, int from_tty, int internal)
 {
-  watch_command_1 (arg, hw_write, from_tty, 0);
+  watch_command_1 (arg, hw_write, from_tty, 0, internal);
 }
 
 /* A helper function that looks for an argument at the start of a
@@ -8407,7 +8512,7 @@ watch_maybe_just_location (char *arg, int accessflag, int from_tty)
       just_location = 1;
     }
 
-  watch_command_1 (arg, accessflag, from_tty, just_location);
+  watch_command_1 (arg, accessflag, from_tty, just_location, 0);
 }
 
 static void
@@ -8417,9 +8522,9 @@ watch_command (char *arg, int from_tty)
 }
 
 void
-rwatch_command_wrapper (char *arg, int from_tty)
+rwatch_command_wrapper (char *arg, int from_tty, int internal)
 {
-  watch_command_1 (arg, hw_read, from_tty, 0);
+  watch_command_1 (arg, hw_read, from_tty, 0, internal);
 }
 
 static void
@@ -8429,9 +8534,9 @@ rwatch_command (char *arg, int from_tty)
 }
 
 void
-awatch_command_wrapper (char *arg, int from_tty)
+awatch_command_wrapper (char *arg, int from_tty, int internal)
 {
-  watch_command_1 (arg, hw_access, from_tty, 0);
+  watch_command_1 (arg, hw_access, from_tty, 0, internal);
 }
 
 static void
@@ -8448,6 +8553,7 @@ struct until_break_command_continuation_args
 {
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2;
+  int thread_num;
 };
 
 /* This function is called by fetch_inferior_event via the
@@ -8462,6 +8568,7 @@ until_break_command_continuation (void *arg)
   delete_breakpoint (a->breakpoint);
   if (a->breakpoint2)
     delete_breakpoint (a->breakpoint2);
+  delete_longjmp_breakpoint (a->thread_num);
 }
 
 void
@@ -8473,6 +8580,8 @@ until_break_command (char *arg, int from_tty, int anywhere)
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2 = NULL;
   struct cleanup *old_chain;
+  int thread;
+  struct thread_info *tp;
 
   clear_proceed_status ();
 
@@ -8511,6 +8620,9 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
   old_chain = make_cleanup_delete_breakpoint (breakpoint);
 
+  tp = inferior_thread ();
+  thread = tp->num;
+
   /* Keep within the current frame, or in frames called by the current
      one.  */
 
@@ -8523,6 +8635,9 @@ until_break_command (char *arg, int from_tty, int anywhere)
                                              frame_unwind_caller_id (frame),
                                              bp_until);
       make_cleanup_delete_breakpoint (breakpoint2);
+
+      set_longjmp_breakpoint (tp, frame_unwind_caller_id (frame));
+      make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
     }
 
   proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
@@ -8539,6 +8654,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
 
       args->breakpoint = breakpoint;
       args->breakpoint2 = breakpoint2;
+      args->thread_num = thread;
 
       discard_cleanups (old_chain);
       add_continuation (inferior_thread (),
@@ -8789,7 +8905,8 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
                     0,
                     AUTO_BOOLEAN_TRUE /* pending */,
                     &gnu_v3_exception_catchpoint_ops, from_tty,
-                    1 /* enabled */);
+                    1 /* enabled */,
+                    0 /* internal */);
 
   return 1;
 }
@@ -9637,7 +9754,7 @@ bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
 {
   struct breakpoint *bpt = data;
 
-  bpstat_remove_bp_location (th->stop_bpstat, bpt);
+  bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
   return 0;
 }
 
@@ -9777,6 +9894,7 @@ delete_command (char *arg, int from_tty)
            && b->type != bp_overlay_event
            && b->type != bp_longjmp_master
            && b->type != bp_std_terminate_master
+           && b->type != bp_exception_master
            && b->number >= 0)
          {
            breaks_to_delete = 1;
@@ -9798,6 +9916,7 @@ delete_command (char *arg, int from_tty)
                && b->type != bp_overlay_event
                && b->type != bp_longjmp_master
                && b->type != bp_std_terminate_master
+               && b->type != bp_exception_master
                && b->number >= 0)
              delete_breakpoint (b);
          }
@@ -10258,6 +10377,7 @@ breakpoint_re_set_one (void *bint)
     case bp_overlay_event:
     case bp_longjmp_master:
     case bp_std_terminate_master:
+    case bp_exception_master:
       delete_breakpoint (b);
       break;
 
@@ -10281,6 +10401,8 @@ breakpoint_re_set_one (void *bint)
     case bp_step_resume:
     case bp_longjmp:
     case bp_longjmp_resume:
+    case bp_exception:
+    case bp_exception_resume:
     case bp_jit_event:
       break;
     }
@@ -10324,6 +10446,7 @@ breakpoint_re_set (void)
   create_longjmp_master_breakpoint ("siglongjmp");
   create_longjmp_master_breakpoint ("_siglongjmp");
   create_std_terminate_master_breakpoint ("std::terminate()");
+  create_exception_master_breakpoint ();
 }
 \f
 /* Reset the thread number of this breakpoint:
@@ -11009,7 +11132,8 @@ trace_command (char *arg, int from_tty)
                         pending_break_support,
                         NULL,
                         from_tty,
-                        1 /* enabled */))
+                        1 /* enabled */,
+                        0 /* internal */))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -11025,7 +11149,8 @@ ftrace_command (char *arg, int from_tty)
                         pending_break_support,
                         NULL,
                         from_tty,
-                        1 /* enabled */))
+                        1 /* enabled */,
+                        0 /* internal */))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -11043,7 +11168,8 @@ strace_command (char *arg, int from_tty)
                         pending_break_support,
                         NULL,
                         from_tty,
-                        1 /* enabled */))
+                        1 /* enabled */,
+                        0 /* internal */))
     set_tracepoint_count (breakpoint_count);
 }
 
@@ -11105,7 +11231,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
                          pending_break_support,
                          NULL,
                          0 /* from_tty */,
-                         utp->enabled /* enabled */))
+                         utp->enabled /* enabled */,
+                         0 /* internal */))
     return NULL;
 
   set_tracepoint_count (breakpoint_count);
@@ -11371,7 +11498,7 @@ save_breakpoints (char *filename, int from_tty,
   ALL_BREAKPOINTS (tp)
   {
     /* Skip internal and momentary breakpoints.  */
-    if (!user_settable_breakpoint (tp))
+    if (!user_settable_breakpoint (tp) || tp->number < 0)
       continue;
 
     /* If we have a filter, only save the breakpoints it accepts.  */
@@ -11409,7 +11536,7 @@ save_breakpoints (char *filename, int from_tty,
   ALL_BREAKPOINTS (tp)
   {
     /* Skip internal and momentary breakpoints.  */
-    if (!user_settable_breakpoint (tp))
+    if (!user_settable_breakpoint (tp) || tp->number < 0)
       continue;
 
     /* If we have a filter, only save the breakpoints it accepts.  */
@@ -11488,7 +11615,7 @@ save_breakpoints (char *filename, int from_tty,
        fprintf_unfiltered (fp, "  commands\n");
        
        ui_out_redirect (uiout, fp);
-       TRY_CATCH (ex, RETURN_MASK_ERROR)
+       TRY_CATCH (ex, RETURN_MASK_ALL)
          {
            print_command_lines (uiout, tp->commands->commands, 2);
          }
@@ -11626,6 +11753,21 @@ save_command (char *arg, int from_tty)
   help_list (save_cmdlist, "save ", -1, gdb_stdout);
 }
 
+struct breakpoint *
+iterate_over_breakpoints (int (*callback) (struct breakpoint *, void *),
+                         void *data)
+{
+  struct breakpoint *b, *temp;
+
+  ALL_BREAKPOINTS_SAFE (b, temp)
+    {
+      if ((*callback) (b, data))
+       return b;
+    }
+
+  return NULL;
+}
+
 void
 _initialize_breakpoint (void)
 {
This page took 0.038927 seconds and 4 git commands to generate.