static int hw_breakpoint_used_count (void);
-static int hw_watchpoint_used_count (enum bptype, int *);
+static int hw_watchpoint_use_count (struct breakpoint *);
+
+static int hw_watchpoint_used_count_others (struct breakpoint *except,
+ enum bptype type,
+ int *other_type_used);
static void hbreak_command (char *, int);
if (reg_cnt)
{
int i, target_resources_ok, other_type_used;
+ enum bptype type;
/* Use an exact watchpoint when there's only one memory region to be
watched, and only one debug register is needed to watch it. */
/* We need to determine how many resources are already
used for all other hardware watchpoints plus this one
to see if we still have enough resources to also fit
- this watchpoint in as well. To guarantee the
- hw_watchpoint_used_count call below counts this
- watchpoint, make sure that it is marked as a hardware
- watchpoint. */
- if (b->base.type == bp_watchpoint)
- b->base.type = bp_hardware_watchpoint;
-
- i = hw_watchpoint_used_count (b->base.type, &other_type_used);
- target_resources_ok = target_can_use_hardware_watchpoint
- (b->base.type, i, other_type_used);
+ this watchpoint in as well. */
+
+ /* If this is a software watchpoint, we try to turn it
+ to a hardware one -- count resources as if B was of
+ hardware watchpoint type. */
+ type = b->base.type;
+ if (type == bp_watchpoint)
+ type = bp_hardware_watchpoint;
+
+ /* This watchpoint may or may not have been placed on
+ the list yet at this point (it won't be in the list
+ if we're trying to create it for the first time,
+ through watch_command), so always account for it
+ manually. */
+
+ /* Count resources used by all watchpoints except B. */
+ i = hw_watchpoint_used_count_others (&b->base, type, &other_type_used);
+
+ /* Add in the resources needed for B. */
+ i += hw_watchpoint_use_count (&b->base);
+
+ target_resources_ok
+ = target_can_use_hardware_watchpoint (type, i, other_type_used);
if (target_resources_ok <= 0)
{
int sw_mode = b->base.ops->works_in_software_mode (&b->base);
else if (target_resources_ok < 0 && !sw_mode)
error (_("There are not enough available hardware "
"resources for this watchpoint."));
- else
- b->base.type = bp_watchpoint;
+
+ /* Downgrade to software watchpoint. */
+ b->base.type = bp_watchpoint;
+ }
+ else
+ {
+ /* If this was a software watchpoint, we've just
+ found we have enough resources to turn it to a
+ hardware watchpoint. Otherwise, this is a
+ nop. */
+ b->base.type = type;
}
}
else if (!b->base.ops->works_in_software_mode (&b->base))
return 1;
}
-/* Modify BS so that the actions will not be performed. */
+/* See breakpoint.h. */
void
-bpstat_clear_actions (bpstat bs)
+bpstat_clear_actions (void)
{
- for (; bs != NULL; bs = bs->next)
+ struct thread_info *tp;
+ bpstat bs;
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+
+ tp = find_thread_ptid (inferior_ptid);
+ if (tp == NULL)
+ return;
+
+ for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
{
decref_counted_command_line (&bs->commands);
- bs->commands_left = NULL;
+
if (bs->old_val != NULL)
{
value_free (bs->old_val);
executing_breakpoint_commands = 0;
}
+/* Return non-zero iff CMD as the first line of a command sequence is `silent'
+ or its equivalent. */
+
+static int
+command_line_is_silent (struct command_line *cmd)
+{
+ return cmd && (strcmp ("silent", cmd->line) == 0
+ || (xdb_commands && strcmp ("Q", cmd->line) == 0));
+}
+
/* Execute all the commands associated with all the breakpoints at
this location. Any of these commands could cause the process to
proceed beyond this point, etc. We look out for such changes by
the tree when we're done. */
ccmd = bs->commands;
bs->commands = NULL;
- this_cmd_tree_chain
- = make_cleanup_decref_counted_command_line (&ccmd);
- cmd = bs->commands_left;
- bs->commands_left = NULL;
+ this_cmd_tree_chain = make_cleanup_decref_counted_command_line (&ccmd);
+ cmd = ccmd ? ccmd->commands : NULL;
+ if (command_line_is_silent (cmd))
+ {
+ /* The action has been already done by bpstat_stop_status. */
+ cmd = cmd->next;
+ }
while (cmd != NULL)
{
void
bpstat_do_actions (void)
{
+ struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
+
/* Do any commands attached to breakpoint we are stopped at. */
while (!ptid_equal (inferior_ptid, null_ptid)
&& target_has_execution
indicate the inferior was not resumed. */
if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
break;
+
+ discard_cleanups (cleanup_if_error);
}
/* Print out the (old or new) value associated with a watchpoint. */
incref_bp_location (bl);
/* If the condition is false, etc., don't do the commands. */
bs->commands = NULL;
- bs->commands_left = NULL;
bs->old_val = NULL;
bs->print_it = print_it_normal;
return bs;
}
else
{
+ struct ui_out *uiout = current_uiout;
+
/* This seems like the only logical thing to do because
if we temporarily ignored the watchpoint, then when
we reenter the block in which it is valid it contains
bs->print = 0;
bs->commands = b->commands;
incref_counted_command_line (bs->commands);
- bs->commands_left = bs->commands ? bs->commands->commands : NULL;
- if (bs->commands_left
- && (strcmp ("silent", bs->commands_left->line) == 0
- || (xdb_commands
- && strcmp ("Q",
- bs->commands_left->line) == 0)))
- {
- bs->commands_left = bs->commands_left->next;
- bs->print = 0;
- }
+ if (command_line_is_silent (bs->commands
+ ? bs->commands->commands : NULL))
+ bs->print = 0;
}
/* Print nothing for this entry if we don't stop or don't print. */
print_breakpoint_location (struct breakpoint *b,
struct bp_location *loc)
{
+ struct ui_out *uiout = current_uiout;
struct cleanup *old_chain = save_current_program_space ();
if (loc != NULL && loc->shlib_disabled)
struct command_line *l;
static char bpenables[] = "nynny";
+ struct ui_out *uiout = current_uiout;
int header_of_multiple = 0;
int part_of_multiple = (loc != NULL);
struct value_print_options opts;
int allflag)
{
struct cleanup *bkpt_chain;
+ struct ui_out *uiout = current_uiout;
bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt");
struct value_print_options opts;
int print_address_bits = 0;
int print_type_col_width = 14;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
static void
default_collect_info (void)
{
+ struct ui_out *uiout = current_uiout;
+
/* If it has no value (which is frequently the case), say nothing; a
message like "No default-collect." gets in user's face when it's
not wanted. */
watchpoints_info (char *args, int from_tty)
{
int num_printed = breakpoint_1 (args, 0, is_watchpoint);
+ struct ui_out *uiout = current_uiout;
if (num_printed == 0)
{
return 0;
}
-/* Print a message describing any breakpoints set at PC. This
+/* Print a message describing any user-breakpoints set at PC. This
concerns with logical breakpoints, so we match program spaces, not
address spaces. */
struct breakpoint *b;
ALL_BREAKPOINTS (b)
- others += breakpoint_has_pc (b, pspace, pc, section);
+ others += (user_breakpoint_p (b)
+ && breakpoint_has_pc (b, pspace, pc, section));
if (others > 0)
{
if (others == 1)
else /* if (others == ???) */
printf_filtered (_("Note: breakpoints "));
ALL_BREAKPOINTS (b)
- if (breakpoint_has_pc (b, pspace, pc, section))
+ if (user_breakpoint_p (b) && breakpoint_has_pc (b, pspace, pc, section))
{
others--;
printf_filtered ("%d", b->number);
{
struct fork_catchpoint *c = (struct fork_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
{
struct fork_catchpoint *c = (struct fork_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
{
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
{
struct exec_catchpoint *c = (struct exec_catchpoint *) b;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
return i;
}
+/* Returns the resources B would use if it were a hardware
+ watchpoint. */
+
static int
-hw_watchpoint_used_count (enum bptype type, int *other_type_used)
+hw_watchpoint_use_count (struct breakpoint *b)
{
int i = 0;
- struct breakpoint *b;
struct bp_location *bl;
+ if (!breakpoint_enabled (b))
+ return 0;
+
+ for (bl = b->loc; bl; bl = bl->next)
+ {
+ /* Special types of hardware watchpoints may use more than
+ one register. */
+ i += b->ops->resources_needed (bl);
+ }
+
+ return i;
+}
+
+/* Returns the sum the used resources of all hardware watchpoints of
+ type TYPE in the breakpoints list. Also returns in OTHER_TYPE_USED
+ the sum of the used resources of all hardware watchpoints of other
+ types _not_ TYPE. */
+
+static int
+hw_watchpoint_used_count_others (struct breakpoint *except,
+ enum bptype type, int *other_type_used)
+{
+ int i = 0;
+ struct breakpoint *b;
+
*other_type_used = 0;
ALL_BREAKPOINTS (b)
{
+ if (b == except)
+ continue;
if (!breakpoint_enabled (b))
continue;
- if (b->type == type)
- for (bl = b->loc; bl; bl = bl->next)
- {
- /* Special types of hardware watchpoints may use more than
- one register. */
- i += b->ops->resources_needed (bl);
- }
- else if (is_hardware_watchpoint (b))
- *other_type_used = 1;
+ if (b->type == type)
+ i += hw_watchpoint_use_count (b);
+ else if (is_hardware_watchpoint (b))
+ *other_type_used = 1;
}
return i;
mention (struct breakpoint *b)
{
b->ops->print_mention (b);
- if (ui_out_is_mi_like_p (uiout))
+ if (ui_out_is_mi_like_p (current_uiout))
return;
printf_filtered ("\n");
}
{
struct breakpoint *b = bs->breakpoint_at;
struct bp_location *bl = b->loc;
+ struct ui_out *uiout = current_uiout;
gdb_assert (b->type == bp_hardware_breakpoint);
{
struct bp_location *bl = b->loc;
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
/* Ranged breakpoints have only one location. */
gdb_assert (bl && bl->next == NULL);
print_mention_ranged_breakpoint (struct breakpoint *b)
{
struct bp_location *bl = b->loc;
+ struct ui_out *uiout = current_uiout;
gdb_assert (bl);
gdb_assert (b->type == bp_hardware_breakpoint);
struct ui_stream *stb;
enum print_stop_action result;
struct watchpoint *w;
+ struct ui_out *uiout = current_uiout;
gdb_assert (bs->bp_location_at != NULL);
{
struct cleanup *ui_out_chain;
struct watchpoint *w = (struct watchpoint *) b;
+ struct ui_out *uiout = current_uiout;
switch (b->type)
{
print_it_masked_watchpoint (bpstat bs)
{
struct breakpoint *b = bs->breakpoint_at;
+ struct ui_out *uiout = current_uiout;
/* Masked watchpoints have only one location. */
gdb_assert (b->loc && b->loc->next == NULL);
print_mention_masked_watchpoint (struct breakpoint *b)
{
struct watchpoint *w = (struct watchpoint *) b;
+ struct ui_out *uiout = current_uiout;
struct cleanup *ui_out_chain;
switch (b->type)
static enum print_stop_action
print_it_exception_catchpoint (bpstat bs)
{
+ struct ui_out *uiout = current_uiout;
struct breakpoint *b = bs->breakpoint_at;
int bp_temp, bp_throw;
struct bp_location **last_loc)
{
struct value_print_options opts;
+ struct ui_out *uiout = current_uiout;
get_user_print_options (&opts);
if (opts.addressprint)
static void
print_mention_exception_catchpoint (struct breakpoint *b)
{
+ struct ui_out *uiout = current_uiout;
int bp_temp;
int bp_throw;
b->language = language_ada;
}
-/* Cleanup function for a syscall filter list. */
-static void
-clean_up_filters (void *arg)
-{
- VEC(int) *iter = *(VEC(int) **) arg;
- VEC_free (int, iter);
-}
-
/* Splits the argument using space as delimiter. Returns an xmalloc'd
filter list, or NULL if no filtering is required. */
static VEC(int) *
catch_syscall_split_args (char *arg)
{
VEC(int) *result = NULL;
- struct cleanup *cleanup = make_cleanup (clean_up_filters, &result);
+ struct cleanup *cleanup = make_cleanup (VEC_cleanup (int), &result);
while (*arg != '\0')
{
static void
say_where (struct breakpoint *b)
{
+ struct ui_out *uiout = current_uiout;
struct value_print_options opts;
get_user_print_options (&opts);
struct breakpoint *b;
const struct bp_location *bl;
int bp_temp;
+ struct ui_out *uiout = current_uiout;
gdb_assert (bs->bp_location_at != NULL);
static void
bkpt_print_mention (struct breakpoint *b)
{
- if (ui_out_is_mi_like_p (uiout))
+ if (ui_out_is_mi_like_p (current_uiout))
return;
switch (b->type)
static enum print_stop_action
momentary_bkpt_print_it (bpstat bs)
{
+ struct ui_out *uiout = current_uiout;
+
if (ui_out_is_mi_like_p (uiout))
{
struct breakpoint *b = bs->breakpoint_at;
static void
tracepoint_print_mention (struct breakpoint *b)
{
- if (ui_out_is_mi_like_p (uiout))
+ if (ui_out_is_mi_like_p (current_uiout))
return;
switch (b->type)
struct symtab_and_line sal;
struct symbol *sym;
struct static_tracepoint_marker *marker;
+ struct ui_out *uiout = current_uiout;
marker = VEC_index (static_tracepoint_marker_p, markers, 0);
static void
tracepoints_info (char *args, int from_tty)
{
+ struct ui_out *uiout = current_uiout;
int num_printed;
num_printed = breakpoint_1 (args, 0, is_tracepoint);
fprintf_unfiltered (fp, " commands\n");
- ui_out_redirect (uiout, fp);
+ ui_out_redirect (current_uiout, fp);
TRY_CATCH (ex, RETURN_MASK_ALL)
{
- print_command_lines (uiout, tp->commands->commands, 2);
+ print_command_lines (current_uiout, tp->commands->commands, 2);
}
- ui_out_redirect (uiout, NULL);
+ ui_out_redirect (current_uiout, NULL);
if (ex.reason < 0)
throw_exception (ex);