gdb
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 4fbda0b6e8e52da944b6810a68bacd5c0a3816a4..051b753d6392fe6640d58fb13b5bfbc7da2f4899 100644 (file)
 #include "gdb-events.h"
 #include "mi/mi-common.h"
 
+#include "gdb_stdint.h"
+
 /* Prototypes for local functions. */
 
-static void until_break_command_continuation (struct continuation_arg *arg);
+static void until_break_command_continuation (struct continuation_arg *arg, 
+                                             int error);
 
 static void catch_command_1 (char *, int, int);
 
@@ -138,19 +141,10 @@ static enum print_stop_action print_it_typical (bpstat);
 
 static enum print_stop_action print_bp_stop_message (bpstat bs);
 
-typedef struct
-  {
-    enum exception_event_kind kind;
-    int enable_p;
-  }
-args_for_catchpoint_enable;
-
 static int watchpoint_check (void *);
 
 static void maintenance_info_breakpoints (char *, int);
 
-static void create_longjmp_breakpoint (char *);
-
 static void create_overlay_event_breakpoint (char *);
 
 static int hw_breakpoint_used_count (void);
@@ -185,10 +179,6 @@ static char *ep_parse_optional_if_clause (char **arg);
 
 static char *ep_parse_optional_filename (char **arg);
 
-static void create_exception_catchpoint (int tempflag, char *cond_string,
-                                        enum exception_event_kind ex_event,
-                                        struct symtab_and_line *sal);
-
 static void catch_exception_command_1 (enum exception_event_kind ex_event, 
                                       char *arg, int tempflag, int from_tty);
 
@@ -205,14 +195,24 @@ static void mark_breakpoints_out (void);
 static struct bp_location *
 allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type);
 
-static void
-unlink_locations_from_global_list (struct breakpoint *bpt);
+static void update_global_location_list (void);
 
-static int
-is_hardware_watchpoint (struct breakpoint *bpt);
+static void update_global_location_list_nothrow (void);
 
-/* Prototypes for exported functions. */
+static int is_hardware_watchpoint (struct breakpoint *bpt);
+
+static void insert_breakpoint_locations (void);
+
+static const char *
+bpdisp_text (enum bpdisp disp)
+{
+  /* NOTE: the following values are a part of MI protocol and represent
+     values of 'disp' field returned when inferior stops at a breakpoint.  */
+  static char *bpdisps[] = {"del", "dstp", "dis", "keep"};
+  return bpdisps[(int) disp];
+}
 
+/* Prototypes for exported functions. */
 /* If FALSE, gdb will not use hardware support for watchpoints, even
    if such is available. */
 static int can_use_hw_watchpoints;
@@ -257,6 +257,18 @@ Automatic usage of hardware breakpoints is %s.\n"),
                    value);
 }
 
+/* If 1, gdb will keep breakpoints inserted even as inferior is stopped, 
+   and immediately insert any new breakpoints.  If 0, gdb will insert 
+   breakpoints into inferior only when resuming it, and will remove 
+   breakpoints upon stop.  */
+static int always_inserted_mode = 0;
+static void 
+show_always_inserted_mode (struct ui_file *file, int from_tty,
+                          struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"), value);
+}
+
 
 void _initialize_breakpoint (void);
 
@@ -302,9 +314,6 @@ struct bp_location *bp_location_chain;
 
 int breakpoint_count;
 
-/* Pointer to current exception event record */
-static struct exception_event_record *current_exception_event;
-
 /* This function returns a pointer to the string representation of the
    pathname of the dynamically-linked library that has just been
    loaded.
@@ -576,44 +585,45 @@ condition_command (char *arg, int from_tty)
 
   ALL_BREAKPOINTS (b)
     if (b->number == bnum)
-    {
-      struct bp_location *loc = b->loc;
-      for (; loc; loc = loc->next)
-       {
-         if (loc->cond)
-           {
-             xfree (loc->cond);
-             loc->cond = 0;
-           }
-       }
-      if (b->cond_string != NULL)
-       xfree (b->cond_string);
+      {
+       struct bp_location *loc = b->loc;
+       for (; loc; loc = loc->next)
+         {
+           if (loc->cond)
+             {
+               xfree (loc->cond);
+               loc->cond = 0;
+             }
+         }
+       if (b->cond_string != NULL)
+         xfree (b->cond_string);
 
-      if (*p == 0)
-       {
-         b->cond_string = NULL;
-         if (from_tty)
-           printf_filtered (_("Breakpoint %d now unconditional.\n"), bnum);
-       }
-      else
-       {
-         arg = p;
-         /* I don't know if it matters whether this is the string the user
-            typed in or the decompiled expression.  */
-         b->cond_string = savestring (arg, strlen (arg));
-         b->condition_not_parsed = 0;
-         for (loc = b->loc; loc; loc = loc->next)
-           {
-             arg = p;
-             loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0);
-             if (*arg)
-               error (_("Junk at end of expression"));
-           }
-       }
-      breakpoints_changed ();
-      breakpoint_modify_event (b->number);
-      return;
-    }
+       if (*p == 0)
+         {
+           b->cond_string = NULL;
+           if (from_tty)
+             printf_filtered (_("Breakpoint %d now unconditional.\n"), bnum);
+         }
+       else
+         {
+           arg = p;
+           /* I don't know if it matters whether this is the string the user
+              typed in or the decompiled expression.  */
+           b->cond_string = savestring (arg, strlen (arg));
+           b->condition_not_parsed = 0;
+           for (loc = b->loc; loc; loc = loc->next)
+             {
+               arg = p;
+               loc->cond =
+                 parse_exp_1 (&arg, block_for_pc (loc->address), 0);
+               if (*arg)
+                 error (_("Junk at end of expression"));
+             }
+         }
+       breakpoints_changed ();
+       breakpoint_modify_event (b->number);
+       return;
+      }
 
   error (_("No breakpoint number %d."), bnum);
 }
@@ -698,7 +708,7 @@ commands_from_control_command (char *arg, struct command_line *cmd)
        breakpoints_changed ();
        breakpoint_modify_event (b->number);
        return simple_control;
-    }
+      }
   error (_("No breakpoint number %d."), bnum);
 }
 \f
@@ -867,14 +877,10 @@ update_watchpoint (struct breakpoint *b, int reparse)
   struct bp_location *loc;
   bpstat bs;
 
-  unlink_locations_from_global_list (b);
-  for (loc = b->loc; loc;)
-    {
-      struct bp_location *loc_next = loc->next;
-      remove_breakpoint (loc, mark_uninserted);
-      xfree (loc);
-      loc = loc_next;
-    }
+  /* We don't free locations.  They are stored in
+     bp_location_chain and update_global_locations will
+     eventually delete them and remove breakpoints if
+     needed.  */
   b->loc = NULL;
 
   if (b->disposition == disp_del_at_next_stop)
@@ -986,14 +992,13 @@ update_watchpoint (struct breakpoint *b, int reparse)
            value_free (v);
        }
 
-      if (reparse && b->cond_string != NULL)
+      /* We just regenerated the list of breakpoint locations.
+         The new location does not have its condition field set to anything
+         and therefore, we must always reparse the cond_string, independently
+         of the value of the reparse flag.  */
+      if (b->cond_string != NULL)
        {
          char *s = b->cond_string;
-         if (b->loc->cond)
-           {
-             xfree (b->loc->cond);
-             b->loc->cond = NULL;
-           }
          b->loc->cond = parse_exp_1 (&s, b->exp_valid_block, 0);
        }
     }
@@ -1013,6 +1018,23 @@ in which its expression is valid.\n"),
 }
 
 
+/* Returns 1 iff breakpoint location should be
+   inserted in the inferior.  */
+static int
+should_be_inserted (struct bp_location *bpt)
+{
+  if (!breakpoint_enabled (bpt->owner))
+    return 0;
+
+  if (bpt->owner->disposition == disp_del_at_next_stop)
+    return 0;
+
+  if (!bpt->enabled || bpt->shlib_disabled || bpt->duplicate)
+    return 0;
+
+  return 1;
+}
+
 /* Insert a low-level "breakpoint" of some type.  BPT is the breakpoint.
    Any error messages are printed to TMP_ERROR_STREAM; and DISABLED_BREAKS,
    PROCESS_WARNING, and HW_BREAKPOINT_ERROR are used to report problems.
@@ -1027,10 +1049,7 @@ insert_bp_location (struct bp_location *bpt,
 {
   int val = 0;
 
-  if (!breakpoint_enabled (bpt->owner))
-    return 0;
-
-  if (!bpt->enabled || bpt->shlib_disabled || bpt->inserted || bpt->duplicate)
+  if (!should_be_inserted (bpt) || bpt->inserted)
     return 0;
 
   /* Initialize the target-specific information.  */
@@ -1231,13 +1250,35 @@ Note: automatically using hardware breakpoints for read-only addresses.\n"));
   return 0;
 }
 
+/* Make sure all breakpoints are inserted in inferior.
+   Throws exception on any error.
+   A breakpoint that is already inserted won't be inserted
+   again, so calling this function twice is safe.  */
+void
+insert_breakpoints (void)
+{
+  struct breakpoint *bpt;
+
+  ALL_BREAKPOINTS (bpt)
+    if (is_hardware_watchpoint (bpt))
+      update_watchpoint (bpt, 0 /* don't reparse. */);
+
+  update_global_location_list ();
+
+  if (!always_inserted_mode && target_has_execution)
+    /* update_global_location_list does not insert breakpoints
+       when always_inserted_mode is not enabled.  Explicitly
+       insert them now.  */
+    insert_breakpoint_locations ();
+}
+
 /* insert_breakpoints is used when starting or continuing the program.
    remove_breakpoints is used when the program stops.
    Both return zero if successful,
    or an `errno' value if could not write the inferior.  */
 
