* rs6000-tdep.c (BL_MASK, BL_INSTRUCTION, BL_DISPLACEMENT_MASK):
[deliverable/binutils-gdb.git] / gdb / breakpoint.c
index 73d962cc945d097e5c44dc0d51a1483a5bf5d7d1..2a10d619c9e1da9f6a8b37f6f58cfaf5deb5facd 100644 (file)
 #include "top.h"
 #include "wrapper.h"
 
-#include "gdb-events.h"
 #include "mi/mi-common.h"
 
 /* Prototypes for local functions. */
 
-static void until_break_command_continuation (struct continuation_arg *arg, 
-                                             int error);
-
 static void catch_command_1 (char *, int, int);
 
 static void enable_delete_command (char *, int);
@@ -188,14 +184,12 @@ static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc);
 
 static void free_bp_location (struct bp_location *loc);
 
-static void mark_breakpoints_out (void);
-
 static struct bp_location *
 allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type);
 
-static void update_global_location_list (void);
+static void update_global_location_list (int);
 
-static void update_global_location_list_nothrow (void);
+static void update_global_location_list_nothrow (int);
 
 static int is_hardware_watchpoint (struct breakpoint *bpt);
 
@@ -624,7 +618,7 @@ condition_command (char *arg, int from_tty)
              }
          }
        breakpoints_changed ();
-       breakpoint_modify_event (b->number);
+       observer_notify_breakpoint_modified (b->number);
        return;
       }
 
@@ -663,7 +657,7 @@ commands_command (char *arg, int from_tty)
        free_command_lines (&b->commands);
        b->commands = l;
        breakpoints_changed ();
-       breakpoint_modify_event (b->number);
+       observer_notify_breakpoint_modified (b->number);
        return;
     }
   error (_("No breakpoint number %d."), bnum);
@@ -709,7 +703,7 @@ commands_from_control_command (char *arg, struct command_line *cmd)
           list after it finishes execution.  */
        b->commands = copy_command_lines (cmd->body_list[0]);
        breakpoints_changed ();
-       breakpoint_modify_event (b->number);
+       observer_notify_breakpoint_modified (b->number);
        return simple_control;
       }
   error (_("No breakpoint number %d."), bnum);
@@ -1266,7 +1260,7 @@ insert_breakpoints (void)
     if (is_hardware_watchpoint (bpt))
       update_watchpoint (bpt, 0 /* don't reparse. */);
 
-  update_global_location_list ();
+  update_global_location_list (1);
 
   if (!always_inserted_mode && target_has_execution)
     /* update_global_location_list does not insert breakpoints
@@ -1326,7 +1320,7 @@ insert_breakpoint_locations (void)
       if (!is_hardware_watchpoint (bpt))
        continue;
 
-      if (bpt->enable_state != bp_enabled)
+      if (!breakpoint_enabled (bpt))
        continue;
 
       if (bpt->disposition == disp_del_at_next_stop)
@@ -1443,18 +1437,18 @@ 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_integer (&always_inserted_mode);
-  always_inserted_mode = 0;
+  struct bp_location *bploc;
+
+  /* We're about to delete breakpoints from GDB's lists.  If the
+     INSERTED flag is true, GDB will try to lift the breakpoints by
+     writing the breakpoints' "shadow contents" back into memory.  The
+     "shadow contents" are NOT valid after an exec, so GDB should not
+     do that.  Instead, the target is responsible from marking
+     breakpoints out as soon as it detects an exec.  We don't do that
+     here instead, because there may be other attempts to delete
+     breakpoints after detecting an exec and before reaching here.  */
+  ALL_BP_LOCATIONS (bploc)
+    gdb_assert (!bploc->inserted);
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
@@ -1545,7 +1539,6 @@ 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
@@ -1699,7 +1692,7 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is)
 
 /* Clear the "inserted" flag in all breakpoints.  */
 
-static void
+void
 mark_breakpoints_out (void)
 {
   struct bp_location *bpt;
@@ -1996,7 +1989,10 @@ bpstat_copy (bpstat bs)
       if (bs->commands != NULL)
        tmp->commands = copy_command_lines (bs->commands);
       if (bs->old_val != NULL)
-       tmp->old_val = value_copy (bs->old_val);
+       {
+         tmp->old_val = value_copy (bs->old_val);
+         release_value (tmp->old_val);
+       }
 
       if (p == NULL)
        /* This is the first thing in the chain.  */
@@ -2316,7 +2312,7 @@ print_it_typical (bpstat bs)
       annotate_catchpoint (b->number);
       printf_filtered (_("\nCatchpoint %d (forked process %d), "),
                       b->number, 
-                      b->forked_inferior_pid);
+                      ptid_get_pid (b->forked_inferior_pid));
       return PRINT_SRC_AND_LOC;
       break;
 
