Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* Organization of breakpoint locations
@ 2007-02-19 11:57 Thomas Neumann
  2007-02-19 12:54 ` Daniel Jacobowitz
  2007-02-21  1:53 ` Michael Snyder
  0 siblings, 2 replies; 10+ messages in thread
From: Thomas Neumann @ 2007-02-19 11:57 UTC (permalink / raw)
  To: gdb

Hi,

I would like some suggestions on the organization of breakpoint
locations in breakpoint.c. Currently, all breakpoint locations are
stored in a linear list. This does not scale if the number of
breakpoints is large, see PR 2230 for an example. Instead the
breakpoints should be stored in a suitable search structure (e.g. a
balanced tree).

I have a patch that converts the list into a splay. Works fine, and the
bottleneck indeed goes away, but I am not satisfied with the approach
itself. Changing the data structure is quite simple due to the access
macros used, so I had to change less than 20 lines. Unfortunately my
patch is still big (about 450 lines), as it contains a complete splay
implementation.

It would be nicer to reuse existing data structures instead of
implementing a new one. I thought about using splay-tree in libiberty,
but the breakpoint locations have some unique characteristics: 1. the
locations have to be organized by address, but the address is not
necessarily unique. So the search structure must handle duplicates. 2.
the test suite (and perhaps other code) expect that a breakpoint is
added "last" in the list, i.e. duplicate handling must keep an order
within the duplicates. 3. it must be possible to iterate over search
structure (directly, without callbacks), as otherwise a lot of code has
to be changed.

The splay implementation from libiberty satisfies none of these
constraints. Is there perhaps something else in the gdb sources that I
can reuse? Or should I submit my (admittedly quite large) patch? But
this would probably no longer count as a "small changes" that according
to CONTRIBUTE do not require a copyright assignment.

Thomas


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 11:57 Organization of breakpoint locations Thomas Neumann
@ 2007-02-19 12:54 ` Daniel Jacobowitz
  2007-02-19 14:40   ` Thomas Neumann
  2007-02-21 17:05   ` Michael Snyder
  2007-02-21  1:53 ` Michael Snyder
  1 sibling, 2 replies; 10+ messages in thread
From: Daniel Jacobowitz @ 2007-02-19 12:54 UTC (permalink / raw)
  To: Thomas Neumann; +Cc: gdb

On Mon, Feb 19, 2007 at 11:38:40AM +0100, Thomas Neumann wrote:
> Hi,
> 
> I would like some suggestions on the organization of breakpoint
> locations in breakpoint.c. Currently, all breakpoint locations are
> stored in a linear list. This does not scale if the number of
> breakpoints is large, see PR 2230 for an example. Instead the
> breakpoints should be stored in a suitable search structure (e.g. a
> balanced tree).
> 
> I have a patch that converts the list into a splay. Works fine, and the
> bottleneck indeed goes away, but I am not satisfied with the approach
> itself.

Have you tested this in any real world use yet?  This is only the
first limitation you'll encounter, I think.  For instance, every time
you step and then stop the program, GDB is going to remove every
breakpoint.  That's going to be just as slow.

> It would be nicer to reuse existing data structures instead of
> implementing a new one. I thought about using splay-tree in libiberty,
> but the breakpoint locations have some unique characteristics: 1. the
> locations have to be organized by address, but the address is not
> necessarily unique. So the search structure must handle duplicates. 2.
> the test suite (and perhaps other code) expect that a breakpoint is
> added "last" in the list, i.e. duplicate handling must keep an order
> within the duplicates. 3. it must be possible to iterate over search
> structure (directly, without callbacks), as otherwise a lot of code has
> to be changed.
> 
> The splay implementation from libiberty satisfies none of these
> constraints.

Why do you think that the splay tree in libiberty can't handle any of
these?  Your key would not be the address, but the address plus the
breakpoint sequence number.  That handles one and two.  Then you can
iterate over items using splay_tree_successor.  The key could be the
same pointer as the value, by the way - it just takes a clever
splay_tree_compare_fn.

Another way is to use the address as a key, but store a VEC of
breakpoints as the values, sorted by number.  That's messier though.