-void
-insert_breakpoints (void)
+static void
+insert_breakpoint_locations (void)
 {
   struct breakpoint *bpt;
   struct bp_location *b, *temp;
@@ -1249,18 +1290,14 @@ insert_breakpoints (void)
 
   struct ui_file *tmp_error_stream = mem_fileopen ();
   make_cleanup_ui_file_delete (tmp_error_stream);
-
+  
   /* Explicitly mark the warning -- this will only be printed if
      there was an error.  */
   fprintf_unfiltered (tmp_error_stream, "Warning:\n");
-
-  ALL_BREAKPOINTS (bpt)
-    if (is_hardware_watchpoint (bpt))
-      update_watchpoint (bpt, 0 /* don't reparse */);      
        
   ALL_BP_LOCATIONS_SAFE (b, temp)
     {
-      if (!breakpoint_enabled (b->owner))
+      if (!should_be_inserted (b) || b->inserted)
        continue;
 
       /* There is no point inserting thread-specific breakpoints if the
@@ -1288,6 +1325,9 @@ insert_breakpoints (void)
 
       if (bpt->enable_state != bp_enabled)
        continue;
+
+      if (bpt->disposition == disp_del_at_next_stop)
+       continue;
       
       for (loc = bpt->loc; loc; loc = loc->next)
        if (!loc->inserted)
@@ -1395,17 +1435,31 @@ reattach_breakpoints (int pid)
   return 0;
 }
 
+static void
+restore_always_inserted_mode (void *p)
+{
+  always_inserted_mode = (uintptr_t) p;
+}
+
 void
 update_breakpoints_after_exec (void)
 {
   struct breakpoint *b;
   struct breakpoint *temp;
+  struct cleanup *cleanup;
 
   /* Doing this first prevents the badness of having delete_breakpoint()
      write a breakpoint's current "shadow contents" to lift the bp.  That
      shadow is NOT valid after an exec()! */
   mark_breakpoints_out ();
 
+  /* The binary we used to debug is now gone, and we're updating
+     breakpoints for the new binary.  Until we're done, we should not
+     try to insert breakpoints.  */
+  cleanup = make_cleanup (restore_always_inserted_mode, 
+                         (void *) (uintptr_t) always_inserted_mode);
+  always_inserted_mode = 0;
+
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
     /* Solib breakpoints must be explicitly reset after an exec(). */
@@ -1430,6 +1484,14 @@ update_breakpoints_after_exec (void)
        continue;
       }
 
+    /* Longjmp and longjmp-resume breakpoints are also meaningless
+       after an exec.  */
+    if (b->type == bp_longjmp || b->type == bp_longjmp_resume)
+      {
+       delete_breakpoint (b);
+       continue;
+      }
+
     /* Don't delete an exec catchpoint, because else the inferior
        won't stop when it ought!
 
@@ -1487,6 +1549,7 @@ update_breakpoints_after_exec (void)
   }
   /* FIXME what about longjmp breakpoints?  Re-create them here?  */
   create_overlay_event_breakpoint ("_ovly_debug_event");
+  do_cleanups (cleanup);
 }
 
 int
@@ -1526,9 +1589,9 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is)
     /* Permanent breakpoints cannot be inserted or removed.  */
     return 0;
 
-  if (b->owner->type == bp_none)
-    warning (_("attempted to remove apparently deleted breakpoint #%d?"), 
-            b->owner->number);
+  /* The type of none suggests that owner is actually deleted.
+     This should not ever happen.  */
+  gdb_assert (b->owner->type != bp_none);
 
   if (b->loc_type == bp_loc_software_breakpoint
       || b->loc_type == bp_loc_hardware_breakpoint)
@@ -2114,11 +2177,30 @@ top:
       do_cleanups (this_cmd_tree_chain);
 
       if (breakpoint_proceeded)
-       /* The inferior is proceeded by the command; bomb out now.
-          The bpstat chain has been blown away by wait_for_inferior.
-          But since execution has stopped again, there is a new bpstat
-          to look at, so start over.  */
-       goto top;
+       {
+         if (target_can_async_p ())
+         /* If we are in async mode, then the target might
+            be still running, not stopped at any breakpoint,
+            so nothing for us to do here -- just return to
+            the event loop.  */
+           break;
+         else
+           /* In sync mode, when execute_control_command returns
+              we're already standing on the next breakpoint.
+              Breakpoint commands for that stop were not run,
+              since execute_command does not run breakpoint
+              commands -- only command_line_handler does, but
+              that one is not involved in execution of breakpoint
+              commands.  So, we can now execute breakpoint commands.
+              There's an implicit assumption that we're called with
+              stop_bpstat, so our parameter is the new bpstat to
+              handle.  
+              It should be noted that making execute_command do
+              bpstat actions is not an option -- in this case we'll
+              have recursive invocation of bpstat for each breakpoint
+              with a command, and can easily blow up GDB stack.  */
+           goto top;
+       }
     }
   do_cleanups (old_chain);
 }
@@ -2162,6 +2244,7 @@ print_it_typical (bpstat bs)
   struct breakpoint *b;
   const struct bp_location *bl;
   struct ui_stream *stb;
+  int bp_temp = 0;  
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
   /* bs->breakpoint_at can be NULL if it was a momentary breakpoint
@@ -2175,15 +2258,22 @@ print_it_typical (bpstat bs)
     {
     case bp_breakpoint:
     case bp_hardware_breakpoint:
+      bp_temp = bs->breakpoint_at->owner->disposition == disp_del;
       if (bl->address != bl->requested_address)
        breakpoint_adjustment_warning (bl->requested_address,
                                       bl->address,
                                       b->number, 1);
       annotate_breakpoint (b->number);
-      ui_out_text (uiout, "\nBreakpoint ");
+      if (bp_temp) 
+       ui_out_text (uiout, "\nTemporary breakpoint ");
+      else
+       ui_out_text (uiout, "\nBreakpoint ");
       if (ui_out_is_mi_like_p (uiout))
-       ui_out_field_string (uiout, "reason", 
-                            async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+       {
+         ui_out_field_string (uiout, "reason", 
+                         async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+         ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+       }
       ui_out_field_int (uiout, "bkptno", b->number);
       ui_out_text (uiout, ", ");
       return PRINT_SRC_AND_LOC;
@@ -2518,8 +2608,9 @@ watchpoints_triggered (struct target_waitstatus *ws)
        for (loc = b->loc; loc; loc = loc->next)
          /* Exact match not required.  Within range is
             sufficient.  */
-         if (addr >= loc->address
-             && addr < loc->address + loc->length)
+         if (target_watchpoint_addr_within_range (&current_target,
+                                                  addr, loc->address,
+                                                  loc->length))
            {
              b->watchpoint_triggered = watch_triggered_yes;
              break;
@@ -2653,6 +2744,252 @@ which its expression is valid.\n");
     }
 }
 
