#include "gdb-events.h"
#include "mi/mi-common.h"
-#include "gdb_stdint.h"
-
/* Prototypes for local functions. */
static void until_break_command_continuation (struct continuation_arg *arg,
static void maintenance_info_breakpoints (char *, int);
-static void create_longjmp_breakpoint (char *);
-
static void create_overlay_event_breakpoint (char *);
static int hw_breakpoint_used_count (void);
static void free_bp_location (struct bp_location *loc);
-static void mark_breakpoints_out (void);
-
static struct bp_location *
allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type);
-static void update_global_location_list (void);
+static void update_global_location_list (int);
-static void update_global_location_list_nothrow (void);
+static void update_global_location_list_nothrow (int);
static int is_hardware_watchpoint (struct breakpoint *bpt);
struct bp_location *bp_location_chain;
+/* The locations that no longer correspond to any breakpoint,
+ unlinked from bp_location_chain, but for which a hit
+ may still be reported by a target. */
+VEC(bp_location_p) *moribund_locations = NULL;
+
/* Number of last breakpoint made. */
int breakpoint_count;
if (is_hardware_watchpoint (bpt))
update_watchpoint (bpt, 0 /* don't reparse. */);
- update_global_location_list ();
+ update_global_location_list (1);
if (!always_inserted_mode && target_has_execution)
/* update_global_location_list does not insert breakpoints
return 0;
}
-static void
-restore_always_inserted_mode (void *p)
-{
- always_inserted_mode = (uintptr_t) p;
-}
-
void
update_breakpoints_after_exec (void)
{
struct breakpoint *b;
struct breakpoint *temp;
- struct cleanup *cleanup;
-
- /* Doing this first prevents the badness of having delete_breakpoint()
- write a breakpoint's current "shadow contents" to lift the bp. That
- shadow is NOT valid after an exec()! */
- mark_breakpoints_out ();
-
- /* The binary we used to debug is now gone, and we're updating
- breakpoints for the new binary. Until we're done, we should not
- try to insert breakpoints. */
- cleanup = make_cleanup (restore_always_inserted_mode,
- (void *) (uintptr_t) always_inserted_mode);
- always_inserted_mode = 0;
+ struct bp_location *bploc;
+
+ /* We're about to delete breakpoints from GDB's lists. If the
+ INSERTED flag is true, GDB will try to lift the breakpoints by
+ writing the breakpoints' "shadow contents" back into memory. The
+ "shadow contents" are NOT valid after an exec, so GDB should not
+ do that. Instead, the target is responsible from marking
+ breakpoints out as soon as it detects an exec. We don't do that
+ here instead, because there may be other attempts to delete
+ breakpoints after detecting an exec and before reaching here. */
+ ALL_BP_LOCATIONS (bploc)
+ gdb_assert (!bploc->inserted);
ALL_BREAKPOINTS_SAFE (b, temp)
{
continue;
}
+ /* Longjmp and longjmp-resume breakpoints are also meaningless
+ after an exec. */
+ if (b->type == bp_longjmp || b->type == bp_longjmp_resume)
+ {
+ delete_breakpoint (b);
+ continue;
+ }
+
/* Don't delete an exec catchpoint, because else the inferior
won't stop when it ought!
}
/* FIXME what about longjmp breakpoints? Re-create them here? */
create_overlay_event_breakpoint ("_ovly_debug_event");
- do_cleanups (cleanup);
}
int
/* Clear the "inserted" flag in all breakpoints. */
-static void
+void
mark_breakpoints_out (void)
{
struct bp_location *bpt;
if (bs->commands != NULL)
tmp->commands = copy_command_lines (bs->commands);
if (bs->old_val != NULL)
- tmp->old_val = value_copy (bs->old_val);
+ {
+ tmp->old_val = value_copy (bs->old_val);
+ release_value (tmp->old_val);
+ }
if (p == NULL)
/* This is the first thing in the chain. */
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (forked process %d), "),
b->number,
- b->forked_inferior_pid);
+ ptid_get_pid (b->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
break;
annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (vforked process %d), "),
b->number,
- b->forked_inferior_pid);
+ ptid_get_pid (b->forked_inferior_pid));
return PRINT_SRC_AND_LOC;
break;
return 0;
if ((b->type == bp_catch_fork)
- && !inferior_has_forked (PIDGET (inferior_ptid),
+ && !inferior_has_forked (inferior_ptid,
&b->forked_inferior_pid))
return 0;
if ((b->type == bp_catch_vfork)
- && !inferior_has_vforked (PIDGET (inferior_ptid),
+ && !inferior_has_vforked (inferior_ptid,
&b->forked_inferior_pid))
return 0;
if ((b->type == bp_catch_exec)
- && !inferior_has_execd (PIDGET (inferior_ptid), &b->exec_pathname))
+ && !inferior_has_execd (inferior_ptid, &b->exec_pathname))
return 0;
return 1;
{
struct breakpoint *b = NULL;
const struct bp_location *bl;
+ struct bp_location *loc;
/* Root of the chain of bpstat's */
struct bpstats root_bs[1];
/* Pointer to the last thing in the chain currently. */
bpstat bs = root_bs;
+ int ix;
ALL_BP_LOCATIONS (bl)
{
if (b->disposition == disp_disable)
{
b->enable_state = bp_disabled;
- update_global_location_list ();
+ update_global_location_list (0);
}
if (b->silent)
bs->print = 0;
bs->print_it = print_it_noop;
}
+ for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ {
+ if (loc->address == bp_addr)
+ {
+ bs = bpstat_alloc (loc, bs);
+ /* For hits of moribund locations, we should just proceed. */
+ bs->stop = 0;
+ bs->print = 0;
+ bs->print_it = print_it_noop;
+ }
+ }
+
bs->next = NULL; /* Terminate the chain */
bs = root_bs->next; /* Re-grab the head of the chain */
if (bs == NULL)
for (bs = root_bs->next; bs != NULL; bs = bs->next)
if (!bs->stop
+ && bs->breakpoint_at->owner
&& (bs->breakpoint_at->owner->type == bp_hardware_watchpoint
|| bs->breakpoint_at->owner->type == bp_read_watchpoint
|| bs->breakpoint_at->owner->type == bp_access_watchpoint))
/* I suspect this can happen if it was a momentary breakpoint
which has since been deleted. */
continue;
+ if (bs->breakpoint_at->owner == NULL)
+ bs_class = bp_nostop;
+ else
switch (bs->breakpoint_at->owner->type)
{
case bp_none:
if (addressprint)
ui_out_field_skip (uiout, "addr");
annotate_field (5);
- if (b->forked_inferior_pid != 0)
+ if (!ptid_equal (b->forked_inferior_pid, null_ptid))
{
ui_out_text (uiout, "process ");
- ui_out_field_int (uiout, "what", b->forked_inferior_pid);
+ ui_out_field_int (uiout, "what",
+ ptid_get_pid (b->forked_inferior_pid));
ui_out_spaces (uiout, 1);
}
break;
bp_read_watchpoint
bp_access_watchpoint
bp_catch_exec
- bp_longjmp_resume
bp_catch_fork
bp_catch_vork */
&& type != bp_read_watchpoint
&& type != bp_access_watchpoint
&& type != bp_catch_exec
- && type != bp_longjmp_resume
&& type != bp_catch_fork
&& type != bp_catch_vfork);
}
b->frame_id = null_frame_id;
b->dll_pathname = NULL;
b->triggered_dll_pathname = NULL;
- b->forked_inferior_pid = 0;
+ b->forked_inferior_pid = null_ptid;
b->exec_pathname = NULL;
b->ops = NULL;
b->condition_not_parsed = 0;
struct breakpoint *b;
struct minimal_symbol *m;
- if (func_name == NULL)
- b = create_internal_breakpoint (0, bp_longjmp_resume);
- else
- {
- if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
- return;
-
- b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
- }
-
- b->enable_state = bp_disabled;
- b->silent = 1;
- if (func_name)
- b->addr_string = xstrdup (func_name);
- update_global_location_list ();
+ if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
+ return;
+ set_momentary_breakpoint_at_pc (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
+ update_global_location_list (1);
}
/* Call this routine when stepping and nexting to enable a breakpoint
set_longjmp_resume_breakpoint() to figure out where we are going. */
void
-enable_longjmp_breakpoint (void)
+set_longjmp_breakpoint (void)
{
struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- if (b->type == bp_longjmp)
+ if (gdbarch_get_longjmp_target_p (current_gdbarch))
{
- b->enable_state = bp_enabled;
- update_global_location_list ();
+ create_longjmp_breakpoint ("longjmp");
+ create_longjmp_breakpoint ("_longjmp");
+ create_longjmp_breakpoint ("siglongjmp");
+ create_longjmp_breakpoint ("_siglongjmp");
}
}
+/* Delete all longjmp breakpoints from THREAD. */
void
-disable_longjmp_breakpoint (void)
+delete_longjmp_breakpoint (int thread)
{
- struct breakpoint *b;
+ struct breakpoint *b, *temp;
- ALL_BREAKPOINTS (b)
- if (b->type == bp_longjmp
- || b->type == bp_longjmp_resume)
- {
- b->enable_state = bp_disabled;
- update_global_location_list ();
- }
+ ALL_BREAKPOINTS_SAFE (b, temp)
+ if (b->type == bp_longjmp)
+ {
+ if (b->thread == thread)
+ delete_breakpoint (b);
+ }
}
static void
b->enable_state = bp_disabled;
overlay_events_enabled = 0;
}
- update_global_location_list ();
+ update_global_location_list (1);
}
void
if (b->type == bp_overlay_event)
{
b->enable_state = bp_enabled;
- update_global_location_list ();
+ update_global_location_list (1);
overlay_events_enabled = 1;
}
}
if (b->type == bp_overlay_event)
{
b->enable_state = bp_disabled;
- update_global_location_list ();
+ update_global_location_list (0);
overlay_events_enabled = 0;
}
}
/* addr_string has to be used or breakpoint_re_set will delete me. */
b->addr_string = xstrprintf ("*0x%s", paddr (b->loc->address));
- update_global_location_list_nothrow ();
+ update_global_location_list_nothrow (1);
return b;
}
struct breakpoint *b;
b = create_internal_breakpoint (address, bp_shlib_event);
- update_global_location_list_nothrow ();
+ update_global_location_list_nothrow (1);
return b;
}
b->addr_string = NULL;
b->enable_state = bp_enabled;
b->disposition = tempflag ? disp_del : disp_donttouch;
- b->forked_inferior_pid = 0;
- update_global_location_list ();
+ b->forked_inferior_pid = null_ptid;
+ update_global_location_list (1);
mention (b);
b->addr_string = NULL;
b->enable_state = bp_enabled;
b->disposition = tempflag ? disp_del : disp_donttouch;
- update_global_location_list ();
+ update_global_location_list (1);
mention (b);
}
return i;
}
-/* Call this after hitting the longjmp() breakpoint. Use this to set
- a new breakpoint at the target of the jmp_buf.
-
- FIXME - This ought to be done by setting a temporary breakpoint
- that gets deleted automatically... */
-
-void
-set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id)
-{
- struct breakpoint *b;
-
- ALL_BREAKPOINTS (b)
- if (b->type == bp_longjmp_resume)
- {
- b->loc->requested_address = pc;
- b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
- b->type);
- b->enable_state = bp_enabled;
- b->frame_id = frame_id;
- update_global_location_list ();
- return;
- }
-}
-
void
disable_watchpoints_before_interactive_call_start (void)
{
&& breakpoint_enabled (b))
{
b->enable_state = bp_call_disabled;
- update_global_location_list ();
+ update_global_location_list (0);
}
}
}
&& (b->enable_state == bp_call_disabled))
{
b->enable_state = bp_enabled;
- update_global_location_list ();
+ update_global_location_list (1);
}
}
}
if (in_thread_list (inferior_ptid))
b->thread = pid_to_thread_id (inferior_ptid);
- update_global_location_list_nothrow ();
+ update_global_location_list_nothrow (1);
return b;
}
+
+struct breakpoint *
+set_momentary_breakpoint_at_pc (CORE_ADDR pc, enum bptype type)
+{
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (pc, 0);
+ sal.pc = pc;
+ sal.section = find_pc_overlay (pc);
+ sal.explicit_pc = 1;
+
+ return set_momentary_breakpoint (sal, null_frame_id, type);
+}
\f
/* Tell the user we have just set a breakpoint B. */
thread, ignore_count, ops, from_tty);
}
- update_global_location_list ();
+ update_global_location_list (1);
}
/* Parse ARG which is assumed to be a SAL specification possibly
b->condition_not_parsed = 1;
b->ops = ops;
- update_global_location_list ();
+ update_global_location_list (1);
mention (b);
}
value_free_to_mark (mark);
mention (b);
- update_global_location_list ();
+ update_global_location_list (1);
}
/* Return count of locations need to be watched and can be handled
deleted when the target stops. Otherwise, we're already stopped and
delete breakpoints via cleanup chain. */
- if (target_can_async_p () && target_executing)
+ if (target_can_async_p () && is_running (inferior_ptid))
{
arg1 =
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
static enum print_stop_action
print_exception_catchpoint (struct breakpoint *b)
{
- annotate_catchpoint (b->number);
+ int bp_temp, bp_throw;
- if (strstr (b->addr_string, "throw") != NULL)
- printf_filtered (_("\nCatchpoint %d (exception thrown)\n"),
- b->number);
- else
- printf_filtered (_("\nCatchpoint %d (exception caught)\n"),
- b->number);
+ annotate_catchpoint (b->number);
+ bp_throw = strstr (b->addr_string, "throw") != NULL;
+ if (b->loc->address != b->loc->requested_address)
+ breakpoint_adjustment_warning (b->loc->requested_address,
+ b->loc->address,
+ b->number, 1);
+ bp_temp = b->loc->owner->disposition == disp_del;
+ ui_out_text (uiout,
+ bp_temp ? "Temporary catchpoint "
+ : "Catchpoint ");
+ if (!ui_out_is_mi_like_p (uiout))
+ ui_out_field_int (uiout, "bkptno", b->number);
+ ui_out_text (uiout,
+ bp_throw ? " (exception thrown), "
+ : " (exception caught), ");
+ if (ui_out_is_mi_like_p (uiout))
+ {
+ ui_out_field_string (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+ ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+ ui_out_field_int (uiout, "bkptno", b->number);
+ }
return PRINT_SRC_AND_LOC;
}
static void
print_mention_exception_catchpoint (struct breakpoint *b)
{
- if (strstr (b->addr_string, "throw") != NULL)
- printf_filtered (_("Catchpoint %d (throw)"), b->number);
- else
- printf_filtered (_("Catchpoint %d (catch)"), b->number);
+ int bp_temp;
+ int bp_throw;
+
+ bp_temp = b->loc->owner->disposition == disp_del;
+ bp_throw = strstr (b->addr_string, "throw") != NULL;
+ ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ")
+ : _("Catchpoint "));
+ ui_out_field_int (uiout, "bkptno", b->number);
+ ui_out_text (uiout, bp_throw ? _(" (throw)")
+ : _(" (catch)"));
}
static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
break_command_really (trigger_func_name, cond_string, -1,
0 /* condition and thread are valid. */,
- 0, 0,
+ tempflag, 0,
0,
AUTO_BOOLEAN_TRUE /* pending */,
&gnu_v3_exception_catchpoint_ops, from_tty);
b->ops = ops;
mention (b);
- update_global_location_list ();
+ update_global_location_list (1);
}
/* Implement the "catch exception" command. */
struct breakpoint *b, *temp;
for (; bs; bs = bs->next)
- if (bs->breakpoint_at && bs->breakpoint_at->owner->disposition == disp_del
+ if (bs->breakpoint_at
+ && bs->breakpoint_at->owner
+ && bs->breakpoint_at->owner->disposition == disp_del
&& bs->stop)
delete_breakpoint (bs->breakpoint_at->owner);
}
}
+/* If SHOULD_INSERT is true, do not insert any breakpoint locations
+ into the inferior, only remove already-inserted locations that no
+ longer should be inserted. Functions that delete a breakpoint or
+ breakpoints should pass false, so that deleting a breakpoint
+ doesn't have the side effect of inserting the locations of other
+ breakpoints that are marked not-inserted, but should_be_inserted
+ returns true on them.
+
+ This behaviour is useful is situations close to tear-down -- e.g.,
+ after an exec, while the target still has execution, but breakpoint
+ shadows of the previous executable image should *NOT* be restored
+ to the new image; or before detaching, where the target still has
+ execution and wants to delete breakpoints from GDB's lists, and all
+ breakpoints had already been removed from the inferior. */
+
static void
-update_global_location_list (void)
+update_global_location_list (int should_insert)
{
struct breakpoint *b;
struct bp_location **next = &bp_location_chain;
/* Tells if 'loc' is found amoung the new locations. If not, we
have to free it. */
int found_object = 0;
+ /* Tells if the location should remain inserted in the target. */
+ int keep_in_target = 0;
+ int removed = 0;
for (loc2 = bp_location_chain; loc2; loc2 = loc2->global_next)
if (loc2 == loc)
{
if (loc->inserted)
{
/* If the location is inserted now, we might have to remove it. */
- int keep = 0;
if (found_object && should_be_inserted (loc))
{
/* The location is still present in the location list, and still
should be inserted. Don't do anything. */
- keep = 1;
+ keep_in_target = 1;
}
else
{
{
loc2->inserted = 1;
loc2->target_info = loc->target_info;
- keep = 1;
+ keep_in_target = 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 (!keep_in_target)
+ {
+ 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);
+ }
+ removed = 1;
+ }
}
if (!found_object)
- free_bp_location (loc);
+ {
+ if (removed)
+ {
+ /* This location was removed from the targets. In non-stop mode,
+ a race condition is possible where we've removed a breakpoint,
+ but stop events for that breakpoint are already queued and will
+ arrive later. To suppress spurious SIGTRAPs reported to user,
+ we keep this breakpoint location for a bit, and will retire it
+ after we see 3 * thread_count events.
+ The theory here is that reporting of events should,
+ "on the average", be fair, so after that many event we'll see
+ events from all threads that have anything of interest, and no
+ longer need to keep this breakpoint. This is just a
+ heuristic, but if it's wrong, we'll report unexpected SIGTRAP,
+ which is usability issue, but not a correctness problem. */
+ loc->events_till_retirement = 3 * (thread_count () + 1);
+ loc->owner = NULL;
+ }
+
+ free_bp_location (loc);
+ }
}
ALL_BREAKPOINTS (b)
check_duplicates (b);
}
- if (always_inserted_mode && target_has_execution)
+ if (always_inserted_mode && should_insert && target_has_execution)
insert_breakpoint_locations ();
}
+void
+breakpoint_retire_moribund (void)
+{
+ struct bp_location *loc;
+ int ix;
+
+ for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ if (--(loc->events_till_retirement) == 0)
+ {
+ free_bp_location (loc);
+ VEC_unordered_remove (bp_location_p, moribund_locations, ix);
+ --ix;
+ }
+}
+
static void
-update_global_location_list_nothrow (void)
+update_global_location_list_nothrow (int inserting)
{
struct gdb_exception e;
TRY_CATCH (e, RETURN_MASK_ERROR)
- update_global_location_list ();
+ update_global_location_list (inserting);
+}
+
+/* Clear BPT from a BPS. */
+static void
+bpstat_remove_breakpoint (bpstat bps, struct breakpoint *bpt)
+{
+ bpstat bs;
+ for (bs = bps; bs; bs = bs->next)
+ if (bs->breakpoint_at && bs->breakpoint_at->owner == bpt)
+ {
+ bs->breakpoint_at = NULL;
+ bs->old_val = NULL;
+ /* bs->commands will be freed later. */
+ }
+}
+
+/* Callback for iterate_over_threads. */
+static int
+bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
+{
+ struct breakpoint *bpt = data;
+ bpstat_remove_breakpoint (th->stop_bpstat, bpt);
+ return 0;
}
/* Delete a breakpoint and clean up all traces of it in the data
delete_breakpoint (struct breakpoint *bpt)
{
struct breakpoint *b;
- bpstat bs;
struct bp_location *loc, *next;
gdb_assert (bpt != NULL);
bpstat_do_actions (&stop_bpstat);
in event-top.c won't do anything, and temporary breakpoints
with commands won't work. */
- for (bs = stop_bpstat; bs; bs = bs->next)
- if (bs->breakpoint_at && bs->breakpoint_at->owner == bpt)
- {
- bs->breakpoint_at = NULL;
- bs->old_val = NULL;
- /* bs->commands will be freed later. */
- }
+
+ /* Clear the current context. */
+ bpstat_remove_breakpoint (stop_bpstat, bpt);
+ /* And from all threads. */
+ iterate_over_threads (bpstat_remove_breakpoint_callback, bpt);
/* Now that breakpoint is removed from breakpoint
list, update the global location list. This
looks at location's owner. It might be better
design to have location completely self-contained,
but it's not the case now. */
- update_global_location_list ();
+ update_global_location_list (0);
/* On the chance that someone will soon try again to delete this same
}
}
- update_global_location_list ();
+ update_global_location_list (1);
}
default:
printf_filtered (_("Deleting unknown breakpoint type %d\n"), b->type);
/* fall through */
- /* Delete longjmp and overlay event breakpoints; they will be
- reset later by breakpoint_re_set. */
- case bp_longjmp:
- case bp_longjmp_resume:
+ /* Delete overlay event breakpoints; they will be reset later by
+ breakpoint_re_set. */
case bp_overlay_event:
delete_breakpoint (b);
break;
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_step_resume:
+ case bp_longjmp:
+ case bp_longjmp_resume:
break;
}
}
set_language (save_language);
input_radix = save_input_radix;
-
- if (gdbarch_get_longjmp_target_p (current_gdbarch))
- {
- create_longjmp_breakpoint ("longjmp");
- create_longjmp_breakpoint ("_longjmp");
- create_longjmp_breakpoint ("siglongjmp");
- create_longjmp_breakpoint ("_siglongjmp");
- create_longjmp_breakpoint (NULL);
- }
create_overlay_event_breakpoint ("_ovly_debug_event");
}
bpt->enable_state = bp_disabled;
- update_global_location_list ();
+ update_global_location_list (0);
if (deprecated_modify_breakpoint_hook)
deprecated_modify_breakpoint_hook (bpt);
struct bp_location *loc = find_location_by_number (args);
if (loc)
loc->enabled = 0;
- update_global_location_list ();
+ update_global_location_list (0);
}
else
map_breakpoint_numbers (args, disable_breakpoint);
if (bpt->enable_state != bp_permanent)
bpt->enable_state = bp_enabled;
bpt->disposition = disposition;
- update_global_location_list ();
+ update_global_location_list (1);
breakpoints_changed ();
if (deprecated_modify_breakpoint_hook)
struct bp_location *loc = find_location_by_number (args);
if (loc)
loc->enabled = 1;
- update_global_location_list ();
+ update_global_location_list (1);
}
else
map_breakpoint_numbers (args, enable_breakpoint);
Set a watchpoint for an expression.\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression changes."));
- set_cmd_completer (c, location_completer);
+ set_cmd_completer (c, expression_completer);
c = add_com ("rwatch", class_breakpoint, rwatch_command, _("\
Set a read watchpoint for an expression.\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression is read."));
- set_cmd_completer (c, location_completer);
+ set_cmd_completer (c, expression_completer);
c = add_com ("awatch", class_breakpoint, awatch_command, _("\
Set a watchpoint for an expression.\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression is either read or written."));
- set_cmd_completer (c, location_completer);
+ set_cmd_completer (c, expression_completer);
add_info ("watchpoints", breakpoints_info,
_("Synonym for ``info breakpoints''."));