@@ -2324,7 +2320,7 @@ print_it_typical (bpstat bs)
       annotate_catchpoint (b->number);
       printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
                       b->number, 
-                      b->forked_inferior_pid);
+                      ptid_get_pid (b->forked_inferior_pid));
       return PRINT_SRC_AND_LOC;
       break;
 
@@ -2654,7 +2650,8 @@ watchpoint_check (void *p)
       /* If we've gotten confused in the unwinder, we might have
         returned a frame that can't describe this variable.  */
       if (within_current_scope
-         && block_function (b->exp_valid_block) != get_frame_function (fr))
+         && (block_linkage_function (b->exp_valid_block)
+             != get_frame_function (fr)))
        within_current_scope = 0;
 
       /* in_function_epilogue_p() returns a non-zero value if we're still
@@ -2816,17 +2813,17 @@ bpstat_check_location (const struct bp_location *bl, CORE_ADDR bp_addr)
     return 0;
 
   if ((b->type == bp_catch_fork)
-      && !inferior_has_forked (PIDGET (inferior_ptid),
+      && !inferior_has_forked (inferior_ptid,
                               &b->forked_inferior_pid))
     return 0;
   
   if ((b->type == bp_catch_vfork)
-      && !inferior_has_vforked (PIDGET (inferior_ptid),
+      && !inferior_has_vforked (inferior_ptid,
                                &b->forked_inferior_pid))
     return 0;
   
   if ((b->type == bp_catch_exec)
-      && !inferior_has_execd (PIDGET (inferior_ptid), &b->exec_pathname))
+      && !inferior_has_execd (inferior_ptid, &b->exec_pathname))
     return 0;
 
   return 1;
@@ -3062,7 +3059,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
        if (b->disposition == disp_disable)
          {
            b->enable_state = bp_disabled;
-           update_global_location_list ();
+           update_global_location_list (0);
          }
        if (b->silent)
          bs->print = 0;
@@ -3672,10 +3669,11 @@ print_one_breakpoint_location (struct breakpoint *b,
        if (addressprint)
          ui_out_field_skip (uiout, "addr");
        annotate_field (5);
-       if (b->forked_inferior_pid != 0)
+       if (!ptid_equal (b->forked_inferior_pid, null_ptid))
          {
            ui_out_text (uiout, "process ");
-           ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+           ui_out_field_int (uiout, "what",
+                             ptid_get_pid (b->forked_inferior_pid));
            ui_out_spaces (uiout, 1);
          }
        break;
@@ -4344,7 +4342,7 @@ set_raw_breakpoint_without_location (enum bptype bptype)
   b->frame_id = null_frame_id;
   b->dll_pathname = NULL;
   b->triggered_dll_pathname = NULL;
-  b->forked_inferior_pid = 0;
+  b->forked_inferior_pid = null_ptid;
   b->exec_pathname = NULL;
   b->ops = NULL;
   b->condition_not_parsed = 0;
@@ -4468,13 +4466,12 @@ create_internal_breakpoint (CORE_ADDR address, enum bptype type)
 static void
 create_longjmp_breakpoint (char *func_name)
 {
-  struct breakpoint *b;
   struct minimal_symbol *m;
 
   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 ();
+  update_global_location_list (1);
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
@@ -4484,8 +4481,6 @@ create_longjmp_breakpoint (char *func_name)
 void
 set_longjmp_breakpoint (void)
 {
-  struct breakpoint *b;
-
   if (gdbarch_get_longjmp_target_p (current_gdbarch))
     {
       create_longjmp_breakpoint ("longjmp");
@@ -4532,7 +4527,7 @@ create_overlay_event_breakpoint (char *func_name)
       b->enable_state = bp_disabled;
       overlay_events_enabled = 0;
     }
-  update_global_location_list ();
+  update_global_location_list (1);
 }
 
 void
@@ -4544,7 +4539,7 @@ enable_overlay_breakpoints (void)
     if (b->type == bp_overlay_event)
     {
       b->enable_state = bp_enabled;
-      update_global_location_list ();
+      update_global_location_list (1);
       overlay_events_enabled = 1;
     }
 }
@@ -4558,7 +4553,7 @@ disable_overlay_breakpoints (void)
     if (b->type == bp_overlay_event)
     {
       b->enable_state = bp_disabled;
-      update_global_location_list ();
+      update_global_location_list (0);
       overlay_events_enabled = 0;
     }
 }
@@ -4574,7 +4569,7 @@ 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 ();
+  update_global_location_list_nothrow (1);
 
   return b;
 }
@@ -4620,7 +4615,7 @@ create_solib_event_breakpoint (CORE_ADDR address)
   struct breakpoint *b;
 
   b = create_internal_breakpoint (address, bp_shlib_event);
-  update_global_location_list_nothrow ();
+  update_global_location_list_nothrow (1);
   return b;
 }
 
@@ -4717,8 +4712,8 @@ create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
   b->addr_string = NULL;
   b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
-  b->forked_inferior_pid = 0;
-  update_global_location_list ();
+  b->forked_inferior_pid = null_ptid;
+  update_global_location_list (1);
 
 
   mention (b);
@@ -4757,7 +4752,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 ();
+  update_global_location_list (1);
 
   mention (b);
 }
@@ -4770,7 +4765,7 @@ hw_breakpoint_used_count (void)
 
   ALL_BREAKPOINTS (b)
   {
-    if (b->type == bp_hardware_breakpoint && b->enable_state == bp_enabled)
+    if (b->type == bp_hardware_breakpoint && breakpoint_enabled (b))
       i++;
   }
 
@@ -4813,7 +4808,7 @@ disable_watchpoints_before_interactive_call_start (void)
        && breakpoint_enabled (b))
       {
        b->enable_state = bp_call_disabled;
-       update_global_location_list ();
+       update_global_location_list (0);
       }
   }
 }
@@ -4832,7 +4827,7 @@ enable_watchpoints_after_interactive_call_stop (void)
        && (b->enable_state == bp_call_disabled))
       {
        b->enable_state = bp_enabled;
-       update_global_location_list ();
+       update_global_location_list (1);
       }
   }
 }
@@ -4858,7 +4853,7 @@ 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 ();
+  update_global_location_list_nothrow (1);
 
   return b;
 }
@@ -4892,11 +4887,8 @@ mention (struct breakpoint *b)
   /* FIXME: This is misplaced; mention() is called by things (like
      hitting a watchpoint) other than breakpoint creation.  It should
      be possible to clean this up and at the same time replace the
-     random calls to breakpoint_changed with this hook, as has already
-     been done for deprecated_delete_breakpoint_hook and so on.  */
-  if (deprecated_create_breakpoint_hook)
-    deprecated_create_breakpoint_hook (b);
-  breakpoint_create_event (b->number);
+     random calls to breakpoint_changed with this hook.  */
+  observer_notify_breakpoint_created (b->number);
 
   if (b->ops != NULL && b->ops->print_mention != NULL)
     b->ops->print_mention (b);