+/* Return true if it looks like target has stopped due to hitting
+   breakpoint location BL.  This function does not check if we
+   should stop, only if BL explains the stop.   */
+static int
+bpstat_check_location (const struct bp_location *bl, CORE_ADDR bp_addr)
+{
+  struct breakpoint *b = bl->owner;
+
+  if (b->type != bp_watchpoint
+      && b->type != bp_hardware_watchpoint
+      && b->type != bp_read_watchpoint
+      && b->type != bp_access_watchpoint
+      && b->type != bp_hardware_breakpoint
+      && b->type != bp_catch_fork
+      && b->type != bp_catch_vfork
+      && b->type != bp_catch_exec)     /* a non-watchpoint bp */
+    {
+      if (bl->address != bp_addr)      /* address doesn't match */
+       return 0;
+      if (overlay_debugging            /* unmapped overlay section */
+         && section_is_overlay (bl->section) 
+         && !section_is_mapped (bl->section))
+       return 0;
+    }
+  
+  /* Continuable hardware watchpoints are treated as non-existent if the
+     reason we stopped wasn't a hardware watchpoint (we didn't stop on
+     some data address).  Otherwise gdb won't stop on a break instruction
+     in the code (not from a breakpoint) when a hardware watchpoint has
+     been defined.  Also skip watchpoints which we know did not trigger
+     (did not match the data address).  */
+  
+  if ((b->type == bp_hardware_watchpoint
+       || b->type == bp_read_watchpoint
+       || b->type == bp_access_watchpoint)
+      && b->watchpoint_triggered == watch_triggered_no)
+    return 0;
+  
+  if (b->type == bp_hardware_breakpoint)
+    {
+      if (bl->address != bp_addr)
+       return 0;
+      if (overlay_debugging            /* unmapped overlay section */
+         && section_is_overlay (bl->section) 
+         && !section_is_mapped (bl->section))
+       return 0;
+    }
+  
+  /* Is this a catchpoint of a load or unload?  If so, did we
+     get a load or unload of the specified library?  If not,
+     ignore it. */
+  if ((b->type == bp_catch_load)
+#if defined(SOLIB_HAVE_LOAD_EVENT)
+      && (!SOLIB_HAVE_LOAD_EVENT (PIDGET (inferior_ptid))
+         || ((b->dll_pathname != NULL)
+             && (strcmp (b->dll_pathname, 
+                         SOLIB_LOADED_LIBRARY_PATHNAME (
+                           PIDGET (inferior_ptid)))
+                 != 0)))
+#endif
+      )
+    return 0;
+  
+  if ((b->type == bp_catch_unload)
+#if defined(SOLIB_HAVE_UNLOAD_EVENT)
+      && (!SOLIB_HAVE_UNLOAD_EVENT (PIDGET (inferior_ptid))
+         || ((b->dll_pathname != NULL)
+             && (strcmp (b->dll_pathname, 
+                         SOLIB_UNLOADED_LIBRARY_PATHNAME (
+                           PIDGET (inferior_ptid)))
+                 != 0)))
+#endif
+      )
+    return 0;
+
+  if ((b->type == bp_catch_fork)
+      && !inferior_has_forked (PIDGET (inferior_ptid),
+                              &b->forked_inferior_pid))
+    return 0;
+  
+  if ((b->type == bp_catch_vfork)
+      && !inferior_has_vforked (PIDGET (inferior_ptid),
+                               &b->forked_inferior_pid))
+    return 0;
+  
+  if ((b->type == bp_catch_exec)
+      && !inferior_has_execd (PIDGET (inferior_ptid), &b->exec_pathname))
+    return 0;
+
+  return 1;
+}
+
+/* If BS refers to a watchpoint, determine if the watched values
+   has actually changed, and we should stop.  If not, set BS->stop
+   to 0.  */
+static void
+bpstat_check_watchpoint (bpstat bs)
+{
+  const struct bp_location *bl = bs->breakpoint_at;
+  struct breakpoint *b = bl->owner;
+
+  if (b->type == bp_watchpoint
+      || b->type == bp_read_watchpoint
+      || b->type == bp_access_watchpoint
+      || b->type == bp_hardware_watchpoint)
+    {
+      CORE_ADDR addr;
+      struct value *v;
+      int must_check_value = 0;
+      
+      if (b->type == bp_watchpoint)
+       /* For a software watchpoint, we must always check the
+          watched value.  */
+       must_check_value = 1;
+      else if (b->watchpoint_triggered == watch_triggered_yes)
+       /* We have a hardware watchpoint (read, write, or access)
+          and the target earlier reported an address watched by
+          this watchpoint.  */
+       must_check_value = 1;
+      else if (b->watchpoint_triggered == watch_triggered_unknown
+              && 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
+          a data address, we can't figure it out.  */
+       must_check_value = 1;
+      
+      if (must_check_value)
+       {
+         char *message = xstrprintf ("Error evaluating expression for watchpoint %d\n",
+                                     b->number);
+         struct cleanup *cleanups = make_cleanup (xfree, message);
+         int e = catch_errors (watchpoint_check, bs, message,
+                               RETURN_MASK_ALL);
+         do_cleanups (cleanups);
+         switch (e)
+           {
+           case WP_DELETED:
+             /* We've already printed what needs to be printed.  */
+             bs->print_it = print_it_done;
+             /* Stop.  */
+             break;
+           case WP_VALUE_CHANGED:
+             if (b->type == bp_read_watchpoint)
+               {
+                 /* Don't stop: read watchpoints shouldn't fire if
+                    the value has changed.  This is for targets
+                    which cannot set read-only watchpoints.  */
+                 bs->print_it = print_it_noop;
+                 bs->stop = 0;
+               }
+             break;
+           case WP_VALUE_NOT_CHANGED:
+             if (b->type == bp_hardware_watchpoint
+                 || b->type == bp_watchpoint)
+               {
+                 /* Don't stop: write watchpoints shouldn't fire if
+                    the value hasn't changed.  */
+                 bs->print_it = print_it_noop;
+                 bs->stop = 0;
+               }
+             /* Stop.  */
+             break;
+           default:
+             /* Can't happen.  */
+           case 0:
+             /* Error from catch_errors.  */
+             printf_filtered (_("Watchpoint %d deleted.\n"), b->number);
+             if (b->related_breakpoint)
+               b->related_breakpoint->disposition = disp_del_at_next_stop;
+             b->disposition = disp_del_at_next_stop;
+             /* We've already printed what needs to be printed.  */
+             bs->print_it = print_it_done;
+             break;
+           }
+       }
+      else     /* must_check_value == 0 */
+       {
+         /* This is a case where some watchpoint(s) triggered, but
+            not at the address of this watchpoint, or else no
+            watchpoint triggered after all.  So don't print
+            anything for this watchpoint.  */
+         bs->print_it = print_it_noop;
+         bs->stop = 0;
+       }
+    }
+}
+
+
+/* Check conditions (condition proper, frame, thread and ignore count)
+   of breakpoint referred to by BS.  If we should not stop for this
+   breakpoint, set BS->stop to 0.  */
+static void
+bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
+{
+  int thread_id = pid_to_thread_id (ptid);
+  const struct bp_location *bl = bs->breakpoint_at;
+  struct breakpoint *b = bl->owner;
+
+  if (frame_id_p (b->frame_id)
+      && !frame_id_eq (b->frame_id, get_frame_id (get_current_frame ())))
+    bs->stop = 0;
+  else if (bs->stop)
+    {
+      int value_is_zero = 0;
+      
+      /* If this is a scope breakpoint, mark the associated
+        watchpoint as triggered so that we will handle the
+        out-of-scope event.  We'll get to the watchpoint next
+        iteration.  */
+      if (b->type == bp_watchpoint_scope)
+       b->related_breakpoint->watchpoint_triggered = watch_triggered_yes;
+      
+      if (bl->cond && bl->owner->disposition != disp_del_at_next_stop)
+       {
+         /* Need to select the frame, with all that implies
+            so that the conditions will have the right context.  */
+         select_frame (get_current_frame ());
+         value_is_zero
+           = catch_errors (breakpoint_cond_eval, (bl->cond),
+                           "Error in testing breakpoint condition:\n",
+                           RETURN_MASK_ALL);
+         /* FIXME-someday, should give breakpoint # */
+         free_all_values ();
+       }
+      if (bl->cond && value_is_zero)
+       {
+         bs->stop = 0;
+       }
+      else if (b->thread != -1 && b->thread != thread_id)
+       {
+         bs->stop = 0;
+       }
+      else if (b->ignore_count > 0)
+       {
+         b->ignore_count--;
+         annotate_ignore_count_change ();
+         bs->stop = 0;
+         /* Increase the hit count even though we don't
+            stop.  */
+         ++(b->hit_count);
+       }       
+    }
+}
+
+
 /* Get a bpstat associated with having just stopped at address
    BP_ADDR in thread PTID.
 
@@ -2679,7 +3016,6 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
   struct bpstats root_bs[1];
   /* Pointer to the last thing in the chain currently.  */
   bpstat bs = root_bs;
-  int thread_id = pid_to_thread_id (ptid);
 
   ALL_BP_LOCATIONS (bl)
   {
@@ -2688,87 +3024,6 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
     if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
       continue;
 
-    if (b->type != bp_watchpoint
-       && b->type != bp_hardware_watchpoint
-       && b->type != bp_read_watchpoint
-       && b->type != bp_access_watchpoint
-       && b->type != bp_hardware_breakpoint
-       && b->type != bp_catch_fork
-       && b->type != bp_catch_vfork
-       && b->type != bp_catch_exec)    /* a non-watchpoint bp */
-      {
-       if (bl->address != bp_addr)     /* address doesn't match */
-         continue;
-       if (overlay_debugging           /* unmapped overlay section */
-           && section_is_overlay (bl->section) 
-           && !section_is_mapped (bl->section))
-         continue;
-      }
-
-    /* Continuable hardware watchpoints are treated as non-existent if the
-       reason we stopped wasn't a hardware watchpoint (we didn't stop on
-       some data address).  Otherwise gdb won't stop on a break instruction
-       in the code (not from a breakpoint) when a hardware watchpoint has
-       been defined.  Also skip watchpoints which we know did not trigger
-       (did not match the data address).  */
-
-    if ((b->type == bp_hardware_watchpoint
-        || b->type == bp_read_watchpoint
-        || b->type == bp_access_watchpoint)
-       && b->watchpoint_triggered == watch_triggered_no)
-      continue;
-
-    if (b->type == bp_hardware_breakpoint)
-      {
-       if (bl->address != bp_addr)
-         continue;
-       if (overlay_debugging           /* unmapped overlay section */
-           && section_is_overlay (bl->section) 
-           && !section_is_mapped (bl->section))
-         continue;
-      }
-
-    /* Is this a catchpoint of a load or unload?  If so, did we
-       get a load or unload of the specified library?  If not,
-       ignore it. */
-    if ((b->type == bp_catch_load)
-#if defined(SOLIB_HAVE_LOAD_EVENT)
-       && (!SOLIB_HAVE_LOAD_EVENT (PIDGET (inferior_ptid))
-           || ((b->dll_pathname != NULL)
-               && (strcmp (b->dll_pathname, 
-                           SOLIB_LOADED_LIBRARY_PATHNAME (
-                             PIDGET (inferior_ptid)))
-                   != 0)))
-#endif
-      )
-      continue;
-
-    if ((b->type == bp_catch_unload)
-#if defined(SOLIB_HAVE_UNLOAD_EVENT)
-       && (!SOLIB_HAVE_UNLOAD_EVENT (PIDGET (inferior_ptid))
-           || ((b->dll_pathname != NULL)
-               && (strcmp (b->dll_pathname, 
-                           SOLIB_UNLOADED_LIBRARY_PATHNAME (
-                             PIDGET (inferior_ptid)))
-                   != 0)))
-#endif
-      )
-      continue;
-
-    if ((b->type == bp_catch_fork)
-       && !inferior_has_forked (PIDGET (inferior_ptid),
-                                &b->forked_inferior_pid))
-      continue;
-
-    if ((b->type == bp_catch_vfork)
-       && !inferior_has_vforked (PIDGET (inferior_ptid),
-                                 &b->forked_inferior_pid))
-      continue;
-
-    if ((b->type == bp_catch_exec)
-       && !inferior_has_execd (PIDGET (inferior_ptid), &b->exec_pathname))
-      continue;
-
     /* For hardware watchpoints, we look only at the first location.
        The watchpoint_check function will work on entire expression,
        not the individual locations.  For read watchopints, the
@@ -2778,176 +3033,52 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
     if (b->type == bp_hardware_watchpoint && bl != b->loc)
       continue;
 
+    if (!bpstat_check_location (bl, bp_addr))
+      continue;
+
     /* Come here if it's a watchpoint, or if the break address matches */
 
     bs = bpstat_alloc (bl, bs);        /* Alloc a bpstat to explain stop */
 
-    /* Watchpoints may change this, if not found to have triggered. */
+    /* Assume we stop.  Should we find watchpoint that is not actually
+       triggered, or if condition of breakpoint is false, we'll reset
+       'stop' to 0.  */
     bs->stop = 1;
     bs->print = 1;
 
-    if (b->type == bp_watchpoint
-       || b->type == bp_read_watchpoint
-       || b->type == bp_access_watchpoint
-       || b->type == bp_hardware_watchpoint)
-      {
-       CORE_ADDR addr;
-       struct value *v;
-       int must_check_value = 0;
-
-       if (b->type == bp_watchpoint)
-         /* For a software watchpoint, we must always check the
-            watched value.  */
-         must_check_value = 1;
-       else if (b->watchpoint_triggered == watch_triggered_yes)
-         /* We have a hardware watchpoint (read, write, or access)
-            and the target earlier reported an address watched by
-            this watchpoint.  */
-         must_check_value = 1;
-       else if (b->watchpoint_triggered == watch_triggered_unknown
-                && 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
-            a data address, we can't figure it out.  */
-         must_check_value = 1;
-
-       if (must_check_value)
-         {
-           char *message = xstrprintf ("Error evaluating expression for watchpoint %d\n",
-                                       b->number);
-           struct cleanup *cleanups = make_cleanup (xfree, message);
-           int e = catch_errors (watchpoint_check, bs, message,
-                                 RETURN_MASK_ALL);
-           do_cleanups (cleanups);
-           switch (e)
-             {
-             case WP_DELETED:
-               /* We've already printed what needs to be printed.  */
-               bs->print_it = print_it_done;
-               /* Stop.  */
-               break;
-             case WP_VALUE_CHANGED:
-               if (b->type == bp_read_watchpoint)
-                 {
-                   /* Don't stop: read watchpoints shouldn't fire if
-                      the value has changed.  This is for targets
-                      which cannot set read-only watchpoints.  */
-                   bs->print_it = print_it_noop;
-                   bs->stop = 0;
-                   continue;
-                 }
-               ++(b->hit_count);
-               break;
-             case WP_VALUE_NOT_CHANGED:
-               if (b->type == bp_hardware_watchpoint
-                   || b->type == bp_watchpoint)
-                 {
-                   /* Don't stop: write watchpoints shouldn't fire if
-                      the value hasn't changed.  */
-                   bs->print_it = print_it_noop;
-                   bs->stop = 0;
-                   continue;
-                 }
-               /* Stop.  */
-               ++(b->hit_count);
-               break;
-             default:
-               /* Can't happen.  */
-             case 0:
-               /* Error from catch_errors.  */
-               printf_filtered (_("Watchpoint %d deleted.\n"), b->number);
-               if (b->related_breakpoint)
-                 b->related_breakpoint->disposition = disp_del_at_next_stop;
-               b->disposition = disp_del_at_next_stop;
-               /* We've already printed what needs to be printed.  */
-               bs->print_it = print_it_done;
-               break;
-             }
-         }
-       else    /* must_check_value == 0 */
-         {
-           /* This is a case where some watchpoint(s) triggered, but
-              not at the address of this watchpoint, or else no
-              watchpoint triggered after all.  So don't print
-              anything for this watchpoint.  */
-           bs->print_it = print_it_noop;
-           bs->stop = 0;
-            continue;
-         }
-      }
-    else
-      {
-       /* By definition, an encountered breakpoint is a triggered
-          breakpoint. */
-       ++(b->hit_count);
-      }
+    bpstat_check_watchpoint (bs);
+    if (!bs->stop)
+      continue;
 
-    if (frame_id_p (b->frame_id)
-       && !frame_id_eq (b->frame_id, get_frame_id (get_current_frame ())))
+    if (b->type == bp_thread_event || b->type == bp_overlay_event)
+      /* We do not stop for these.  */
       bs->stop = 0;
     else
+      bpstat_check_breakpoint_conditions (bs, ptid);
+  
+    if (bs->stop)
       {
-       int value_is_zero = 0;
-
-       /* If this is a scope breakpoint, mark the associated
-          watchpoint as triggered so that we will handle the
-          out-of-scope event.  We'll get to the watchpoint next
-          iteration.  */
-       if (b->type == bp_watchpoint_scope)
-         b->related_breakpoint->watchpoint_triggered = watch_triggered_yes;
+       ++(b->hit_count);
 
-       if (bl->cond && bl->owner->disposition != disp_del_at_next_stop)
-         {
-           /* Need to select the frame, with all that implies
-              so that the conditions will have the right context.  */
-           select_frame (get_current_frame ());
-           value_is_zero
-             = catch_errors (breakpoint_cond_eval, (bl->cond),
-                             "Error in testing breakpoint condition:\n",
-                             RETURN_MASK_ALL);
-           /* FIXME-someday, should give breakpoint # */
-           free_all_values ();
-         }
-       if (bl->cond && value_is_zero)
-         {
-           bs->stop = 0;
-           /* Don't consider this a hit.  */
-           --(b->hit_count);
-         }
-       else if (b->thread != -1 && b->thread != thread_id)
-         {
-           bs->stop = 0;
-           /* Don't consider this a hit.  */
-           --(b->hit_count);
-         }
-       else if (b->ignore_count > 0)
+       /* We will stop here */
+       if (b->disposition == disp_disable)
          {
-           b->ignore_count--;
-           annotate_ignore_count_change ();
-           bs->stop = 0;
+           b->enable_state = bp_disabled;
+           update_global_location_list ();
          }
-       else if (b->type == bp_thread_event || b->type == bp_overlay_event)
-         /* We do not stop for these.  */
-         bs->stop = 0;
-       else
+       if (b->silent)
+         bs->print = 0;
+       bs->commands = b->commands;
+       if (bs->commands &&
+           (strcmp ("silent", bs->commands->line) == 0
+            || (xdb_commands && strcmp ("Q", bs->commands->line) == 0)))
          {
-           /* We will stop here */
-           if (b->disposition == disp_disable)
-             b->enable_state = bp_disabled;
-           if (b->silent)
-             bs->print = 0;
-           bs->commands = b->commands;
-           if (bs->commands &&
-               (strcmp ("silent", bs->commands->line) == 0
-                || (xdb_commands && strcmp ("Q", bs->commands->line) == 0)))
-             {
-               bs->commands = bs->commands->next;
-               bs->print = 0;
-             }
-           bs->commands = copy_command_lines (bs->commands);
+           bs->commands = bs->commands->next;
+           bs->print = 0;
          }
+       bs->commands = copy_command_lines (bs->commands);
       }
+
     /* Print nothing for this entry if we dont stop or if we dont print.  */
     if (bs->stop == 0 || bs->print == 0)
       bs->print_it = print_it_noop;
@@ -3036,7 +3167,6 @@ bpstat_what (bpstat bs)
 #define sgl BPSTAT_WHAT_SINGLE
 #define slr BPSTAT_WHAT_SET_LONGJMP_RESUME
 #define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
-#define clrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
 #define sr BPSTAT_WHAT_STEP_RESUME
 #define shl BPSTAT_WHAT_CHECK_SHLIBS
 #define shlr BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
@@ -3061,10 +3191,9 @@ bpstat_what (bpstat bs)
      ordering is:
 
      kc   < clr sgl shl shlr slr sn sr ss
-     sgl  < clrs shl shlr slr sn sr ss
+     sgl  < shl shlr slr sn sr ss
      slr  < err shl shlr sn sr ss
-     clr  < clrs err shl shlr sn sr ss
-     clrs < err shl shlr sn sr ss
+     clr  < err shl shlr sn sr ss
      ss   < shl shlr sn sr
      sn   < shl shlr sr
      shl  < shlr sr
@@ -3075,9 +3204,7 @@ bpstat_what (bpstat bs)
      here.  If you just put the rows and columns in the right order,
      it'd look awfully regular.  We could simply walk the bpstat list
      and choose the highest priority action we find, with a little
-     logic to handle the 'err' cases, and the CLEAR_LONGJMP_RESUME/
-     CLEAR_LONGJMP_RESUME_SINGLE distinction (which breakpoint.h says
-     is messy anyway).  */
+     logic to handle the 'err' cases.  */
 
   /* step_resume entries: a step resume breakpoint overrides another
      breakpoint of signal handling (see comment in wait_for_inferior
@@ -3087,30 +3214,30 @@ bpstat_what (bpstat bs)
     table[(int) class_last][(int) BPSTAT_WHAT_LAST] =
   {
   /*                              old action */
-  /*       kc    ss    sn    sgl    slr   clr    clrs   sr   shl   shlr
+  /*       kc    ss    sn    sgl    slr   clr   sr   shl   shlr
    */
 /*no_effect */
-    {kc, ss, sn, sgl, slr, clr, clrs, sr, shl, shlr},
+    {kc, ss, sn, sgl, slr, clr, sr, shl, shlr},
 /*wp_silent */
-    {ss, ss, sn, ss, ss, ss, ss, sr, shl, shlr},
+    {ss, ss, sn, ss, ss, ss, sr, shl, shlr},
 /*wp_noisy */
-    {sn, sn, sn, sn, sn, sn, sn, sr, shl, shlr},
+    {sn, sn, sn, sn, sn, sn, sr, shl, shlr},
 /*bp_nostop */
-    {sgl, ss, sn, sgl, slr, clrs, clrs, sr, shl, shlr},
+    {sgl, ss, sn, sgl, slr, slr, sr, shl, shlr},
 /*bp_silent */
-    {ss, ss, sn, ss, ss, ss, ss, sr, shl, shlr},
+    {ss, ss, sn, ss, ss, ss, sr, shl, shlr},
 /*bp_noisy */
-    {sn, sn, sn, sn, sn, sn, sn, sr, shl, shlr},
+    {sn, sn, sn, sn, sn, sn, sr, shl, shlr},
 /*long_jump */
-    {slr, ss, sn, slr, slr, err, err, sr, shl, shlr},
+    {slr, ss, sn, slr, slr, err, sr, shl, shlr},
 /*long_resume */
-    {clr, ss, sn, clrs, err, err, err, sr, shl, shlr},
+    {clr, ss, sn, err, err, err, sr, shl, shlr},
 /*step_resume */
-    {sr, sr, sr, sr, sr, sr, sr, sr, sr, sr},
+    {sr, sr, sr, sr, sr, sr, sr, sr, sr},
 /*shlib */
-    {shl, shl, shl, shl, shl, shl, shl, sr, shl, shlr},
+    {shl, shl, shl, shl, shl, shl, sr, shl, shlr},
 /*catch_shlib */
-    {shlr, shlr, shlr, shlr, shlr, shlr, shlr, sr, shlr, shlr}
+    {shlr, shlr, shlr, shlr, shlr, shlr, sr, shlr, shlr}
   };
 
 #undef kc
@@ -3119,7 +3246,6 @@ bpstat_what (bpstat bs)
 #undef sgl
 #undef slr
 #undef clr
-#undef clrs
 #undef err
 #undef sr
 #undef ts
@@ -3393,8 +3519,6 @@ print_one_breakpoint_location (struct breakpoint *b,
     {bp_catch_exec, "catch exec"}
   };
   
-  static char *bpdisps[] =
-  {"del", "dstp", "dis", "keep"};
   static char bpenables[] = "nynny";
   char wrap_indent[80];
   struct ui_stream *stb = ui_out_stream_new (uiout);
@@ -3451,7 +3575,7 @@ print_one_breakpoint_location (struct breakpoint *b,
   if (part_of_multiple)
     ui_out_field_skip (uiout, "disp");
   else
-    ui_out_field_string (uiout, "disp", bpdisps[(int) b->disposition]);
+    ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
 
 
   /* 4 */
@@ -3574,7 +3698,7 @@ print_one_breakpoint_location (struct breakpoint *b,
            annotate_field (4);
            if (header_of_multiple)
              ui_out_field_string (uiout, "addr", "<MULTIPLE>");
-           if (b->loc == NULL || loc->shlib_disabled)
+           else if (b->loc == NULL || loc->shlib_disabled)
              ui_out_field_string (uiout, "addr", "<PENDING>");
            else
              ui_out_field_core_addr (uiout, "addr", loc->address);
@@ -3664,6 +3788,15 @@ print_one_breakpoint_location (struct breakpoint *b,
       print_command_lines (uiout, l, 4);
       do_cleanups (script_chain);
     }
+
+  if (ui_out_is_mi_like_p (uiout) && !part_of_multiple)
+    {
+      if (b->addr_string)
+       ui_out_field_string (uiout, "original-location", b->addr_string);
+      else if (b->exp_string)
+       ui_out_field_string (uiout, "original-location", b->exp_string);
+    }
+       
   do_cleanups (bkpt_chain);
   do_cleanups (old_chain);
 }
@@ -3954,7 +4087,6 @@ set_default_breakpoint (int valid, CORE_ADDR addr, struct symtab *symtab,
       bp_read_watchpoint
       bp_access_watchpoint
       bp_catch_exec
-      bp_longjmp_resume
       bp_catch_fork
       bp_catch_vork */
 
@@ -3968,7 +4100,6 @@ breakpoint_address_is_meaningful (struct breakpoint *bpt)
          && type != bp_read_watchpoint
          && type != bp_access_watchpoint
          && type != bp_catch_exec
-         && type != bp_longjmp_resume
          && type != bp_catch_fork
          && type != bp_catch_vfork);
 }
@@ -4162,18 +4293,6 @@ allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type)
       internal_error (__FILE__, __LINE__, _("unknown breakpoint type"));
     }
 