> Is there perhaps something else in the gdb sources that I
> can reuse? Or should I submit my (admittedly quite large) patch? But
> this would probably no longer count as a "small changes" that according
> to CONTRIBUTE do not require a copyright assignment.

To be honest, I don't think this will be a small change either way.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 12:54 ` Daniel Jacobowitz
@ 2007-02-19 14:40   ` Thomas Neumann
  2007-02-19 14:48     ` Daniel Jacobowitz
  2007-02-21 17:05   ` Michael Snyder
  1 sibling, 1 reply; 10+ messages in thread
From: Thomas Neumann @ 2007-02-19 14:40 UTC (permalink / raw)
  To: Thomas Neumann, gdb

Daniel Jacobowitz schrieb:
> Have you tested this in any real world use yet?  This is only the
> first limitation you'll encounter, I think.  For instance, every time
>   
hm, I only did manual tests yet. And for a single continue, even a scan
over 50000 breakpoints is not that bad. But I see your point:
Ultimately, this large number of breakpoints comes from automatic
program tracing, which will stop and continue thousands of times.

> these?  Your key would not be the address, but the address plus the
> breakpoint sequence number.  That handles one and two.  Then you can
>   
good idea. I thought that a breakpoint could have more than one
bp_location associated with it, preventing such a scheme (but even then
a breakpoint would probably not have more than one location with the
same address).
> To be honest, I don't think this will be a small change either way.
>   
I will give the libiberty splay a try, that should be easy. But if
resetting breakpoints is indeed as slow as you indicated, by patch is
probably pointless. What a shame. That would have been a very portable
and nice way to automatically trace execution flow.

Thomas


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 14:40   ` Thomas Neumann
@ 2007-02-19 14:48     ` Daniel Jacobowitz
  2007-02-19 14:54       ` Michael Veksler
  2007-02-20  4:46       ` Thomas Neumann
  0 siblings, 2 replies; 10+ messages in thread
From: Daniel Jacobowitz @ 2007-02-19 14:48 UTC (permalink / raw)
  To: Thomas Neumann; +Cc: gdb

On Mon, Feb 19, 2007 at 01:54:27PM +0100, Thomas Neumann wrote:
> > these?  Your key would not be the address, but the address plus the
> > breakpoint sequence number.  That handles one and two.  Then you can
> >   
> good idea. I thought that a breakpoint could have more than one
> bp_location associated with it, preventing such a scheme (but even then
> a breakpoint would probably not have more than one location with the
> same address).

It can't yet have more than one bp_location, but the separation is
there for a reason - I think the one to many mapping will arrive
sometime this year.  But I think we can add a sequence number to
bp_location's just like breakpoints have.

> > To be honest, I don't think this will be a small change either way.
> >   
> I will give the libiberty splay a try, that should be easy. But if
> resetting breakpoints is indeed as slow as you indicated, by patch is
> probably pointless. What a shame. That would have been a very portable
> and nice way to automatically trace execution flow.

I'd like GDB to be able to manage huge breakpoint lists; I'm just
warning you that a lot more work will have to be done first ;-)

One nice thing is that if you kill or crash GDB today, it tends 
to leave breakpoints removed.  If it didn't do this huge massive
removal, it probably wouldn't - perhaps we should add a signal handler
that takes care of that if we change it.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 14:48     ` Daniel Jacobowitz
@ 2007-02-19 14:54       ` Michael Veksler
  2007-02-19 21:24         ` Daniel Jacobowitz
  2007-02-20  4:46       ` Thomas Neumann
  1 sibling, 1 reply; 10+ messages in thread
From: Michael Veksler @ 2007-02-19 14:54 UTC (permalink / raw)
  To: Thomas Neumann, gdb

Daniel Jacobowitz wrote:
> One nice thing is that if you kill or crash GDB today, it tends 
> to leave breakpoints removed.  If it didn't do this huge massive
> removal, it probably wouldn't - perhaps we should add a signal handler
> that takes care of that if we change it.
>   
I always thought (speculated) that breakpoint removal was to simplify 
things like

    (gdb) x /i $pc

Where you don't want to see the INT instruction, but the original value.
GDB crash does sound like another reason.
Being curios, I'd like to ask what was the original reason for
this behavior? Does anyone know? I never saw it documented anywhere.

-- 
Michael Veksler
http:///tx.technion.ac.il/~mveksler


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 14:54       ` Michael Veksler
@ 2007-02-19 21:24         ` Daniel Jacobowitz
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Jacobowitz @ 2007-02-19 21:24 UTC (permalink / raw)
  To: Michael Veksler; +Cc: Thomas Neumann, gdb

On Mon, Feb 19, 2007 at 04:40:42PM +0200, Michael Veksler wrote:
> I always thought (speculated) that breakpoint removal was to simplify 
> things like
> 
>    (gdb) x /i $pc
> 
> Where you don't want to see the INT instruction, but the original value.

Some parts of GDB won't work if we leave breakpoints in.  But, it's
not hard to fix - we have the right helper routines for it nowadays.
Joel made some changes like this in the last year.

> GDB crash does sound like another reason.
> Being curios, I'd like to ask what was the original reason for
> this behavior? Does anyone know? I never saw it documented anywhere.

I don't know either; I'm just guessing.  It may have just been easiest
at the time and no one came back to think about it later.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 14:48     ` Daniel Jacobowitz
  2007-02-19 14:54       ` Michael Veksler
@ 2007-02-20  4:46       ` Thomas Neumann
  2007-02-20 10:26         ` Thomas Neumann
  1 sibling, 1 reply; 10+ messages in thread
From: Thomas Neumann @ 2007-02-20  4:46 UTC (permalink / raw)
  To: Thomas Neumann, gdb

[-- Attachment #1: Type: text/plain, Size: 886 bytes --]

Daniel Jacobowitz schrieb:
> sometime this year.  But I think we can add a sequence number to
> bp_location's just like breakpoints have.
>   
and in fact a separate number seems to be needed, as the breakpoint
number is unknown (zero) when the breakpoint location is created. I did
not investigate this further and  just added a number to bp_location.
> I'd like GDB to be able to manage huge breakpoint lists; I'm just
> warning you that a lot more work will have to be done first ;-)
>   
ok, here is a first step: attached is small patch that stores the
breakpoint locations in a splay instead of a list. The patch is fairly
straight forward: mostly one compare function for splay-tree.c and a
number of iterator functions to simplify the access macros. It even
survived a make check. I hope this patch motivates someone to fix the
scalability issues with breakpoints ;-)


Thomas


[-- Attachment #2: breakpointsinsplay.patch --]
[-- Type: text/plain, Size: 5781 bytes --]

diff -r -u -b gdb-6.6.original/gdb/breakpoint.c gdb-6.6/gdb/breakpoint.c
--- gdb-6.6.original/gdb/breakpoint.c	2006-10-19 17:58:25.000000000 +0200
+++ gdb-6.6/gdb/breakpoint.c	2007-02-19 22:46:09.283209500 +0100
@@ -53,6 +53,7 @@
 #include "solist.h"
 #include "observer.h"
 #include "exceptions.h"
+#include "splay-tree.h"
 
 #include "gdb-events.h"
 #include "mi/mi-common.h"
@@ -254,11 +255,16 @@
 
 /* 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_tree_first();B!=NULL;B = bp_location_tree_next(B))
+
+#define ALL_BP_LOCATIONS_ADDR(B,a)				\
+	for (B = bp_location_tree_first_address(a);B!=NULL;	\
+             B = bp_location_tree_next_address(B,a))
 
 #define ALL_BP_LOCATIONS_SAFE(B,TMP)	\
-	for (B = bp_location_chain;	\
-	     B ? (TMP=B->next, 1): 0;	\
+	for (B = bp_location_tree_first();			\
+            (B!=NULL)?(TMP=bp_location_tree_next(B),1):0;	\
 	     B = TMP)
 
 /* True if breakpoint hit counts should be displayed in breakpoint info.  */
@@ -269,7 +275,9 @@
 
 struct breakpoint *breakpoint_chain;
 
-struct bp_location *bp_location_chain;
+static splay_tree bp_location_tree;
+
+static int bp_location_number;
 
 /* Number of last breakpoint made.  */
 
@@ -339,6 +347,76 @@
    error (_("catch of library unloads not yet implemented on this platform"))
 #endif
 
+/** Compare entries in the breakpoint tree */
+static int
+bp_location_tree_cmp (splay_tree_key l, splay_tree_key r)
+{
+  struct bp_location *lp=(struct bp_location*)l, *rp=(struct bp_location*)r;
+  if (lp->address < rp->address)
+    return -1;
+  if (lp->address > rp->address)
+    return 1;
+  if (lp->number < rp->number)
+    return -1;
+  if (lp->number > rp->number)
+    return 1;
+  return 0;
+}
+
+/** Find the first entry in the breakpoint tree */
+static struct bp_location*
+bp_location_tree_first ()
+{
+  if (bp_location_tree == NULL)
+    return NULL;
+  return (struct bp_location*)splay_tree_min(bp_location_tree)->value;
+}
+
+/** Find the next entry in the breakpoint tree */
+static struct bp_location*
+bp_location_tree_next (struct bp_location* b)
+{
+  splay_tree_node n = splay_tree_successor (bp_location_tree,
+                        (splay_tree_key)b);
+  if (n == NULL)
+    return NULL;
+  return (struct bp_location*)n->value;
+}
+
+/** Find the first entry in the breakpoint tree with a given address*/
+static struct bp_location*
+bp_location_tree_first_address (CORE_ADDR a)
+{
+  struct breakpoint b;
+  struct bp_location l,*r;
+  splay_tree_node n;
+
+  if (bp_location_tree == NULL)
+    return NULL;
+
+  b.number = INT_MIN;
+  l.owner = &b;
+  l.address = a;
+  n = splay_tree_successor (bp_location_tree,(splay_tree_key)&l);
+
+  if (n == NULL)
+    return NULL;
+  r = (struct bp_location*)n->value;
+  if (r->address != a)
+    return NULL;
+  return r;
+}
+
+/** Find the next entry in the breakpoint tree with a given address */
+static struct bp_location*
+bp_location_tree_next_address (struct bp_location* b, CORE_ADDR a)
+{
+  struct bp_location* r = bp_location_tree_next (b);
+  if ((r == NULL)||(r->address != a))
+     return NULL;
+  return r;
+}
+
 /* Return whether a breakpoint is an active enabled breakpoint.  */
 static int
 breakpoint_enabled (struct breakpoint *b)
@@ -3889,7 +3967,7 @@
   if (! breakpoint_address_is_meaningful (bpt))
     return;
 
-  ALL_BP_LOCATIONS (b)
+  ALL_BP_LOCATIONS_ADDR (b, address)
     if (b->owner->enable_state != bp_disabled
 	&& b->owner->enable_state != bp_shlib_disabled
 	&& !b->owner->pending
@@ -4054,18 +4132,6 @@
       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->next)
-	loc_p = loc_p->next;
-      loc_p->next = loc;
-    }
-
   return loc;
 }
 
@@ -4095,6 +4161,14 @@
   b->loc->requested_address = sal.pc;
   b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
                                                bptype);
+  /* Add this breakpoint at the back of the tree.  */
+  b->loc->number = bp_location_number ++;
+  if (bp_location_tree == NULL)
+    bp_location_tree = splay_tree_new (bp_location_tree_cmp, NULL, NULL);
+  splay_tree_insert (bp_location_tree,
+                     (splay_tree_key)b->loc,
+                     (splay_tree_value)b->loc);
+
   if (sal.symtab == NULL)
     b->source_file = NULL;
   else
@@ -6777,8 +6851,7 @@
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
 
-  if (bp_location_chain == bpt->loc)
-    bp_location_chain = bpt->loc->next;
+  splay_tree_remove (bp_location_tree, (splay_tree_key)bpt->loc);
 
   /* If we have callback-style exception catchpoints, don't go through
      the adjustments to the C++ runtime library etc. if the inferior
@@ -6809,13 +6882,6 @@
       break;
     }
 
-  ALL_BP_LOCATIONS (loc)
-    if (loc->next == bpt->loc)
-      {
-	loc->next = bpt->loc->next;
-	break;
-      }
-
   check_duplicates (bpt);
   /* If this breakpoint was inserted, and there is another breakpoint
      at the same address, we need to insert the other breakpoint.  */
diff -r -u -b gdb-6.6.original/gdb/breakpoint.h gdb-6.6/gdb/breakpoint.h
--- gdb-6.6.original/gdb/breakpoint.h	2006-04-18 21:20:06.000000000 +0200
+++ gdb-6.6/gdb/breakpoint.h	2007-02-19 22:41:24.485410750 +0100
@@ -238,8 +238,8 @@
 
 struct bp_location
 {
-  /* Chain pointer to the next breakpoint location.  */
-  struct bp_location *next;
+  /* Unique number used for sorting */
+  int number;
 
   /* Type of this breakpoint location.  */
   enum bp_loc_type loc_type;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-20  4:46       ` Thomas Neumann