@@ -5280,7 +5272,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
                         thread, ignore_count, ops, from_tty);
     }
 
-  update_global_location_list ();
+  update_global_location_list (1);
 }
 
 /* Parse ARG which is assumed to be a SAL specification possibly
@@ -5601,7 +5593,7 @@ break_command_really (char *arg, char *cond_string, int thread,
       b->condition_not_parsed = 1;
       b->ops = ops;
 
-      update_global_location_list ();
+      update_global_location_list (1);
       mention (b);
     }
   
@@ -5702,7 +5694,7 @@ resolve_sal_pc (struct symtab_and_line *sal)
       bv = blockvector_for_pc_sect (sal->pc, 0, &b, sal->symtab);
       if (bv != NULL)
        {
-         sym = block_function (b);
+         sym = block_linkage_function (b);
          if (sym != NULL)
            {
              fixup_symbol_section (sym, sal->symtab->objfile);
@@ -6030,7 +6022,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
 
   value_free_to_mark (mark);
   mention (b);
-  update_global_location_list ();
+  update_global_location_list (1);
 }
 
 /* Return count of locations need to be watched and can be handled
@@ -6150,16 +6142,24 @@ awatch_command (char *arg, int from_tty)
 /* Helper routines for the until_command routine in infcmd.c.  Here
    because it uses the mechanisms of breakpoints.  */
 