-  /* Add this breakpoint to the end of the chain.  */
-
-  loc_p = bp_location_chain;
-  if (loc_p == 0)
-    bp_location_chain = loc;
-  else
-    {
-      while (loc_p->global_next)
-       loc_p = loc_p->global_next;
-      loc_p->global_next = loc;
-    }
-
   return loc;
 }
 
@@ -4181,6 +4300,10 @@ static void free_bp_location (struct bp_location *loc)
 {
   if (loc->cond)
     xfree (loc->cond);
+
+  if (loc->function_name)
+    xfree (loc->function_name);
+  
   xfree (loc);
 }
 
@@ -4285,7 +4408,6 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
 
   set_breakpoint_location_function (b->loc);
 
-  check_duplicates (b);
   breakpoints_changed ();
 
   return b;
@@ -4335,20 +4457,10 @@ create_longjmp_breakpoint (char *func_name)
   struct breakpoint *b;
   struct minimal_symbol *m;
 
-  if (func_name == NULL)
-    b = create_internal_breakpoint (0, bp_longjmp_resume);
-  else
-    {
-      if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
-       return;
-      b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
-    }
-
-  b->enable_state = bp_disabled;
-  b->silent = 1;
-  if (func_name)
-    b->addr_string = xstrdup (func_name);
+  if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
+    return;
+  set_momentary_breakpoint_at_pc (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
+  update_global_location_list ();
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
@@ -4356,30 +4468,31 @@ create_longjmp_breakpoint (char *func_name)
    set_longjmp_resume_breakpoint() to figure out where we are going. */
 
 void
-enable_longjmp_breakpoint (void)
+set_longjmp_breakpoint (void)
 {
   struct breakpoint *b;
 
-  ALL_BREAKPOINTS (b)
-    if (b->type == bp_longjmp)
+  if (gdbarch_get_longjmp_target_p (current_gdbarch))
     {
-      b->enable_state = bp_enabled;
-      check_duplicates (b);
+      create_longjmp_breakpoint ("longjmp");
+      create_longjmp_breakpoint ("_longjmp");
+      create_longjmp_breakpoint ("siglongjmp");
+      create_longjmp_breakpoint ("_siglongjmp");
     }
 }
 
+/* Delete all longjmp breakpoints from THREAD.  */
 void
-disable_longjmp_breakpoint (void)
+delete_longjmp_breakpoint (int thread)
 {
-  struct breakpoint *b;
+  struct breakpoint *b, *temp;
 
-  ALL_BREAKPOINTS (b)
-    if (b->type == bp_longjmp
-       || b->type == bp_longjmp_resume)
-    {
-      b->enable_state = bp_disabled;
-      check_duplicates (b);
-    }
+  ALL_BREAKPOINTS_SAFE (b, temp)
+    if (b->type == bp_longjmp)
+      {
+       if (b->thread == thread)
+         delete_breakpoint (b);
+      }
 }
 
 static void
@@ -4405,6 +4518,7 @@ create_overlay_event_breakpoint (char *func_name)
       b->enable_state = bp_disabled;
       overlay_events_enabled = 0;
     }
