This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Keep breakpoints always inserted.


This patch makes breakpoint always inserted. There are not 
regressions on x86. I think the patch is almost ready,
and comments are appreciated.

It's RFC, and not RFA because:

- There's no option to disable always-inserted mode
- I would like to add a separate option to report
breakpoint insert/remove operations, to facilitate testing
now and in future
- I just want the code to "soak" for about a week

Comments?

- Volodya

	* breakpoint.h (bp_location_p): New typedef.
	Register a vector of bp_location_p.
	* breakpoint.c (unlink_locations_from_global_list):
	Remove.
	(update_global_location_list)
	(update_global_location_list_nothrow): New.
	(update_watchpoint): Don't free locations.
	(should_insert_location): New.
	(insert_bp_location): Use should_insert_location.
	(insert_breakpoint_locations): Copied from
	insert_breakpoints.
	(insert_breakpoint): Use insert_breakpoint_locations.
	(bpstat_stop_status): Call update_global_location_list
	when disabling breakpoint.
	(allocate_bp_location): Don't add to bp_location_chain.
	(set_raw_breakpoint)
	(create_longjmp_breakpoint, enable_longjmp_breakpoint)
	(disable_longjmp_breakpoint, create_overlay_event_breakpoint)
	(enable_overlay_breakpoints, disable_overlay_breakpoints)
	(set_longjmp_resume_breakpoint)
	(enable_watchpoints_after_interactive_call_stop)
	(disable_watchpoints_before_interactive_call_start)
	(create_internal_breakpoint)
	(create_fork_vfork_event_catchpoint)
	(create_exec_event_catchpoint, set_momentary_breakpoint)
	(create_breakpoints, break_command_1, watch_command_1)
	(create_exception_catchpoint)
	(handle_gnu_v3_exceptions)
	(disable_breakpoint, breakpoint_re_set_one)
	(create_thread_event_breakpoint, create_solib_event_breakpoint)
	(create_ada_exception_breakpoint): : Don't call check_duplicates.
	Call update_global_location_list.
	(delete_breakpoint): Don't remove locations and don't
	try to reinsert them. Call update_global_location_list.
	(update_breakpoint_locations): Likewise.

	* infrun.c (proceed): Remove breakpoints while stepping
	over breakpoint.
	(handle_inferior_event): Don't remove or insert
	breakpoints.
	* linux-fork.c (checkpoint_command): Remove breakpoints
	before fork and insert after.
	(linux_fork_context): Remove breakpoints before switch
	and insert after.
---
 gdb/breakpoint.c |  345 +++++++++++++++++++++++++++---------------------------
 gdb/breakpoint.h |    3 +
 gdb/infrun.c     |   37 ++----
 gdb/linux-fork.c |    7 +
 4 files changed, 194 insertions(+), 198 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 4365a3a..46e3c4a 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -205,11 +205,14 @@ 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);
+
+static int is_hardware_watchpoint (struct breakpoint *bpt);
+
+static void
+insert_breakpoint_locations (void);
 
 /* Prototypes for exported functions. */
 
@@ -829,14 +832,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)
@@ -981,6 +980,20 @@ in which its expression is valid.\n"),
 }
 
 
+/* Returns 1 iff breakpoint location should be
+   inserted in the inferior.  */
+static int
+should_insert_location (struct bp_location *bpt)
+{
+  if (!breakpoint_enabled (bpt->owner))
+    return 0;
+
+  if (!bpt->enabled || bpt->shlib_disabled || bpt->inserted || 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.
@@ -995,10 +1008,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_insert_location (bpt))
     return 0;
 
   /* Initialize the target-specific information.  */
@@ -1254,13 +1264,29 @@ 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 ();
+}
+
 /* 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;
@@ -1276,10 +1302,6 @@ insert_breakpoints (void)
   /* 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)
     {
@@ -3044,7 +3066,10 @@ bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid)
 	  {
 	    /* We will stop here */
 	    if (b->disposition == disp_disable)
-	      b->enable_state = bp_disabled;
+	      {
+		b->enable_state = bp_disabled;
+		update_global_location_list ();
+	      }
 	    if (b->silent)
 	      bs->print = 0;
 	    bs->commands = b->commands;
@@ -4338,18 +4363,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;
 }
 
@@ -4357,6 +4370,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);
 }
 
@@ -4461,7 +4478,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;
@@ -4525,6 +4541,7 @@ create_longjmp_breakpoint (char *func_name)
   b->silent = 1;
   if (func_name)
     b->addr_string = xstrdup (func_name);