+struct until_break_command_continuation_args
+{
+  struct breakpoint *breakpoint;
+  struct breakpoint *breakpoint2;
+};
+
 /* This function is called by fetch_inferior_event via the
    cmd_continuation pointer, to complete the until command. It takes
    care of cleaning up the temporary breakpoints set up by the until
    command. */
 static void
-until_break_command_continuation (struct continuation_arg *arg, int error)
+until_break_command_continuation (void *arg)
 {
-  delete_breakpoint ((struct breakpoint *)(arg->data.pointer));
-  if (arg->next)
-    delete_breakpoint ((struct breakpoint *)(arg->next->data.pointer));
+  struct until_break_command_continuation_args *a = arg;
+
+  delete_breakpoint (a->breakpoint);
+  if (a->breakpoint2)
+    delete_breakpoint (a->breakpoint2);
 }
 
 void
@@ -6172,9 +6172,6 @@ until_break_command (char *arg, int from_tty, int anywhere)
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2 = NULL;
   struct cleanup *old_chain;
-  struct continuation_arg *arg1;
-  struct continuation_arg *arg2;
-
 
   clear_proceed_status ();
 
@@ -6229,24 +6226,17 @@ until_break_command (char *arg, int from_tty, int anywhere)
      deleted when the target stops.  Otherwise, we're already stopped and
      delete breakpoints via cleanup chain.  */
 
-  if (target_can_async_p () && target_executing)
+  if (target_can_async_p () && is_running (inferior_ptid))
     {
-      arg1 =
-       (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
-      arg1->next         = NULL;
-      arg1->data.pointer = breakpoint;
+      struct until_break_command_continuation_args *args;
+      args = xmalloc (sizeof (*args));
 
-      if (breakpoint2)
-       {
-         arg2 = (struct continuation_arg *)
-           xmalloc ( sizeof (struct continuation_arg));
-         arg2->next         = NULL;
-         arg2->data.pointer = breakpoint2;
-         arg1->next = arg2;       
-       }
+      args->breakpoint = breakpoint;
+      args->breakpoint2 = breakpoint2;
 
       discard_cleanups (old_chain);
-      add_continuation (until_break_command_continuation, arg1);
+      add_continuation (until_break_command_continuation, args,
+                       xfree);
     }
   else
     do_cleanups (old_chain);
@@ -6668,7 +6658,7 @@ create_ada_exception_breakpoint (struct symtab_and_line sal,
   b->ops = ops;
 
   mention (b);
-  update_global_location_list ();
+  update_global_location_list (1);
 }
 
 /* Implement the "catch exception" command.  */
@@ -6992,8 +6982,23 @@ breakpoint_auto_delete (bpstat bs)
   }
 }
 
+/* If SHOULD_INSERT is true, do not insert any breakpoint locations
+   into the inferior, only remove already-inserted locations that no
+   longer should be inserted.  Functions that delete a breakpoint or
+   breakpoints should pass false, so that deleting a breakpoint
+   doesn't have the side effect of inserting the locations of other
+   breakpoints that are marked not-inserted, but should_be_inserted
+   returns true on them.
+
+   This behaviour is useful is situations close to tear-down -- e.g.,
+   after an exec, while the target still has execution, but breakpoint
+   shadows of the previous executable image should *NOT* be restored
+   to the new image; or before detaching, where the target still has
+   execution and wants to delete breakpoints from GDB's lists, and all
+   breakpoints had already been removed from the inferior.  */
+
 static void
-update_global_location_list (void)
+update_global_location_list (int should_insert)
 {
   struct breakpoint *b;
   struct bp_location **next = &bp_location_chain;
@@ -7125,7 +7130,7 @@ update_global_location_list (void)
       check_duplicates (b);
     }
 
-  if (always_inserted_mode && target_has_execution)
+  if (always_inserted_mode && should_insert && target_has_execution)
     insert_breakpoint_locations ();
 }
 
@@ -7145,11 +7150,34 @@ breakpoint_retire_moribund (void)
 }
 
 static void