+  update_global_location_list ();
 }
 
 void
@@ -4416,7 +4530,7 @@ enable_overlay_breakpoints (void)
     if (b->type == bp_overlay_event)
     {
       b->enable_state = bp_enabled;
-      check_duplicates (b);
+      update_global_location_list ();
       overlay_events_enabled = 1;
     }
 }
@@ -4430,7 +4544,7 @@ disable_overlay_breakpoints (void)
     if (b->type == bp_overlay_event)
     {
       b->enable_state = bp_disabled;
-      check_duplicates (b);
+      update_global_location_list ();
       overlay_events_enabled = 0;
     }
 }
@@ -4446,6 +4560,8 @@ create_thread_event_breakpoint (CORE_ADDR address)
   /* addr_string has to be used or breakpoint_re_set will delete me.  */
   b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
 
+  update_global_location_list_nothrow ();
+
   return b;
 }
 
@@ -4490,6 +4606,7 @@ create_solib_event_breakpoint (CORE_ADDR address)
   struct breakpoint *b;
 
   b = create_internal_breakpoint (address, bp_shlib_event);
+  update_global_location_list_nothrow ();
   return b;
 }
 
@@ -4587,6 +4704,8 @@ create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
   b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
   b->forked_inferior_pid = 0;
+  update_global_location_list ();
+
 
   mention (b);
 }
@@ -4624,6 +4743,7 @@ create_exec_event_catchpoint (int tempflag, char *cond_string)
   b->addr_string = NULL;
   b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
+  update_global_location_list ();
 
   mention (b);
 }
@@ -4665,30 +4785,6 @@ hw_watchpoint_used_count (enum bptype type, int *other_type_used)
   return i;
 }
 
-/* Call this after hitting the longjmp() breakpoint.  Use this to set
-   a new breakpoint at the target of the jmp_buf.
-
-   FIXME - This ought to be done by setting a temporary breakpoint
-   that gets deleted automatically... */
-
-void
-set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id)
-{
-  struct breakpoint *b;
-
-  ALL_BREAKPOINTS (b)
-    if (b->type == bp_longjmp_resume)
-    {
-      b->loc->requested_address = pc;
-      b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
-                                                   b->type);
-      b->enable_state = bp_enabled;
-      b->frame_id = frame_id;
-      check_duplicates (b);
-      return;
-    }
-}
-
 void
 disable_watchpoints_before_interactive_call_start (void)
 {
@@ -4703,7 +4799,7 @@ disable_watchpoints_before_interactive_call_start (void)
        && breakpoint_enabled (b))
       {
        b->enable_state = bp_call_disabled;
-       check_duplicates (b);
+       update_global_location_list ();
       }
   }
 }
@@ -4722,7 +4818,7 @@ enable_watchpoints_after_interactive_call_stop (void)
        && (b->enable_state == bp_call_disabled))
       {
        b->enable_state = bp_enabled;
-       check_duplicates (b);
+       update_global_location_list ();
       }
   }
 }
@@ -4748,8 +4844,23 @@ set_momentary_breakpoint (struct symtab_and_line sal, struct frame_id frame_id,
   if (in_thread_list (inferior_ptid))
     b->thread = pid_to_thread_id (inferior_ptid);
 
+  update_global_location_list_nothrow ();
+
   return b;
 }
