This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
patch for invalid hw breakpoints
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gdb at sourceware dot org
- Date: Thu, 01 Jun 2006 14:20:40 +0100
- Subject: patch for invalid hw breakpoints
I have a remote target w/o hw watchpoint support. I set a watchpoint only to
find that I then get an undeletable watchpoint as we try and remove it.
The bug is that when insert_bp_location fails to insert one of the watched
addresses for a watch expression it then goes and tries to remove all the
addresses of that watched expression, rather than just the previous fragments of
the expression.
This patch adds a stop parameter to remove_breakpoint so that it can be told
only to remove the initial watchpoints. With it I now get a sane error message
and can delete the actual watchpoint.
ok?
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2006-06-01 Nathan Sidwell <nathan@codesourcery.com>
* gdb/breakpoint.c (insert_bp_location): Remember the failing
watchpoint address and pass to remove_breakpoint.
(remove_breakpoints, remove_hw_watchpoints, reattach_breakpoints,
detach_breakpoints): Adjust remove_breakpoint call.
(remove_breakpoint): Add VAL_FAILED parameter. Stop removing
watchpoint addresses when it is reached.
(delete_breakpoint): Adjust remove_breakpoint call.
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.223.2.1
diff -c -3 -p -r1.223.2.1 breakpoint.c
*** breakpoint.c 3 Apr 2006 00:47:37 -0000 1.223.2.1
--- breakpoint.c 1 Jun 2006 11:26:06 -0000
*************** typedef enum
*** 129,135 ****
}
insertion_state_t;
! static int remove_breakpoint (struct bp_location *, insertion_state_t);
static enum print_stop_action print_it_typical (bpstat);
--- 129,136 ----
}
insertion_state_t;
! static int remove_breakpoint (struct bp_location *, insertion_state_t,
! struct value *);
static enum print_stop_action print_it_typical (bpstat);
*************** insert_bp_location (struct bp_location *
*** 948,953 ****
--- 949,955 ----
if (within_current_scope)
{
+ struct value *val_failed = NULL;
free_valchain (bpt);
/* Evaluate the expression and cut the chain of values
*************** insert_bp_location (struct bp_location *
*** 995,1007 ****
val = target_insert_watchpoint (addr, len, type);
if (val == -1)
{
! /* Don't exit the loop, try to insert
! every value on the value chain. That's
! because we will be removing all the
! watches below, and removing a
! watchpoint we didn't insert could have
! adverse effects. */
! bpt->inserted = 0;
}
val = 0;
}
--- 997,1004 ----
val = target_insert_watchpoint (addr, len, type);
if (val == -1)
{
! val_failed = v;
! break;
}
val = 0;
}
*************** insert_bp_location (struct bp_location *
*** 1009,1017 ****
}
/* Failure to insert a watchpoint on any memory value in the
value chain brings us here. */
! if (!bpt->inserted)
{
! remove_breakpoint (bpt, mark_uninserted);
*hw_breakpoint_error = 1;
fprintf_unfiltered (tmp_error_stream,
"Could not insert hardware watchpoint %d.\n",
--- 1006,1015 ----
}
/* Failure to insert a watchpoint on any memory value in the
value chain brings us here. */
! if (val_failed)
{
! remove_breakpoint (bpt, mark_uninserted, val_failed);
! bpt->inserted = 0;
*hw_breakpoint_error = 1;
fprintf_unfiltered (tmp_error_stream,
"Could not insert hardware watchpoint %d.\n",
*************** remove_breakpoints (void)
*** 1199,1205 ****
{
if (b->inserted)
{
! val = remove_breakpoint (b, mark_uninserted);
if (val != 0)
return val;
}
--- 1197,1203 ----
{
if (b->inserted)
{
! val = remove_breakpoint (b, mark_uninserted, NULL);
if (val != 0)
return val;
}
*************** remove_hw_watchpoints (void)
*** 1217,1223 ****
{
if (b->inserted && b->loc_type == bp_loc_hardware_watchpoint)
{
! val = remove_breakpoint (b, mark_uninserted);
if (val != 0)
return val;
}
--- 1215,1221 ----
{
if (b->inserted && b->loc_type == bp_loc_hardware_watchpoint)
{
! val = remove_breakpoint (b, mark_uninserted, NULL);
if (val != 0)
return val;
}
*************** reattach_breakpoints (int pid)
*** 1238,1244 ****
{
if (b->inserted)
{
! remove_breakpoint (b, mark_inserted);
if (b->loc_type == bp_loc_hardware_breakpoint)
val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
else
--- 1236,1242 ----
{
if (b->inserted)
{
! remove_breakpoint (b, mark_inserted, NULL);
if (b->loc_type == bp_loc_hardware_breakpoint)
val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
else
*************** detach_breakpoints (int pid)
*** 1406,1412 ****
{
if (b->inserted)
{
! val = remove_breakpoint (b, mark_inserted);
if (val != 0)
{
do_cleanups (old_chain);
--- 1404,1410 ----
{
if (b->inserted)
{
! val = remove_breakpoint (b, mark_inserted, NULL);
if (val != 0)
{
do_cleanups (old_chain);
*************** detach_breakpoints (int pid)
*** 1418,1425 ****
return 0;
}
static int
! remove_breakpoint (struct bp_location *b, insertion_state_t is)
{
int val;
--- 1416,1428 ----
return 0;
}
+ /* Remove the breakpoints for B. FAILED_VAL, if non-null is the value
+ in the bpt->owner->val_chain that failed to be inserted. We stop
+ at that point. */
+
static int
! remove_breakpoint (struct bp_location *b, insertion_state_t is,
! struct value *val_failed)
{
int val;
*************** remove_breakpoint (struct bp_location *b
*** 1503,1509 ****
b->inserted = (is == mark_inserted);
/* Walk down the saved value chain. */
! for (v = b->owner->val_chain; v; v = value_next (v))
{
/* For each memory reference remove the watchpoint
at that address. */
--- 1506,1512 ----
b->inserted = (is == mark_inserted);
/* Walk down the saved value chain. */
! for (v = b->owner->val_chain; v != val_failed; v = value_next (v))
{
/* For each memory reference remove the watchpoint
at that address. */
*************** delete_breakpoint (struct breakpoint *bp
*** 6775,6781 ****
breakpoint_delete_event (bpt->number);
if (bpt->loc->inserted)
! remove_breakpoint (bpt->loc, mark_inserted);
free_valchain (bpt->loc);
--- 6778,6784 ----
breakpoint_delete_event (bpt->number);
if (bpt->loc->inserted)
! remove_breakpoint (bpt->loc, mark_inserted, NULL);
free_valchain (bpt->loc);