@ 2007-02-20 10:26         ` Thomas Neumann
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas Neumann @ 2007-02-20 10:26 UTC (permalink / raw)
  To: Thomas Neumann; +Cc: gdb

[-- Attachment #1: Type: text/plain, Size: 302 bytes --]

I should re-read my patches _before_ pressing send... Sorry for the
double post, my original patch set the wrong start number in
bp_location_tree_first_address. Which will not matter most of the time
(apparently not triggered by make check), but does not make sense . Here
is the fixed patch.

Thomas


[-- Attachment #2: breakpointsinsplay.patch --]
[-- Type: text/plain, Size: 5740 bytes --]

diff -r -u -b gdb-6.6.original/gdb/breakpoint.c gdb-6.6/gdb/breakpoint.c
--- gdb-6.6.original/gdb/breakpoint.c	2006-10-19 17:58:25.000000000 +0200
+++ gdb-6.6/gdb/breakpoint.c	2007-02-19 23:10:32.858677250 +0100
@@ -53,6 +53,7 @@
 #include "solist.h"
 #include "observer.h"
 #include "exceptions.h"
+#include "splay-tree.h"
 
 #include "gdb-events.h"
 #include "mi/mi-common.h"
@@ -254,11 +255,16 @@
 
 /* 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_tree_first();B!=NULL;B = bp_location_tree_next(B))
+
+#define ALL_BP_LOCATIONS_ADDR(B,a)				\
+	for (B = bp_location_tree_first_address(a);B!=NULL;	\
+             B = bp_location_tree_next_address(B,a))
 
 #define ALL_BP_LOCATIONS_SAFE(B,TMP)	\
-	for (B = bp_location_chain;	\
-	     B ? (TMP=B->next, 1): 0;	\
+	for (B = bp_location_tree_first();			\
+            (B!=NULL)?(TMP=bp_location_tree_next(B),1):0;	\
 	     B = TMP)
 
 /* True if breakpoint hit counts should be displayed in breakpoint info.  */
@@ -269,7 +275,9 @@
 
 struct breakpoint *breakpoint_chain;
 
-struct bp_location *bp_location_chain;
+static splay_tree bp_location_tree;
+
+static int bp_location_number;
 
 /* Number of last breakpoint made.  */
 
@@ -339,6 +347,74 @@
    error (_("catch of library unloads not yet implemented on this platform"))
 #endif
 
+/** Compare entries in the breakpoint tree */
+static int
+bp_location_tree_cmp (splay_tree_key l, splay_tree_key r)
+{
+  struct bp_location *lp=(struct bp_location*)l, *rp=(struct bp_location*)r;
+  if (lp->address < rp->address)
+    return -1;
+  if (lp->address > rp->address)
+    return 1;
+  if (lp->number < rp->number)
+    return -1;
+  if (lp->number > rp->number)
+    return 1;
+  return 0;
+}
+
+/** Find the first entry in the breakpoint tree */
+static struct bp_location*
+bp_location_tree_first ()
+{
+  if (bp_location_tree == NULL)
+    return NULL;
+  return (struct bp_location*)splay_tree_min(bp_location_tree)->value;
+}
+
+/** Find the next entry in the breakpoint tree */
+static struct bp_location*
+bp_location_tree_next (struct bp_location* b)
+{
+  splay_tree_node n = splay_tree_successor (bp_location_tree,
+                        (splay_tree_key)b);
+  if (n == NULL)
+    return NULL;
+  return (struct bp_location*)n->value;
+}
+
+/** Find the first entry in the breakpoint tree with a given address*/
+static struct bp_location*
+bp_location_tree_first_address (CORE_ADDR a)
+{
+  struct bp_location l,*r;
+  splay_tree_node n;
+
+  if (bp_location_tree == NULL)
+    return NULL;
+
+  l.address = a;
+  l.number = INT_MIN;
+  n = splay_tree_successor (bp_location_tree,(splay_tree_key)&l);
+
+  if (n == NULL)
+    return NULL;
+  r = (struct bp_location*)n->value;
+  if (r->address != a)
+    return NULL;
+  return r;
+}
+
+/** Find the next entry in the breakpoint tree with a given address */
+static struct bp_location*
+bp_location_tree_next_address (struct bp_location* b, CORE_ADDR a)
+{
+  struct bp_location* r = bp_location_tree_next (b);
+  if ((r == NULL)||(r->address != a))
+     return NULL;
+  return r;
+}
+
 /* Return whether a breakpoint is an active enabled breakpoint.  */
 static int
 breakpoint_enabled (struct breakpoint *b)
@@ -3889,7 +3965,7 @@
   if (! breakpoint_address_is_meaningful (bpt))
     return;
 
-  ALL_BP_LOCATIONS (b)
+  ALL_BP_LOCATIONS_ADDR (b, address)
     if (b->owner->enable_state != bp_disabled
 	&& b->owner->enable_state != bp_shlib_disabled
 	&& !b->owner->pending
@@ -4054,18 +4130,6 @@
       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->next)
-	loc_p = loc_p->next;
-      loc_p->next = loc;
-    }
-
   return loc;
 }
 
@@ -4095,6 +4159,14 @@
   b->loc->requested_address = sal.pc;
   b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
                                                bptype);
+  /* Add this breakpoint at the back of the tree.  */
+  b->loc->number = bp_location_number ++;
+  if (bp_location_tree == NULL)
+    bp_location_tree = splay_tree_new (bp_location_tree_cmp, NULL, NULL);
+  splay_tree_insert (bp_location_tree,
+                     (splay_tree_key)b->loc,
+                     (splay_tree_value)b->loc);
+
   if (sal.symtab == NULL)
     b->source_file = NULL;
   else
@@ -6777,8 +6849,7 @@
   if (breakpoint_chain == bpt)
     breakpoint_chain = bpt->next;
 
-  if (bp_location_chain == bpt->loc)
-    bp_location_chain = bpt->loc->next;
+  splay_tree_remove (bp_location_tree, (splay_tree_key)bpt->loc);
 
   /* If we have callback-style exception catchpoints, don't go through
      the adjustments to the C++ runtime library etc. if the inferior
@@ -6809,13 +6880,6 @@
       break;
     }
 
-  ALL_BP_LOCATIONS (loc)
-    if (loc->next == bpt->loc)
-      {
-	loc->next = bpt->loc->next;
-	break;
-      }
-
   check_duplicates (bpt);
   /* If this breakpoint was inserted, and there is another breakpoint
      at the same address, we need to insert the other breakpoint.  */
diff -r -u -b gdb-6.6.original/gdb/breakpoint.h gdb-6.6/gdb/breakpoint.h
--- gdb-6.6.original/gdb/breakpoint.h	2006-04-18 21:20:06.000000000 +0200
+++ gdb-6.6/gdb/breakpoint.h	2007-02-19 22:41:24.485410750 +0100
@@ -238,8 +238,8 @@
 
 struct bp_location
 {
-  /* Chain pointer to the next breakpoint location.  */
-  struct bp_location *next;
+  /* Unique number used for sorting */
+  int number;
 
   /* Type of this breakpoint location.  */
   enum bp_loc_type loc_type;

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 11:57 Organization of breakpoint locations Thomas Neumann
  2007-02-19 12:54 ` Daniel Jacobowitz