+  update_global_location_list ();
 }
 
 /* Call this routine when stepping and nexting to enable a breakpoint
@@ -4540,7 +4557,7 @@ enable_longjmp_breakpoint (void)
     if (b->type == bp_longjmp)
     {
       b->enable_state = bp_enabled;
-      check_duplicates (b);
+      update_global_location_list ();
     }
 }
 
@@ -4554,7 +4571,7 @@ disable_longjmp_breakpoint (void)
 	|| b->type == bp_longjmp_resume)
     {
       b->enable_state = bp_disabled;
-      check_duplicates (b);
+      update_global_location_list ();
     }
 }
 
@@ -4581,6 +4598,7 @@ create_overlay_event_breakpoint (char *func_name)
       b->enable_state = bp_disabled;
       overlay_events_enabled = 0;
     }
+  update_global_location_list ();
 }
 
 void
@@ -4592,7 +4610,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;
     }
 }
@@ -4606,7 +4624,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;
     }
 }
@@ -4622,6 +4640,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;
 }
 
@@ -4666,6 +4686,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;
 }
 
@@ -4763,6 +4784,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);
 }
@@ -4800,6 +4823,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);
 }
@@ -4860,7 +4884,7 @@ set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id)
                                                    b->type);
       b->enable_state = bp_enabled;
       b->frame_id = frame_id;
-      check_duplicates (b);
+      update_global_location_list ();
       return;
     }
 }
@@ -4880,7 +4904,7 @@ disable_watchpoints_before_interactive_call_start (void)
 	&& breakpoint_enabled (b))
       {
 	b->enable_state = bp_call_disabled;
-	check_duplicates (b);
+	update_global_location_list ();
       }
   }
 }
@@ -4900,7 +4924,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 ();
       }
   }
 }
@@ -4926,6 +4950,8 @@ 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;
 }
 
@@ -5331,6 +5357,8 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
 			 cond_string, type, disposition,
 			 thread, ignore_count, from_tty);
     }
+
+  update_global_location_list ();
 }
 
 /* Parse ARG which is assumed to be a SAL specification possibly
@@ -5632,6 +5660,8 @@ break_command_1 (char *arg, int flag, int from_tty)
       b->ignore_count = ignore_count;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->condition_not_parsed = 1;
+
+      update_global_location_list ();
       mention (b);
     }
   
@@ -6054,6 +6084,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
@@ -6571,6 +6602,7 @@ create_exception_catchpoint (int tempflag, char *cond_string,
   b->enable_state = bp_enabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
   mention (b);
+  update_global_location_list ();
 }
 
 static enum print_stop_action
@@ -6653,6 +6685,7 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
 
   xfree (sals.sals);
   mention (b);
+  update_global_location_list ();
   return 1;
 }
 
@@ -6738,6 +6771,7 @@ create_ada_exception_breakpoint (struct symtab_and_line sal,
   b->ops = ops;
 
   mention (b);
+  update_global_location_list ();
 }
 
 /* Implement the "catch exception" command.  */
@@ -7076,33 +7110,104 @@ 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;
+  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);
 
-  if (here == NULL)
-    return;
+  bp_location_chain = NULL;
+  ALL_BREAKPOINTS (b)
+    {
+      for (loc = b->loc; loc; loc = loc->next)
+	{
+	  *next = loc;
+	  next = &(loc->global_next);
+	  *next = NULL;
+	}
+    }
 
-  for (; *tmp && here;)
+  /* Identify bp_location instances that are not
+     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)
     {
-      if (*tmp == here)
+      int found_object = 0;
+      int found_address = 0;
+      for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next)
+	if (loc2 == loc)
+	  {
+	    found_object = 1;
+	    break;
+	  }
+
+      /* If this location is not longer present, and
+	 inserted, look if there's maybe 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 window
+	 where a breakpoint at certian location is not
+	 inserted.  */
+      if (!found_object && loc->inserted)
 	{
-	  *tmp = here->global_next;
-	  here = here->next;
+	  /* See if there's another location at the same
+	     address, in which case we don't need to
+	     remove this one.  */
+	  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 the check_duplicates will fix up this later.  */
+		loc2->duplicate = 0;
+		if (should_insert_location (loc2)
+		    && loc2 != loc && loc2->address == loc->address)
+		  {		  
+		    loc2->inserted = 1;
+		    loc2->target_info = loc->target_info;
+		    found_address = 1;
+		    break;
+		  }
+	      }
 	}
-      else
+
+      if (loc->inserted && !found_object && !found_address)
 	{
-	  tmp = &((*tmp)->global_next);
+	  /* FIXME? Handle error? */
+	  remove_breakpoint (loc, mark_uninserted);
 	}
+
+      if (!found_object)
+	free_bp_location (loc);
+    }
+    
+  ALL_BREAKPOINTS (b)
+    {
+      check_duplicates (b);
     }
+
+  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
@@ -7113,7 +7218,7 @@ delete_breakpoint (struct breakpoint *bpt)
 {
   struct breakpoint *b;
   bpstat bs;
-  struct bp_location *loc;
+  struct bp_location *loc, *next;
 
   gdb_assert (bpt != NULL);
 
@@ -7137,18 +7242,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;
 
@@ -7181,84 +7274,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 ");
-			  deprecated_print_address_numeric (loc2->address, 1, 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);
@@ -7299,13 +7314,9 @@ delete_breakpoint (struct breakpoint *bpt)
      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);