+
+struct breakpoint *
+set_momentary_breakpoint_at_pc (CORE_ADDR pc, enum bptype type)
+{
+  struct symtab_and_line sal;
+
+  sal = find_pc_line (pc, 0);
+  sal.pc = pc;
+  sal.section = find_pc_overlay (pc);
+  sal.explicit_pc = 1;
+
+  return set_momentary_breakpoint (sal, null_frame_id, type);
+}
 \f
 
 /* Tell the user we have just set a breakpoint B.  */
@@ -4823,7 +4934,11 @@ mention (struct breakpoint *b)
            say_where = 0;
            break;
          }
-       printf_filtered (_("Breakpoint %d"), b->number);
+       if (b->disposition == disp_del)
+         printf_filtered (_("Temporary breakpoint"));
+       else
+         printf_filtered (_("Breakpoint"));
+       printf_filtered (_(" %d"), b->number);
        say_where = 1;
        break;
       case bp_hardware_breakpoint:
@@ -4931,7 +5046,8 @@ static void
 create_breakpoint (struct symtabs_and_lines sals, char *addr_string,
                   char *cond_string,
                   enum bptype type, enum bpdisp disposition,
-                  int thread, int ignore_count, int from_tty)
+                  int thread, int ignore_count, 
+                  struct breakpoint_ops *ops, int from_tty)
 {
   struct breakpoint *b = NULL;
   int i;
@@ -4991,6 +5107,7 @@ create_breakpoint (struct symtabs_and_lines sals, char *addr_string,
        me.  */
     b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
 
+  b->ops = ops;
   mention (b);
 }
 
@@ -5135,7 +5252,8 @@ static void
 create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
                    char *cond_string,
                    enum bptype type, enum bpdisp disposition,
-                   int thread, int ignore_count, int from_tty)
+                   int thread, int ignore_count, 
+                   struct breakpoint_ops *ops, int from_tty)
 {
   int i;
   for (i = 0; i < sals.nelts; ++i)
@@ -5145,8 +5263,10 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
 
       create_breakpoint (expanded, addr_string[i],
                         cond_string, type, disposition,
-                        thread, ignore_count, from_tty);
+                        thread, ignore_count, ops, from_tty);
     }
+
+  update_global_location_list ();
 }
 
 /* Parse ARG which is assumed to be a SAL specification possibly
@@ -5311,6 +5431,7 @@ break_command_really (char *arg, char *cond_string, int thread,
                      int tempflag, int hardwareflag, 
                      int ignore_count,
                      enum auto_boolean pending_break_support,
+                     struct breakpoint_ops *ops,
                      int from_tty)
 {
   struct gdb_exception e;
@@ -5419,7 +5540,7 @@ break_command_really (char *arg, char *cond_string, int thread,
      breakpoint. */
   if (!pending)
     {
-        if (parse_condition_and_thread)
+      if (parse_condition_and_thread)
         {
             /* Here we only parse 'arg' to separate condition
                from thread number, so parsing in context of first
@@ -5431,7 +5552,7 @@ break_command_really (char *arg, char *cond_string, int thread,
             if (cond_string)
                 make_cleanup (xfree, cond_string);
         }
-        else
+      else
         {
             /* Create a private copy of condition string.  */
             if (cond_string)
@@ -5444,7 +5565,7 @@ break_command_really (char *arg, char *cond_string, int thread,
                          hardwareflag ? bp_hardware_breakpoint 
                          : bp_breakpoint,
                          tempflag ? disp_del : disp_donttouch,
-                         thread, ignore_count, from_tty);
+                         thread, ignore_count, ops, from_tty);
     }
   else
     {
@@ -5464,6 +5585,9 @@ break_command_really (char *arg, char *cond_string, int thread,
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
+      b->ops = ops;
+
+      update_global_location_list ();
       mention (b);
     }
   
@@ -5494,7 +5618,9 @@ break_command_1 (char *arg, int flag, int from_tty)
                        NULL, 0, 1 /* parse arg */,
                        tempflag, hardwareflag,
                        0 /* Ignore count */,
-                       pending_break_support, from_tty);
+                       pending_break_support, 
+                       NULL /* breakpoint_ops */,
+                       from_tty);
 }
 
 
@@ -5510,7 +5636,7 @@ set_breakpoint (char *address, char *condition,
                        ignore_count,
                        pending 
                        ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
-                       0);
+                       NULL, 0);
 }
 
 /* Adjust SAL to the first instruction past the function prologue.
@@ -5890,6 +6016,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
 
   value_free_to_mark (mark);
   mention (b);
+  update_global_location_list ();
 }
 
 /* Return count of locations need to be watched and can be handled
@@ -6014,12 +6141,11 @@ awatch_command (char *arg, int from_tty)
    care of cleaning up the temporary breakpoints set up by the until
    command. */
 static void
-until_break_command_continuation (struct continuation_arg *arg)
+until_break_command_continuation (struct continuation_arg *arg, int error)
 {
-  struct cleanup *cleanups;
-
-  cleanups = (struct cleanup *) arg->data.pointer;
-  do_exec_cleanups (cleanups);
+  delete_breakpoint ((struct breakpoint *)(arg->data.pointer));
+  if (arg->next)
+    delete_breakpoint ((struct breakpoint *)(arg->next->data.pointer));
 }
 
 void
@@ -6030,8 +6156,10 @@ until_break_command (char *arg, int from_tty, int anywhere)
   struct frame_info *frame = get_selected_frame (NULL);
   struct frame_info *prev_frame = get_prev_frame (frame);
   struct breakpoint *breakpoint;
+  struct breakpoint *breakpoint2 = NULL;
   struct cleanup *old_chain;
   struct continuation_arg *arg1;
+  struct continuation_arg *arg2;
 
 
   clear_proceed_status ();
@@ -6067,31 +6195,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
     breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame),
                                           bp_until);
 
-  if (!target_can_async_p ())
-    old_chain = make_cleanup_delete_breakpoint (breakpoint);
-  else
-    old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
-
-  /* If we are running asynchronously, and the target supports async
-     execution, we are not waiting for the target to stop, in the call
-     tp proceed, below. This means that we cannot delete the
-     brekpoints until the target has actually stopped. The only place
-     where we get a chance to do that is in fetch_inferior_event, so
-     we must set things up for that. */
-
-  if (target_can_async_p ())
-    {
-      /* In this case the arg for the continuation is just the point
-         in the exec_cleanups chain from where to start doing
-         cleanups, because all the continuation does is the cleanups in
-         the exec_cleanup_chain. */
-      arg1 =
-       (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
-      arg1->next         = NULL;
-      arg1->data.pointer = old_chain;
-
-      add_continuation (until_break_command_continuation, arg1);
-    }
+  old_chain = make_cleanup_delete_breakpoint (breakpoint);
 
   /* Keep within the current frame, or in frames called by the current
      one.  */
@@ -6099,18 +6203,38 @@ until_break_command (char *arg, int from_tty, int anywhere)
     {
       sal = find_pc_line (get_frame_pc (prev_frame), 0);
       sal.pc = get_frame_pc (prev_frame);
-      breakpoint = set_momentary_breakpoint (sal, get_frame_id (prev_frame),
-                                            bp_until);
-      if (!target_can_async_p ())
-       make_cleanup_delete_breakpoint (breakpoint);
-      else
-       make_exec_cleanup_delete_breakpoint (breakpoint);
+      breakpoint2 = set_momentary_breakpoint (sal, get_frame_id (prev_frame),
+                                             bp_until);
+      make_cleanup_delete_breakpoint (breakpoint2);
     }
 
   proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
-  /* Do the cleanups now, anly if we are not running asynchronously,
-     of if we are, but the target is still synchronous. */
-  if (!target_can_async_p ())
+
+  /* If we are running asynchronously, and proceed call above has actually
+     managed to start the target, arrange for breakpoints to be
+     deleted when the target stops.  Otherwise, we're already stopped and
+     delete breakpoints via cleanup chain.  */
+
+  if (target_can_async_p () && target_executing)
+    {
+      arg1 =
+       (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+      arg1->next         = NULL;
+      arg1->data.pointer = breakpoint;
+
+      if (breakpoint2)
+       {
+         arg2 = (struct continuation_arg *)
+           xmalloc ( sizeof (struct continuation_arg));
+         arg2->next         = NULL;
+         arg2->data.pointer = breakpoint2;
+         arg1->next = arg2;       
+       }
+
+      discard_cleanups (old_chain);
+      add_continuation (until_break_command_continuation, arg1);
+    }
+  else
     do_cleanups (old_chain);
 }
 
@@ -6371,15 +6495,31 @@ catch_unload_command_1 (char *arg, int tempflag, int from_tty)
 static enum print_stop_action
 print_exception_catchpoint (struct breakpoint *b)
 {
-  annotate_catchpoint (b->number);
+  int bp_temp, bp_throw;
 
-  if (strstr (b->addr_string, "throw") != NULL)
-    printf_filtered (_("\nCatchpoint %d (exception thrown)\n"),
-                    b->number);
-  else
-    printf_filtered (_("\nCatchpoint %d (exception caught)\n"),
-                    b->number);
+  annotate_catchpoint (b->number);
 
+  bp_throw = strstr (b->addr_string, "throw") != NULL;
+  if (b->loc->address != b->loc->requested_address)
+    breakpoint_adjustment_warning (b->loc->requested_address,
+                                  b->loc->address,
+                                  b->number, 1);
+  bp_temp = b->loc->owner->disposition == disp_del;
+  ui_out_text (uiout, 
+              bp_temp ? "Temporary catchpoint "
+                      : "Catchpoint ");
+  if (!ui_out_is_mi_like_p (uiout))
+    ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout,
+              bp_throw ? " (exception thrown), "
+                       : " (exception caught), ");
+  if (ui_out_is_mi_like_p (uiout))
+    {
+      ui_out_field_string (uiout, "reason", 
+                          async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      ui_out_field_int (uiout, "bkptno", b->number);
+    }
   return PRINT_SRC_AND_LOC;
 }
 
@@ -6389,10 +6529,14 @@ print_one_exception_catchpoint (struct breakpoint *b, CORE_ADDR *last_addr)
   if (addressprint)
     {
       annotate_field (4);
-      ui_out_field_core_addr (uiout, "addr", b->loc->address);
+      if (b->loc == NULL || b->loc->shlib_disabled)
+       ui_out_field_string (uiout, "addr", "<PENDING>");
+      else
+       ui_out_field_core_addr (uiout, "addr", b->loc->address);
     }
   annotate_field (5);
-  *last_addr = b->loc->address;
+  if (b->loc)
+    *last_addr = b->loc->address;
   if (strstr (b->addr_string, "throw") != NULL)
     ui_out_field_string (uiout, "what", "exception throw");
   else
@@ -6402,10 +6546,16 @@ print_one_exception_catchpoint (struct breakpoint *b, CORE_ADDR *last_addr)
 static void
 print_mention_exception_catchpoint (struct breakpoint *b)
 {
-  if (strstr (b->addr_string, "throw") != NULL)
-    printf_filtered (_("Catchpoint %d (throw)"), b->number);
-  else
-    printf_filtered (_("Catchpoint %d (catch)"), b->number);
+  int bp_temp;
+  int bp_throw;
+
+  bp_temp = b->loc->owner->disposition == disp_del;
+  bp_throw = strstr (b->addr_string, "throw") != NULL;
+  ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ")
+                             : _("Catchpoint "));
+  ui_out_field_int (uiout, "bkptno", b->number);
+  ui_out_text (uiout, bp_throw ? _(" (throw)")
+                              : _(" (catch)"));
 }
 
 static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