-update_global_location_list_nothrow (void)
+update_global_location_list_nothrow (int inserting)
 {
   struct gdb_exception e;
   TRY_CATCH (e, RETURN_MASK_ERROR)
-    update_global_location_list ();
+    update_global_location_list (inserting);
+}
+
+/* Clear BPT from a BPS.  */
+static void
+bpstat_remove_breakpoint (bpstat bps, struct breakpoint *bpt)
+{
+  bpstat bs;
+  for (bs = bps; bs; bs = bs->next)
+    if (bs->breakpoint_at && bs->breakpoint_at->owner == bpt)
+      {
+       bs->breakpoint_at = NULL;
+       bs->old_val = NULL;
+       /* bs->commands will be freed later.  */
+      }
+}
+
+/* Callback for iterate_over_threads.  */
+static int
+bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
+{
+  struct breakpoint *bpt = data;
+  bpstat_remove_breakpoint (th->stop_bpstat, bpt);
+  return 0;
 }
 
 /* Delete a breakpoint and clean up all traces of it in the data
@@ -7159,7 +7187,6 @@ void
 delete_breakpoint (struct breakpoint *bpt)
 {
   struct breakpoint *b;
-  bpstat bs;
   struct bp_location *loc, *next;
 
   gdb_assert (bpt != NULL);
@@ -7180,9 +7207,7 @@ delete_breakpoint (struct breakpoint *bpt)
   if (bpt->type == bp_none)
     return;
 
-  if (deprecated_delete_breakpoint_hook)
-    deprecated_delete_breakpoint_hook (bpt);
-  breakpoint_delete_event (bpt->number);
+  observer_notify_breakpoint_deleted (bpt->number);
 
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
@@ -7223,13 +7248,11 @@ delete_breakpoint (struct breakpoint *bpt)
          bpstat_do_actions (&stop_bpstat);
      in event-top.c won't do anything, and temporary breakpoints
      with commands won't work.  */
-  for (bs = stop_bpstat; bs; bs = bs->next)
-    if (bs->breakpoint_at && bs->breakpoint_at->owner == bpt)
-      {
-       bs->breakpoint_at = NULL;
-       bs->old_val = NULL;
-       /* bs->commands will be freed later.  */
-      }
+
+  /* Clear the current context.  */
+  bpstat_remove_breakpoint (stop_bpstat, bpt);
+  /* And from all threads.  */
+  iterate_over_threads (bpstat_remove_breakpoint_callback, bpt);
 
   /* Now that breakpoint is removed from breakpoint
      list, update the global location list.  This
@@ -7239,7 +7262,7 @@ delete_breakpoint (struct breakpoint *bpt)
      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 ();
+  update_global_location_list (0);
 
 
   /* On the chance that someone will soon try again to delete this same
@@ -7449,7 +7472,7 @@ update_breakpoint_locations (struct breakpoint *b,
       }
   }
 
-  update_global_location_list ();
+  update_global_location_list (1);
 }
 
 
@@ -7689,7 +7712,7 @@ set_ignore_count (int bptnum, int count, int from_tty)
                             count, bptnum);
        }
       breakpoints_changed ();
-      breakpoint_modify_event (b->number);
+      observer_notify_breakpoint_modified (b->number);
       return;
     }
 
@@ -7835,11 +7858,9 @@ disable_breakpoint (struct breakpoint *bpt)
 
   bpt->enable_state = bp_disabled;
 
-  update_global_location_list ();
+  update_global_location_list (0);
 
-  if (deprecated_modify_breakpoint_hook)
-    deprecated_modify_breakpoint_hook (bpt);
-  breakpoint_modify_event (bpt->number);
+  observer_notify_breakpoint_modified (bpt->number);
 }
 
 static void
@@ -7874,7 +7895,7 @@ disable_command (char *args, int from_tty)
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
        loc->enabled = 0;
-      update_global_location_list ();
+      update_global_location_list (0);
     }
   else
     map_breakpoint_numbers (args, disable_breakpoint);
@@ -7959,12 +7980,10 @@ have been allocated for other watchpoints.\n"), bpt->number);
   if (bpt->enable_state != bp_permanent)
     bpt->enable_state = bp_enabled;
   bpt->disposition = disposition;
-  update_global_location_list ();
+  update_global_location_list (1);
   breakpoints_changed ();
   
-  if (deprecated_modify_breakpoint_hook)
-    deprecated_modify_breakpoint_hook (bpt);
-  breakpoint_modify_event (bpt->number);
+  observer_notify_breakpoint_modified (bpt->number);
 }
 
 
@@ -8010,7 +8029,7 @@ enable_command (char *args, int from_tty)
       struct bp_location *loc = find_location_by_number (args);
       if (loc)
        loc->enabled = 1;
-      update_global_location_list ();
+      update_global_location_list (1);
     }
   else
     map_breakpoint_numbers (args, enable_breakpoint);
This page took 0.034138 seconds and 4 git commands to generate.