+
+  update_global_location_list ();
 }
 
 static void
@@ -7399,7 +7410,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)
@@ -7459,12 +7469,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 ();
 }
 
 
@@ -7560,10 +7565,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;
 
@@ -7866,7 +7867,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);
@@ -7907,7 +7908,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);
@@ -7992,7 +7993,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)
@@ -8045,7 +8046,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);
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 9f98718..cedeb1c 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -338,6 +338,9 @@ enum watchpoint_triggered
   watch_triggered_yes  
 };
 
+typedef struct bp_location *bp_location_p;
+DEF_VEC_P(bp_location_p);
+
 /* Note that the ->silent field is not currently used by any commands
    (though the code is in there if it was to be, and set_raw_breakpoint
    does set it to 0).  I implemented it because I thought it would be
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 6c62b60..b87d14e 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -797,9 +797,17 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
     oneproc = 1;
 
   if (oneproc)
-    /* We will get a trace trap after one instruction.
-       Continue it automatically and insert breakpoints then.  */
-    stepping_over_breakpoint = 1;
+    {
+      /* We will get a trace trap after one instruction.
+	 Continue it automatically and insert breakpoints then.  */
+      stepping_over_breakpoint = 1;
+      /* FIXME: if breakpoints are always inserted, we'll trap
+       if trying to single-step over breakpoint.  Disable
+      all breakpoints.  In future, we'd need to invent some
+      smart way of stepping over breakpoint instruction without
+      hitting breakpoint.  */
+      remove_breakpoints ();
+    }
   else
     insert_breakpoints ();
 
@@ -1344,10 +1352,6 @@ handle_inferior_event (struct execution_control_state *ecs)
          established.  */
       if (stop_soon == NO_STOP_QUIETLY)
 	{
-	  /* Remove breakpoints, SOLIB_ADD might adjust
-	     breakpoint addresses via breakpoint_re_set.  */
-	  remove_breakpoints ();
-
 	  /* Check for any newly added shared libraries if we're
 	     supposed to be adding them automatically.  Switch
 	     terminal for any messages produced by
@@ -1387,9 +1391,6 @@ handle_inferior_event (struct execution_control_state *ecs)
 
 	  /* NOTE drow/2007-05-11: This might be a good place to check
 	     for "catch load".  */
-
-	  /* Reinsert breakpoints and continue.  */
-	  insert_breakpoints ();
 	}
 
       /* If we are skipping through a shell, or through shared library
@@ -2236,10 +2237,6 @@ process_event_stop_test:
 	{
           if (debug_infrun)
 	    fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_CHECK_SHLIBS\n");
-	  /* Remove breakpoints, we eventually want to step over the
-	     shlib event breakpoint, and SOLIB_ADD might adjust
-	     breakpoint addresses via breakpoint_re_set.  */
-	  remove_breakpoints ();
 
 	  /* Check for any newly added shared libraries if we're
 	     supposed to be adding them automatically.  Switch
@@ -3154,18 +3151,6 @@ normal_stop (void)
        gdbarch_decr_pc_after_break needs to just go away.  */
     deprecated_update_frame_pc_hack (get_current_frame (), read_pc ());
 
-  if (target_has_execution)
-    {
-      if (remove_breakpoints ())
-	{
-	  target_terminal_ours_for_output ();
-	  printf_filtered (_("\
-Cannot remove breakpoints because program is no longer writable.\n\
-It might be running in another process.\n\
-Further execution is probably impossible.\n"));
-	}
-    }
-
   /* Delete the breakpoint we stopped at, if it wants to be deleted.
      Delete any breakpoint that is to be deleted at the next stop.  */
 
diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c
index 9c81d88..4e7e213 100644
--- a/gdb/linux-fork.c
+++ b/gdb/linux-fork.c
@@ -536,6 +536,10 @@ checkpoint_command (char *args, int from_tty)
   /* Make this temp var static, 'cause it's used in the error context.  */
   static int temp_detach_fork;
 
+  /* Remove breakpoints, so that they are not inserted
+     in the forked process.  */
+  remove_breakpoints ();
+
   /* Make the inferior fork, record its (and gdb's) state.  */
 
   if (lookup_minimal_symbol ("fork", NULL, NULL) != NULL)
@@ -576,6 +580,7 @@ checkpoint_command (char *args, int from_tty)
   if (!fp)
     error (_("Failed to find new fork"));
   fork_save_infrun_state (fp, 1);
+  insert_breakpoints ();
 }
 
 static void
@@ -593,7 +598,9 @@ linux_fork_context (struct fork_info *newfp, int from_tty)
     oldfp = add_fork (ptid_get_pid (inferior_ptid));
 
   fork_save_infrun_state (oldfp, 1);
+  remove_breakpoints ();
   fork_load_infrun_state (newfp);
+  insert_breakpoints ();
 
   printf_filtered (_("Switching to %s\n"), 
 		   target_pid_to_str (inferior_ptid));
-- 
1.5.3.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]