@@ -6418,36 +6568,20 @@ static int
 handle_gnu_v3_exceptions (int tempflag, char *cond_string,
                          enum exception_event_kind ex_event, int from_tty)
 {
-  char *trigger_func_name, *nameptr;
-  struct symtabs_and_lines sals;
-  struct breakpoint *b;
-
+  char *trigger_func_name;
   if (ex_event == EX_EVENT_CATCH)
-    trigger_func_name = xstrdup ("__cxa_begin_catch");
+    trigger_func_name = "__cxa_begin_catch";
   else
-    trigger_func_name = xstrdup ("__cxa_throw");
-
-  nameptr = trigger_func_name;
-  sals = decode_line_1 (&nameptr, 1, NULL, 0, NULL, NULL);
-  if (sals.nelts == 0)
-    {
-      xfree (trigger_func_name);
-      return 0;
-    }
+    trigger_func_name = "__cxa_throw";
 
-  b = set_raw_breakpoint (sals.sals[0], bp_breakpoint);
-  set_breakpoint_count (breakpoint_count + 1);
-  b->number = breakpoint_count;
-  b->cond_string = (cond_string == NULL) ? 
-    NULL : savestring (cond_string, strlen (cond_string));
-  b->thread = -1;
-  b->addr_string = trigger_func_name;
-  b->enable_state = bp_enabled;
-  b->disposition = tempflag ? disp_del : disp_donttouch;
-  b->ops = &gnu_v3_exception_catchpoint_ops;
+  break_command_really (trigger_func_name, cond_string, -1,
+                       0 /* condition and thread are valid.  */,
+                       tempflag, 0,
+                       0,
+                       AUTO_BOOLEAN_TRUE /* pending */,
+                       &gnu_v3_exception_catchpoint_ops, from_tty);
 
-  xfree (sals.sals);
-  mention (b);
   return 1;
 }
 
@@ -6520,6 +6654,7 @@ create_ada_exception_breakpoint (struct symtab_and_line sal,
   b->ops = ops;
 
   mention (b);
+  update_global_location_list ();
 }
 
 /* Implement the "catch exception" command.  */
@@ -6841,33 +6976,124 @@ breakpoint_auto_delete (bpstat bs)
   }
 }
 
-/* Remove locations of breakpoint BPT from
-   the global list of breakpoint locations.  */
-
 static void
-unlink_locations_from_global_list (struct breakpoint *bpt)
+update_global_location_list (void)
 {
-  /* This code assumes that the locations
-     of a breakpoint are found in the global list
-     in the same order,  but not necessary adjacent.  */
-  struct bp_location **tmp = &bp_location_chain;
-  struct bp_location *here = bpt->loc;
-
-  if (here == NULL)
-    return;
+  struct breakpoint *b;
+  struct bp_location **next = &bp_location_chain;
+  struct bp_location *loc;
+  struct bp_location *loc2;
+  struct gdb_exception e;
+  VEC(bp_location_p) *old_locations = NULL;
+  int ret;
+  int ix;
+  
+  /* Store old locations for future reference.  */
+  for (loc = bp_location_chain; loc; loc = loc->global_next)
+    VEC_safe_push (bp_location_p, old_locations, loc);
 
-  for (; *tmp && here;)
+  bp_location_chain = NULL;
+  ALL_BREAKPOINTS (b)
     {
-      if (*tmp == here)
+      for (loc = b->loc; loc; loc = loc->next)
        {
-         *tmp = here->global_next;
-         here = here->next;
+         *next = loc;
+         next = &(loc->global_next);
+         *next = NULL;
        }
-      else
+    }
+
+  /* Identify bp_location instances that are no longer present in the new
+     list, and therefore should be freed.  Note that it's not necessary that
+     those locations should be removed from inferior -- if there's another
+     location at the same address (previously marked as duplicate),
+     we don't need to remove/insert the location.  */
+  for (ix = 0; VEC_iterate(bp_location_p, old_locations, ix, loc); ++ix)
+    {
+      /* Tells if 'loc' is found amoung the new locations.  If not, we
+        have to free it.  */
+      int found_object = 0;
+      for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next)
+       if (loc2 == loc)
+         {
+           found_object = 1;
+           break;
+         }
+
+      /* If this location is no longer present, and inserted, look if there's
+        maybe a new location at the same address.  If so, mark that one 
+        inserted, and don't remove this one.  This is needed so that we 
+        don't have a time window where a breakpoint at certain location is not
+        inserted.  */
+
+      if (loc->inserted)
        {
-         tmp = &((*tmp)->global_next);
+         /* If the location is inserted now, we might have to remove it.  */
+         int keep = 0;
+
+         if (found_object && should_be_inserted (loc))
+           {
+             /* The location is still present in the location list, and still
+                should be inserted.  Don't do anything.  */
+             keep = 1;
+           }
+         else
+           {
+             /* The location is either no longer present, or got disabled.
+                See if there's another location at the same address, in which 
+                case we don't need to remove this one from the target.  */
+             if (breakpoint_address_is_meaningful (loc->owner))
+               for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next)
+                 {
+                   /* For the sake of should_insert_location.  The
+                      call to check_duplicates will fix up this later.  */
+                   loc2->duplicate = 0;
+                   if (should_be_inserted (loc2)
+                       && loc2 != loc && loc2->address == loc->address)
+                     {           
+                       loc2->inserted = 1;
+                       loc2->target_info = loc->target_info;
+                       keep = 1;
+                       break;
+                     }
+                 }
+           }
+
+         if (!keep)
+           if (remove_breakpoint (loc, mark_uninserted))
+             {
+               /* This is just about all we can do.  We could keep this
+                  location on the global list, and try to remove it next
+                  time, but there's no particular reason why we will
+                  succeed next time.  
+
+                  Note that at this point, loc->owner is still valid,
+                  as delete_breakpoint frees the breakpoint only
+                  after calling us.  */
+               printf_filtered (_("warning: Error removing breakpoint %d\n"), 
+                                loc->owner->number);
+             }
        }
+
+      if (!found_object)
+       free_bp_location (loc);
+    }
+    
+  ALL_BREAKPOINTS (b)
+    {
+      check_duplicates (b);
     }
