[RFA] Keep breakpoints always inserted.

Pedro Alves pedro@codesourcery.com
Wed Apr 23 21:18:00 GMT 2008


> On Thu, Apr 10, 2008 at 02:27:00AM +0400, Vladimir Prus wrote:
> > I attach the revised patch, together with the delta relative to the
> > previous one. This has no regressions, neither in always-inserted nor
> > default mode. OK?
>

Testing with this patch applied and with displaced stepping on top
revealed one problem.

One should be able to call insert_breakpoints several times
in succession and the effect should be as if only one call was made.

There is a bug in the patch where if there is more than
one breakpoint at the same address, the second insert_breakpoints
call will remove the breakpoint location from the target.

This happens because should_insert_location returns false if the
location is already inserted.  

 /* Returns 1 iff breakpoint location should be
    inserted in the inferior.  */
 static int
 should_insert_location (struct bp_location *bpt)
 {
   if (!breakpoint_enabled (bpt->owner))
     return 0;

   if (bpt->owner->disposition == disp_del_at_next_stop)
     return 0;

   if (!bpt->enabled || bpt->shlib_disabled || bpt->inserted ||  
bpt->duplicate)
     return 0;

   return 1;
 }

On the case were we have two locations at the same address, when we
get to the loop the patch is touching looking for another location
at the same address, we'll fail to mark this location as to be kept,
and go on to remove the breakpoint from the target,

	  if (!keep)
	    if (remove_breakpoint (loc, mark_uninserted))
	      {

The attached patch inlines the tests we're really interested in
at this point (I'm not sure about the disposition test), and removes
the need for the (incomplete) hack of setting loc2->duplicate = 0
before calling should_insert_location.

This failed with the displaced stepping patch on top,
because with that patch there are now several code paths
that call insert_breakpoints without a remove_breakpoints
call in between.  You can also reproduce this easilly
by applying something like this:


---
 gdb/infrun.c |    2 ++
 1 file changed, 2 insertions(+)

Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c       2008-04-23 18:38:33.000000000 +0100
+++ src/gdb/infrun.c    2008-04-23 18:38:47.000000000 +0100
@@ -2921,6 +2921,8 @@ keep_going (struct execution_control_sta
          TRY_CATCH (e, RETURN_MASK_ERROR)
            {
              insert_breakpoints ();
+             insert_breakpoints ();
+             insert_breakpoints ();
            }
          if (e.reason < 0)
            {

The test case that made this visible was thread-specific.exp,
which inserts more than one breakpoint at the same location
(although marked for different threads).

The symptom is that the inferior will not stop at the
breakpoint.
Easilly tested in any test, by "b main; b main; run".

I've tested this patch on top of Vladimir's and with displaced
stepping on, on x86-pc-linux-gnu.  Luis tested it on PPC, where
it also fixed things.

P.S.:
Anyone object to adding debug output support to the
breakpoint module?  I've writen something similar twice
already, and I'd like to not have to a third time.  Something
like "set debug breakpoint 1", where it prints
"breakpoints inserted", "breakpoints removed", etc.

-- 
Pedro Alves
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fix_displaced.diff
Type: text/x-diff
Size: 1056 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/gdb-patches/attachments/20080423/3bd543a4/attachment.bin>


More information about the Gdb-patches mailing list