(struct breakpoint *b, const struct event_location *location,
struct program_space *search_pspace);
-static int can_use_hardware_watchpoint (struct value *);
+static int can_use_hardware_watchpoint
+ (const std::vector<value_ref_ptr> &vals);
static void mention (struct breakpoint *);
error (_("The 'while-stepping' command can "
"only be used for tracepoints"));
- for (i = 0; i < c->body_count; ++i)
- check_no_tracepoint_commands ((c->body_list)[i]);
+ check_no_tracepoint_commands (c->body_list_0.get ());
+ check_no_tracepoint_commands (c->body_list_1.get ());
/* Not that command parsing removes leading whitespace and comment
lines and also empty lines. So, we only need to check for
{
struct command_line *c2;
- gdb_assert (while_stepping->body_count == 1);
- c2 = while_stepping->body_list[0];
+ gdb_assert (while_stepping->body_list_1 == nullptr);
+ c2 = while_stepping->body_list_0.get ();
for (; c2; c2 = c2->next)
{
if (c2->control_type == while_stepping_control)
void
breakpoint_set_commands (struct breakpoint *b,
- command_line_up &&commands)
+ counted_command_line &&commands)
{
validate_commands_for_breakpoint (b, commands.get ());
gdb::observers::breakpoint_modified.notify (b);
}
-void
-check_tracepoint_command (char *line, void *closure)
-{
- struct breakpoint *b = (struct breakpoint *) closure;
-
- validate_actionline (line, b);
-}
-
static void
commands_command_1 (const char *arg, int from_tty,
struct command_line *control)
if (cmd == NULL)
{
if (control != NULL)
- cmd = copy_command_lines (control->body_list[0]);
+ cmd = control->body_list_0;
else
{
std::string str
"%s, one per line."),
arg);
- cmd = read_command_lines (&str[0],
- from_tty, 1,
- (is_tracepoint (b)
- ? check_tracepoint_command : 0),
- b);
+ auto do_validate = [=] (const char *line)
+ {
+ validate_actionline (line, b);
+ };
+ gdb::function_view<void (const char *)> validator;
+ if (is_tracepoint (b))
+ validator = do_validate;
+
+ cmd = read_command_lines (str.c_str (), from_tty, 1, validator);
}
}
no longer relevant. We don't want to report a watchpoint hit
to the user when the old value and the new value may actually
be completely different objects. */
- value_free (b->val);
b->val = NULL;
b->val_valid = 0;
else if (within_current_scope && b->exp)
{
int pc = 0;
- struct value *val_chain, *v, *result, *next;
+ std::vector<value_ref_ptr> val_chain;
+ struct value *v, *result, *next;
struct program_space *frame_pspace;
fetch_subexp_value (b->exp.get (), &pc, &v, &result, &val_chain, 0);
if (!b->val_valid && !is_masked_watchpoint (b))
{
if (b->val_bitsize != 0)
- {
- v = extract_bitfield_from_watchpoint_value (b, v);
- if (v != NULL)
- release_value (v);
- }
- b->val = v;
+ v = extract_bitfield_from_watchpoint_value (b, v);
+ b->val = release_value (v);
b->val_valid = 1;
}
frame_pspace = get_frame_program_space (get_selected_frame (NULL));
/* Look at each value on the value chain. */
- for (v = val_chain; v; v = value_next (v))
+ gdb_assert (!val_chain.empty ());
+ for (const value_ref_ptr &iter : val_chain)
{
+ v = iter.get ();
+
/* If it's a memory location, and GDB actually needed
its contents to evaluate the expression, then we
must watch it. If the first value returned is
still lazy, that means an error occurred reading it;
watch it anyway in case it becomes readable. */
if (VALUE_LVAL (v) == lval_memory
- && (v == val_chain || ! value_lazy (v)))
+ && (v == val_chain[0] || ! value_lazy (v)))
{
struct type *vtype = check_typedef (value_type (v));
bl->loc_type = loc_type;
}
- for (v = val_chain; v; v = next)
- {
- next = value_next (v);
- if (v != b->val)
- value_free (v);
- }
-
/* If a software watchpoint is not watching any memory, then the
above left it without any location set up. But,
bpstat_stop_status requires a location to be able to report
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
- ¤t_target);
+ current_top_target ());
b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
{
/* Reset val field to force reread of starting value in
insert_breakpoints. */
- if (w->val)
- value_free (w->val);
- w->val = NULL;
+ w->val.reset (nullptr);
w->val_valid = 0;
}
}
bpstats::~bpstats ()
{
- if (old_val != NULL)
- value_free (old_val);
if (bp_location_at != NULL)
decref_bp_location (&bp_location_at);
}
bp_location_at (other.bp_location_at),
breakpoint_at (other.breakpoint_at),
commands (other.commands),
- old_val (other.old_val),
print (other.print),
stop (other.stop),
print_it (other.print_it)
{
- if (old_val != NULL)
- {
- old_val = value_copy (old_val);
- release_value (old_val);
- }
+ if (other.old_val != NULL)
+ old_val = release_value (value_copy (other.old_val.get ()));
incref_bp_location (bp_location_at);
}
for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
{
bs->commands = NULL;
-
- if (bs->old_val != NULL)
- {
- value_free (bs->old_val);
- bs->old_val = NULL;
- }
+ bs->old_val.reset (nullptr);
}
}
print_solib_event (int is_catchpoint)
{
bool any_deleted = !current_program_space->deleted_solibs.empty ();
- int any_added
- = !VEC_empty (so_list_ptr, current_program_space->added_solibs);
+ bool any_added = !current_program_space->added_solibs.empty ();
if (!is_catchpoint)
{
if (any_added)
{
- struct so_list *iter;
- int ix;
-
current_uiout->text (_(" Inferior loaded "));
ui_out_emit_list list_emitter (current_uiout, "added");
- for (ix = 0;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
+ bool first = true;
+ for (so_list *iter : current_program_space->added_solibs)
{
- if (ix > 0)
+ if (!first)
current_uiout->text (" ");
+ first = false;
current_uiout->field_string ("library", iter->so_name);
current_uiout->text ("\n");
}
bp_location_at (bl),
breakpoint_at (bl->owner),
commands (NULL),
- old_val (NULL),
print (0),
stop (0),
print_it (print_it_normal)
bp_location_at (NULL),
breakpoint_at (NULL),
commands (NULL),
- old_val (NULL),
print (0),
stop (0),
print_it (print_it_normal)
int
watchpoints_triggered (struct target_waitstatus *ws)
{
- int stopped_by_watchpoint = target_stopped_by_watchpoint ();
+ bool stopped_by_watchpoint = target_stopped_by_watchpoint ();
CORE_ADDR addr;
struct breakpoint *b;
return 0;
}
- if (!target_stopped_data_address (¤t_target, &addr))
+ if (!target_stopped_data_address (current_top_target (), &addr))
{
/* We were stopped by a watchpoint, but we don't know where.
Mark all watchpoints as unknown. */
}
}
/* Exact match not required. Within range is sufficient. */
- else if (target_watchpoint_addr_within_range (¤t_target,
+ else if (target_watchpoint_addr_within_range (current_top_target (),
addr, loc->address,
loc->length))
{
the address of the array instead of its contents. This is
not what we want. */
if ((b->val != NULL) != (new_val != NULL)
- || (b->val != NULL && !value_equal_contents (b->val, new_val)))
+ || (b->val != NULL && !value_equal_contents (b->val.get (),
+ new_val)))
{
- if (new_val != NULL)
- {
- release_value (new_val);
- value_free_to_mark (mark);
- }
bs->old_val = b->val;
- b->val = new_val;
+ b->val = release_value (new_val);
b->val_valid = 1;
+ if (new_val != NULL)
+ value_free_to_mark (mark);
return WP_VALUE_CHANGED;
}
else
&& !target_supports_stopped_by_hw_breakpoint ()));
}
-
-/* Get a bpstat associated with having just stopped at address
- BP_ADDR in thread PTID.
-
- Determine whether we stopped at a breakpoint, etc, or whether we
- don't understand this stop. Result is a chain of bpstat's such
- that:
-
- if we don't understand the stop, the result is a null pointer.
-
- if we understand why we stopped, the result is not null.
-
- Each element of the chain refers to a particular breakpoint or
- watchpoint at which we have stopped. (We may have stopped for
- several reasons concurrently.)
-
- Each element of the chain has valid next, breakpoint_at,
- commands, FIXME??? fields. */
+/* See breakpoint.h. */
bpstat
-bpstat_stop_status (const address_space *aspace,
- CORE_ADDR bp_addr, ptid_t ptid,
+build_bpstat_chain (const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
- struct breakpoint *b = NULL;
- struct bp_location *bl;
- struct bp_location *loc;
- /* First item of allocated bpstat's. */
+ struct breakpoint *b;
bpstat bs_head = NULL, *bs_link = &bs_head;
- /* Pointer to the last thing in the chain currently. */
- bpstat bs;
- int ix;
- int need_remove_insert;
- int removed_any;
-
- /* First, build the bpstat chain with locations that explain a
- target stop, while being careful to not set the target running,
- as that may invalidate locations (in particular watchpoint
- locations are recreated). Resuming will happen here with
- breakpoint conditions or watchpoint expressions that include
- inferior function calls. */
ALL_BREAKPOINTS (b)
{
if (!breakpoint_enabled (b))
continue;
- for (bl = b->loc; bl != NULL; bl = bl->next)
+ for (bp_location *bl = b->loc; bl != NULL; bl = bl->next)
{
/* For hardware watchpoints, we look only at the first
location. The watchpoint_check function will work on the
/* Come here if it's a watchpoint, or if the break address
matches. */
- bs = new bpstats (bl, &bs_link); /* Alloc a bpstat to
- explain stop. */
+ bpstat bs = new bpstats (bl, &bs_link); /* Alloc a bpstat to
+ explain stop. */
/* Assume we stop. Should we find a watchpoint that is not
actually triggered, or if the condition of the breakpoint
if (!target_supports_stopped_by_sw_breakpoint ()
|| !target_supports_stopped_by_hw_breakpoint ())
{
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ bp_location *loc;
+
+ for (int ix = 0;
+ VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
{
if (breakpoint_location_address_match (loc, aspace, bp_addr)
&& need_moribund_for_location_type (loc))
{
- bs = new bpstats (loc, &bs_link);
+ bpstat bs = new bpstats (loc, &bs_link);
/* For hits of moribund locations, we should just proceed. */
bs->stop = 0;
bs->print = 0;
}
}
+ return bs_head;
+}
+
+/* See breakpoint.h. */
+
+bpstat
+bpstat_stop_status (const address_space *aspace,
+ CORE_ADDR bp_addr, ptid_t ptid,
+ const struct target_waitstatus *ws,
+ bpstat stop_chain)
+{
+ struct breakpoint *b = NULL;
+ /* First item of allocated bpstat's. */
+ bpstat bs_head = stop_chain;
+ bpstat bs;
+ int need_remove_insert;
+ int removed_any;
+
+ /* First, build the bpstat chain with locations that explain a
+ target stop, while being careful to not set the target running,
+ as that may invalidate locations (in particular watchpoint
+ locations are recreated). Resuming will happen here with
+ breakpoint conditions or watchpoint expressions that include
+ inferior function calls. */
+ if (bs_head == NULL)
+ bs_head = build_bpstat_chain (aspace, bp_addr, ws);
+
/* A bit of special processing for shlib breakpoints. We need to
process solib loading here, so that the lists of loaded and
unloaded libraries are correct before we handle "catch load" and
|| loc->owner->type == bp_hardware_breakpoint
|| is_tracepoint (loc->owner))
{
- int is_gnu_ifunc;
const char *function_name;
- CORE_ADDR func_addr;
- find_pc_partial_function_gnu_ifunc (loc->address, &function_name,
- &func_addr, NULL, &is_gnu_ifunc);
-
- if (is_gnu_ifunc && !explicit_loc)
+ if (loc->msymbol != NULL
+ && (MSYMBOL_TYPE (loc->msymbol) == mst_text_gnu_ifunc
+ || MSYMBOL_TYPE (loc->msymbol) == mst_data_gnu_ifunc)
+ && !explicit_loc)
{
struct breakpoint *b = loc->owner;
- gdb_assert (loc->pspace == current_program_space);
- if (gnu_ifunc_resolve_name (function_name,
- &loc->requested_address))
- {
- /* Recalculate ADDRESS based on new REQUESTED_ADDRESS. */
- loc->address = adjust_breakpoint_address (loc->gdbarch,
- loc->requested_address,
- b->type);
- }
- else if (b->type == bp_breakpoint && b->loc == loc
- && loc->next == NULL && b->related_breakpoint == b)
+ function_name = MSYMBOL_LINKAGE_NAME (loc->msymbol);
+
+ if (b->type == bp_breakpoint && b->loc == loc
+ && loc->next == NULL && b->related_breakpoint == b)
{
/* Create only the whole new breakpoint of this type but do not
mess more complicated breakpoints with multiple locations. */
b->type = bp_gnu_ifunc_resolver;
/* Remember the resolver's address for use by the return
breakpoint. */
- loc->related_address = func_addr;
+ loc->related_address = loc->address;
}
}
+ else
+ find_pc_partial_function (loc->address, &function_name, NULL, NULL);
if (function_name)
loc->function_name = xstrdup (function_name);
if (self->is_load)
{
- struct so_list *iter;
-
- for (int ix = 0;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
+ for (so_list *iter : current_program_space->added_solibs)
{
if (!self->regex
|| self->compiled->exec (iter->so_name, 0, NULL, 0) == 0)
mention (struct breakpoint *b)
{
b->ops->print_mention (b);
- if (current_uiout->is_mi_like_p ())
- return;
- printf_filtered ("\n");
+ current_uiout->text ("\n");
}
\f
loc->line_number = sal->line;
loc->symtab = sal->symtab;
loc->symbol = sal->symbol;
+ loc->msymbol = sal->msymbol;
+ loc->objfile = sal->objfile;
set_breakpoint_location_function (loc,
sal->explicit_pc || sal->explicit_line);
_("Invalid dprintf style."));
gdb_assert (printf_line != NULL);
- /* Manufacture a printf sequence. */
- {
- struct command_line *printf_cmd_line = XNEW (struct command_line);
-
- printf_cmd_line->control_type = simple_control;
- printf_cmd_line->body_count = 0;
- printf_cmd_line->body_list = NULL;
- printf_cmd_line->next = NULL;
- printf_cmd_line->line = printf_line;
- breakpoint_set_commands (b, command_line_up (printf_cmd_line));
- }
+ /* Manufacture a printf sequence. */
+ struct command_line *printf_cmd_line
+ = new struct command_line (simple_control, printf_line);
+ breakpoint_set_commands (b, counted_command_line (printf_cmd_line,
+ command_lines_deleter ()));
}
/* Update all dprintf commands, making their command lists reflect
gdb_assert (bl);
gdb_assert (b->type == bp_hardware_breakpoint);
- if (uiout->is_mi_like_p ())
- return;
-
- printf_filtered (_("Hardware assisted ranged breakpoint %d from %s to %s."),
- b->number, paddress (bl->gdbarch, bl->address),
- paddress (bl->gdbarch, bl->address + bl->length - 1));
+ uiout->message (_("Hardware assisted ranged breakpoint %d from %s to %s."),
+ b->number, paddress (bl->gdbarch, bl->address),
+ paddress (bl->gdbarch, bl->address + bl->length - 1));
}
/* Implement the "print_recreate" breakpoint_ops method for
{
xfree (this->exp_string);
xfree (this->exp_string_reparse);
- value_free (this->val);
}
/* Implement the "re_set" breakpoint_ops method for watchpoints. */
mention (b);
tuple_emitter.emplace (uiout, "value");
uiout->text ("\nOld value = ");
- watchpoint_value_print (bs->old_val, &stb);
+ watchpoint_value_print (bs->old_val.get (), &stb);
uiout->field_stream ("old", stb);
uiout->text ("\nNew value = ");
- watchpoint_value_print (w->val, &stb);
+ watchpoint_value_print (w->val.get (), &stb);
uiout->field_stream ("new", stb);
uiout->text ("\n");
/* More than one watchpoint may have been triggered. */
mention (b);
tuple_emitter.emplace (uiout, "value");
uiout->text ("\nValue = ");
- watchpoint_value_print (w->val, &stb);
+ watchpoint_value_print (w->val.get (), &stb);
uiout->field_stream ("value", stb);
uiout->text ("\n");
result = PRINT_UNKNOWN;
mention (b);
tuple_emitter.emplace (uiout, "value");
uiout->text ("\nOld value = ");
- watchpoint_value_print (bs->old_val, &stb);
+ watchpoint_value_print (bs->old_val.get (), &stb);
uiout->field_stream ("old", stb);
uiout->text ("\nNew value = ");
}
tuple_emitter.emplace (uiout, "value");
uiout->text ("\nValue = ");
}
- watchpoint_value_print (w->val, &stb);
+ watchpoint_value_print (w->val.get (), &stb);
uiout->field_stream ("new", stb);
uiout->text ("\n");
result = PRINT_UNKNOWN;
{
struct breakpoint *scope_breakpoint = NULL;
const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
- struct value *val, *mark, *result;
+ struct value *mark, *result;
int saved_bitpos = 0, saved_bitsize = 0;
const char *exp_start = NULL;
const char *exp_end = NULL;
exp_valid_block = innermost_block.block ();
mark = value_mark ();
- fetch_subexp_value (exp.get (), &pc, &val, &result, NULL, just_location);
+ struct value *val_as_value = nullptr;
+ fetch_subexp_value (exp.get (), &pc, &val_as_value, &result, NULL,
+ just_location);
- if (val != NULL && just_location)
+ if (val_as_value != NULL && just_location)
{
- saved_bitpos = value_bitpos (val);
- saved_bitsize = value_bitsize (val);
+ saved_bitpos = value_bitpos (val_as_value);
+ saved_bitsize = value_bitsize (val_as_value);
}
+ value_ref_ptr val;
if (just_location)
{
int ret;
exp_valid_block = NULL;
- val = value_addr (result);
- release_value (val);
+ val = release_value (value_addr (result));
value_free_to_mark (mark);
if (use_mask)
{
- ret = target_masked_watch_num_registers (value_as_address (val),
+ ret = target_masked_watch_num_registers (value_as_address (val.get ()),
mask);
if (ret == -1)
error (_("This target does not support masked watchpoints."));
error (_("Invalid mask or memory region."));
}
}
- else if (val != NULL)
- release_value (val);
+ else if (val_as_value != NULL)
+ val = release_value (val_as_value);
tok = skip_spaces (arg);
end_tok = skip_to_space (tok);
w->cond_exp_valid_block = cond_exp_valid_block;
if (just_location)
{
- struct type *t = value_type (val);
- CORE_ADDR addr = value_as_address (val);
+ struct type *t = value_type (val.get ());
+ CORE_ADDR addr = value_as_address (val.get ());
w->exp_string_reparse
= current_language->la_watch_location_expression (t, addr).release ();
If the watchpoint cannot be handled in hardware return zero. */
static int
-can_use_hardware_watchpoint (struct value *v)
+can_use_hardware_watchpoint (const std::vector<value_ref_ptr> &vals)
{
int found_memory_cnt = 0;
- struct value *head = v;
/* Did the user specifically forbid us to use hardware watchpoints? */
if (!can_use_hw_watchpoints)
return 0;
+ gdb_assert (!vals.empty ());
+ struct value *head = vals[0].get ();
+
/* Make sure that the value of the expression depends only upon
memory contents, and values computed from them within GDB. If we
find any register references or function calls, we can't use a
function calls are special in any way. So this function may not
notice that an expression involving an inferior function call
can't be watched with hardware watchpoints. FIXME. */
- for (; v; v = value_next (v))
+ for (const value_ref_ptr &iter : vals)
{
+ struct value *v = iter.get ();
+
if (VALUE_LVAL (v) == lval_memory)
{
if (v != head && value_lazy (v))
ambiguous_names_p (struct bp_location *loc)
{
struct bp_location *l;
- htab_t htab = htab_create_alloc (13, htab_hash_string,
- (int (*) (const void *,
- const void *)) streq,
- NULL, xcalloc, xfree);
+ htab_t htab = htab_create_alloc (13, htab_hash_string, streq_hash, NULL,
+ xcalloc, xfree);
for (l = loc; l != NULL; l = l->next)
{
scoped_restore save_input_radix = make_scoped_restore (&input_radix);
scoped_restore_current_pspace_and_thread restore_pspace_thread;
+ /* breakpoint_re_set_one sets the current_language to the language
+ of the breakpoint it is resetting (see prepare_re_set_context)
+ before re-evaluating the breakpoint's location. This change can
+ unfortunately get undone by accident if the language_mode is set
+ to auto, and we either switch frames, or more likely in this context,
+ we select the current frame.
+
+ We prevent this by temporarily turning the language_mode to
+ language_mode_manual. We restore it once all breakpoints
+ have been reset. */
+ scoped_restore save_language_mode = make_scoped_restore (&language_mode);
+ language_mode = language_mode_manual;
+
/* Note: we must not try to insert locations until after all
breakpoints have been re-set. Otherwise, e.g., when re-setting
breakpoint 1, we'd insert the locations of breakpoint 2, which
{
struct watchpoint *wp = (struct watchpoint *) bp;
- if (wp->val_valid && wp->val)
+ if (wp->val_valid && wp->val != nullptr)
{
struct bp_location *loc;
&& loc->address + loc->length > addr
&& addr + len > loc->address)
{
- value_free (wp->val);
wp->val = NULL;
wp->val_valid = 0;
}
static char *
read_uploaded_action (void)
{
- char *rslt;
+ char *rslt = nullptr;
- VEC_iterate (char_ptr, this_utp->cmd_strings, next_cmd, rslt);
-
- next_cmd++;
+ if (next_cmd < this_utp->cmd_strings.size ())
+ {
+ rslt = this_utp->cmd_strings[next_cmd];
+ next_cmd++;
+ }
return rslt;
}
special-purpose "reader" function and call the usual command line
reader, then pass the result to the breakpoint command-setting
function. */
- if (!VEC_empty (char_ptr, utp->cmd_strings))
+ if (!utp->cmd_strings.empty ())
{
- command_line_up cmd_list;
+ counted_command_line cmd_list;
this_utp = utp;
next_cmd = 0;
- cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
+ cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL);
breakpoint_set_commands (tp, std::move (cmd_list));
}
- else if (!VEC_empty (char_ptr, utp->actions)
- || !VEC_empty (char_ptr, utp->step_actions))
+ else if (!utp->actions.empty ()
+ || !utp->step_actions.empty ())
warning (_("Uploaded tracepoint %d actions "
"have no source form, ignoring them"),
utp->number);