#include "mi/mi-common.h"
#include "extension.h"
+#include <algorithm>
/* Enums for exception-handling support. */
enum exception_event_kind
static void enable_command (char *, int);
-static void map_breakpoint_numbers (char *, void (*) (struct breakpoint *,
- void *),
+static void map_breakpoint_numbers (const char *,
+ void (*) (struct breakpoint *,
+ void *),
void *);
static void ignore_command (char *, int);
{
struct watchpoint *w = (struct watchpoint *) b;
- xfree (w->cond_exp);
- w->cond_exp = NULL;
+ w->cond_exp.reset ();
}
else
{
for (loc = b->loc; loc; loc = loc->next)
{
- xfree (loc->cond);
- loc->cond = NULL;
+ loc->cond.reset ();
/* No need to free the condition agent expression
bytecode (if we have one). We will handle this
int from_tty;
/* The breakpoint range spec. */
- char *arg;
+ const char *arg;
/* Non-NULL if the body of the commands are being read from this
already-parsed command. */
}
static void
-commands_command_1 (char *arg, int from_tty,
+commands_command_1 (const char *arg, int from_tty,
struct command_line *control)
{
struct cleanup *cleanups;
extra reference to the commands that we must clean up. */
cleanups = make_cleanup_decref_counted_command_line (&info.cmd);
+ std::string new_arg;
+
if (arg == NULL || !*arg)
{
if (breakpoint_count - prev_breakpoint_count > 1)
- arg = xstrprintf ("%d-%d", prev_breakpoint_count + 1,
- breakpoint_count);
+ new_arg = string_printf ("%d-%d", prev_breakpoint_count + 1,
+ breakpoint_count);
else if (breakpoint_count > 0)
- arg = xstrprintf ("%d", breakpoint_count);
- else
- {
- /* So that we don't try to free the incoming non-NULL
- argument in the cleanup below. Mapping breakpoint
- numbers will fail in this case. */
- arg = NULL;
- }
+ new_arg = string_printf ("%d", breakpoint_count);
}
else
- /* The command loop has some static state, so we need to preserve
- our argument. */
- arg = xstrdup (arg);
+ new_arg = arg;
- if (arg != NULL)
- make_cleanup (xfree, arg);
-
- info.arg = arg;
+ info.arg = new_arg.c_str ();
- map_breakpoint_numbers (arg, do_map_commands_command, &info);
+ map_breakpoint_numbers (info.arg, do_map_commands_command, &info);
if (info.cmd == NULL)
error (_("No breakpoints specified."));
This is used by cli-script.c to DTRT with breakpoint commands
that are part of if and while bodies. */
enum command_control_type
-commands_from_control_command (char *arg, struct command_line *cmd)
+commands_from_control_command (const char *arg, struct command_line *cmd)
{
commands_command_1 (arg, 0, cmd);
return simple_control;
{
const char *s;
- if (b->exp)
- {
- xfree (b->exp);
- b->exp = NULL;
- }
+ b->exp.reset ();
s = b->exp_string_reparse ? b->exp_string_reparse : b->exp_string;
b->exp = parse_exp_1 (&s, 0, b->exp_valid_block, 0);
/* If the meaning of expression itself changed, the old value is
locations (re)created below. */
if (b->base.cond_string != NULL)
{
- if (b->cond_exp != NULL)
- {
- xfree (b->cond_exp);
- b->cond_exp = NULL;
- }
+ b->cond_exp.reset ();
s = b->base.cond_string;
b->cond_exp = parse_exp_1 (&s, 0, b->cond_exp_valid_block, 0);
struct value *val_chain, *v, *result, *next;
struct program_space *frame_pspace;
- fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain, 0);
+ fetch_subexp_value (b->exp.get (), &pc, &v, &result, &val_chain, 0);
/* Avoid setting b->val if it's already set. The meaning of
b->val is 'the last value' user saw, and we should update
by the bytecode interpreter. Return NULL if there was
any error during parsing. */
-static struct agent_expr *
+static agent_expr_up
parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
{
- struct agent_expr *aexpr = NULL;
-
- if (!cond)
+ if (cond == NULL)
return NULL;
+ agent_expr_up aexpr;
+
/* We don't want to stop processing, so catch any errors
that may show up. */
TRY
/* If we got here, it means the condition could not be parsed to a valid
bytecode expression and thus can't be evaluated on the target's side.
It's no use iterating through the conditions. */
- return NULL;
}
END_CATCH
struct bp_location *loc;
/* Release conditions left over from a previous insert. */
- VEC_free (agent_expr_p, bl->target_info.conditions);
+ bl->target_info.conditions.clear ();
/* This is only meaningful if the target is
evaluating conditions and if the user has
{
if (modified)
{
- struct agent_expr *aexpr;
-
/* Re-parse the conditions since something changed. In that
case we already freed the condition bytecodes (see
force_breakpoint_reinsertion). We just
need to parse the condition to bytecodes again. */
- aexpr = parse_cond_to_aexpr (bl->address, loc->cond);
- loc->cond_bytecode = aexpr;
+ loc->cond_bytecode = parse_cond_to_aexpr (bl->address,
+ loc->cond.get ());
}
/* If we have a NULL bytecode expression, it means something
if (!loc->cond_bytecode)
return;
- free_agent_expr (loc->cond_bytecode);
- loc->cond_bytecode = NULL;
+ loc->cond_bytecode.reset ();
}
}
}
&& loc->pspace->num == bl->pspace->num
&& loc->owner->enable_state == bp_enabled
&& loc->enabled)
- /* Add the condition to the vector. This will be used later to send the
- conditions to the target. */
- VEC_safe_push (agent_expr_p, bl->target_info.conditions,
- loc->cond_bytecode);
+ {
+ /* Add the condition to the vector. This will be used later
+ to send the conditions to the target. */
+ bl->target_info.conditions.push_back (loc->cond_bytecode.get ());
+ }
}
return;
bytecode suitable for evaluation by the bytecode interpreter.
Return NULL if there was any error during parsing. */
-static struct agent_expr *
+static agent_expr_up
parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
{
struct cleanup *old_cleanups = 0;
- struct expression *expr, **argvec;
- struct agent_expr *aexpr = NULL;
+ struct expression **argvec;
const char *cmdrest;
const char *format_start, *format_end;
struct format_piece *fpieces;
int nargs;
struct gdbarch *gdbarch = get_current_arch ();
- if (!cmd)
+ if (cmd == NULL)
return NULL;
cmdrest = cmd;
const char *cmd1;
cmd1 = cmdrest;
- expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
- argvec[nargs++] = expr;
+ expression_up expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
+ argvec[nargs++] = expr.release ();
cmdrest = cmd1;
if (*cmdrest == ',')
++cmdrest;
}
+ agent_expr_up aexpr;
+
/* We don't want to stop processing, so catch any errors
that may show up. */
TRY
/* If we got here, it means the command could not be parsed to a valid
bytecode expression and thus can't be evaluated on the target's side.
It's no use iterating through the other commands. */
- aexpr = NULL;
}
END_CATCH
int modified = bl->needs_update;
struct bp_location *loc;
- /* Release commands left over from a previous insert. */
- VEC_free (agent_expr_p, bl->target_info.tcommands);
+ /* Clear commands left over from a previous insert. */
+ bl->target_info.tcommands.clear ();
if (!target_can_run_breakpoint_commands ())
return;
{
if (modified)
{
- struct agent_expr *aexpr;
-
/* Re-parse the commands since something changed. In that
case we already freed the command bytecodes (see
force_breakpoint_reinsertion). We just
need to parse the command to bytecodes again. */
- aexpr = parse_cmd_to_aexpr (bl->address,
- loc->owner->extra_string);
- loc->cmd_bytecode = aexpr;
+ loc->cmd_bytecode
+ = parse_cmd_to_aexpr (bl->address,
+ loc->owner->extra_string);
}
/* If we have a NULL bytecode expression, it means something
if (loc->cmd_bytecode == NULL)
return;
- free_agent_expr (loc->cmd_bytecode);
- loc->cmd_bytecode = NULL;
+ loc->cmd_bytecode.reset ();
}
}
}
&& loc->pspace->num == bl->pspace->num
&& loc->owner->enable_state == bp_enabled
&& loc->enabled)
- /* Add the command to the vector. This will be used later
- to send the commands to the target. */
- VEC_safe_push (agent_expr_p, bl->target_info.tcommands,
- loc->cmd_bytecode);
+ {
+ /* Add the command to the vector. This will be used later
+ to send the commands to the target. */
+ bl->target_info.tcommands.push_back (loc->cmd_bytecode.get ());
+ }
}
bl->target_info.persist = 0;
bl->target_info.persist = 1;
}
+/* Return the kind of breakpoint on address *ADDR. Get the kind
+ of breakpoint according to ADDR except single-step breakpoint.
+ Get the kind of single-step breakpoint according to the current
+ registers state. */
+
+static int
+breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr)
+{
+ if (bl->owner->type == bp_single_step)
+ {
+ struct thread_info *thr = find_thread_global_id (bl->owner->thread);
+ struct regcache *regcache;
+
+ regcache = get_thread_regcache (thr->ptid);
+
+ return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
+ regcache, addr);
+ }
+ else
+ return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr);
+}
+
/* Insert a low-level "breakpoint" of some type. BL is the breakpoint
location. Any error messages are printed to TMP_ERROR_STREAM; and
DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
{
int val;
+ bl->overlay_target_info.kind
+ = breakpoint_kind (bl, &addr);
+ bl->overlay_target_info.placed_address = addr;
val = target_insert_breakpoint (bl->gdbarch,
&bl->overlay_target_info);
if (val)
CORE_ADDR l, h;
/* Check for intersection. */
- l = max (loc->address, addr);
- h = min (loc->address + loc->length, addr + len);
+ l = std::max<CORE_ADDR> (loc->address, addr);
+ h = std::min<CORE_ADDR> (loc->address + loc->length, addr + len);
if (l < h)
return 1;
}
return WP_VALUE_CHANGED;
mark = value_mark ();
- fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL, 0);
+ fetch_subexp_value (b->exp.get (), &pc, &new_val, NULL, NULL, 0);
if (b->val_bitsize != 0)
new_val = extract_bitfield_from_watchpoint_value (b, new_val);
}
else
{
- struct switch_thru_all_uis state;
-
/* 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
already. So we have no choice but print the information
here. */
- SWITCH_THRU_ALL_UIS (state)
+ SWITCH_THRU_ALL_UIS ()
{
struct ui_out *uiout = current_uiout;
case 0:
/* Error from catch_errors. */
{
- struct switch_thru_all_uis state;
-
- SWITCH_THRU_ALL_UIS (state)
+ SWITCH_THRU_ALL_UIS ()
{
printf_filtered (_("Watchpoint %d deleted.\n"),
b->base.number);
{
struct watchpoint *w = (struct watchpoint *) b;
- cond = w->cond_exp;
+ cond = w->cond_exp.get ();
}
else
- cond = bl->cond;
+ cond = bl->cond.get ();
if (cond && b->disposition != disp_del_at_next_stop)
{
_("bpstat_what: unhandled bptype %d"), (int) bptype);
}
- retval.main_action = max (retval.main_action, this_action);
+ retval.main_action = std::max (retval.main_action, this_action);
}
return retval;
&& target_can_accel_watchpoint_condition (loc1->address,
loc1->length,
loc1->watchpoint_type,
- w1->cond_exp))
+ w1->cond_exp.get ()))
|| (w2->cond_exp
&& target_can_accel_watchpoint_condition (loc2->address,
loc2->length,
loc2->watchpoint_type,
- w2->cond_exp)))
+ w2->cond_exp.get ())))
return 0;
/* Note that this checks the owner's type, not the location's. In
loc->ops = ops;
loc->owner = owner;
- loc->cond = NULL;
loc->cond_bytecode = NULL;
loc->shlib_disabled = 0;
loc->enabled = 1;
free_bp_location (struct bp_location *loc)
{
loc->ops->dtor (loc);
- xfree (loc);
+ delete loc;
}
/* Increment reference count. */
enum bptype bptype,
const struct breakpoint_ops *ops)
{
- struct breakpoint *b = XNEW (struct breakpoint);
+ struct breakpoint *b = new breakpoint ();
init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
add_to_breakpoint_chain (b);
struct symtab_and_line sal, enum bptype bptype,
const struct breakpoint_ops *ops)
{
- struct breakpoint *b = XNEW (struct breakpoint);
+ struct breakpoint *b = new breakpoint ();
init_raw_breakpoint (b, gdbarch, sal, bptype, ops);
add_to_breakpoint_chain (b);
arg = "";
arg = skip_spaces (arg);
- c = XCNEW (struct solib_catchpoint);
+ c = new solib_catchpoint ();
cleanup = make_cleanup (xfree, c);
if (*arg != '\0')
int tempflag, char *cond_string,
const struct breakpoint_ops *ops)
{
- struct fork_catchpoint *c = XNEW (struct fork_catchpoint);
+ struct fork_catchpoint *c = new fork_catchpoint ();
init_catchpoint (&c->base, gdbarch, tempflag, cond_string, ops);
static struct breakpoint *
new_single_step_breakpoint (int thread, struct gdbarch *gdbarch)
{
- struct breakpoint *b = XNEW (struct breakpoint);
+ struct breakpoint *b = new breakpoint ();
init_raw_breakpoint_without_location (b, gdbarch, bp_single_step,
&momentary_breakpoint_ops);
{
struct tracepoint *t;
- t = XCNEW (struct tracepoint);
+ t = new tracepoint ();
b = &t->base;
}
else
- b = XNEW (struct breakpoint);
+ b = new breakpoint ();
old_chain = make_cleanup (xfree, b);
old_chain = make_cleanup (xfree, msg);
if (!rslt)
- error (_("May not have a fast tracepoint at 0x%s%s"),
+ error (_("May not have a fast tracepoint at %s%s"),
paddress (sarch, sal->pc), (msg ? msg : ""));
do_cleanups (old_chain);
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
{
- struct expression *expr;
-
tok = cond_start = end_tok + 1;
- expr = parse_exp_1 (&tok, pc, block_for_pc (pc), 0);
- xfree (expr);
+ parse_exp_1 (&tok, pc, block_for_pc (pc), 0);
cond_end = tok;
*cond_string = savestring (cond_start, cond_end - cond_start);
}
{
struct tracepoint *t;
- t = XCNEW (struct tracepoint);
+ t = new tracepoint ();
b = &t->base;
}
else
- b = XNEW (struct breakpoint);
+ b = new breakpoint ();
init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
b->location = copy_event_location (location);
{
struct watchpoint *w = (struct watchpoint *) self;
- xfree (w->cond_exp);
- xfree (w->exp);
xfree (w->exp_string);
xfree (w->exp_string_reparse);
value_free (w->val);
int length = w->exact ? 1 : bl->length;
return target_insert_watchpoint (bl->address, length, bl->watchpoint_type,
- w->cond_exp);
+ w->cond_exp.get ());
}
/* Implement the "remove" breakpoint_ops method for hardware watchpoints. */
int length = w->exact ? 1 : bl->length;
return target_remove_watchpoint (bl->address, length, bl->watchpoint_type,
- w->cond_exp);
+ w->cond_exp.get ());
}
static int
int just_location, int internal)
{
struct breakpoint *b, *scope_breakpoint = NULL;
- struct expression *exp;
const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
struct value *val, *mark, *result;
int saved_bitpos = 0, saved_bitsize = 0;
expression = savestring (arg, exp_end - arg);
back_to = make_cleanup (xfree, expression);
exp_start = arg = expression;
- exp = parse_exp_1 (&arg, 0, 0, 0);
+ expression_up exp = parse_exp_1 (&arg, 0, 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
--exp_end;
/* Checking if the expression is not constant. */
- if (watchpoint_exp_is_const (exp))
+ if (watchpoint_exp_is_const (exp.get ()))
{
int len;
exp_valid_block = innermost_block;
mark = value_mark ();
- fetch_subexp_value (exp, &pc, &val, &result, NULL, just_location);
+ fetch_subexp_value (exp.get (), &pc, &val, &result, NULL, just_location);
if (val != NULL && just_location)
{
toklen = end_tok - tok;
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
{
- struct expression *cond;
-
innermost_block = NULL;
tok = cond_start = end_tok + 1;
- cond = parse_exp_1 (&tok, 0, 0, 0);
+ parse_exp_1 (&tok, 0, 0, 0);
/* The watchpoint expression may not be local, but the condition
may still be. E.g.: `watch global if local > 0'. */
cond_exp_valid_block = innermost_block;
- xfree (cond);
cond_end = tok;
}
if (*tok)
else
bp_type = bp_hardware_watchpoint;
- w = XCNEW (struct watchpoint);
+ w = new watchpoint ();
b = &w->base;
if (use_mask)
init_raw_breakpoint_without_location (b, NULL, bp_type,
b->thread = thread;
b->disposition = disp_donttouch;
b->pspace = current_program_space;
- w->exp = exp;
+ w->exp = std::move (exp);
w->exp_valid_block = exp_valid_block;
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);
- char *name;
t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
- name = type_to_string (t);
- w->exp_string_reparse = xstrprintf ("* (%s *) %s", name,
+ std::string name = type_to_string (t);
+
+ w->exp_string_reparse = xstrprintf ("* (%s *) %s", name.c_str (),
core_addr_to_string (addr));
- xfree (name);
w->exp_string = xstrprintf ("-location %.*s",
(int) (exp_end - exp_start), exp_start);
if ((*arg != '\0') && !isspace (*arg))
error (_("Junk at end of arguments."));
- c = XNEW (struct exec_catchpoint);
+ c = new exec_catchpoint ();
init_catchpoint (&c->base, gdbarch, tempflag, cond_string,
&catch_exec_breakpoint_ops);
c->exec_pathname = NULL;
/* Free the agent expression bytecode as well. We will compute
it later on. */
- if (loc->cond_bytecode)
- {
- free_agent_expr (loc->cond_bytecode);
- loc->cond_bytecode = NULL;
- }
+ loc->cond_bytecode.reset ();
}
}
/* Called whether new breakpoints are created, or existing breakpoints
static void
bp_location_dtor (struct bp_location *self)
{
- xfree (self->cond);
- if (self->cond_bytecode)
- free_agent_expr (self->cond_bytecode);
xfree (self->function_name);
-
- VEC_free (agent_expr_p, self->target_info.conditions);
- VEC_free (agent_expr_p, self->target_info.tcommands);
}
static const struct bp_location_ops bp_location_ops =
{
struct bp_location *loc;
- loc = XNEW (struct bp_location);
+ loc = new struct bp_location ();
init_bp_location (loc, &bp_location_ops, self);
return loc;
}
static int
bkpt_insert_location (struct bp_location *bl)
{
+ CORE_ADDR addr = bl->target_info.reqstd_address;
+
+ bl->target_info.kind = breakpoint_kind (bl, &addr);
+ bl->target_info.placed_address = addr;
+
if (bl->loc_type == bp_loc_hardware_breakpoint)
return target_insert_hw_breakpoint (bl->gdbarch, &bl->target_info);
else
location = copy_event_location (canonical->location);
old_chain = make_cleanup_delete_event_location (location);
- tp = XCNEW (struct tracepoint);
+ tp = new tracepoint ();
init_breakpoint_sal (&tp->base, gdbarch, expanded,
location, NULL,
cond_string, extra_string,
/* On the chance that someone will soon try again to delete this
same bp, we mark it as deleted before freeing its storage. */
bpt->type = bp_none;
- xfree (bpt);
+ delete bpt;
}
static void
whose numbers are given in ARGS. */
static void
-map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *,
- void *),
+map_breakpoint_numbers (const char *args,
+ void (*function) (struct breakpoint *,
+ void *),
void *data)
{
int num;
struct breakpoint *b, *tmp;
- int match;
- struct get_number_or_range_state state;
if (args == 0 || *args == '\0')
error_no_arg (_("one or more breakpoint numbers"));
- init_number_or_range (&state, args);
+ number_or_range_parser parser (args);
- while (!state.finished)
+ while (!parser.finished ())
{
- const char *p = state.string;
-
- match = 0;
+ const char *p = parser.cur_tok ();
+ bool match = false;
- num = get_number_or_range (&state);
+ num = parser.get_number ();
if (num == 0)
{
warning (_("bad breakpoint number at or near '%s'"), p);
ALL_BREAKPOINTS_SAFE (b, tmp)
if (b->number == num)
{
- match = 1;
+ match = true;
function (b, data);
break;
}
- if (match == 0)
+ if (!match)
printf_unfiltered (_("No breakpoint number %d.\n"), num);
}
}
update_global_location_list (UGLL_INSERT);
}
+/* Insert single step breakpoints according to the current state. */
+
+int
+insert_single_step_breakpoints (struct gdbarch *gdbarch)
+{
+ struct regcache *regcache = get_current_regcache ();
+ VEC (CORE_ADDR) * next_pcs;
+
+ next_pcs = gdbarch_software_single_step (gdbarch, regcache);
+
+ if (next_pcs != NULL)
+ {
+ int i;
+ CORE_ADDR pc;
+ struct frame_info *frame = get_current_frame ();
+ struct address_space *aspace = get_frame_address_space (frame);
+
+ for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
+ insert_single_step_breakpoint (gdbarch, aspace, pc);
+
+ VEC_free (CORE_ADDR, next_pcs);
+
+ return 1;
+ }
+ else
+ return 0;
+}
+
/* See breakpoint.h. */
int
}
else
{
- struct get_number_or_range_state state;
-
- init_number_or_range (&state, args);
- while (!state.finished)
+ number_or_range_parser parser (args);
+ while (!parser.finished ())
{
- t1 = get_tracepoint_by_number (&args, &state);
+ t1 = get_tracepoint_by_number (&args, &parser);
if (t1)
trace_pass_set_count (t1, count, from_tty);
}
struct tracepoint *
get_tracepoint_by_number (char **arg,
- struct get_number_or_range_state *state)
+ number_or_range_parser *parser)
{
struct breakpoint *t;
int tpnum;
char *instring = arg == NULL ? NULL : *arg;
- if (state)
+ if (parser != NULL)
{
- gdb_assert (!state->finished);
- tpnum = get_number_or_range (state);
+ gdb_assert (!parser->finished ());
+ tpnum = parser->get_number ();
}
else if (arg == NULL || *arg == NULL || ! **arg)
tpnum = tracepoint_count;