+
+  if (always_inserted_mode && target_has_execution)
+    insert_breakpoint_locations ();
+}
+
+static void
+update_global_location_list_nothrow (void)
+{
+  struct gdb_exception e;
+  TRY_CATCH (e, RETURN_MASK_ERROR)
+    update_global_location_list ();
 }
 
 /* Delete a breakpoint and clean up all traces of it in the data
@@ -6878,7 +7104,7 @@ delete_breakpoint (struct breakpoint *bpt)
 {
   struct breakpoint *b;
   bpstat bs;
-  struct bp_location *loc;
+  struct bp_location *loc, *next;
 
   gdb_assert (bpt != NULL);
 
@@ -6902,18 +7128,6 @@ delete_breakpoint (struct breakpoint *bpt)
     deprecated_delete_breakpoint_hook (bpt);
   breakpoint_delete_event (bpt->number);
 
-  for (loc = bpt->loc; loc; loc = loc->next)
-    {
-      if (loc->inserted)
-       remove_breakpoint (loc, mark_inserted);
-      
-      if (loc->cond)
-       xfree (loc->cond);
-
-      if (loc->function_name)
-       xfree (loc->function_name);
-    }
-
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
 
@@ -6924,85 +7138,6 @@ delete_breakpoint (struct breakpoint *bpt)
       break;
     }
 
-  unlink_locations_from_global_list (bpt);
-
-  check_duplicates (bpt);
-
-  if (bpt->type != bp_hardware_watchpoint
-      && bpt->type != bp_read_watchpoint
-      && bpt->type != bp_access_watchpoint
-      && bpt->type != bp_catch_fork
-      && bpt->type != bp_catch_vfork
-      && bpt->type != bp_catch_exec)
-    for (loc = bpt->loc; loc; loc = loc->next)
-      {
-       /* If this breakpoint location was inserted, and there is 
-          another breakpoint at the same address, we need to 
-          insert the other breakpoint.  */
-       if (loc->inserted)
-         {
-           struct bp_location *loc2;
-           ALL_BP_LOCATIONS (loc2)
-             if (loc2->address == loc->address
-                 && loc2->section == loc->section
-                 && !loc->duplicate
-                 && loc2->owner->enable_state != bp_disabled
-                 && loc2->enabled 
-                 && !loc2->shlib_disabled
-                 && loc2->owner->enable_state != bp_call_disabled)
-               {
-                 int val;
-
-                 /* We should never reach this point if there is a permanent
-                    breakpoint at the same address as the one being deleted.
-                    If there is a permanent breakpoint somewhere, it should
-                    always be the only one inserted.  */
-                 if (loc2->owner->enable_state == bp_permanent)
-                   internal_error (__FILE__, __LINE__,
-                                   _("another breakpoint was inserted on top of "
-                                     "a permanent breakpoint"));
-
-                 memset (&loc2->target_info, 0, sizeof (loc2->target_info));
-                 loc2->target_info.placed_address = loc2->address;
-                 if (b->type == bp_hardware_breakpoint)
-                   val = target_insert_hw_breakpoint (&loc2->target_info);
-                 else
-                   val = target_insert_breakpoint (&loc2->target_info);
-
-                 /* If there was an error in the insert, print a message, then stop execution.  */
-                 if (val != 0)
-                   {
-                     struct ui_file *tmp_error_stream = mem_fileopen ();
-                     make_cleanup_ui_file_delete (tmp_error_stream);
-                     
-                     
-                     if (b->type == bp_hardware_breakpoint)
-                       {
-                         fprintf_unfiltered (tmp_error_stream, 
-                                             "Cannot insert hardware breakpoint %d.\n"
-                                             "You may have requested too many hardware breakpoints.\n",
-                                             b->number);
-                       }
-                     else
-                       {
-                         fprintf_unfiltered (tmp_error_stream, "Cannot insert breakpoint %d.\n", b->number);
-                         fprintf_filtered (tmp_error_stream, "Error accessing memory address ");
-                         fputs_filtered (paddress (loc2->address),
-                                         tmp_error_stream);
-                         fprintf_filtered (tmp_error_stream, ": %s.\n",
-                                           safe_strerror (val));
-                       }
-                     
-                     fprintf_unfiltered (tmp_error_stream,"The same program may be running in another process.");
-                     target_terminal_ours_for_output ();
-                     error_stream(tmp_error_stream); 
-                   }
-                 else
-                   loc2->inserted = 1;
-               }
-         }
-      }
-
   free_command_lines (&bpt->commands);
   if (bpt->cond_string != NULL)
     xfree (bpt->cond_string);
@@ -7039,16 +7174,22 @@ delete_breakpoint (struct breakpoint *bpt)
        bs->old_val = NULL;
        /* bs->commands will be freed later.  */
       }
+
+  /* Now that breakpoint is removed from breakpoint
+     list, update the global location list.  This
+     will remove locations that used to belong to
+     this breakpoint.  Do this before freeing
+     the breakpoint itself, since remove_breakpoint
+     looks at location's owner.  It might be better
+     design to have location completely self-contained,
+     but it's not the case now.  */
+  update_global_location_list ();
+
+
   /* 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;
 
-  for (loc = bpt->loc; loc;)
-    {
-      struct bp_location *loc_next = loc->next;
-      xfree (loc);
-      loc = loc_next;
-    }
   xfree (bpt);
 }
 
@@ -7064,12 +7205,6 @@ make_cleanup_delete_breakpoint (struct breakpoint *b)
   return make_cleanup (do_delete_breakpoint_cleanup, b);
 }
 
-struct cleanup *
-make_exec_cleanup_delete_breakpoint (struct breakpoint *b)
-{
-  return make_exec_cleanup (do_delete_breakpoint_cleanup, b);
-}
-
 void
 delete_command (char *arg, int from_tty)
 {
@@ -7180,7 +7315,6 @@ update_breakpoint_locations (struct breakpoint *b,
   if (all_locations_are_pending (existing_locations) && sals.nelts == 0)
     return;
 
-  unlink_locations_from_global_list (b);
   b->loc = NULL;
 
   for (i = 0; i < sals.nelts; ++i)
@@ -7259,12 +7393,7 @@ update_breakpoint_locations (struct breakpoint *b,
       }
   }
 
-  while (existing_locations)
-    {
-      struct bp_location *next = existing_locations->next;
-      free_bp_location (existing_locations);
-      existing_locations = next;
-    }
+  update_global_location_list ();
 }
 
 
@@ -7360,10 +7489,6 @@ breakpoint_re_set_one (void *bint)
       expanded = expand_line_sal_maybe (sals.sals[0]);
       update_breakpoint_locations (b, expanded);
 
-      /* Now that this is re-enabled, check_duplicates
-        can be used. */
-      check_duplicates (b);
-
       xfree (sals.sals);
       break;
 
@@ -7409,10 +7534,8 @@ breakpoint_re_set_one (void *bint)
     default:
       printf_filtered (_("Deleting unknown breakpoint type %d\n"), b->type);
       /* fall through */
-      /* Delete longjmp and overlay event breakpoints; they will be
-         reset later by breakpoint_re_set.  */
-    case bp_longjmp:
-    case bp_longjmp_resume:
+      /* Delete overlay event breakpoints; they will be reset later by
+         breakpoint_re_set.  */
     case bp_overlay_event:
       delete_breakpoint (b);
       break;
@@ -7434,6 +7557,8 @@ breakpoint_re_set_one (void *bint)
     case bp_watchpoint_scope:
     case bp_call_dummy:
     case bp_step_resume:
+    case bp_longjmp:
+    case bp_longjmp_resume:
       break;
     }
 
@@ -7461,15 +7586,6 @@ breakpoint_re_set (void)
   }
   set_language (save_language);
   input_radix = save_input_radix;
-
-  if (gdbarch_get_longjmp_target_p (current_gdbarch))
-    {
-      create_longjmp_breakpoint ("longjmp");
-      create_longjmp_breakpoint ("_longjmp");
-      create_longjmp_breakpoint ("siglongjmp");
-      create_longjmp_breakpoint ("_siglongjmp");
-      create_longjmp_breakpoint (NULL);
-    }
   
   create_overlay_event_breakpoint ("_ovly_debug_event");
 }
@@ -7663,7 +7779,7 @@ disable_breakpoint (struct breakpoint *bpt)
 
   bpt->enable_state = bp_disabled;
 
-  check_duplicates (bpt);
+  update_global_location_list ();
 
   if (deprecated_modify_breakpoint_hook)
     deprecated_modify_breakpoint_hook (bpt);
@@ -7702,7 +7818,7 @@ disable_command (char *args, int from_tty)
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
        loc->enabled = 0;
-      check_duplicates (loc->owner);
+      update_global_location_list ();
     }
   else
     map_breakpoint_numbers (args, disable_breakpoint);
@@ -7787,7 +7903,7 @@ have been allocated for other watchpoints.\n"), bpt->number);
   if (bpt->enable_state != bp_permanent)
     bpt->enable_state = bp_enabled;
   bpt->disposition = disposition;
-  check_duplicates (bpt);
+  update_global_location_list ();
   breakpoints_changed ();
   
   if (deprecated_modify_breakpoint_hook)
@@ -7838,7 +7954,7 @@ enable_command (char *args, int from_tty)
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
        loc->enabled = 1;
-      check_duplicates (loc->owner);
+      update_global_location_list ();
     }
   else
     map_breakpoint_numbers (args, enable_breakpoint);
@@ -8006,6 +8122,11 @@ single_step_breakpoint_inserted_here_p (CORE_ADDR pc)
   return 0;
 }
 
+int breakpoints_always_inserted_mode (void)
+{
+  return always_inserted_mode;
+}
+
 \f
 /* This help string is used for the break, hbreak, tbreak and thbreak commands.
    It is defined as a macro to prevent duplication.
@@ -8334,19 +8455,19 @@ by using \"enable delete\" on the catchpoint number."));
 Set a watchpoint for an expression.\n\
 A watchpoint stops execution of your program whenever the value of\n\
 an expression changes."));
-  set_cmd_completer (c, location_completer);
+  set_cmd_completer (c, expression_completer);
 
   c = add_com ("rwatch", class_breakpoint, rwatch_command, _("\
 Set a read watchpoint for an expression.\n\
 A watchpoint stops execution of your program whenever the value of\n\
 an expression is read."));
-  set_cmd_completer (c, location_completer);
+  set_cmd_completer (c, expression_completer);
 
   c = add_com ("awatch", class_breakpoint, awatch_command, _("\
 Set a watchpoint for an expression.\n\
 A watchpoint stops execution of your program whenever the value of\n\
 an expression is either read or written."));
-  set_cmd_completer (c, location_completer);
+  set_cmd_completer (c, expression_completer);
 
   add_info ("watchpoints", breakpoints_info,
            _("Synonym for ``info breakpoints''."));
@@ -8407,6 +8528,19 @@ a warning will be emitted for such breakpoints."),
                           show_automatic_hardware_breakpoints,
                           &breakpoint_set_cmdlist,
                           &breakpoint_show_cmdlist);
+
+  add_setshow_boolean_cmd ("always-inserted", class_support,
+                          &always_inserted_mode, _("\
+Set mode for inserting breakpoints."), _("\
+Show mode for inserting breakpoints."), _("\
+When this mode is off (which is the default), breakpoints are inserted in\n\
+inferior when it is resumed, and removed when execution stops.  When this\n\
+mode is on, breakpoints are inserted immediately and removed only when\n\
+the user deletes the breakpoint."),
+                          NULL,
+                          &show_always_inserted_mode,
+                          &breakpoint_set_cmdlist,
+                          &breakpoint_show_cmdlist);
   
   automatic_hardware_breakpoints = 1;
 }
This page took 0.051342 seconds and 4 git commands to generate.