@ 2007-02-21  1:53 ` Michael Snyder
  1 sibling, 0 replies; 10+ messages in thread
From: Michael Snyder @ 2007-02-21  1:53 UTC (permalink / raw)
  To: Thomas Neumann; +Cc: gdb

May I add a thought?  

The code and data structure for breakpoints is actually 
duplicated a number of times in Gdb -- tracepoints and
checkpoints, that I know of, and probably others.  Gdb
also has lists of threads and so forth.

I've thought that it would be nice to have something like
a "gdb_list" data structure, so we could just reuse this
code instead of repeatedly copying it.

Maybe this is an opportunity?


On Mon, 2007-02-19 at 11:38 +0100, Thomas Neumann wrote:
> Hi,
> 
> I would like some suggestions on the organization of breakpoint
> locations in breakpoint.c. Currently, all breakpoint locations are
> stored in a linear list. This does not scale if the number of
> breakpoints is large, see PR 2230 for an example. Instead the
> breakpoints should be stored in a suitable search structure (e.g. a
> balanced tree).
> 
> I have a patch that converts the list into a splay. Works fine, and the
> bottleneck indeed goes away, but I am not satisfied with the approach
> itself. Changing the data structure is quite simple due to the access
> macros used, so I had to change less than 20 lines. Unfortunately my
> patch is still big (about 450 lines), as it contains a complete splay
> implementation.
> 
> It would be nicer to reuse existing data structures instead of
> implementing a new one. I thought about using splay-tree in libiberty,
> but the breakpoint locations have some unique characteristics: 1. the
> locations have to be organized by address, but the address is not
> necessarily unique. So the search structure must handle duplicates. 2.
> the test suite (and perhaps other code) expect that a breakpoint is
> added "last" in the list, i.e. duplicate handling must keep an order
> within the duplicates. 3. it must be possible to iterate over search
> structure (directly, without callbacks), as otherwise a lot of code has
> to be changed.
> 
> The splay implementation from libiberty satisfies none of these
> constraints. Is there perhaps something else in the gdb sources that I
> can reuse? Or should I submit my (admittedly quite large) patch? But
> this would probably no longer count as a "small changes" that according
> to CONTRIBUTE do not require a copyright assignment.
> 
> Thomas


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Organization of breakpoint locations
  2007-02-19 12:54 ` Daniel Jacobowitz
  2007-02-19 14:40   ` Thomas Neumann
@ 2007-02-21 17:05   ` Michael Snyder
  1 sibling, 0 replies; 10+ messages in thread
