#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);
static void condition_command (char *, int);
-typedef enum
- {
- mark_inserted,
- mark_uninserted
- }
-insertion_state_t;
-
-static int remove_breakpoint (struct bp_location *, insertion_state_t);
-static int remove_breakpoint_1 (struct bp_location *, insertion_state_t);
+static int remove_breakpoint (struct bp_location *);
+static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
static enum print_stop_action print_bp_stop_message (bpstat bs);
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 = new_arg.c_str ();
- info.arg = arg;
-
- 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;
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)
{
for (loc = bpt->loc; loc; loc = loc->next)
if (loc->inserted)
- remove_breakpoint (loc, mark_uninserted);
+ remove_breakpoint (loc);
hw_breakpoint_error = 1;
fprintf_unfiltered (tmp_error_stream,
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->inserted && !is_tracepoint (bl->owner))
- val |= remove_breakpoint (bl, mark_uninserted);
+ val |= remove_breakpoint (bl);
}
return val;
}
if (bl->inserted && !bl->target_info.persist)
{
- val = remove_breakpoint (bl, mark_uninserted);
+ val = remove_breakpoint (bl);
if (val != 0)
return val;
}
continue;
if (bl->inserted)
- val |= remove_breakpoint_1 (bl, mark_inserted);
+ val |= remove_breakpoint_1 (bl, DETACH_BREAKPOINT);
}
do_cleanups (old_chain);
*not* look at bl->pspace->aspace here. */
static int
-remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
+remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
{
int val;
&& !memory_validate_breakpoint (bl->gdbarch, &bl->target_info))
val = 0;
else
- val = bl->owner->ops->remove_location (bl);
+ val = bl->owner->ops->remove_location (bl, reason);
}
else
{
&bl->overlay_target_info);
else
target_remove_breakpoint (bl->gdbarch,
- &bl->overlay_target_info);
+ &bl->overlay_target_info,
+ reason);
}
/* Did we set a breakpoint at the VMA?
If so, we will have marked the breakpoint 'inserted'. */
wrong code with the saved shadow contents. */
if (bl->loc_type == bp_loc_hardware_breakpoint
|| section_is_mapped (bl->section))
- val = bl->owner->ops->remove_location (bl);
+ val = bl->owner->ops->remove_location (bl, reason);
else
val = 0;
}
if (val)
return val;
- bl->inserted = (is == mark_inserted);
+ bl->inserted = (reason == DETACH_BREAKPOINT);
}
else if (bl->loc_type == bp_loc_hardware_watchpoint)
{
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->remove_location != NULL);
- bl->inserted = (is == mark_inserted);
- bl->owner->ops->remove_location (bl);
+ bl->inserted = (reason == DETACH_BREAKPOINT);
+ bl->owner->ops->remove_location (bl, reason);
/* Failure to remove any of the hardware watchpoints comes here. */
- if ((is == mark_uninserted) && (bl->inserted))
+ if (reason == REMOVE_BREAKPOINT && bl->inserted)
warning (_("Could not remove hardware watchpoint %d."),
bl->owner->number);
}
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->remove_location != NULL);
- val = bl->owner->ops->remove_location (bl);
+ val = bl->owner->ops->remove_location (bl, reason);
if (val)
return val;
- bl->inserted = (is == mark_inserted);
+ bl->inserted = (reason == DETACH_BREAKPOINT);
}
return 0;
}
static int
-remove_breakpoint (struct bp_location *bl, insertion_state_t is)
+remove_breakpoint (struct bp_location *bl)
{
int ret;
struct cleanup *old_chain;
switch_to_program_space_and_thread (bl->pspace);
- ret = remove_breakpoint_1 (bl, is);
+ ret = remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
do_cleanups (old_chain);
return ret;
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;
}
}
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);
_("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;
catchpoints. */
static int
-remove_catch_fork (struct bp_location *bl)
+remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason)
{
return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
}
catchpoints. */
static int
-remove_catch_vfork (struct bp_location *bl)
+remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason)
{
return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
}
}
static int
-remove_catch_solib (struct bp_location *ignore)
+remove_catch_solib (struct bp_location *ignore, enum remove_bp_reason reason)
{
return 0;
}
}
static int
-remove_catch_exec (struct bp_location *bl)
+remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason)
{
return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
}
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);
/* Implement the "remove" breakpoint_ops method for hardware watchpoints. */
static int
-remove_watchpoint (struct bp_location *bl)
+remove_watchpoint (struct bp_location *bl, enum remove_bp_reason reason)
{
struct watchpoint *w = (struct watchpoint *) bl->owner;
int length = w->exact ? 1 : bl->length;
masked hardware watchpoints. */
static int
-remove_masked_watchpoint (struct bp_location *bl)
+remove_masked_watchpoint (struct bp_location *bl, enum remove_bp_reason reason)
{
struct watchpoint *w = (struct watchpoint *) bl->owner;
if (!keep_in_target)
{
- if (remove_breakpoint (old_loc, mark_uninserted))
+ if (remove_breakpoint (old_loc))
{
/* This is just about all we can do. We could keep
this location on the global list, and try to
}
static int
-base_breakpoint_remove_location (struct bp_location *bl)
+base_breakpoint_remove_location (struct bp_location *bl,
+ enum remove_bp_reason reason)
{
internal_error_pure_virtual_called ();
}
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
}
static int
-bkpt_remove_location (struct bp_location *bl)
+bkpt_remove_location (struct bp_location *bl, enum remove_bp_reason reason)
{
if (bl->loc_type == bp_loc_hardware_breakpoint)
return target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info);
else
- return target_remove_breakpoint (bl->gdbarch, &bl->target_info);
+ return target_remove_breakpoint (bl->gdbarch, &bl->target_info, reason);
}
static int
}
static int
-bkpt_probe_remove_location (struct bp_location *bl)
+bkpt_probe_remove_location (struct bp_location *bl,
+ enum remove_bp_reason reason)
{
/* Let's clear the semaphore before removing the location. */
if (bl->probe.probe->pops->clear_semaphore != NULL)
bl->probe.objfile,
bl->gdbarch);
- return bkpt_remove_location (bl);
+ return bkpt_remove_location (bl, reason);
}
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;
+ const char *p = parser.cur_tok ();
+ bool match = false;
- match = 0;
-
- 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 frame_info *frame = get_current_frame ();
+ VEC (CORE_ADDR) * next_pcs;
+
+ next_pcs = gdbarch_software_single_step (gdbarch, frame);
+
+ if (next_pcs != NULL)
+ {
+ int i;
+ CORE_ADDR pc;
+ 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;