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]

Re: [8/9] multiple locations


On Saturday 08 September 2007 15:46:48 Eli Zaretskii wrote:
> > From: Vladimir Prus <vladimir@codesourcery.com>
> > Date: Sat, 8 Sep 2007 02:48:52 +0400
> > 
> > @@ -3397,30 +3448,79 @@ print_one_breakpoint (struct breakpoint 
> >    struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
> >    struct cleanup *bkpt_chain;
> >  [...]
> > -  ui_out_field_int (uiout, "number", b->number);
> > +  if (part_of_multiple)
> > +    {
> > +      char buf[30];
> 
> Why 30?  GNU coding standards frown on arbitrary constant sizes.

> > Clearly, '30' is sufficient for 2^32 breakpoints, each having 2^32
> > locations.
>
> Are we talking only about 32-bit machines?

The address size is not important -- we only care about the *number*
of breakpoints and locations. And having 2^32 breakpoints each with
2^32 locations is seriously beyond reasonable number.

Anyway, to avoid further discussion, I've changed code to use
asprintf.

> > +      sprintf (buf, "%d.%d", b->number, loc_number);
> > +      ui_out_field_string (uiout, "number", buf);
> 
> I'm worried about this N.M thing: when the number of locations takes
> 2 or 3 digits, won't it disrupt the display alignment?

I've increased the field width from 3 to 7 -- which will tolerate
3 digits of breakpoint number, dot, and 3 digits of breakpoint location
number. Clearly, this still can overflow, but we can get overflow in
the current gdb, too.

> > +/* set_raw_breakpoint() is a low level routine for allocating and
> 
> Another GNU coding standards thing: foo() should not be used as an
> indication that `foo' is a function.  Just say `foo' instead; foo()
> looks like a call to `foo' with no arguments, which is not what you
> mean.

Changed.

I attach revised patch. Does it look OK?

Thanks,
Volodya


Attachment: mainline_8_multiple_locations.ChangeLog
Description: Text document

--- gdb/breakpoint.c	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/breakpoint.c	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -275,11 +275,11 @@ static int overlay_events_enabled;
 
 /* Similar iterators for the low-level breakpoints.  */
 
-#define ALL_BP_LOCATIONS(B)  for (B = bp_location_chain; B; B = B->next)
+#define ALL_BP_LOCATIONS(B)  for (B = bp_location_chain; B; B = B->global_next)
 
 #define ALL_BP_LOCATIONS_SAFE(B,TMP)	\
 	for (B = bp_location_chain;	\
-	     B ? (TMP=B->next, 1): 0;	\
+	     B ? (TMP=B->global_next, 1): 0;	\
 	     B = TMP)
 
 /* True if breakpoint hit counts should be displayed in breakpoint info.  */
@@ -356,7 +356,7 @@ static struct exception_event_record *cu
 static int
 breakpoint_enabled (struct breakpoint *b)
 {
-  return (b->enable_state == bp_enabled && !b->pending);
+  return (b->enable_state == bp_enabled);
 }
 
 /* Set breakpoint count to NUM.  */
@@ -572,10 +572,13 @@ condition_command (char *arg, int from_t
     if (b->number == bnum)
     {
       struct bp_location *loc = b->loc;
-      if (loc->cond)
+      for (; loc; loc = loc->next)
 	{
-	  xfree (loc->cond);
-	  loc->cond = 0;
+	  if (loc->cond)
+	    {
+	      xfree (loc->cond);
+	      loc->cond = 0;
+	    }
 	}
       if (b->cond_string != NULL)
 	xfree (b->cond_string);
@@ -592,10 +595,11 @@ condition_command (char *arg, int from_t
 	  /* 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));
-	  if (!b->pending)
+	  b->condition_not_parsed = 0;
+	  for (loc = b->loc; loc; loc = loc->next)
 	    {
-	      b->loc->cond = parse_exp_1 (&arg, 
-					  block_for_pc (b->loc->address), 0);
+	      arg = p;
+	      loc->cond = parse_exp_1 (&arg, block_for_pc (loc->address), 0);
 	      if (*arg)
 		error (_("Junk at end of expression"));
 	    }
@@ -846,7 +850,7 @@ insert_bp_location (struct bp_location *
   if (!breakpoint_enabled (bpt->owner))
     return 0;
 
-  if (bpt->inserted || bpt->duplicate)
+  if (!bpt->enabled || bpt->shlib_disabled || bpt->inserted || bpt->duplicate)
     return 0;
 
   /* Initialize the target-specific information.  */
@@ -969,7 +973,7 @@ Note: automatically using hardware break
 	    {
 	      /* See also: disable_breakpoints_in_shlibs. */
 	      val = 0;
-	      bpt->owner->enable_state = bp_shlib_disabled;
+	      bpt->shlib_disabled = 1;
 	      if (!*disabled_breaks)
 		{
 		  fprintf_unfiltered (tmp_error_stream, 
@@ -1808,9 +1812,7 @@ software_breakpoint_inserted_here_p (COR
       if (bpt->loc_type != bp_loc_software_breakpoint)
 	continue;
 
-      if ((breakpoint_enabled (bpt->owner)
-	   || bpt->owner->enable_state == bp_permanent)
-	  && bpt->inserted
+      if (bpt->inserted
 	  && bpt->address == pc)	/* bp is enabled and matches pc */
 	{
 	  if (overlay_debugging 
@@ -2160,6 +2162,7 @@ print_it_typical (bpstat bs)
 {
   struct cleanup *old_chain, *ui_out_chain;
   struct breakpoint *b;
+  struct bp_location *bl;
   struct ui_stream *stb;
   stb = ui_out_stream_new (uiout);
   old_chain = make_cleanup_ui_out_stream_delete (stb);
@@ -2167,15 +2170,16 @@ print_it_typical (bpstat bs)
      which has since been deleted.  */
   if (bs->breakpoint_at == NULL)
     return PRINT_UNKNOWN;
-  b = bs->breakpoint_at->owner;
+  bl = bs->breakpoint_at;
+  b = bl->owner;
 
   switch (b->type)
     {
     case bp_breakpoint:
     case bp_hardware_breakpoint:
-      if (b->loc->address != b->loc->requested_address)
-	breakpoint_adjustment_warning (b->loc->requested_address,
-	                               b->loc->address,
+      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 ");
@@ -2672,7 +2676,8 @@ which its expression is valid.\n");     
 bpstat
 bpstat_stop_status (CORE_ADDR bp_addr, ptid_t ptid, int stopped_by_watchpoint)
 {
-  struct breakpoint *b, *temp;
+  struct breakpoint *b = NULL;
+  struct bp_location *bl;
   /* True if we've hit a breakpoint (as opposed to a watchpoint).  */
   int real_breakpoint = 0;
   /* Root of the chain of bpstat's */
@@ -2681,8 +2686,10 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
   bpstat bs = root_bs;
   int thread_id = pid_to_thread_id (ptid);
 
-  ALL_BREAKPOINTS_SAFE (b, temp)
+  ALL_BP_LOCATIONS (bl)
   {
+    b = bl->owner;
+    gdb_assert (b);
     if (!breakpoint_enabled (b) && b->enable_state != bp_permanent)
       continue;
 
@@ -2697,11 +2704,11 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
 	&& b->type != bp_catch_catch
 	&& b->type != bp_catch_throw)	/* a non-watchpoint bp */
       {
-	if (b->loc->address != bp_addr) 	/* address doesn't match */
+	if (bl->address != bp_addr) 	/* address doesn't match */
 	  continue;
 	if (overlay_debugging		/* unmapped overlay section */
-	    && section_is_overlay (b->loc->section) 
-	    && !section_is_mapped (b->loc->section))
+	    && section_is_overlay (bl->section) 
+	    && !section_is_mapped (bl->section))
 	  continue;
       }
 
@@ -2719,11 +2726,11 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
 
     if (b->type == bp_hardware_breakpoint)
       {
-	if (b->loc->address != bp_addr)
+	if (bl->address != bp_addr)
 	  continue;
 	if (overlay_debugging		/* unmapped overlay section */
-	    && section_is_overlay (b->loc->section) 
-	    && !section_is_mapped (b->loc->section))
+	    && section_is_overlay (bl->section) 
+	    && !section_is_mapped (bl->section))
 	  continue;
       }
 
@@ -2774,7 +2781,7 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
 
     /* Come here if it's a watchpoint, or if the break address matches */
 
-    bs = bpstat_alloc (b->loc, bs);	/* Alloc a bpstat to explain stop */
+    bs = bpstat_alloc (bl, bs);	/* Alloc a bpstat to explain stop */
 
     /* Watchpoints may change this, if not found to have triggered. */
     bs->stop = 1;
@@ -2926,19 +2933,19 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
       {
 	int value_is_zero = 0;
 
-	if (b->loc->cond)
+	if (bl->cond)
 	  {
 	    /* 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, (b->loc->cond),
+	      = 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 (b->loc->cond && value_is_zero)
+	if (bl->cond && value_is_zero)
 	  {
 	    bs->stop = 0;
 	    /* Don't consider this a hit.  */
@@ -2985,9 +2992,9 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
   /* The value of a hardware watchpoint hasn't changed, but the
      intermediate memory locations we are watching may have.  */
   if (bs && !bs->stop &&
-      (bs->breakpoint_at->owner->type == bp_hardware_watchpoint ||
-       bs->breakpoint_at->owner->type == bp_read_watchpoint ||
-       bs->breakpoint_at->owner->type == bp_access_watchpoint))
+      (b->type == bp_hardware_watchpoint ||
+       b->type == bp_read_watchpoint ||
+       b->type == bp_access_watchpoint))
     {
       remove_breakpoints ();
       insert_breakpoints ();
@@ -3349,10 +3356,54 @@ bpstat_get_triggered_catchpoints (bpstat
   *cp_list = bs;
 }
 
+static void print_breakpoint_location (struct breakpoint *b,
+				       struct bp_location *loc,
+				       char *wrap_indent,
+				       struct ui_stream *stb)
+{
+  if (b->source_file)
+    {
+      struct symbol *sym 
+	= find_pc_sect_function (loc->address, loc->section);
+      if (sym)
+	{
+	  ui_out_text (uiout, "in ");
+	  ui_out_field_string (uiout, "func",
+			       SYMBOL_PRINT_NAME (sym));
+	  ui_out_wrap_hint (uiout, wrap_indent);
+	  ui_out_text (uiout, " at ");
+	}
+      ui_out_field_string (uiout, "file", b->source_file);
+      ui_out_text (uiout, ":");
+      
+      if (ui_out_is_mi_like_p (uiout))
+	{
+	  struct symtab_and_line sal = find_pc_line (loc->address, 0);
+	  char *fullname = symtab_to_fullname (sal.symtab);
+	  
+	  if (fullname)
+	    ui_out_field_string (uiout, "fullname", fullname);
+	}
+      
+      ui_out_field_int (uiout, "line", b->line_number);
+    }
+  else if (!b->loc)
+    {
+      ui_out_field_string (uiout, "pending", b->addr_string);
+    }
+  else
+    {
+      print_address_symbolic (loc->address, stb->stream, demangle, "");
+      ui_out_field_stream (uiout, "at", stb);
+    }
+}
+
 /* Print B to gdb_stdout. */
 static void
-print_one_breakpoint (struct breakpoint *b,
-		      CORE_ADDR *last_addr)
+print_one_breakpoint_location (struct breakpoint *b,
+			       struct bp_location *loc,
+			       int loc_number,
+			       CORE_ADDR *last_addr)
 {
   struct command_line *l;
   struct symbol *sym;
@@ -3397,30 +3448,80 @@ print_one_breakpoint (struct breakpoint 
   struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
   struct cleanup *bkpt_chain;
 
+  int header_of_multiple = 0;
+  int part_of_multiple = (loc != NULL);
+
+  gdb_assert (!loc || loc_number != 0);
+  /* See comment in print_one_breakpoint concerning
+     treatment of breakpoints with single disabled
+     location.  */
+  if (loc == NULL 
+      && (b->loc != NULL 
+	  && (b->loc->next != NULL || !b->loc->enabled)))
+    header_of_multiple = 1;
+  if (loc == NULL)
+    loc = b->loc;
+
   annotate_record ();
   bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt");
 
   /* 1 */
   annotate_field (0);
-  ui_out_field_int (uiout, "number", b->number);
+  if (part_of_multiple)
+    {
+      char *formatted;
+      asprintf (&formatted, "%d.%d", b->number, loc_number);
+      ui_out_field_string (uiout, "number", formatted);
+      xfree (formatted);
+    }
+  else
+    {
+      ui_out_field_int (uiout, "number", b->number);
+    }
 
   /* 2 */
   annotate_field (1);
-  if (((int) b->type >= (sizeof (bptypes) / sizeof (bptypes[0])))
-      || ((int) b->type != bptypes[(int) b->type].type))
-    internal_error (__FILE__, __LINE__,
-		    _("bptypes table does not describe type #%d."),
-		    (int) b->type);
-  ui_out_field_string (uiout, "type", bptypes[(int) b->type].description);
+  if (part_of_multiple)
+    ui_out_field_skip (uiout, "type");
+  else 
+    {
+      if (((int) b->type >= (sizeof (bptypes) / sizeof (bptypes[0])))
+	  || ((int) b->type != bptypes[(int) b->type].type))
+	internal_error (__FILE__, __LINE__,
+			_("bptypes table does not describe type #%d."),
+			(int) b->type);
+      ui_out_field_string (uiout, "type", bptypes[(int) b->type].description);
+    }
 
   /* 3 */
   annotate_field (2);
-  ui_out_field_string (uiout, "disp", bpdisps[(int) b->disposition]);
+  if (part_of_multiple)
+    ui_out_field_skip (uiout, "disp");
+  else
+    ui_out_field_string (uiout, "disp", bpdisps[(int) b->disposition]);
+
 
   /* 4 */
   annotate_field (3);
-  ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int) b->enable_state]);
-  ui_out_spaces (uiout, 2);
+  if (part_of_multiple)
+    ui_out_field_string (uiout, "enabled", 
+			 loc->shlib_disabled 
+			 ? (loc->enabled ? "y(p)" : "n(p)")
+			 : (loc->enabled ? "y" : "n"));
+  else
+    {
+      int pending = (b->loc == NULL || b->loc->shlib_disabled);
+      /* For header of multiple, there's no point showing pending
+	 state -- it will be apparent from the locations.  */
+      if (header_of_multiple)
+	pending = 0;
+      ui_out_field_fmt (uiout, "enabled", "%c%s", 
+			bpenables[(int) b->enable_state],
+			pending ? "(p)" : "");
+      if (!pending)
+	ui_out_spaces (uiout, 3);
+    }
+
   
   /* 5 and 6 */
   strcpy (wrap_indent, "                           ");
@@ -3433,7 +3534,14 @@ print_one_breakpoint (struct breakpoint 
     }
 
   if (b->ops != NULL && b->ops->print_one != NULL)
-    b->ops->print_one (b, last_addr);
+    {
+      /* Although the print_one can possibly print
+	 all locations,  calling it here is not likely
+	 to get any nice result.  So, make sure there's
+	 just one location.  */
+      gdb_assert (b->loc == NULL || b->loc->next == NULL);
+      b->ops->print_one (b, last_addr);
+    }
   else
     switch (b->type)
       {
@@ -3545,51 +3653,22 @@ print_one_breakpoint (struct breakpoint 
 	if (addressprint)
 	  {
 	    annotate_field (4);
-	    if (b->pending)
+	    if (b->loc == NULL)
 	      ui_out_field_string (uiout, "addr", "<PENDING>");
+	    else if (header_of_multiple)
+	      ui_out_field_string (uiout, "addr", "<MULTIPLE>");
 	    else
-	      ui_out_field_core_addr (uiout, "addr", b->loc->address);
+	      ui_out_field_core_addr (uiout, "addr", loc->address);
 	  }
 	annotate_field (5);
-	*last_addr = b->loc->address;
-	if (b->source_file)
-	  {
-	    sym = find_pc_sect_function (b->loc->address, b->loc->section);
-	    if (sym)
-	      {
-		ui_out_text (uiout, "in ");
-		ui_out_field_string (uiout, "func",
-				     SYMBOL_PRINT_NAME (sym));
-		ui_out_wrap_hint (uiout, wrap_indent);
-		ui_out_text (uiout, " at ");
-	      }
-	    ui_out_field_string (uiout, "file", b->source_file);
-	    ui_out_text (uiout, ":");
-
-            if (ui_out_is_mi_like_p (uiout))
-              {
-                struct symtab_and_line sal = find_pc_line (b->loc->address, 0);
-                char *fullname = symtab_to_fullname (sal.symtab);
-
-                if (fullname)
-                  ui_out_field_string (uiout, "fullname", fullname);
-              }
-
-	    ui_out_field_int (uiout, "line", b->line_number);
-	  }
-	else if (b->pending)
-	  {
-	    ui_out_field_string (uiout, "pending", b->addr_string);
-	  }
-	else
-	  {
-	    print_address_symbolic (b->loc->address, stb->stream, demangle, "");
-	    ui_out_field_stream (uiout, "at", stb);
-	  }
+	if (!header_of_multiple)
+	  print_breakpoint_location (b, loc, wrap_indent, stb);
+	if (b->loc)
+	  *last_addr = b->loc->address;
 	break;
       }
 
-  if (b->thread != -1)
+  if (!part_of_multiple && b->thread != -1)
     {
       /* FIXME: This seems to be redundant and lost here; see the
 	 "stop only in" line a little further down. */
@@ -3599,7 +3678,7 @@ print_one_breakpoint (struct breakpoint 
   
   ui_out_text (uiout, "\n");
   
-  if (frame_id_p (b->frame_id))
+  if (part_of_multiple && frame_id_p (b->frame_id))
     {
       annotate_field (6);
       ui_out_text (uiout, "\tstop only in stack frame at ");
@@ -3609,27 +3688,18 @@ print_one_breakpoint (struct breakpoint 
       ui_out_text (uiout, "\n");
     }
   
-  if (b->loc->cond && !ada_exception_catchpoint_p (b))
+  if (!part_of_multiple && b->cond_string && !ada_exception_catchpoint_p (b))
     {
       /* We do not print the condition for Ada exception catchpoints
          because the condition is an internal implementation detail
          that we do not want to expose to the user.  */
       annotate_field (7);
       ui_out_text (uiout, "\tstop only if ");
-      print_expression (b->loc->cond, stb->stream);
-      ui_out_field_stream (uiout, "cond", stb);
-      ui_out_text (uiout, "\n");
-    }
-
-  if (b->pending && b->cond_string)
-    {
-      annotate_field (7);
-      ui_out_text (uiout, "\tstop only if ");
       ui_out_field_string (uiout, "cond", b->cond_string);
       ui_out_text (uiout, "\n");
     }
 
-  if (b->thread != -1)
+  if (!part_of_multiple && b->thread != -1)
     {
       /* FIXME should make an annotation for this */
       ui_out_text (uiout, "\tstop only in thread ");
@@ -3637,7 +3707,7 @@ print_one_breakpoint (struct breakpoint 
       ui_out_text (uiout, "\n");
     }
   
-  if (show_breakpoint_hit_counts && b->hit_count)
+  if (!part_of_multiple && show_breakpoint_hit_counts && b->hit_count)
     {
       /* FIXME should make an annotation for this */
       if (ep_is_catchpoint (b))
@@ -3655,10 +3725,10 @@ print_one_breakpoint (struct breakpoint 
   /* Output the count also if it is zero, but only if this is
      mi. FIXME: Should have a better test for this. */
   if (ui_out_is_mi_like_p (uiout))
-    if (show_breakpoint_hit_counts && b->hit_count == 0)
+    if (!part_of_multiple && show_breakpoint_hit_counts && b->hit_count == 0)
       ui_out_field_int (uiout, "times", b->hit_count);
 
-  if (b->ignore_count)
+  if (!part_of_multiple && b->ignore_count)
     {
       annotate_field (8);
       ui_out_text (uiout, "\tignore next ");
@@ -3666,7 +3736,7 @@ print_one_breakpoint (struct breakpoint 
       ui_out_text (uiout, " hits\n");
     }
   
-  if ((l = b->commands))
+  if (!part_of_multiple && (l = b->commands))
     {
       struct cleanup *script_chain;
 
@@ -3679,6 +3749,35 @@ print_one_breakpoint (struct breakpoint 
   do_cleanups (old_chain);
 }
 
+static void
+print_one_breakpoint (struct breakpoint *b,
+		      CORE_ADDR *last_addr)
+{
+  print_one_breakpoint_location (b, NULL, 0, last_addr);
+
+  /* If this breakpoint has custom print function,
+     it's already printed.  Otherwise, print individual
+     locations, if any.  */
+  if (b->ops == NULL || b->ops->print_one == NULL)
+    {
+      /* If breakpoint has a single location that is
+	 disabled, we print it as if it had
+	 several locations, since otherwise it's hard to
+	 represent "breakpoint enabled, location disabled"
+	 situation.  */	 
+      if (b->loc 
+	  && (b->loc->next || !b->loc->enabled)
+	  && !ui_out_is_mi_like_p (uiout))
+	{
+	  struct bp_location *loc;
+	  int n = 1;
+	  for (loc = b->loc; loc; loc = loc->next, ++n)
+	    print_one_breakpoint_location (b, loc, n, last_addr);
+	}
+    }
+}
+
+
 struct captured_breakpoint_query_args
   {
     int bnum;
@@ -3771,7 +3870,7 @@ breakpoint_1 (int bnum, int allflag)
     annotate_breakpoints_headers ();
   if (nr_printable_breakpoints > 0)
     annotate_field (0);
-  ui_out_table_header (uiout, 3, ui_left, "number", "Num");		/* 1 */
+  ui_out_table_header (uiout, 7, ui_left, "number", "Num");		/* 1 */
   if (nr_printable_breakpoints > 0)
     annotate_field (1);
   ui_out_table_header (uiout, 14, ui_left, "type", "Type");		/* 2 */
@@ -3780,7 +3879,7 @@ breakpoint_1 (int bnum, int allflag)
   ui_out_table_header (uiout, 4, ui_left, "disp", "Disp");		/* 3 */
   if (nr_printable_breakpoints > 0)
     annotate_field (3);
-  ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");	/* 4 */
+  ui_out_table_header (uiout, 4, ui_left, "enabled", "Enb");	/* 4 */
   if (addressprint)
 	{
 	  if (nr_printable_breakpoints > 0)
@@ -3852,6 +3951,19 @@ maintenance_info_breakpoints (char *bnum
   breakpoint_1 (bnum, 1);
 }
 
+static int
+breakpoint_has_pc (struct breakpoint *b, CORE_ADDR pc, asection *section)
+{
+  struct bp_location *bl = b->loc;
+  for (; bl; bl = bl->next)
+    {
+      if (bl->address == pc
+	  && (!overlay_debugging || bl->section == section))
+	return 1;	  
+    }
+  return 0;
+}
+
 /* Print a message describing any breakpoints set at PC.  */
 
 static void
@@ -3861,9 +3973,7 @@ describe_other_breakpoints (CORE_ADDR pc
   struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
-    if (b->loc->address == pc)	/* address match / overlay match */
-      if (!b->pending && (!overlay_debugging || b->loc->section == section))
-	others++;
+    others += breakpoint_has_pc (b, pc, section);
   if (others > 0)
     {
       if (others == 1)
@@ -3871,26 +3981,24 @@ describe_other_breakpoints (CORE_ADDR pc
       else /* if (others == ???) */
 	printf_filtered (_("Note: breakpoints "));
       ALL_BREAKPOINTS (b)
-	if (b->loc->address == pc)	/* address match / overlay match */
-	  if (!b->pending && (!overlay_debugging || b->loc->section == section))
-	    {
-	      others--;
-	      printf_filtered ("%d", b->number);
-	      if (b->thread == -1 && thread != -1)
-		printf_filtered (" (all threads)");
-	      else if (b->thread != -1)
-		printf_filtered (" (thread %d)", b->thread);
-	      printf_filtered ("%s%s ",
-			       ((b->enable_state == bp_disabled || 
-				 b->enable_state == bp_shlib_disabled || 
-				 b->enable_state == bp_call_disabled) 
-				? " (disabled)"
-				: b->enable_state == bp_permanent 
-				? " (permanent)"
-				: ""),
-			       (others > 1) ? "," 
-			       : ((others == 1) ? " and" : ""));
-	    }
+	if (breakpoint_has_pc (b, pc, section))
+	  {
+	    others--;
+	    printf_filtered ("%d", b->number);
+	    if (b->thread == -1 && thread != -1)
+	      printf_filtered (" (all threads)");
+	    else if (b->thread != -1)
+	      printf_filtered (" (thread %d)", b->thread);
+	    printf_filtered ("%s%s ",
+			     ((b->enable_state == bp_disabled || 
+			       b->enable_state == bp_call_disabled) 
+			      ? " (disabled)"
+			      : b->enable_state == bp_permanent 
+			      ? " (permanent)"
+			      : ""),
+			     (others > 1) ? "," 
+			     : ((others == 1) ? " and" : ""));
+	  }
       printf_filtered (_("also set at pc "));
       deprecated_print_address_numeric (pc, 1, gdb_stdout);
       printf_filtered (".\n");
@@ -3951,22 +4059,17 @@ breakpoint_address_is_meaningful (struct
    that one the official one, and the rest as duplicates.  */
 
 static void
-check_duplicates (struct breakpoint *bpt)
+check_duplicates_for (CORE_ADDR address, asection *section)
 {
   struct bp_location *b;
   int count = 0;
   struct bp_location *perm_bp = 0;
-  CORE_ADDR address = bpt->loc->address;
-  asection *section = bpt->loc->section;
-
-  if (! breakpoint_address_is_meaningful (bpt))
-    return;
 
   ALL_BP_LOCATIONS (b)
     if (b->owner->enable_state != bp_disabled
-	&& b->owner->enable_state != bp_shlib_disabled
-	&& !b->owner->pending
 	&& b->owner->enable_state != bp_call_disabled
+	&& b->enabled
+	&& !b->shlib_disabled
 	&& b->address == address	/* address / overlay match */
 	&& (!overlay_debugging || b->section == section)
 	&& breakpoint_address_is_meaningful (b->owner))
@@ -3999,9 +4102,8 @@ check_duplicates (struct breakpoint *bpt
 	if (b != perm_bp)
 	  {
 	    if (b->owner->enable_state != bp_disabled
-		&& b->owner->enable_state != bp_shlib_disabled
-		&& !b->owner->pending
 		&& b->owner->enable_state != bp_call_disabled
+		&& b->enabled && !b->shlib_disabled		
 		&& b->address == address	/* address / overlay match */
 		&& (!overlay_debugging || b->section == section)
 		&& breakpoint_address_is_meaningful (b->owner))
@@ -4018,6 +4120,18 @@ check_duplicates (struct breakpoint *bpt
 }
 
 static void
+check_duplicates (struct breakpoint *bpt)
+{
+  struct bp_location *bl = bpt->loc;
+
+  if (! breakpoint_address_is_meaningful (bpt))
+    return;
+
+  for (; bl; bl = bl->next)
+    check_duplicates_for (bl->address, bl->section);    
+}
+
+static void
 breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr,
                                int bnum, int have_bnum)
 {
@@ -4089,6 +4203,8 @@ allocate_bp_location (struct breakpoint 
 
   loc->owner = bpt;
   loc->cond = NULL;
+  loc->shlib_disabled = 0;
+  loc->enabled = 1;
 
   switch (bp_type)
     {
@@ -4134,9 +4250,9 @@ allocate_bp_location (struct breakpoint 
     bp_location_chain = loc;
   else
     {
-      while (loc_p->next)
-	loc_p = loc_p->next;
-      loc_p->next = loc;
+      while (loc_p->global_next)
+	loc_p = loc_p->global_next;
+      loc_p->global_next = loc;
     }
 
   return loc;
@@ -4149,53 +4265,21 @@ static void free_bp_location (struct bp_
   xfree (loc);
 }
 
-/* set_raw_breakpoint() is a low level routine for allocating and
-   partially initializing a breakpoint of type BPTYPE.  The newly
-   created breakpoint's address, section, source file name, and line
-   number are provided by SAL.  The newly created and partially
-   initialized breakpoint is added to the breakpoint chain and
-   is also returned as the value of this function.
-
-   It is expected that the caller will complete the initialization of
-   the newly created breakpoint struct as well as output any status
-   information regarding the creation of a new breakpoint.  In
-   particular, set_raw_breakpoint() does NOT set the breakpoint
-   number!  Care should be taken to not allow an error() to occur
-   prior to completing the initialization of the breakpoint.  If this
-   should happen, a bogus breakpoint will be left on the chain.  */
+/* Helper to set_raw_breakpoint below.  Creates a breakpoint
+   that has type BPTYPE and has no locations as yet.  */
 
 struct breakpoint *
-set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
+set_raw_breakpoint_without_location (enum bptype bptype)
 {
   struct breakpoint *b, *b1;
-  CORE_ADDR adjusted_address;
 
   b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
   memset (b, 0, sizeof (*b));
 
-  /* Adjust the breakpoint's address prior to allocating a location.
-     Once we call allocate_bp_location(), that mostly uninitialized
-     location will be placed on the location chain.  Adjustment of the
-     breakpoint may cause read_memory_nobpt() to be called and we do
-     not want its scan of the location chain to find a breakpoint and
-     location that's only been partially initialized.  */
-  adjusted_address = adjust_breakpoint_address (sal.pc, bptype);
-
-  b->loc = allocate_bp_location (b, bptype);
-  b->loc->requested_address = sal.pc;
-  b->loc->address = adjusted_address;
-
-  if (sal.symtab == NULL)
-    b->source_file = NULL;
-  else
-    b->source_file = savestring (sal.symtab->filename,
-				 strlen (sal.symtab->filename));
-  b->loc->section = sal.section;
   b->type = bptype;
   b->language = current_language->la_language;
   b->input_radix = input_radix;
   b->thread = -1;
-  b->line_number = sal.line;
   b->enable_state = bp_enabled;
   b->next = 0;
   b->silent = 0;
@@ -4207,7 +4291,7 @@ set_raw_breakpoint (struct symtab_and_li
   b->forked_inferior_pid = 0;
   b->exec_pathname = NULL;
   b->ops = NULL;
-  b->pending = 0;
+  b->condition_not_parsed = 0;
 
   /* Add this breakpoint to the end of the chain
      so that a list of breakpoints will come out in order
@@ -4222,6 +4306,65 @@ set_raw_breakpoint (struct symtab_and_li
 	b1 = b1->next;
       b1->next = b;
     }
+  return b;
+}
+
+/* Initialize loc->function_name.  */
+static void
+set_breakpoint_location_function (struct bp_location *loc)
+{
+  if (loc->owner->type == bp_breakpoint
+      || loc->owner->type == bp_hardware_breakpoint)
+    {
+      find_pc_partial_function (loc->address, &(loc->function_name), 
+				NULL, NULL);
+      if (loc->function_name)
+	loc->function_name = xstrdup (loc->function_name);
+    }
+}
+
+/* set_raw_breakpoint is a low level routine for allocating and
+   partially initializing a breakpoint of type BPTYPE.  The newly
+   created breakpoint's address, section, source file name, and line
+   number are provided by SAL.  The newly created and partially
+   initialized breakpoint is added to the breakpoint chain and
+   is also returned as the value of this function.
+
+   It is expected that the caller will complete the initialization of
+   the newly created breakpoint struct as well as output any status
+   information regarding the creation of a new breakpoint.  In
+   particular, set_raw_breakpoint does NOT set the breakpoint
+   number!  Care should be taken to not allow an error to occur
+   prior to completing the initialization of the breakpoint.  If this
+   should happen, a bogus breakpoint will be left on the chain.  */
+
+struct breakpoint *
+set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
+{
+  struct breakpoint *b = set_raw_breakpoint_without_location (bptype);
+  CORE_ADDR adjusted_address;
+
+  /* Adjust the breakpoint's address prior to allocating a location.
+     Once we call allocate_bp_location(), that mostly uninitialized
+     location will be placed on the location chain.  Adjustment of the
+     breakpoint may cause read_memory_nobpt() to be called and we do
+     not want its scan of the location chain to find a breakpoint and
+     location that's only been partially initialized.  */
+  adjusted_address = adjust_breakpoint_address (sal.pc, bptype);
+
+  b->loc = allocate_bp_location (b, bptype);
+  b->loc->requested_address = sal.pc;
+  b->loc->address = adjusted_address;
+
+  if (sal.symtab == NULL)
+    b->source_file = NULL;
+  else
+    b->source_file = savestring (sal.symtab->filename,
+				 strlen (sal.symtab->filename));
+  b->loc->section = sal.section;
+  b->line_number = sal.line;
+
+  set_breakpoint_location_function (b->loc);
 
   check_duplicates (b);
   breakpoints_changed ();
@@ -4235,10 +4378,16 @@ set_raw_breakpoint (struct symtab_and_li
 void
 make_breakpoint_permanent (struct breakpoint *b)
 {
+  struct bp_location *bl;
   b->enable_state = bp_permanent;
 
-  /* By definition, permanent breakpoints are already present in the code.  */
-  b->loc->inserted = 1;
+  /* By definition, permanent breakpoints are already present in the code. 
+     Mark all locations as inserted.  For now, make_breakpoint_permanent
+     is called in just one place, so it's hard to say if it's reasonable
+     to have permanent breakpoint with multiple locations or not,
+     but it's easy to implmement.  */
+  for (bl = b->loc; bl; bl = bl->next)
+    bl->inserted = 1;
 }
 
 static struct breakpoint *
@@ -4431,20 +4580,28 @@ create_solib_event_breakpoint (CORE_ADDR
 void
 disable_breakpoints_in_shlibs (void)
 {
-  struct breakpoint *b;
+  struct bp_location *loc;
   int disabled_shlib_breaks = 0;
 
-  ALL_BREAKPOINTS (b)
+  ALL_BP_LOCATIONS (loc)
   {
+    struct breakpoint *b = loc->owner;
+    /* We apply the check to all breakpoints, including disabled
+       for those with loc->duplicate set.  This is so that when breakpoint
+       becomes enabled, or the duplicate is removed, gdb will try to insert
+       all breakpoints.  If we don't set shlib_disabled here, we'll try
+       to insert those breakpoints and fail.  */
     if (((b->type == bp_breakpoint) || (b->type == bp_hardware_breakpoint))
-	&& breakpoint_enabled (b) && !b->loc->duplicate
+	&& !loc->shlib_disabled
 #ifdef PC_SOLIB
-	&& PC_SOLIB (b->loc->address)
+	&& PC_SOLIB (loc->address)
 #else
-	&& solib_address (b->loc->address)
+	&& solib_address (loc->address)
 #endif
 	)
-	b->enable_state = bp_shlib_disabled;
+      {
+	loc->shlib_disabled = 1;
+      }
   }
 }
 
@@ -4454,27 +4611,28 @@ disable_breakpoints_in_shlibs (void)
 void
 disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
 {
-  struct breakpoint *b;
+  struct bp_location *loc;
   int disabled_shlib_breaks = 0;
 
-  ALL_BREAKPOINTS (b)
+  ALL_BP_LOCATIONS (loc)
   {
-    if ((b->loc->loc_type == bp_loc_hardware_breakpoint
-	|| b->loc->loc_type == bp_loc_software_breakpoint)
-	&& breakpoint_enabled (b) && !b->loc->duplicate)
+    struct breakpoint *b = loc->owner;
+    if ((loc->loc_type == bp_loc_hardware_breakpoint
+	 || loc->loc_type == bp_loc_software_breakpoint)
+	&& !loc->shlib_disabled)
       {
 #ifdef PC_SOLIB
-	char *so_name = PC_SOLIB (b->loc->address);
+	char *so_name = PC_SOLIB (loc->address);
 #else
-	char *so_name = solib_address (b->loc->address);
+	char *so_name = solib_address (loc->address);
 #endif
 	if (so_name && !strcmp (so_name, solib->so_name))
           {
-	    b->enable_state = bp_shlib_disabled;
+	    loc->shlib_disabled = 1;
 	    /* At this point, we cannot rely on remove_breakpoint
 	       succeeding so we must mark the breakpoint as not inserted
 	       to prevent future errors occurring in remove_breakpoints.  */
-	    b->loc->inserted = 0;
+	    loc->inserted = 0;
 	    if (!disabled_shlib_breaks)
 	      {
 		target_terminal_ours_for_output ();
@@ -4894,7 +5052,7 @@ mention (struct breakpoint *b)
     {
       /* i18n: cagney/2005-02-11: Below needs to be merged into a
 	 single string.  */
-      if (b->pending)
+      if (b->loc == NULL)
 	{
 	  printf_filtered (_(" (%s) pending."), b->addr_string);
 	}
@@ -4908,6 +5066,16 @@ mention (struct breakpoint *b)
 	  if (b->source_file)
 	    printf_filtered (": file %s, line %d.",
 			     b->source_file, b->line_number);
+	  
+	  if (b->loc->next)
+	    {
+	      struct bp_location *loc = b->loc;
+	      int n = 0;
+	      for (; loc; loc = loc->next)
+		++n;
+	      printf_filtered (" (%d locations)", n);		
+	    }
+
 	}
     }
   do_cleanups (old_chain);
@@ -4917,6 +5085,24 @@ mention (struct breakpoint *b)
 }
 
 
+static struct bp_location *
+add_location_to_breakpoint (struct breakpoint *b, enum bptype bptype,
+			    const struct symtab_and_line *sal)
+{
+  struct bp_location *loc, **tmp;
+
+  loc = allocate_bp_location (b, bptype);
+  for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
+    ;
+  *tmp = loc;
+  loc->requested_address = sal->pc;
+  loc->address = adjust_breakpoint_address (loc->requested_address,
+					    bptype);
+  loc->section = sal->section;
+
+  set_breakpoint_location_function (loc);
+  return loc;
+}
 
 /* Create a breakpoint with SAL as location.  Use ADDR_STRING
    as textual description of the location, and COND_STRING
@@ -4926,13 +5112,14 @@ mention (struct breakpoint *b)
    create_breakpoints function.  */
 
 static void
-create_breakpoint (struct symtab_and_line sal, char *addr_string,
+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,
 		   struct breakpoint *pending_bp)
 {
-  struct breakpoint *b;
+  struct breakpoint *b = NULL;
+  int i;
 
   if (type == bp_hardware_breakpoint)
     {
@@ -4946,50 +5133,46 @@ create_breakpoint (struct symtab_and_lin
 	error (_("Hardware breakpoints used exceeds limit."));
     }
 
-  if (from_tty)
-    describe_other_breakpoints (sal.pc, sal.section, thread);
-  
-  b = set_raw_breakpoint (sal, type);
-  set_breakpoint_count (breakpoint_count + 1);
-  b->number = breakpoint_count;
-  b->thread = thread;
+  for (i = 0; i < sals.nelts; ++i)
+    {
+      struct symtab_and_line sal = sals.sals[i];
+      struct bp_location *loc;
+
+      if (from_tty)
+	describe_other_breakpoints (sal.pc, sal.section, thread);
+
+      if (i == 0)
+	{
+	  b = set_raw_breakpoint (sal, type);
+	  set_breakpoint_count (breakpoint_count + 1);
+	  b->number = breakpoint_count;
+	  b->thread = thread;
   
-  b->cond_string = cond_string;
-  b->ignore_count = ignore_count;
-  b->enable_state = bp_enabled;
-  b->disposition = disposition;
-  /* If resolving a pending breakpoint, a check must be made to see if
-     the user has specified a new condition or commands for the 
-     breakpoint.  A new condition will override any condition that was 
-     initially specified with the initial breakpoint command.  */
-  if (pending_bp)
-    {
-      if (pending_bp->cond_string)
-	b->cond_string = savestring (pending_bp->cond_string, 
-				     strlen (pending_bp->cond_string));
-      
-      /* If there are commands associated with the breakpoint, they should 
-	 be copied too.  */
-      if (pending_bp->commands)
-	b->commands = copy_command_lines (pending_bp->commands);
-	    
-      /* We have to copy over the ignore_count and thread as well.  */
-      b->ignore_count = pending_bp->ignore_count;
-      b->thread = pending_bp->thread;
-    }
+	  b->cond_string = cond_string;
+	  b->ignore_count = ignore_count;
+	  b->enable_state = bp_enabled;
+	  b->disposition = disposition;
 
-  if (b->cond_string)
-    {
-      char *arg = b->cond_string;
-      b->loc->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0);
-      if (*arg)
+	  loc = b->loc;
+	}
+      else
 	{
-	  if (pending_bp)
-	    error (_("Junk at end of pending breakpoint condition expression"));
-	  else
-	    error (_("Garbage %s follows condition"), arg);
+	  loc = add_location_to_breakpoint (b, type, &sal);
 	}
-    }	    
+
+      if (b->cond_string)
+	{
+	  char *arg = b->cond_string;
+	  b->loc->cond = parse_exp_1 (&arg, block_for_pc (b->loc->address), 0);
+	  if (*arg)
+	    {
+	      if (pending_bp)
+		error (_("Junk at end of pending breakpoint condition expression"));
+	      else
+		error (_("Garbage %s follows condition"), arg);
+	    }
+	}
+    }   
 
   if (addr_string)
     b->addr_string = addr_string;
@@ -5031,7 +5214,11 @@ create_breakpoints (struct symtabs_and_l
   int i;
   for (i = 0; i < sals.nelts; ++i)
     {
-      create_breakpoint (sals.sals[i], addr_string[i],
+      struct symtabs_and_lines sals2;
+      sals2.sals = sals.sals + i;
+      sals2.nelts = 1;
+
+      create_breakpoint (sals2, addr_string[i],
 			 cond_string, type, disposition,
 			 thread, ignore_count, from_tty,
 			 pending_bp);
@@ -5360,19 +5547,19 @@ break_command_1 (char *arg, int flag, in
 
       make_cleanup (xfree, copy_arg);
 
-      b = set_raw_breakpoint (sal, hardwareflag ? bp_hardware_breakpoint 
-		              : bp_breakpoint);
+      b = set_raw_breakpoint_without_location (hardwareflag 
+					       ? bp_hardware_breakpoint 
+					       : bp_breakpoint);
       set_breakpoint_count (breakpoint_count + 1);
       b->number = breakpoint_count;
-      b->loc->cond = NULL;
       b->thread = thread;
       b->addr_string = addr_string[0];
       b->cond_string = cond_string;
       b->ignore_count = ignore_count;
-      b->pending = 1;
       b->disposition = tempflag ? disp_del : disp_donttouch;
       b->from_tty = from_tty;
       b->flag = flag;
+      b->condition_not_parsed = 1;
       mention (b);
     }
   
@@ -5411,7 +5598,7 @@ do_captured_breakpoint (struct ui_out *u
   struct cleanup *breakpoint_chain = NULL;
   int i;
   char **addr_string;
-  char *cond_string;
+  char *cond_string = 0;
 
   char *address_end;
 
@@ -5440,10 +5627,6 @@ do_captured_breakpoint (struct ui_out *u
   cond = xcalloc (sals.nelts, sizeof (struct expression *));
   make_cleanup (xfree, cond);
 
-  /* Allocate space for all the cond strings. */
-  cond_string = xcalloc (sals.nelts, sizeof (char **));
-  make_cleanup (xfree, cond_string);
-
   /* ----------------------------- SNIP -----------------------------
      Anything added to the cleanup chain beyond this point is assumed
      to be part of a breakpoint.  If the breakpoint create goes
@@ -6733,23 +6916,35 @@ clear_command (char *arg, int from_tty)
 	 breakpoint chain, and add them to the 'found' chain.  */
       ALL_BREAKPOINTS_SAFE (b, tmp)
 	{
+	  int match = 0;
 	  /* Are we going to delete b? */
 	  if (b->type != bp_none
 	      && b->type != bp_watchpoint
 	      && b->type != bp_hardware_watchpoint
 	      && b->type != bp_read_watchpoint
-	      && b->type != bp_access_watchpoint
-	      /* Not if b is a watchpoint of any sort... */
-	      && (((sal.pc && (b->loc->address == sal.pc)) 
-		   && (!section_is_overlay (b->loc->section)
-		       || b->loc->section == sal.section))
-		  /* Yes, if sal.pc matches b (modulo overlays).  */
-		  || ((default_match || (0 == sal.pc))
-		      && b->source_file != NULL
-		      && sal.symtab != NULL
-		      && strcmp (b->source_file, sal.symtab->filename) == 0
-		      && b->line_number == sal.line)))
-	    /* Yes, if sal source file and line matches b.  */
+	      && b->type != bp_access_watchpoint)
+	    {
+	      struct bp_location *loc = b->loc;
+	      for (; loc; loc = loc->next)
+		{
+		  int pc_match = sal.pc 
+		    && (loc->address == sal.pc)
+		    && (!section_is_overlay (loc->section)
+			|| loc->section == sal.section);
+		  int line_match = ((default_match || (0 == sal.pc))
+				    && b->source_file != NULL
+				    && sal.symtab != NULL
+				    && strcmp (b->source_file, sal.symtab->filename) == 0
+				    && b->line_number == sal.line);
+		  if (pc_match || line_match)
+		    {
+		      match = 1;
+		      break;
+		    }
+		}
+	    }
+
+	  if (match)
 	    {
 	      /* Remove it from breakpoint_chain...  */
 	      if (b == breakpoint_chain)
@@ -6824,6 +7019,35 @@ 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)
+{
+  /* 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;
+
+  for (; *tmp && here;)
+    {
+      if (*tmp == here)
+	{
+	  *tmp = here->global_next;
+	  here = here->next;
+	}
+      else
+	{
+	  tmp = &((*tmp)->global_next);
+	}
+    }
+}
+
 /* Delete a breakpoint and clean up all traces of it in the data
    structures. */
 
@@ -6856,17 +7080,23 @@ delete_breakpoint (struct breakpoint *bp
     deprecated_delete_breakpoint_hook (bpt);
   breakpoint_delete_event (bpt->number);
 
-  if (bpt->loc->inserted)
-    remove_breakpoint (bpt->loc, mark_inserted);
+  for (loc = bpt->loc; loc; loc = loc->next)
+    {
+      if (loc->inserted)
+	remove_breakpoint (loc, mark_inserted);
+
+      free_valchain (loc);
 
-  free_valchain (bpt->loc);
+      if (loc->cond)
+	xfree (loc->cond);
+
+      if (loc->function_name)
+	xfree (loc->function_name);
+    }
 
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
 
-  if (bp_location_chain == bpt->loc)
-    bp_location_chain = bpt->loc->next;
-
   /* If we have callback-style exception catchpoints, don't go through
      the adjustments to the C++ runtime library etc. if the inferior
      isn't actually running.  target_enable_exception_callback for a
@@ -6896,82 +7126,83 @@ delete_breakpoint (struct breakpoint *bp
       break;
     }
 
-  ALL_BP_LOCATIONS (loc)
-    if (loc->next == bpt->loc)
-      {
-	loc->next = bpt->loc->next;
-	break;
-      }
+  unlink_locations_from_global_list (bpt);
 
   check_duplicates (bpt);
-  /* If this breakpoint was inserted, and there is another breakpoint
-     at the same address, we need to insert the other breakpoint.  */
-  if (bpt->loc->inserted
-      && bpt->type != bp_hardware_watchpoint
+
+  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)
-    {
-      ALL_BREAKPOINTS (b)
-	if (b->loc->address == bpt->loc->address
-	    && b->loc->section == bpt->loc->section
-	    && !b->loc->duplicate
-	    && b->enable_state != bp_disabled
-	    && b->enable_state != bp_shlib_disabled
-	    && !b->pending
-	    && b->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 (b->enable_state == bp_permanent)
-	    internal_error (__FILE__, __LINE__,
-			    _("another breakpoint was inserted on top of "
-			    "a permanent breakpoint"));
-
-	  memset (&b->loc->target_info, 0, sizeof (b->loc->target_info));
-	  b->loc->target_info.placed_address = b->loc->address;
-	  if (b->type == bp_hardware_breakpoint)
-	    val = target_insert_hw_breakpoint (&b->loc->target_info);
-	  else
-	    val = target_insert_breakpoint (&b->loc->target_info);
+    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;
 
-	  /* 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);
-	     
+		  /* 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 (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 (b->loc->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
-	    b->loc->inserted = 1;
-	}
-    }
+		  /* 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)
@@ -7013,9 +7244,12 @@ delete_breakpoint (struct breakpoint *bp
      bp, we mark it as deleted before freeing its storage. */
   bpt->type = bp_none;
 
-  if (bpt->loc->cond)
-    xfree (bpt->loc->cond);
-  xfree (bpt->loc);
+  for (loc = bpt->loc; loc;)
+    {
+      struct bp_location *loc_next = loc->next;
+      xfree (loc);
+      loc = loc_next;
+    }
   xfree (bpt);
 }
 
@@ -7083,94 +7317,95 @@ delete_command (char *arg, int from_tty)
     map_breakpoint_numbers (arg, delete_breakpoint);
 }
 
-static void
-unlink_locations_from_global_list (struct breakpoint *bpt)
-  /* Remove locations of this breakpoint from the list of
-     all breakpoint locations.  */
+static int
+all_locations_are_pending (struct bp_location *loc)
 {
-  struct bp_location **tmp = &bp_location_chain;
-  struct bp_location *here = bpt->loc;
-
-  if (here == NULL)
-    return;
-
-  for (; *tmp && *tmp != here; tmp = &((*tmp)->next));
-  gdb_assert (*tmp);
-       
-  *tmp = here->next;	
+  for (; loc; loc = loc->next)
+    if (!loc->shlib_disabled)
+      return 0;
+  return 1;
 }
 
-
 static void
-update_breakpoint_location (struct breakpoint *b,
-			    struct symtabs_and_lines sals)
+update_breakpoint_locations (struct breakpoint *b,
+			     struct symtabs_and_lines sals)
 {
   int i;
   char *s;
-  /* FIXME: memleak.  */
-  struct bp_location *existing = b->loc;
-  struct bp_location *loc;
-  struct symtab_and_line sal;
-  
-  if (b->enable_state == bp_shlib_disabled && sals.nelts == 0)
+  struct bp_location *existing_locations = b->loc;
+
+  /* If there's no new locations, and all existing locations
+     are pending, don't do anything.  This optimizes
+     the common case where all locations are in the same
+     shared library, that was unloaded. We'd like to
+     retain the location, so that when the library
+     is loaded again, we don't loose the enabled/disabled
+     status of the individual locations.  */
+  if (all_locations_are_pending (existing_locations) && sals.nelts == 0)
     return;
 
   unlink_locations_from_global_list (b);
   b->loc = NULL;
 
-  gdb_assert (sals.nelts == 0 || sals.nelts == 1);
-  if (sals.nelts == 0)
-    return;
-  sal = sals.sals[0];
-
-  loc = allocate_bp_location (b, b->type);
-  loc->requested_address = sal.pc;
-  loc->address = adjust_breakpoint_address (loc->requested_address,
-					    b->type);
-  loc->section = sal.section;
-  b->loc = loc;
-
-  /* Reparse conditions, they might contain references to the
-     old symtab.  */
-  if (b->cond_string != NULL)
+  for (i = 0; i < sals.nelts; ++i)
     {
-      struct gdb_exception e;
-      
-      s = b->cond_string;
-      TRY_CATCH (e, RETURN_MASK_ERROR)
-	{
-	  loc->cond = parse_exp_1 (&s, block_for_pc (sal.pc), 
-				   0);
-	}
-      if (e.reason < 0)
-	{
-	  warning (_("failed to reevaluate condition for breakpoint %d: %s"), 
-		   b->number, e.message);
-	  b->enable_state = bp_disabled;
-	}
-    }
+      struct bp_location *new_loc = 
+	add_location_to_breakpoint (b, b->type, &(sals.sals[i]));
 
-  if (b->source_file != NULL)
-    xfree (b->source_file);
-  if (sal.symtab == NULL)
-    b->source_file = NULL;
-  else
-    b->source_file =
-      savestring (sal.symtab->filename,
-		  strlen (sal.symtab->filename));
+      /* Reparse conditions, they might contain references to the
+	 old symtab.  */
+      if (b->cond_string != NULL)
+	{
+	  struct gdb_exception e;
 
-  if (b->line_number == 0)
-    b->line_number = sal.line;
+	  s = b->cond_string;
+	  TRY_CATCH (e, RETURN_MASK_ERROR)
+	    {
+	      new_loc->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 
+					   0);
+	    }
+	  if (e.reason < 0)
+	    {
+	      warning (_("failed to reevaluate condition for breakpoint %d: %s"), 
+		       b->number, e.message);
+	      new_loc->enabled = 0;
+	    }
+	}
 
-  if (b->enable_state == bp_shlib_disabled)
-    b->enable_state = bp_enabled;
+      if (b->source_file != NULL)
+	xfree (b->source_file);
+      if (sals.sals[i].symtab == NULL)
+	b->source_file = NULL;
+      else
+	b->source_file =
+	  savestring (sals.sals[i].symtab->filename,
+		      strlen (sals.sals[i].symtab->filename));
 
-  b->pending = 0;
+      if (b->line_number == 0)
+	b->line_number = sals.sals[i].line;
+    }
 
-  check_duplicates (b);
+  /* If possible, carry over 'disable' status from existing breakpoints.  */
+  {
+    struct bp_location *e = existing_locations;
+    for (; e; e = e->next)
+      {
+	if (!e->enabled && e->function_name)
+	  {
+	    struct bp_location *l = b->loc;
+	    for (; l; l = l->next)
+	      if (l->function_name 
+		  && strcmp (e->function_name, l->function_name) == 0)
+		{
+		  l->enabled = 0;
+		  break;
+		}
+	  }
+      }
+  }
 
-  if (existing)
-    free_bp_location (existing);
+  if (existing_locations)
+    free_bp_location (existing_locations);
 }
 
 
@@ -7227,8 +7462,10 @@ breakpoint_re_set_one (void *bint)
 	     don't need extra messages.  If breakpoint is in bp_shlib_disabled
 	     state, then user already saw the message about that breakpoint
 	     being disabled, and don't want to see more errors.  */
-	  if (not_found && (b->pending || b->enable_state == bp_shlib_disabled
-			    || b->enable_state == bp_disabled))
+	  if (not_found 
+	      && (b->condition_not_parsed 
+		  || (b->loc && b->loc->shlib_disabled)
+		  || b->enable_state == bp_disabled))
 	    not_found_and_ok = 1;
 
 	  if (!not_found_and_ok)
@@ -7249,7 +7486,7 @@ breakpoint_re_set_one (void *bint)
       
       gdb_assert (sals.nelts == 1);
       resolve_sal_pc (&sals.sals[0]);
-      if (b->pending && s && s[0])
+      if (b->condition_not_parsed && s && s[0])
 	{
 	  char *cond_string = 0;
 	  int thread = -1;
@@ -7258,9 +7495,14 @@ breakpoint_re_set_one (void *bint)
 	  if (cond_string)
 	    b->cond_string = cond_string;
 	  b->thread = thread;
+	  b->condition_not_parsed = 0;
 	}
 
-      update_breakpoint_location (b, sals);
+      update_breakpoint_locations (b, sals);
+
+      /* Now that this is re-enabled, check_duplicates
+	 can be used. */
+      check_duplicates (b);
 
       xfree (sals.sals);
       break;
@@ -7524,6 +7766,48 @@ map_breakpoint_numbers (char *args, void
     }
 }
 
+static struct bp_location *
+find_location_by_number (char *number)
+{
+  char *dot = strchr (number, '.');
+  char *p1;
+  int bp_num;
+  int loc_num;
+  struct breakpoint *b;
+  struct bp_location *loc;  
+
+  *dot = '\0';
+
+  p1 = number;
+  bp_num = get_number_or_range (&p1);
+  if (bp_num == 0)
+    error (_("Bad breakpoint number '%s'"), number);
+
+  ALL_BREAKPOINTS (b)
+    if (b->number == bp_num)
+      {
+	break;
+      }
+
+  if (!b || b->number != bp_num)
+    error (_("Bad breakpoint number '%s'"), number);
+  
+  p1 = dot+1;
+  loc_num = get_number_or_range (&p1);
+  if (loc_num == 0)
+    error (_("Bad breakpoint location number '%s'"), number);
+
+  --loc_num;
+  loc = b->loc;
+  for (;loc_num && loc; --loc_num, loc = loc->next)
+    ;
+  if (!loc)
+    error (_("Bad breakpoint location number '%s'"), dot+1);
+    
+  return loc;  
+}
+
+
 /* Set ignore-count of breakpoint number BPTNUM to COUNT.
    If from_tty is nonzero, it prints a message to that effect,
    which ends with a period (no newline).  */
@@ -7579,6 +7863,13 @@ disable_command (char *args, int from_tt
       default:
 	continue;
       }
+  else if (strchr (args, '.'))
+    {
+      struct bp_location *loc = find_location_by_number (args);
+      if (loc)
+	loc->enabled = 0;
+      check_duplicates (loc->owner);
+    }
   else
     map_breakpoint_numbers (args, disable_breakpoint);
 }
@@ -7711,6 +8002,13 @@ enable_command (char *args, int from_tty
       default:
 	continue;
       }
+  else if (strchr (args, '.'))
+    {
+      struct bp_location *loc = find_location_by_number (args);
+      if (loc)
+	loc->enabled = 1;
+      check_duplicates (loc->owner);
+    }
   else
     map_breakpoint_numbers (args, enable_breakpoint);
 }
--- gdb/breakpoint.h	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/breakpoint.h	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -143,9 +143,6 @@ enum enable_state
   {
     bp_disabled,	/* The eventpoint is inactive, and cannot trigger. */
     bp_enabled,		/* The eventpoint is active, and can trigger. */
-    bp_shlib_disabled,	/* The eventpoint's address is in an unloaded solib.
-			   The eventpoint will be automatically enabled 
-			   and reset when that solib is loaded. */
     bp_call_disabled,	/* The eventpoint has been disabled while a call 
 			   into the inferior is "in flight", because some 
 			   eventpoints interfere with the implementation of 
@@ -232,9 +229,14 @@ enum bp_loc_type
 
 struct bp_location
 {
-  /* Chain pointer to the next breakpoint location.  */
+  /* Chain pointer to the next breakpoint location for
+     the same parent breakpoint.  */
   struct bp_location *next;
 
+  /* Pointer to the next breakpoint location, in a global
+     list of all breakpoint locations.  */
+  struct bp_location *global_next;
+ 
   /* Type of this breakpoint location.  */
   enum bp_loc_type loc_type;
 
@@ -249,6 +251,14 @@ struct bp_location
      locations,  the evaluation of expression can be different for
      different locations.  */
   struct expression *cond;
+
+  /* This location's address is in an unloaded solib, and so this
+     location should not be inserted.  It will be automatically
+     enabled when that solib is loaded.  */
+  char shlib_disabled; 
+
+  /* Is this particular location enabled.  */
+  char enabled;
   
   /* Nonzero if this breakpoint is now inserted.  */
   char inserted;
@@ -281,6 +291,8 @@ struct bp_location
      processor's architectual constraints.  */
   CORE_ADDR requested_address;
 
+  char *function_name;
+
   /* Details of the placed breakpoint, when inserted.  */
   struct bp_target_info target_info;
 
@@ -423,8 +435,10 @@ struct breakpoint
        second bit : 0 normal breakpoint, 1 hardware breakpoint. */
     int flag;
 
-    /* Is breakpoint pending on shlib loads?  */
-    int pending;
+    /* Is breakpoint's condition not yet parsed because we found
+       no location initially so had no context to parse
+       the condition in.  */
+    int condition_not_parsed;
   };
 
 /* The following stuff is an abstract data type "bpstat" ("breakpoint
--- gdb/testsuite/gdb.cp/ovldbreak.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.cp/ovldbreak.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -153,7 +153,7 @@ set_bp_overloaded "foo::overload1arg" "$
 # Verify the breakpoints.
 
 gdb_test "info break" \
-    "Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
+    "Num     Type\[\t \]+Disp Enb  Address\[\t \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
@@ -211,7 +211,7 @@ gdb_expect {
 }
 
 gdb_test "info break" \
-    "Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
+    "Num     Type\[\t \]+Disp Enb  Address\[\t \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
@@ -290,7 +290,7 @@ gdb_expect {
 }
 
 gdb_test "info break" \
-    "Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
+    "Num     Type\[\t \]+Disp Enb  Address\[\t \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
--- gdb/testsuite/gdb.base/pending.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.base/pending.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -71,8 +71,8 @@ gdb_test_multiple "break pendfunc1" "set
 }
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*pendfunc1.*" \
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*pendfunc1.*" \
 "single pending breakpoint info"
 
 #
@@ -86,8 +86,8 @@ gdb_test "break main" \
     "breakpoint function"
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*pendfunc1.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*pendfunc1.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$mainline" \
 "pending plus real breakpoint info"
 
@@ -108,8 +108,8 @@ gdb_test_multiple "break pendfunc2" "Don
 gdb_test "condition 1 k == 1" ""
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*pendfunc1.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*pendfunc1.*
 \[\t \]+stop only if k == 1.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$mainline" \
 "pending plus condition"
@@ -121,8 +121,8 @@ gdb_test "info break" \
 gdb_test "disable 1" ""
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep n.*PENDING.*pendfunc1.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep n\\(p\\).*PENDING.*pendfunc1.*
 \[\t \]+stop only if k == 1.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$mainline" \
 "pending disabled"
@@ -134,8 +134,8 @@ gdb_test "commands 1\nprint k\nend" "" \
         "Set commands for pending breakpoint"
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep n.*PENDING.*pendfunc1.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep n\\(p\\).*PENDING.*pendfunc1.*
 \[\t \]+stop only if k == 1.*
 \[\t \]+print k.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$mainline" \
@@ -154,12 +154,12 @@ gdb_test_multiple "break pendshr.c:$bp2_
 }
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep n.*PENDING.*pendfunc1.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep n\\(p\\).*PENDING.*pendfunc1.*
 \[\t \]+stop only if k == 1.*
 \[\t \]+print k.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$mainline.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*pendshr.c:$bp2_loc if x > 3.*" \
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*pendshr.c:$bp2_loc if x > 3.*" \
 "multiple pending breakpoints"
 
 
@@ -179,13 +179,13 @@ gdb_test {ignore $bpnum 2} "Will ignore 
     "set ignore count on pending breakpoint 3"
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep n.*PENDING.*pendfunc1.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep n\\(p\\).*PENDING.*pendfunc1.*
 \[\t \]+stop only if k == 1.*
 \[\t \]+print k.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$mainline.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*pendshr.c:$bp2_loc if x > 3.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*pendshr.c:$bp3_loc.*ignore next 2 hits.*" \
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*pendshr.c:$bp2_loc if x > 3.*
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*pendshr.c:$bp3_loc.*ignore next 2 hits.*" \
 "multiple pending breakpoints 2"
 
 #
@@ -253,7 +253,7 @@ gdb_test_multiple "break imaginary" "set
 rerun_to_main
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$mainline.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*imaginary.*" \
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*imaginary.*" \
 "verify pending breakpoint after restart"
--- gdb/testsuite/gdb.base/break.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.base/break.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -179,7 +179,7 @@ set bp_location8 [gdb_get_line_number "s
 set bp_location9 [gdb_get_line_number "set breakpoint 9 here" $srcfile1]
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$main_line.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in marker2 at .*$srcfile1:($bp_location8|$bp_location9).*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in factorial$proto at .*$srcfile:$bp_location7.*
@@ -309,7 +309,7 @@ gdb_test  "tbreak $srcfile:$bp_location1
 #
 # check to see what breakpoints are set (temporary this time)
 #
-gdb_test "info break" "Num Type.*Disp Enb Address.*What.*\[\r\n\]
+gdb_test "info break" "Num     Type.*Disp Enb  Address.*What.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$main_line.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in factorial$proto at .*$srcfile:$bp_location7.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location1.*\[\r\n\]
--- gdb/testsuite/gdb.base/annota3.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.base/annota3.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -127,8 +127,8 @@ gdb_expect {
 send_gdb "info break\n" 
 gdb_expect_list "breakpoint info" "$gdb_prompt$" {
     "\r\n\032\032post-prompt\r\n"
-    "Num Type           Disp Enb Address    +What\r\n"
-    "1   breakpoint     keep y   0x\[0-9a-zA-Z\]+ +in main at .*annota3.c:32\r\n"
+    "Num     Type           Disp Enb  Address    +What\r\n"
+    "1       breakpoint     keep y    0x\[0-9a-zA-Z\]+ +in main at .*annota3.c:32\r\n"
 }
 
 
--- gdb/testsuite/gdb.base/sepdebug.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.base/sepdebug.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -179,7 +179,7 @@ set bp_location8 [gdb_get_line_number "s
 set bp_location9 [gdb_get_line_number "set breakpoint 9 here"]
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$main_line.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in marker2 at .*$srcfile:($bp_location8|$bp_location9).*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in factorial at .*$srcfile:$bp_location7.*
@@ -298,7 +298,7 @@ gdb_test  "tbreak $srcfile:$bp_location1
 #
 # check to see what breakpoints are set (temporary this time)
 #
-gdb_test "info break" "Num Type.*Disp Enb Address.*What.*\[\r\n\]
+gdb_test "info break" "Num     Type.*Disp Enb  Address.*What.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$main_line.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in factorial at .*$srcfile:$bp_location7.*\[\r\n\]
 \[0-9\]+\[\t \]+breakpoint     del.*y.*in main at .*$srcfile:$bp_location1.*\[\r\n\]
--- gdb/testsuite/gdb.base/condbreak.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.base/condbreak.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -125,14 +125,14 @@ if {$hp_aCC_compiler} {
 }
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location6.*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in marker1$marker1_proto at .*$srcfile1:($bp_location15|$bp_location16).*
-\[\t \]+stop only if 1 == 1.*
+\[\t \]+stop only if \\(1==1\\).*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in main at .*$srcfile:$bp_location1.*
-\[\t \]+stop only if 1 == 1.*
+\[\t \]+stop only if \\(1==1\\).*
 \[0-9\]+\[\t \]+breakpoint     keep y.* in marker2$marker2_proto at .*$srcfile1:($bp_location8|$bp_location9).*
-\[\t \]+stop only if a == 43.*" \
+\[\t \]+stop only if \\(a==43\\).*" \
     "breakpoint info"
 
 
--- gdb/testsuite/gdb.base/unload.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.base/unload.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -81,8 +81,8 @@ gdb_test_multiple "break shrfunc1" "set 
 }
 
 gdb_test "info break" \
-    "Num Type\[ \]+Disp Enb Address\[ \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y.*PENDING.*shrfunc1.*" \
+    "Num     Type\[ \]+Disp Enb  Address\[ \]+What.*
+\[0-9\]+\[\t \]+breakpoint     keep y\\(p\\).*PENDING.*shrfunc1.*" \
 "single pending breakpoint info"
 
 set unloadshr_line [gdb_get_line_number "unloadshr break" ${libsrcfile}]
--- gdb/testsuite/gdb.base/annota1.exp	(/work/mb_mainline/7_pending)	(revision 4831)
+++ gdb/testsuite/gdb.base/annota1.exp	(/work/mb_mainline/8_multiple_locations)	(revision 4831)
@@ -117,9 +117,9 @@ gdb_expect {
 #
 send_gdb "info break\n" 
 gdb_expect {
-    -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-headers\r\n\r\n\032\032field 0\r\nNum \r\n\032\032field 1\r\nType           \r\n\032\032field 2\r\nDisp \r\n\032\032field 3\r\nEnb \r\n\032\032field 4\r\nAddress    +\r\n\032\032field 5\r\nWhat\r\n\r\n\032\032breakpoints-table\r\n\r\n\032\032record\r\n\r\n\032\032field 0\r\n1   \r\n\032\032field 1\r\nbreakpoint     \r\n\032\032field 2\r\nkeep \r\n\032\032field 3\r\ny   \r\n\032\032field 4\r\n$hex +\r\n\032\032field 5\r\nin main at ${escapedsrcfile}:$main_line\r\n\r\n\032\032breakpoints-table-end\r\n$gdb_prompt$" \
+    -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-headers\r\n\r\n\032\032field 0\r\nNum     \r\n\032\032field 1\r\nType           \r\n\032\032field 2\r\nDisp \r\n\032\032field 3\r\nEnb  \r\n\032\032field 4\r\nAddress    +\r\n\032\032field 5\r\nWhat\r\n\r\n\032\032breakpoints-table\r\n\r\n\032\032record\r\n\r\n\032\032field 0\r\n1       \r\n\032\032field 1\r\nbreakpoint     \r\n\032\032field 2\r\nkeep \r\n\032\032field 3\r\ny    \r\n\032\032field 4\r\n$hex +\r\n\032\032field 5\r\nin main at ${escapedsrcfile}:$main_line\r\n\r\n\032\032breakpoints-table-end\r\n$gdb_prompt$" \
 	{pass "breakpoint info"}
-    -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-headers\r\n\r\n\032\032field 0\r\nNum \r\n\032\032field 1\r\nType           \r\n\032\032field 2\r\nDisp \r\n\032\032field 3\r\nEnb \r\n\032\032field 4\r\nAddress    +\r\n\032\032field 5\r\nWhat\r\n\r\n\032\032breakpoints-table\r\n\r\n\032\032record\r\n\r\n\032\032field 0\r\n1   \r\n\032\032field 1\r\nbreakpoint     \r\n\032\032field 2\r\nkeep \r\n\032\032field 3\r\ny   \r\n\032\032field 4\r\n$hex +\r\n\032\032field 5\r\nin main at .*${srcfile}:$main_line\r\n\r\n\032\032breakpoints-table-end\r\n$gdb_prompt$" \
+    -re "\r\n\032\032post-prompt\r\n\r\n\032\032breakpoints-headers\r\n\r\n\032\032field 0\r\nNum     \r\n\032\032field 1\r\nType           \r\n\032\032field 2\r\nDisp \r\n\032\032field 3\r\nEnb  \r\n\032\032field 4\r\nAddress    +\r\n\032\032field 5\r\nWhat\r\n\r\n\032\032breakpoints-table\r\n\r\n\032\032record\r\n\r\n\032\032field 0\r\n1       \r\n\032\032field 1\r\nbreakpoint     \r\n\032\032field 2\r\nkeep \r\n\032\032field 3\r\ny    \r\n\032\032field 4\r\n$hex +\r\n\032\032field 5\r\nin main at .*${srcfile}:$main_line\r\n\r\n\032\032breakpoints-table-end\r\n$gdb_prompt$" \
 	{ setup_xfail "*-*-*" 1270
           fail "breakpoint info"}
    -re ".*$gdb_prompt$" { fail "breakpoint info" }

Property changes on: 
___________________________________________________________________
Name: svk:merge
  d48a11ec-ee1c-0410-b3f5-c20844f99675:/work/mb_mainline/4_bpstat_owner:4823
  d48a11ec-ee1c-0410-b3f5-c20844f99675:/work/mb_mainline/5_per_loc_cond:4824
  d48a11ec-ee1c-0410-b3f5-c20844f99675:/work/mb_mainline/6_create_breakpoints_refactoring:4825
 +d48a11ec-ee1c-0410-b3f5-c20844f99675:/work/mb_mainline/7_pending:4829
  e7755896-6108-0410-9592-8049d3e74e28:/mirrors/gdb/trunk:182811


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