diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 73a30df..3087f8f 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1033,6 +1033,9 @@ 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; @@ -1301,7 +1304,7 @@ insert_breakpoint_locations (void) ALL_BP_LOCATIONS_SAFE (b, temp) { - if (!breakpoint_enabled (b->owner)) + if (!should_insert_location (b)) continue; /* There is no point inserting thread-specific breakpoints if the @@ -1329,6 +1332,9 @@ insert_breakpoint_locations (void) if (bpt->enable_state != bp_enabled) continue; + + if (bpt->disposition == disp_del_at_next_stop) + continue; for (loc = bpt->loc; loc; loc = loc->next) if (!loc->inserted) @@ -6961,8 +6967,9 @@ update_global_location_list (void) we don't need to remove/insert the location. */ for (ix = 0; VEC_iterate(bp_location_p, old_locations, ix, loc); ++ix) { + /* Tells if 'loc' is found amoung the new locations. If not, we + have to free it. */ int found_object = 0; - int found_address = 0; for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next) if (loc2 == loc) { @@ -6975,42 +6982,56 @@ update_global_location_list (void) inserted, and don't remove this one. This is needed so that we don't have a time window where a breakpoint at certain location is not inserted. */ - if (!found_object && loc->inserted) + + if (loc->inserted) { - /* See if there's another location at the same address, in which - case we don't need to remove this one. */ - if (breakpoint_address_is_meaningful (loc->owner)) - for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next) - { - /* For the sake of should_insert_location. The - call to check_duplicates will fix up this later. */ - loc2->duplicate = 0; - if (should_insert_location (loc2) - && loc2 != loc && loc2->address == loc->address) - { - loc2->inserted = 1; - loc2->target_info = loc->target_info; - found_address = 1; - break; + /* If the location is inserted now, we might have to remove it. */ + int keep = 0; + + if (found_object && should_insert_location (loc)) + { + /* The location is still present in the location list, and still + should be inserted. Don't do anything. */ + keep = 1; + } + else + { + /* The location is either no longer present, or got disabled. + See if there's another location at the same address, in which + case we don't need to remove this one from the target. */ + if (breakpoint_address_is_meaningful (loc->owner)) + for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next) + { + /* For the sake of should_insert_location. The + call to check_duplicates will fix up this later. */ + loc2->duplicate = 0; + if (should_insert_location (loc2) + && loc2 != loc && loc2->address == loc->address) + { + loc2->inserted = 1; + loc2->target_info = loc->target_info; + keep = 1; + break; + } } + } + + if (!keep) + if (remove_breakpoint (loc, mark_uninserted)) + { + /* This is just about all we can do. We could keep this + location on the global list, and try to remove it next + time, but there's no particular reason why we will + succeed next time. + + Note that at this point, loc->owner is still valid, + as delete_breakpoint frees the breakpoint only + after calling us. */ + printf_filtered (_("warning: Error removing breakpoint %d\n"), + loc->owner->number); } } - if (loc->inserted && !found_object && !found_address) - if (remove_breakpoint (loc, mark_uninserted)) - { - /* This is just about all we can do. We could keep this - location on the global list, and try to remove it next - time, but there's no particular reason why we will - succeed next time. - - Note that at this point, loc->owner is still valid, - as delete_breakpoint frees the breakpoint only - after calling us. */ - printf_filtered (_("warning: Error removing breakpoint %d\n"), - loc->owner->number); - } - if (!found_object) free_bp_location (loc); }