From: Michael Snyder @ 2007-02-21 17:05 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Thomas Neumann, gdb

On Mon, 2007-02-19 at 06:57 -0500, Daniel Jacobowitz wrote:
> On Mon, Feb 19, 2007 at 11:38:40AM +0100, Thomas Neumann wrote:
> > Hi,
> > 
> > I would like some suggestions on the organization of breakpoint
> > locations in breakpoint.c. Currently, all breakpoint locations are
> > stored in a linear list. This does not scale if the number of
> > breakpoints is large, see PR 2230 for an example. Instead the
> > breakpoints should be stored in a suitable search structure (e.g. a
> > balanced tree).
> > 
> > I have a patch that converts the list into a splay. Works fine, and the
> > bottleneck indeed goes away, but I am not satisfied with the approach
> > itself.
> 
> Have you tested this in any real world use yet?  This is only the
> first limitation you'll encounter, I think.  For instance, every time
> you step and then stop the program, GDB is going to remove every
> breakpoint.  That's going to be just as slow.

Maybe not.  If they're grouped by address, and if there are
a lot of duplicates, gdb could set/clear the breakpoint at
that address once, and then mark them all inserted or not.



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-02-21  1:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-19 11:57 Organization of breakpoint locations Thomas Neumann
2007-02-19 12:54 ` Daniel Jacobowitz
2007-02-19 14:40   ` Thomas Neumann
2007-02-19 14:48     ` Daniel Jacobowitz
2007-02-19 14:54       ` Michael Veksler
2007-02-19 21:24         ` Daniel Jacobowitz
2007-02-20  4:46       ` Thomas Neumann
2007-02-20 10:26         ` Thomas Neumann
2007-02-21 17:05   ` Michael Snyder
2007-02-21  1:53 ` Michael Snyder

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox