in b->loc->cond.
- Update the list of values that must be watched in B->loc.
- If the watchpoint is disabled, do nothing. If this is
- local watchpoint that is out of scope, delete it. */
+ If the watchpoint disposition is disp_del_at_next_stop, then do nothing.
+ If this is local watchpoint that is out of scope, delete it. */
static void
update_watchpoint (struct breakpoint *b, int reparse)
{
int hw_breakpoint_error = 0;
struct ui_file *tmp_error_stream = mem_fileopen ();
- make_cleanup_ui_file_delete (tmp_error_stream);
+ struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
/* Explicitly mark the warning -- this will only be printed if
there was an error. */
target_terminal_ours_for_output ();
error_stream (tmp_error_stream);
}
+
+ do_cleanups (cleanups);
}
int
static enum print_stop_action
print_it_typical (bpstat bs)
{
- struct cleanup *old_chain, *ui_out_chain;
+ struct cleanup *old_chain;
struct breakpoint *b;
const struct bp_location *bl;
struct ui_stream *stb;
- int bp_temp = 0;
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
+ int bp_temp = 0;
+ enum print_stop_action result;
+
/* bs->breakpoint_at can be NULL if it was a momentary breakpoint
which has since been deleted. */
if (bs->breakpoint_at == NULL)
bl = bs->breakpoint_at;
b = bl->owner;
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+
switch (b->type)
{
case bp_breakpoint:
}
ui_out_field_int (uiout, "bkptno", b->number);
ui_out_text (uiout, ", ");
- return PRINT_SRC_AND_LOC;
+ result = PRINT_SRC_AND_LOC;
break;
case bp_shlib_event:
variable? (If so, we report this as a generic, "Stopped due
to shlib event" message.) */
printf_filtered (_("Stopped due to shared library event\n"));
- return PRINT_NOTHING;
+ result = PRINT_NOTHING;
break;
case bp_thread_event:
/* Not sure how we will get here.
GDB should not stop for these breakpoints. */
printf_filtered (_("Thread Event Breakpoint: gdb should not stop!\n"));
- return PRINT_NOTHING;
+ result = PRINT_NOTHING;
break;
case bp_overlay_event:
/* By analogy with the thread event, GDB should not stop for these. */
printf_filtered (_("Overlay Event Breakpoint: gdb should not stop!\n"));
- return PRINT_NOTHING;
+ result = PRINT_NOTHING;
break;
case bp_watchpoint:
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
mention (b);
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
ui_out_text (uiout, "\nOld value = ");
watchpoint_value_print (bs->old_val, stb->stream);
ui_out_field_stream (uiout, "old", stb);
ui_out_text (uiout, "\nNew value = ");
watchpoint_value_print (b->val, stb->stream);
ui_out_field_stream (uiout, "new", stb);
- do_cleanups (ui_out_chain);
ui_out_text (uiout, "\n");
/* More than one watchpoint may have been triggered. */
- return PRINT_UNKNOWN;
+ result = PRINT_UNKNOWN;
break;
case bp_read_watchpoint:
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
mention (b);
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
ui_out_text (uiout, "\nValue = ");
watchpoint_value_print (b->val, stb->stream);
ui_out_field_stream (uiout, "value", stb);
- do_cleanups (ui_out_chain);
ui_out_text (uiout, "\n");
- return PRINT_UNKNOWN;
+ result = PRINT_UNKNOWN;
break;
case bp_access_watchpoint:
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
mention (b);
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
ui_out_text (uiout, "\nOld value = ");
watchpoint_value_print (bs->old_val, stb->stream);
ui_out_field_stream (uiout, "old", stb);
ui_out_field_string
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
ui_out_text (uiout, "\nValue = ");
}
watchpoint_value_print (b->val, stb->stream);
ui_out_field_stream (uiout, "new", stb);
- do_cleanups (ui_out_chain);
ui_out_text (uiout, "\n");
- return PRINT_UNKNOWN;
+ result = PRINT_UNKNOWN;
break;
/* Fall through, we don't deal with these types of breakpoints
ui_out_field_string
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED));
- return PRINT_UNKNOWN;
+ result = PRINT_UNKNOWN;
break;
case bp_until:
ui_out_field_string
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
- return PRINT_UNKNOWN;
+ result = PRINT_UNKNOWN;
break;
case bp_none:
case bp_watchpoint_scope:
case bp_call_dummy:
default:
- return PRINT_UNKNOWN;
+ result = PRINT_UNKNOWN;
+ break;
}
+
+ do_cleanups (old_chain);
+ return result;
}
/* Generic routine for printing messages indicating why we
if (opts.addressprint)
ui_out_field_skip (uiout, "addr");
annotate_field (5);
- print_expression (b->exp, stb->stream);
- ui_out_field_stream (uiout, "what", stb);
+ ui_out_field_string (uiout, "what", b->exp_string);
break;
case bp_breakpoint:
mention (struct breakpoint *b)
{
int say_where = 0;
- struct cleanup *old_chain, *ui_out_chain;
- struct ui_stream *stb;
+ struct cleanup *ui_out_chain;
struct value_print_options opts;
get_user_print_options (&opts);
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
-
/* FIXME: This is misplaced; mention() is called by things (like
hitting a watchpoint) other than breakpoint creation. It should
be possible to clean this up and at the same time replace the
ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
ui_out_field_int (uiout, "number", b->number);
ui_out_text (uiout, ": ");
- print_expression (b->exp, stb->stream);
- ui_out_field_stream (uiout, "exp", stb);
+ ui_out_field_string (uiout, "exp", b->exp_string);
do_cleanups (ui_out_chain);
break;
case bp_hardware_watchpoint:
ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
ui_out_field_int (uiout, "number", b->number);
ui_out_text (uiout, ": ");
- print_expression (b->exp, stb->stream);
- ui_out_field_stream (uiout, "exp", stb);
+ ui_out_field_string (uiout, "exp", b->exp_string);
do_cleanups (ui_out_chain);
break;
case bp_read_watchpoint:
ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
ui_out_field_int (uiout, "number", b->number);
ui_out_text (uiout, ": ");
- print_expression (b->exp, stb->stream);
- ui_out_field_stream (uiout, "exp", stb);
+ ui_out_field_string (uiout, "exp", b->exp_string);
do_cleanups (ui_out_chain);
break;
case bp_access_watchpoint:
ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
ui_out_field_int (uiout, "number", b->number);
ui_out_text (uiout, ": ");
- print_expression (b->exp, stb->stream);
- ui_out_field_stream (uiout, "exp", stb);
+ ui_out_field_string (uiout, "exp", b->exp_string);
do_cleanups (ui_out_chain);
break;
case bp_breakpoint:
}
}
- do_cleanups (old_chain);
if (ui_out_is_mi_like_p (uiout))
return;
printf_filtered ("\n");
char *cond_string,
enum bptype type, enum bpdisp disposition,
int thread, int ignore_count,
- struct breakpoint_ops *ops, int from_tty)
+ struct breakpoint_ops *ops, int from_tty, int enabled)
{
struct breakpoint *b = NULL;
int i;
b->cond_string = cond_string;
b->ignore_count = ignore_count;
- b->enable_state = bp_enabled;
+ b->enable_state = enabled ? bp_enabled : bp_disabled;
b->disposition = disposition;
loc = b->loc;
char *cond_string,
enum bptype type, enum bpdisp disposition,
int thread, int ignore_count,
- struct breakpoint_ops *ops, int from_tty)
+ struct breakpoint_ops *ops, int from_tty,
+ int enabled)
{
int i;
for (i = 0; i < sals.nelts; ++i)
create_breakpoint (expanded, addr_string[i],
cond_string, type, disposition,
- thread, ignore_count, ops, from_tty);
+ thread, ignore_count, ops, from_tty, enabled);
}
update_global_location_list (1);
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
{
+ struct expression *expr;
+
tok = cond_start = end_tok + 1;
- parse_exp_1 (&tok, block_for_pc (pc), 0);
+ expr = parse_exp_1 (&tok, block_for_pc (pc), 0);
+ xfree (expr);
cond_end = tok;
*cond_string = savestring (cond_start,
cond_end - cond_start);
int ignore_count,
enum auto_boolean pending_break_support,
struct breakpoint_ops *ops,
- int from_tty)
+ int from_tty,
+ int enabled)
{
struct gdb_exception e;
struct symtabs_and_lines sals;
hardwareflag ? bp_hardware_breakpoint
: bp_breakpoint,
tempflag ? disp_del : disp_donttouch,
- thread, ignore_count, ops, from_tty);
+ thread, ignore_count, ops, from_tty, enabled);
}
else
{
b->disposition = tempflag ? disp_del : disp_donttouch;
b->condition_not_parsed = 1;
b->ops = ops;
+ b->enable_state = enabled ? bp_enabled : bp_disabled;
update_global_location_list (1);
mention (b);
0 /* Ignore count */,
pending_break_support,
NULL /* breakpoint_ops */,
- from_tty);
+ from_tty,
+ 1 /* enabled */);
}
set_breakpoint (char *address, char *condition,
int hardwareflag, int tempflag,
int thread, int ignore_count,
- int pending)
+ int pending, int enabled)
{
break_command_really (address, condition, thread,
0 /* condition and thread are valid. */,
ignore_count,
pending
? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
- NULL, 0);
+ NULL, 0, enabled);
}
/* Adjust SAL to the first instruction past the function prologue.
exp_start = arg;
exp = parse_exp_1 (&arg, 0, 0);
exp_end = arg;
+ /* Remove trailing whitespace from the expression before saving it.
+ This makes the eventual display of the expression string a bit
+ prettier. */
+ while (exp_end > exp_start && (exp_end[-1] == ' ' || exp_end[-1] == '\t'))
+ --exp_end;
+
exp_valid_block = innermost_block;
mark = value_mark ();
fetch_watchpoint_value (exp, &val, NULL, NULL);
tempflag, 0,
0,
AUTO_BOOLEAN_TRUE /* pending */,
- &gnu_v3_exception_catchpoint_ops, from_tty);
+ &gnu_v3_exception_catchpoint_ops, from_tty,
+ 1 /* enabled */);
return 1;
}
}
}
+/* A cleanup function which destroys a vector. */
+
+static void
+do_vec_free (void *p)
+{
+ VEC(bp_location_p) **vec = p;
+ if (*vec)
+ VEC_free (bp_location_p, *vec);
+}
+
/* If SHOULD_INSERT is false, 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
struct bp_location **next = &bp_location_chain;
struct bp_location *loc;
struct bp_location *loc2;
- struct gdb_exception e;
VEC(bp_location_p) *old_locations = NULL;
int ret;
int ix;
-
+ struct cleanup *cleanups;
+
+ cleanups = make_cleanup (do_vec_free, &old_locations);
/* Store old locations for future reference. */
for (loc = bp_location_chain; loc; loc = loc->global_next)
VEC_safe_push (bp_location_p, old_locations, loc);
|| (gdbarch_has_global_solist (target_gdbarch)
&& target_supports_multi_process ())))
insert_breakpoint_locations ();
+
+ do_cleanups (cleanups);
}
void
char *s;
enum enable_state save_enable;
struct gdb_exception e;
-
+ struct cleanup *cleanups;
switch (b->type)
{
b->condition_not_parsed = 0;
}
expanded = expand_line_sal_maybe (sals.sals[0]);
+ cleanups = make_cleanup (xfree, sals.sals);
update_breakpoint_locations (b, expanded);
-
- xfree (sals.sals);
+ do_cleanups (cleanups);
break;
case bp_watchpoint:
bpt->type == bp_read_watchpoint ||
bpt->type == bp_access_watchpoint)
{
- struct frame_id saved_frame_id;
-
- saved_frame_id = get_frame_id (get_selected_frame (NULL));
- if (bpt->exp_valid_block != NULL)
+ struct gdb_exception e;
+
+ TRY_CATCH (e, RETURN_MASK_ALL)
{
- struct frame_info *fr =
- fr = frame_find_by_id (bpt->watchpoint_frame);
- if (fr == NULL)
- {
- printf_filtered (_("\
-Cannot enable watchpoint %d because the block in which its expression\n\
-is valid is not currently in scope.\n"), bpt->number);
- return;
- }
- select_frame (fr);
+ update_watchpoint (bpt, 1 /* reparse */);
}
-
- if (bpt->val)
- value_free (bpt->val);
- mark = value_mark ();
- fetch_watchpoint_value (bpt->exp, &bpt->val, NULL, NULL);
- if (bpt->val)
- release_value (bpt->val);
- bpt->val_valid = 1;
-
- if (bpt->type == bp_hardware_watchpoint ||
- bpt->type == bp_read_watchpoint ||
- bpt->type == bp_access_watchpoint)
+ if (e.reason < 0)
{
- int i = hw_watchpoint_used_count (bpt->type, &other_type_used);
- int mem_cnt = can_use_hardware_watchpoint (bpt->val);
-
- /* Hack around 'unused var' error for some targets here */
- (void) mem_cnt, (void) i;
- target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT (
- bpt->type, i + mem_cnt, other_type_used);
- /* we can consider of type is bp_hardware_watchpoint, convert to
- bp_watchpoint in the following condition */
- if (target_resources_ok < 0)
- {
- printf_filtered (_("\
-Cannot enable watchpoint %d because target watch resources\n\
-have been allocated for other watchpoints.\n"), bpt->number);
- value_free_to_mark (mark);
- return;
- }
+ exception_fprintf (gdb_stderr, e, _("Cannot enable watchpoint %d: "),
+ bpt->number);
+ return;
}
-
- select_frame (frame_find_by_id (saved_frame_id));
- value_free_to_mark (mark);
}
if (bpt->enable_state != bp_permanent)