/* Everything about breakpoints, for GDB.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "source.h"
#include "linespec.h"
#include "completer.h"
-#include "gdb.h"
#include "ui-out.h"
#include "cli/cli-script.h"
#include "block.h"
#include "solib.h"
#include "solist.h"
-#include "observer.h"
+#include "observable.h"
#include "memattr.h"
#include "ada-lang.h"
#include "top.h"
/* Prototypes for local functions. */
-static void enable_delete_command (char *, int);
-
-static void enable_once_command (char *, int);
-
-static void enable_count_command (char *, int);
-
-static void disable_command (char *, int);
-
-static void enable_command (char *, int);
-
static void map_breakpoint_numbers (const char *,
- void (*) (struct breakpoint *,
- void *),
- void *);
-
-static void ignore_command (char *, int);
-
-static int breakpoint_re_set_one (void *);
+ gdb::function_view<void (breakpoint *)>);
static void breakpoint_re_set_default (struct breakpoint *);
(struct breakpoint *b, const struct event_location *location,
struct program_space *search_pspace);
-static void clear_command (char *, int);
-
-static void catch_command (char *, int);
-
-static int can_use_hardware_watchpoint (struct value *);
-
-static void break_command_1 (char *, int, int);
+static int can_use_hardware_watchpoint
+ (const std::vector<value_ref_ptr> &vals);
static void mention (struct breakpoint *);
struct bp_location *loc2);
static int breakpoint_location_address_match (struct bp_location *bl,
- struct address_space *aspace,
+ const struct address_space *aspace,
CORE_ADDR addr);
static int breakpoint_location_address_range_overlap (struct bp_location *,
- struct address_space *,
+ const address_space *,
CORE_ADDR, int);
-static void info_breakpoints_command (char *, int);
-
-static void info_watchpoints_command (char *, int);
-
-static int breakpoint_1 (char *, int,
- int (*) (const struct breakpoint *));
-
-static int breakpoint_cond_eval (void *);
-
-static void cleanup_executing_breakpoints (void *);
-
-static void commands_command (char *, int);
-
-static void condition_command (char *, int);
-
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);
-static int watchpoint_check (void *);
-
-static void maintenance_info_breakpoints (char *, int);
-
static int hw_breakpoint_used_count (void);
static int hw_watchpoint_use_count (struct breakpoint *);
enum bptype type,
int *other_type_used);
-static void hbreak_command (char *, int);
-
-static void thbreak_command (char *, int);
-
static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
int count);
-static void stop_command (char *arg, int from_tty);
-
-static void stopin_command (char *arg, int from_tty);
-
-static void stopat_command (char *arg, int from_tty);
-
-static void tcatch_command (char *arg, int from_tty);
-
static void free_bp_location (struct bp_location *loc);
static void incref_bp_location (struct bp_location *loc);
static void decref_bp_location (struct bp_location **loc);
static void insert_breakpoint_locations (void);
-static void info_tracepoints_command (char *, int);
-
-static void delete_trace_command (char *, int);
-
-static void enable_trace_command (char *, int);
-
-static void disable_trace_command (char *, int);
-
-static void trace_pass_command (char *, int);
+static void trace_pass_command (const char *, int);
static void set_tracepoint_count (int num);
has disconnected. */
static int disconnected_dprintf = 1;
-/* A reference-counted struct command_line. This lets multiple
- breakpoints share a single command list. */
-struct counted_command_line
-{
- /* The reference count. */
- int refc;
-
- /* The command list. */
- struct command_line *commands;
-};
-
struct command_line *
breakpoint_commands (struct breakpoint *b)
{
- return b->commands ? b->commands->commands : NULL;
+ return b->commands ? b->commands.get () : NULL;
}
/* Flag indicating that a command has proceeded the inferior past the
/* Called at the start an "rbreak" command to record the first
breakpoint made. */
-void
-start_rbreak_breakpoints (void)
+scoped_rbreak_breakpoints::scoped_rbreak_breakpoints ()
{
rbreak_start_breakpoint_count = breakpoint_count;
}
/* Called at the end of an "rbreak" command to record the last
breakpoint made. */
-void
-end_rbreak_breakpoints (void)
+scoped_rbreak_breakpoints::~scoped_rbreak_breakpoints ()
{
prev_breakpoint_count = rbreak_start_breakpoint_count;
}
b->hit_count = 0;
}
-/* Allocate a new counted_command_line with reference count of 1.
- The new structure owns COMMANDS. */
-
-static struct counted_command_line *
-alloc_counted_command_line (struct command_line *commands)
-{
- struct counted_command_line *result = XNEW (struct counted_command_line);
-
- result->refc = 1;
- result->commands = commands;
-
- return result;
-}
-
-/* Increment reference count. This does nothing if CMD is NULL. */
-
-static void
-incref_counted_command_line (struct counted_command_line *cmd)
-{
- if (cmd)
- ++cmd->refc;
-}
-
-/* Decrement reference count. If the reference count reaches 0,
- destroy the counted_command_line. Sets *CMDP to NULL. This does
- nothing if *CMDP is NULL. */
-
-static void
-decref_counted_command_line (struct counted_command_line **cmdp)
-{
- if (*cmdp)
- {
- if (--(*cmdp)->refc == 0)
- {
- free_command_lines (&(*cmdp)->commands);
- xfree (*cmdp);
- }
- *cmdp = NULL;
- }
-}
-
-/* A cleanup function that calls decref_counted_command_line. */
-
-static void
-do_cleanup_counted_command_line (void *arg)
-{
- decref_counted_command_line ((struct counted_command_line **) arg);
-}
-
-/* Create a cleanup that calls decref_counted_command_line on the
- argument. */
-
-static struct cleanup *
-make_cleanup_decref_counted_command_line (struct counted_command_line **cmdp)
-{
- return make_cleanup (do_cleanup_counted_command_line, cmdp);
-}
-
\f
/* Return the breakpoint with the specified number, or NULL
if the number does not refer to an existing breakpoint. */
condition_evaluation_mode. */
static void
-set_condition_evaluation_mode (char *args, int from_tty,
+set_condition_evaluation_mode (const char *args, int from_tty,
struct cmd_list_element *c)
{
const char *old_mode, *new_mode;
{
struct watchpoint *w = (struct watchpoint *) b;
- innermost_block = NULL;
+ innermost_block.reset ();
arg = exp;
w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
if (*arg)
error (_("Junk at end of expression"));
- w->cond_exp_valid_block = innermost_block;
+ w->cond_exp_valid_block = innermost_block.block ();
}
else
{
}
mark_breakpoint_modified (b);
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
/* Completion for the "condition" command. */
{
int len;
struct breakpoint *b;
- VEC (char_ptr) *result = NULL;
if (text[0] == '$')
{
/* condition N EXP -- set break condition of breakpoint N to EXP. */
static void
-condition_command (char *arg, int from_tty)
+condition_command (const char *arg, int from_tty)
{
struct breakpoint *b;
- char *p;
+ const char *p;
int bnum;
if (arg == 0)
{
validate_commands_for_breakpoint (b, commands.get ());
- decref_counted_command_line (&b->commands);
- b->commands = alloc_counted_command_line (commands.release ());
- observer_notify_breakpoint_modified (b);
+ b->commands = std::move (commands);
+ gdb::observers::breakpoint_modified.notify (b);
}
/* Set the internal `silent' flag on the breakpoint. Note that this
b->silent = silent;
if (old_silent != silent)
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
/* Set the thread for this breakpoint. If THREAD is -1, make the
b->thread = thread;
if (old_thread != thread)
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
/* Set the task for this breakpoint. If TASK is 0, make the
b->task = task;
if (old_task != task)
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
void
validate_actionline (line, b);
}
-/* A structure used to pass information through
- map_breakpoint_numbers. */
-
-struct commands_info
-{
- /* True if the command was typed at a tty. */
- int from_tty;
-
- /* The breakpoint range spec. */
- const char *arg;
-
- /* Non-NULL if the body of the commands are being read from this
- already-parsed command. */
- struct command_line *control;
-
- /* The command lines read from the user, or NULL if they have not
- yet been read. */
- struct counted_command_line *cmd;
-};
-
-/* A callback for map_breakpoint_numbers that sets the commands for
- commands_command. */
-
-static void
-do_map_commands_command (struct breakpoint *b, void *data)
-{
- struct commands_info *info = (struct commands_info *) data;
-
- if (info->cmd == NULL)
- {
- command_line_up l;
-
- if (info->control != NULL)
- l = copy_command_lines (info->control->body_list[0]);
- else
- {
- struct cleanup *old_chain;
- char *str;
-
- str = xstrprintf (_("Type commands for breakpoint(s) "
- "%s, one per line."),
- info->arg);
-
- old_chain = make_cleanup (xfree, str);
-
- l = read_command_lines (str,
- info->from_tty, 1,
- (is_tracepoint (b)
- ? check_tracepoint_command : 0),
- b);
-
- do_cleanups (old_chain);
- }
-
- info->cmd = alloc_counted_command_line (l.release ());
- }
-
- /* If a breakpoint was on the list more than once, we don't need to
- do anything. */
- if (b->commands != info->cmd)
- {
- validate_commands_for_breakpoint (b, info->cmd->commands);
- incref_counted_command_line (info->cmd);
- decref_counted_command_line (&b->commands);
- b->commands = info->cmd;
- observer_notify_breakpoint_modified (b);
- }
-}
-
static void
commands_command_1 (const char *arg, int from_tty,
struct command_line *control)
{
- struct cleanup *cleanups;
- struct commands_info info;
-
- info.from_tty = from_tty;
- info.control = control;
- info.cmd = NULL;
- /* If we read command lines from the user, then `info' will hold an
- extra reference to the commands that we must clean up. */
- cleanups = make_cleanup_decref_counted_command_line (&info.cmd);
+ counted_command_line cmd;
std::string new_arg;
breakpoint_count);
else if (breakpoint_count > 0)
new_arg = string_printf ("%d", breakpoint_count);
- }
- else
- new_arg = arg;
-
- info.arg = new_arg.c_str ();
-
- map_breakpoint_numbers (info.arg, do_map_commands_command, &info);
-
- if (info.cmd == NULL)
- error (_("No breakpoints specified."));
-
- do_cleanups (cleanups);
-}
-
-static void
-commands_command (char *arg, int from_tty)
+ arg = new_arg.c_str ();
+ }
+
+ map_breakpoint_numbers
+ (arg, [&] (breakpoint *b)
+ {
+ if (cmd == NULL)
+ {
+ if (control != NULL)
+ cmd = copy_command_lines (control->body_list[0]);
+ else
+ {
+ std::string str
+ = string_printf (_("Type commands for breakpoint(s) "
+ "%s, one per line."),
+ arg);
+
+ cmd = read_command_lines (&str[0],
+ from_tty, 1,
+ (is_tracepoint (b)
+ ? check_tracepoint_command : 0),
+ b);
+ }
+ }
+
+ /* If a breakpoint was on the list more than once, we don't need to
+ do anything. */
+ if (b->commands != cmd)
+ {
+ validate_commands_for_breakpoint (b, cmd.get ());
+ b->commands = cmd;
+ gdb::observers::breakpoint_modified.notify (b);
+ }
+ });
+}
+
+static void
+commands_command (const char *arg, int from_tty)
{
commands_command_1 (arg, from_tty, NULL);
}
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));
loc->gdbarch = get_type_arch (value_type (v));
loc->pspace = frame_pspace;
- loc->address = addr;
+ loc->address = address_significant (loc->gdbarch, addr);
if (bitsize != 0)
{
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
static agent_expr_up
parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
{
- struct cleanup *old_cleanups = 0;
- 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 == NULL)
format_start = cmdrest;
- fpieces = parse_format_string (&cmdrest);
-
- old_cleanups = make_cleanup (free_format_pieces_cleanup, &fpieces);
+ format_pieces fpieces (&cmdrest);
format_end = cmdrest;
/* For each argument, make an expression. */
- argvec = (struct expression **) alloca (strlen (cmd)
- * sizeof (struct expression *));
-
- nargs = 0;
+ std::vector<struct expression *> argvec;
while (*cmdrest != '\0')
{
const char *cmd1;
cmd1 = cmdrest;
expression_up expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
- argvec[nargs++] = expr.release ();
+ argvec.push_back (expr.release ());
cmdrest = cmd1;
if (*cmdrest == ',')
++cmdrest;
{
aexpr = gen_printf (scope, gdbarch, 0, 0,
format_start, format_end - format_start,
- fpieces, nargs, argvec);
+ argvec.size (), argvec.data ());
}
CATCH (ex, RETURN_MASK_ERROR)
{
}
END_CATCH
- do_cleanups (old_cleanups);
-
/* We have a valid agent expression, return it. */
return aexpr;
}
int *hw_breakpoint_error,
int *hw_bp_error_explained_already)
{
- enum errors bp_err = GDB_NO_ERROR;
- const char *bp_err_message = NULL;
+ gdb_exception bp_excpt = exception_none;
if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
return 0;
val = bl->owner->ops->insert_location (bl);
if (val)
- bp_err = GENERIC_ERROR;
+ bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
CATCH (e, RETURN_MASK_ALL)
{
- bp_err = e.error;
- bp_err_message = e.message;
+ bp_excpt = e;
}
END_CATCH
}
val = target_insert_breakpoint (bl->gdbarch,
&bl->overlay_target_info);
if (val)
- bp_err = GENERIC_ERROR;
+ bp_excpt
+ = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
CATCH (e, RETURN_MASK_ALL)
{
- bp_err = e.error;
- bp_err_message = e.message;
+ bp_excpt = e;
}
END_CATCH
- if (bp_err != GDB_NO_ERROR)
+ if (bp_excpt.reason != 0)
fprintf_unfiltered (tmp_error_stream,
"Overlay breakpoint %d "
"failed: in ROM?\n",
val = bl->owner->ops->insert_location (bl);
if (val)
- bp_err = GENERIC_ERROR;
+ bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
CATCH (e, RETURN_MASK_ALL)
{
- bp_err = e.error;
- bp_err_message = e.message;
+ bp_excpt = e;
}
END_CATCH
}
}
}
- if (bp_err != GDB_NO_ERROR)
+ if (bp_excpt.reason != 0)
{
/* Can't set the breakpoint. */
breakpoint insertion failed (e.g., the remote target
doesn't define error codes), so we must treat generic
errors as memory errors. */
- if ((bp_err == GENERIC_ERROR || bp_err == MEMORY_ERROR)
+ if (bp_excpt.reason == RETURN_ERROR
+ && (bp_excpt.error == GENERIC_ERROR
+ || bp_excpt.error == MEMORY_ERROR)
&& bl->loc_type == bp_loc_software_breakpoint
&& (solib_name_from_address (bl->pspace, bl->address)
|| shared_objfile_contains_address_p (bl->pspace,
{
/* See also: disable_breakpoints_in_shlibs. */
bl->shlib_disabled = 1;
- observer_notify_breakpoint_modified (bl->owner);
+ gdb::observers::breakpoint_modified.notify (bl->owner);
if (!*disabled_breaks)
{
fprintf_unfiltered (tmp_error_stream,
if (bl->loc_type == bp_loc_hardware_breakpoint)
{
*hw_breakpoint_error = 1;
- *hw_bp_error_explained_already = bp_err_message != NULL;
+ *hw_bp_error_explained_already = bp_excpt.message != NULL;
fprintf_unfiltered (tmp_error_stream,
"Cannot insert hardware breakpoint %d%s",
- bl->owner->number, bp_err_message ? ":" : ".\n");
- if (bp_err_message != NULL)
- fprintf_unfiltered (tmp_error_stream, "%s.\n", bp_err_message);
+ bl->owner->number,
+ bp_excpt.message ? ":" : ".\n");
+ if (bp_excpt.message != NULL)
+ fprintf_unfiltered (tmp_error_stream, "%s.\n",
+ bp_excpt.message);
}
else
{
- if (bp_err_message == NULL)
+ if (bp_excpt.message == NULL)
{
std::string message
= memory_error_message (TARGET_XFER_E_IO,
fprintf_unfiltered (tmp_error_stream,
"Cannot insert breakpoint %d: %s\n",
bl->owner->number,
- bp_err_message);
+ bp_excpt.message);
}
}
return 1;
return 0;
}
-int
-reattach_breakpoints (int pid)
-{
- struct bp_location *bl, **blp_tmp;
- int val;
- int dummy1 = 0, dummy2 = 0, dummy3 = 0;
- struct inferior *inf;
- struct thread_info *tp;
-
- tp = any_live_thread_of_process (pid);
- if (tp == NULL)
- return 1;
-
- inf = find_inferior_pid (pid);
-
- scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
- inferior_ptid = tp->ptid;
-
- string_file tmp_error_stream;
-
- ALL_BP_LOCATIONS (bl, blp_tmp)
- {
- if (bl->pspace != inf->pspace)
- continue;
-
- if (bl->inserted)
- {
- bl->inserted = 0;
- val = insert_bp_location (bl, &tmp_error_stream, &dummy1, &dummy2, &dummy3);
- if (val != 0)
- return val;
- }
- }
- return 0;
-}
-
static int internal_breakpoint_number = -1;
/* Set the breakpoint number of B, depending on the value of INTERNAL.
struct breakpoint_objfile_data
{
/* Minimal symbol for "_ovly_debug_event" (if any). */
- struct bound_minimal_symbol overlay_msym;
+ struct bound_minimal_symbol overlay_msym {};
/* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */
- struct bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES];
+ struct bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES] {};
/* True if we have looked for longjmp probes. */
- int longjmp_searched;
+ int longjmp_searched = 0;
- /* SystemTap probe points for longjmp (if any). */
- VEC (probe_p) *longjmp_probes;
+ /* SystemTap probe points for longjmp (if any). These are non-owning
+ references. */
+ std::vector<probe *> longjmp_probes;
/* Minimal symbol for "std::terminate()" (if any). */
- struct bound_minimal_symbol terminate_msym;
+ struct bound_minimal_symbol terminate_msym {};
/* Minimal symbol for "_Unwind_DebugHook" (if any). */
- struct bound_minimal_symbol exception_msym;
+ struct bound_minimal_symbol exception_msym {};
/* True if we have looked for exception probes. */
- int exception_searched;
+ int exception_searched = 0;
- /* SystemTap probe points for unwinding (if any). */
- VEC (probe_p) *exception_probes;
+ /* SystemTap probe points for unwinding (if any). These are non-owning
+ references. */
+ std::vector<probe *> exception_probes;
};
static const struct objfile_data *breakpoint_objfile_key;
objfile_data (objfile, breakpoint_objfile_key));
if (bp_objfile_data == NULL)
{
- bp_objfile_data =
- XOBNEW (&objfile->objfile_obstack, struct breakpoint_objfile_data);
-
- memset (bp_objfile_data, 0, sizeof (*bp_objfile_data));
+ bp_objfile_data = new breakpoint_objfile_data ();
set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
}
return bp_objfile_data;
}
static void
-free_breakpoint_probes (struct objfile *obj, void *data)
+free_breakpoint_objfile_data (struct objfile *obj, void *data)
{
struct breakpoint_objfile_data *bp_objfile_data
= (struct breakpoint_objfile_data *) data;
- VEC_free (probe_p, bp_objfile_data->longjmp_probes);
- VEC_free (probe_p, bp_objfile_data->exception_probes);
+ delete bp_objfile_data;
}
static void
if (!bp_objfile_data->longjmp_searched)
{
- VEC (probe_p) *ret;
+ std::vector<probe *> ret
+ = find_probes_in_objfile (objfile, "libc", "longjmp");
- ret = find_probes_in_objfile (objfile, "libc", "longjmp");
- if (ret != NULL)
+ if (!ret.empty ())
{
/* We are only interested in checking one element. */
- struct probe *p = VEC_index (probe_p, ret, 0);
+ probe *p = ret[0];
- if (!can_evaluate_probe_arguments (p))
+ if (!p->can_evaluate_arguments ())
{
/* We cannot use the probe interface here, because it does
not know how to evaluate arguments. */
- VEC_free (probe_p, ret);
- ret = NULL;
+ ret.clear ();
}
}
bp_objfile_data->longjmp_probes = ret;
bp_objfile_data->longjmp_searched = 1;
}
- if (bp_objfile_data->longjmp_probes != NULL)
+ if (!bp_objfile_data->longjmp_probes.empty ())
{
- int i;
- struct probe *probe;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- for (i = 0;
- VEC_iterate (probe_p,
- bp_objfile_data->longjmp_probes,
- i, probe);
- ++i)
+ for (probe *p : bp_objfile_data->longjmp_probes)
{
struct breakpoint *b;
b = create_internal_breakpoint (gdbarch,
- get_probe_address (probe,
- objfile),
+ p->get_relocated_address (objfile),
bp_longjmp_master,
&internal_breakpoint_ops);
b->location = new_probe_location ("-probe-stap libc:longjmp");
/* We prefer the SystemTap probe point if it exists. */
if (!bp_objfile_data->exception_searched)
{
- VEC (probe_p) *ret;
+ std::vector<probe *> ret
+ = find_probes_in_objfile (objfile, "libgcc", "unwind");
- ret = find_probes_in_objfile (objfile, "libgcc", "unwind");
-
- if (ret != NULL)
+ if (!ret.empty ())
{
/* We are only interested in checking one element. */
- struct probe *p = VEC_index (probe_p, ret, 0);
+ probe *p = ret[0];
- if (!can_evaluate_probe_arguments (p))
+ if (!p->can_evaluate_arguments ())
{
/* We cannot use the probe interface here, because it does
not know how to evaluate arguments. */
- VEC_free (probe_p, ret);
- ret = NULL;
+ ret.clear ();
}
}
bp_objfile_data->exception_probes = ret;
bp_objfile_data->exception_searched = 1;
}
- if (bp_objfile_data->exception_probes != NULL)
+ if (!bp_objfile_data->exception_probes.empty ())
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- int i;
- struct probe *probe;
-
- for (i = 0;
- VEC_iterate (probe_p,
- bp_objfile_data->exception_probes,
- i, probe);
- ++i)
+
+ for (probe *p : bp_objfile_data->exception_probes)
{
struct breakpoint *b;
b = create_internal_breakpoint (gdbarch,
- get_probe_address (probe,
- objfile),
+ p->get_relocated_address (objfile),
bp_exception_master,
&internal_breakpoint_ops);
b->location = new_probe_location ("-probe-stap libgcc:unwind");
{
/* 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;
}
}
the target, to advance the PC past the breakpoint. */
enum breakpoint_here
-breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
+breakpoint_here_p (const address_space *aspace, CORE_ADDR pc)
{
struct bp_location *bl, **blp_tmp;
int any_breakpoint_here = 0;
/* See breakpoint.h. */
int
-breakpoint_in_range_p (struct address_space *aspace,
+breakpoint_in_range_p (const address_space *aspace,
CORE_ADDR addr, ULONGEST len)
{
struct bp_location *bl, **blp_tmp;
/* Return true if there's a moribund breakpoint at PC. */
int
-moribund_breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
+moribund_breakpoint_here_p (const address_space *aspace, CORE_ADDR pc)
{
struct bp_location *loc;
int ix;
static int
bp_location_inserted_here_p (struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR pc)
+ const address_space *aspace, CORE_ADDR pc)
{
if (bl->inserted
&& breakpoint_address_match (bl->pspace->aspace, bl->address,
/* Returns non-zero iff there's a breakpoint inserted at PC. */
int
-breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc)
+breakpoint_inserted_here_p (const address_space *aspace, CORE_ADDR pc)
{
struct bp_location **blp, **blp_tmp = NULL;
inserted at PC. */
int
-software_breakpoint_inserted_here_p (struct address_space *aspace,
+software_breakpoint_inserted_here_p (const address_space *aspace,
CORE_ADDR pc)
{
struct bp_location **blp, **blp_tmp = NULL;
/* See breakpoint.h. */
int
-hardware_breakpoint_inserted_here_p (struct address_space *aspace,
+hardware_breakpoint_inserted_here_p (const address_space *aspace,
CORE_ADDR pc)
{
struct bp_location **blp, **blp_tmp = NULL;
}
int
-hardware_watchpoint_inserted_in_range (struct address_space *aspace,
+hardware_watchpoint_inserted_in_range (const address_space *aspace,
CORE_ADDR addr, ULONGEST len)
{
struct breakpoint *bpt;
/* Frees any storage that is part of a bpstat. Does not walk the
'next' chain. */
-static void
-bpstat_free (bpstat bs)
+bpstats::~bpstats ()
{
- if (bs->old_val != NULL)
- value_free (bs->old_val);
- decref_counted_command_line (&bs->commands);
- decref_bp_location (&bs->bp_location_at);
- xfree (bs);
+ if (bp_location_at != NULL)
+ decref_bp_location (&bp_location_at);
}
/* Clear a bpstat so that it says we are not at any breakpoint.
while (p != NULL)
{
q = p->next;
- bpstat_free (p);
+ delete p;
p = q;
}
*bsp = NULL;
}
+bpstats::bpstats (const bpstats &other)
+ : next (NULL),
+ bp_location_at (other.bp_location_at),
+ breakpoint_at (other.breakpoint_at),
+ commands (other.commands),
+ print (other.print),
+ stop (other.stop),
+ print_it (other.print_it)
+{
+ if (other.old_val != NULL)
+ old_val = release_value (value_copy (other.old_val.get ()));
+ incref_bp_location (bp_location_at);
+}
+
/* Return a copy of a bpstat. Like "bs1 = bs2" but all storage that
is part of the bpstat is copied as well. */
for (; bs != NULL; bs = bs->next)
{
- tmp = (bpstat) xmalloc (sizeof (*tmp));
- memcpy (tmp, bs, sizeof (*tmp));
- incref_counted_command_line (tmp->commands);
- incref_bp_location (tmp->bp_location_at);
- if (bs->old_val != NULL)
- {
- tmp->old_val = value_copy (bs->old_val);
- release_value (tmp->old_val);
- }
+ tmp = new bpstats (*bs);
if (p == NULL)
/* This is the first thing in the chain. */
for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
{
- decref_counted_command_line (&bs->commands);
-
- if (bs->old_val != NULL)
- {
- value_free (bs->old_val);
- bs->old_val = NULL;
- }
+ bs->commands = NULL;
+ bs->old_val.reset (nullptr);
}
}
breakpoint_proceeded = 1;
}
-/* Stub for cleaning up our state if we error-out of a breakpoint
- command. */
-static void
-cleanup_executing_breakpoints (void *ignore)
-{
- executing_breakpoint_commands = 0;
-}
-
/* Return non-zero iff CMD as the first line of a command sequence is `silent'
or its equivalent. */
bpstat_do_actions_1 (bpstat *bsp)
{
bpstat bs;
- struct cleanup *old_chain;
int again = 0;
/* Avoid endless recursion if a `source' command is contained
if (executing_breakpoint_commands)
return 0;
- executing_breakpoint_commands = 1;
- old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
+ scoped_restore save_executing
+ = make_scoped_restore (&executing_breakpoint_commands, 1);
scoped_restore preventer = prevent_dont_repeat ();
breakpoint_proceeded = 0;
for (; bs != NULL; bs = bs->next)
{
- struct counted_command_line *ccmd;
- struct command_line *cmd;
- struct cleanup *this_cmd_tree_chain;
+ struct command_line *cmd = NULL;
/* Take ownership of the BSP's command tree, if it has one.
commands are only executed once, we don't need to copy it; we
can clear the pointer in the bpstat, and make sure we free
the tree when we're done. */
- ccmd = bs->commands;
+ counted_command_line ccmd = bs->commands;
bs->commands = NULL;
- this_cmd_tree_chain = make_cleanup_decref_counted_command_line (&ccmd);
- cmd = ccmd ? ccmd->commands : NULL;
+ if (ccmd != NULL)
+ cmd = ccmd.get ();
if (command_line_is_silent (cmd))
{
/* The action has been already done by bpstat_stop_status. */
cmd = cmd->next;
}
- /* We can free this command tree now. */
- do_cleanups (this_cmd_tree_chain);
-
if (breakpoint_proceeded)
{
if (current_ui->async)
break;
}
}
- do_cleanups (old_chain);
return again;
}
static void
print_solib_event (int is_catchpoint)
{
- int any_deleted
- = !VEC_empty (char_ptr, current_program_space->deleted_solibs);
+ bool any_deleted = !current_program_space->deleted_solibs.empty ();
int any_added
= !VEC_empty (so_list_ptr, current_program_space->added_solibs);
if (any_deleted)
{
- char *name;
- int ix;
-
current_uiout->text (_(" Inferior unloaded "));
ui_out_emit_list list_emitter (current_uiout, "removed");
- for (ix = 0;
- VEC_iterate (char_ptr, current_program_space->deleted_solibs,
- ix, name);
- ++ix)
+ for (int ix = 0; ix < current_program_space->deleted_solibs.size (); ix++)
{
+ const std::string &name = current_program_space->deleted_solibs[ix];
+
if (ix > 0)
current_uiout->text (" ");
current_uiout->field_string ("library", name);
return PRINT_UNKNOWN;
}
-/* Evaluate the expression EXP and return 1 if value is zero.
- This returns the inverse of the condition because it is called
- from catch_errors which returns 0 if an exception happened, and if an
- exception happens we want execution to stop.
- The argument is a "struct expression *" that has been cast to a
- "void *" to make it pass through catch_errors. */
+/* Evaluate the boolean expression EXP and return the result. */
-static int
-breakpoint_cond_eval (void *exp)
+static bool
+breakpoint_cond_eval (expression *exp)
{
struct value *mark = value_mark ();
- int i = !value_true (evaluate_expression ((struct expression *) exp));
+ bool res = value_true (evaluate_expression (exp));
value_free_to_mark (mark);
- return i;
+ return res;
}
/* Allocate a new bpstat. Link it to the FIFO list by BS_LINK_POINTER. */
-static bpstat
-bpstat_alloc (struct bp_location *bl, bpstat **bs_link_pointer)
+bpstats::bpstats (struct bp_location *bl, bpstat **bs_link_pointer)
+ : next (NULL),
+ bp_location_at (bl),
+ breakpoint_at (bl->owner),
+ commands (NULL),
+ print (0),
+ stop (0),
+ print_it (print_it_normal)
{
- bpstat bs;
-
- bs = (bpstat) xmalloc (sizeof (*bs));
- bs->next = NULL;
- **bs_link_pointer = bs;
- *bs_link_pointer = &bs->next;
- bs->breakpoint_at = bl->owner;
- bs->bp_location_at = bl;
incref_bp_location (bl);
- /* If the condition is false, etc., don't do the commands. */
- bs->commands = NULL;
- bs->old_val = NULL;
- bs->print_it = print_it_normal;
- return bs;
+ **bs_link_pointer = this;
+ *bs_link_pointer = &next;
+}
+
+bpstats::bpstats ()
+ : next (NULL),
+ bp_location_at (NULL),
+ breakpoint_at (NULL),
+ commands (NULL),
+ print (0),
+ stop (0),
+ print_it (print_it_normal)
+{
}
\f
/* The target has stopped with waitstatus WS. Check if any hardware
return 1;
}
-/* Possible return values for watchpoint_check (this can't be an enum
- because of check_errors). */
-/* The watchpoint has been deleted. */
-#define WP_DELETED 1
-/* The value has changed. */
-#define WP_VALUE_CHANGED 2
-/* The value has not changed. */
-#define WP_VALUE_NOT_CHANGED 3
-/* Ignore this watchpoint, no matter if the value changed or not. */
-#define WP_IGNORE 4
+/* Possible return values for watchpoint_check. */
+enum wp_check_result
+ {
+ /* The watchpoint has been deleted. */
+ WP_DELETED = 1,
+
+ /* The value has changed. */
+ WP_VALUE_CHANGED = 2,
+
+ /* The value has not changed. */
+ WP_VALUE_NOT_CHANGED = 3,
+
+ /* Ignore this watchpoint, no matter if the value changed or not. */
+ WP_IGNORE = 4,
+ };
#define BP_TEMPFLAG 1
#define BP_HARDWAREFLAG 2
/* Evaluate watchpoint condition expression and check if its value
- changed.
-
- P should be a pointer to struct bpstat, but is defined as a void *
- in order for this function to be usable with catch_errors. */
+ changed. */
-static int
-watchpoint_check (void *p)
+static wp_check_result
+watchpoint_check (bpstat bs)
{
- bpstat bs = (bpstat) p;
struct watchpoint *b;
struct frame_info *fr;
int within_current_scope;
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
}
/* Make sure the watchpoint's commands aren't executed. */
- decref_counted_command_line (&b->commands);
+ b->commands = NULL;
watchpoint_del_at_next_stop (b);
return WP_DELETED;
static int
bpstat_check_location (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
struct breakpoint *b = bl->owner;
if (must_check_value)
{
- char *message
- = xstrprintf ("Error evaluating expression for watchpoint %d\n",
- b->number);
- struct cleanup *cleanups = make_cleanup (xfree, message);
- int e = catch_errors (watchpoint_check, bs, message,
- RETURN_MASK_ALL);
- do_cleanups (cleanups);
+ wp_check_result e;
+
+ TRY
+ {
+ e = watchpoint_check (bs);
+ }
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ exception_fprintf (gdb_stderr, ex,
+ "Error evaluating expression "
+ "for watchpoint %d\n",
+ b->number);
+
+ SWITCH_THRU_ALL_UIS ()
+ {
+ printf_filtered (_("Watchpoint %d deleted.\n"),
+ b->number);
+ }
+ watchpoint_del_at_next_stop (b);
+ e = WP_DELETED;
+ }
+ END_CATCH
+
switch (e)
{
case WP_DELETED:
break;
default:
/* Can't happen. */
- case 0:
- /* Error from catch_errors. */
- {
- SWITCH_THRU_ALL_UIS ()
- {
- printf_filtered (_("Watchpoint %d deleted.\n"),
- b->number);
- }
- watchpoint_del_at_next_stop (b);
- /* We've already printed what needs to be printed. */
- bs->print_it = print_it_done;
- }
break;
}
}
{
const struct bp_location *bl;
struct breakpoint *b;
- int value_is_zero = 0;
+ /* Assume stop. */
+ bool condition_result = true;
struct expression *cond;
gdb_assert (bs->stop);
within_current_scope = 0;
}
if (within_current_scope)
- value_is_zero
- = catch_errors (breakpoint_cond_eval, cond,
- "Error in testing breakpoint condition:\n",
- RETURN_MASK_ALL);
+ {
+ TRY
+ {
+ condition_result = breakpoint_cond_eval (cond);
+ }
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ exception_fprintf (gdb_stderr, ex,
+ "Error in testing breakpoint condition:\n");
+ }
+ END_CATCH
+ }
else
{
warning (_("Watchpoint condition cannot be tested "
"in the current scope"));
/* If we failed to set the right context for this
watchpoint, unconditionally report it. */
- value_is_zero = 0;
}
/* FIXME-someday, should give breakpoint #. */
value_free_to_mark (mark);
}
- if (cond && value_is_zero)
+ if (cond && !condition_result)
{
bs->stop = 0;
}
bs->stop = 0;
/* Increase the hit count even though we don't stop. */
++(b->hit_count);
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
}
commands, FIXME??? fields. */
bpstat
-bpstat_stop_status (struct address_space *aspace,
+bpstat_stop_status (const address_space *aspace,
CORE_ADDR bp_addr, ptid_t ptid,
const struct target_waitstatus *ws)
{
/* Come here if it's a watchpoint, or if the break address
matches. */
- bs = bpstat_alloc (bl, &bs_link); /* Alloc a bpstat to
+ bs = new bpstats (bl, &bs_link); /* Alloc a bpstat to
explain stop. */
/* Assume we stop. Should we find a watchpoint that is not
if (breakpoint_location_address_match (loc, aspace, bp_addr)
&& need_moribund_for_location_type (loc))
{
- bs = bpstat_alloc (loc, &bs_link);
+ bs = new bpstats (loc, &bs_link);
/* For hits of moribund locations, we should just proceed. */
bs->stop = 0;
bs->print = 0;
if (bs->stop)
{
++(b->hit_count);
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
/* We will stop here. */
if (b->disposition == disp_disable)
if (b->silent)
bs->print = 0;
bs->commands = b->commands;
- incref_counted_command_line (bs->commands);
if (command_line_is_silent (bs->commands
- ? bs->commands->commands : NULL))
+ ? bs->commands.get () : NULL))
bs->print = 0;
b->ops->after_condition_true (bs);
uiout->field_string ("what", event_location_to_string (b->location.get ()));
else if (loc && loc->symtab)
{
- struct symbol *sym
- = find_pc_sect_function (loc->address, loc->section);
+ const struct symbol *sym = loc->symbol;
+
+ if (sym == NULL)
+ sym = find_pc_sect_function (loc->address, loc->section);
+
if (sym)
{
uiout->text ("in ");
static void
output_thread_groups (struct ui_out *uiout,
const char *field_name,
- VEC(int) *inf_num,
+ const std::vector<int> &inf_nums,
int mi_only)
{
int is_mi = uiout->is_mi_like_p ();
- int inf;
- int i;
/* For backward compatibility, don't display inferiors in CLI unless
there are several. Always display them for MI. */
ui_out_emit_list list_emitter (uiout, field_name);
- for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
+ for (size_t i = 0; i < inf_nums.size (); i++)
{
if (is_mi)
{
char mi_group[10];
- xsnprintf (mi_group, sizeof (mi_group), "i%d", inf);
+ xsnprintf (mi_group, sizeof (mi_group), "i%d", inf_nums[i]);
uiout->field_string (NULL, mi_group);
}
else
else
uiout->text (", ");
- uiout->text (plongest (inf));
+ uiout->text (plongest (inf_nums[i]));
}
}
}
if (loc != NULL && !header_of_multiple)
{
struct inferior *inf;
- VEC(int) *inf_num = NULL;
+ std::vector<int> inf_nums;
int mi_only = 1;
ALL_INFERIORS (inf)
{
if (inf->pspace == loc->pspace)
- VEC_safe_push (int, inf_num, inf->num);
+ inf_nums.push_back (inf->num);
}
/* For backward compatibility, don't display inferiors in CLI unless
moribund_locations and thus having NULL OWNER. */
&& loc->owner->type != bp_catchpoint))
mi_only = 0;
- output_thread_groups (uiout, "thread-groups", inf_num, mi_only);
- VEC_free (int, inf_num);
+ output_thread_groups (uiout, "thread-groups", inf_nums, mi_only);
}
if (!part_of_multiple)
}
}
- l = b->commands ? b->commands->commands : NULL;
+ l = b->commands ? b->commands.get () : NULL;
if (!part_of_multiple && l)
{
annotate_field (9);
return print_address_bits;
}
-struct captured_breakpoint_query_args
- {
- int bnum;
- };
+/* See breakpoint.h. */
-static int
-do_captured_breakpoint_query (struct ui_out *uiout, void *data)
+void
+print_breakpoint (breakpoint *b)
{
- struct captured_breakpoint_query_args *args
- = (struct captured_breakpoint_query_args *) data;
- struct breakpoint *b;
struct bp_location *dummy_loc = NULL;
-
- ALL_BREAKPOINTS (b)
- {
- if (args->bnum == b->number)
- {
- print_one_breakpoint (b, &dummy_loc, 0);
- return GDB_RC_OK;
- }
- }
- return GDB_RC_NONE;
-}
-
-enum gdb_rc
-gdb_breakpoint_query (struct ui_out *uiout, int bnum,
- char **error_message)
-{
- struct captured_breakpoint_query_args args;
-
- args.bnum = bnum;
- /* For the moment we don't trust print_one_breakpoint() to not throw
- an error. */
- if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
- error_message, RETURN_MASK_ALL) < 0)
- return GDB_RC_FAIL;
- else
- return GDB_RC_OK;
+ print_one_breakpoint (b, &dummy_loc, 0);
}
/* Return true if this breakpoint was set by the user, false if it is
breakpoints listed. */
static int
-breakpoint_1 (char *args, int allflag,
+breakpoint_1 (const char *args, int allflag,
int (*filter) (const struct breakpoint *))
{
struct breakpoint *b;
}
static void
-info_breakpoints_command (char *args, int from_tty)
+info_breakpoints_command (const char *args, int from_tty)
{
breakpoint_1 (args, 0, NULL);
}
static void
-info_watchpoints_command (char *args, int from_tty)
+info_watchpoints_command (const char *args, int from_tty)
{
int num_printed = breakpoint_1 (args, 0, is_watchpoint);
struct ui_out *uiout = current_uiout;
}
static void
-maintenance_info_breakpoints (char *args, int from_tty)
+maintenance_info_breakpoints (const char *args, int from_tty)
{
breakpoint_1 (args, 1, NULL);
/* See breakpoint.h. */
int
-breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1,
- struct address_space *aspace2, CORE_ADDR addr2)
+breakpoint_address_match (const address_space *aspace1, CORE_ADDR addr1,
+ const address_space *aspace2, CORE_ADDR addr2)
{
return ((gdbarch_has_global_breakpoints (target_gdbarch ())
|| aspace1 == aspace2)
space doesn't really matter. */
static int
-breakpoint_address_match_range (struct address_space *aspace1, CORE_ADDR addr1,
- int len1, struct address_space *aspace2,
+breakpoint_address_match_range (const address_space *aspace1,
+ CORE_ADDR addr1,
+ int len1, const address_space *aspace2,
CORE_ADDR addr2)
{
return ((gdbarch_has_global_breakpoints (target_gdbarch ())
static int
breakpoint_location_address_match (struct bp_location *bl,
- struct address_space *aspace,
+ const address_space *aspace,
CORE_ADDR addr)
{
return (breakpoint_address_match (bl->pspace->aspace, bl->address,
static int
breakpoint_location_address_range_overlap (struct bp_location *bl,
- struct address_space *aspace,
+ const address_space *aspace,
CORE_ADDR addr, int len)
{
if (gdbarch_has_global_breakpoints (target_gdbarch ())
adjust_breakpoint_address (struct gdbarch *gdbarch,
CORE_ADDR bpaddr, enum bptype bptype)
{
- if (!gdbarch_adjust_breakpoint_address_p (gdbarch))
- {
- /* Very few targets need any kind of breakpoint adjustment. */
- return bpaddr;
- }
- else if (bptype == bp_watchpoint
- || bptype == bp_hardware_watchpoint
- || bptype == bp_read_watchpoint
- || bptype == bp_access_watchpoint
- || bptype == bp_catchpoint)
+ if (bptype == bp_watchpoint
+ || bptype == bp_hardware_watchpoint
+ || bptype == bp_read_watchpoint
+ || bptype == bp_access_watchpoint
+ || bptype == bp_catchpoint)
{
/* Watchpoints and the various bp_catch_* eventpoints should not
have their addresses modified. */
}
else
{
- CORE_ADDR adjusted_bpaddr;
+ CORE_ADDR adjusted_bpaddr = bpaddr;
- /* Some targets have architectural constraints on the placement
- of breakpoint instructions. Obtain the adjusted address. */
- adjusted_bpaddr = gdbarch_adjust_breakpoint_address (gdbarch, bpaddr);
+ if (gdbarch_adjust_breakpoint_address_p (gdbarch))
+ {
+ /* Some targets have architectural constraints on the placement
+ of breakpoint instructions. Obtain the adjusted address. */
+ adjusted_bpaddr = gdbarch_adjust_breakpoint_address (gdbarch, bpaddr);
+ }
+
+ adjusted_bpaddr = address_significant (gdbarch, adjusted_bpaddr);
/* An adjusted breakpoint address can significantly alter
a user's expectations. Print a warning if an adjustment
loc->inserted = 0;
/* This may cause duplicate notifications for the same breakpoint. */
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
if (!disabled_shlib_breaks)
{
}
if (bp_modified)
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
}
static int
breakpoint_hit_catch_fork (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
static int
breakpoint_hit_catch_vfork (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
static int
breakpoint_hit_catch_solib (const struct bp_location *bl,
- struct address_space *aspace,
+ const address_space *aspace,
CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
{
struct solib_catchpoint *self
= (struct solib_catchpoint *) bs->breakpoint_at;
- int ix;
if (self->is_load)
{
struct so_list *iter;
- for (ix = 0;
+ for (int ix = 0;
VEC_iterate (so_list_ptr, current_program_space->added_solibs,
ix, iter);
++ix)
}
else
{
- char *iter;
-
- for (ix = 0;
- VEC_iterate (char_ptr, current_program_space->deleted_solibs,
- ix, iter);
- ++ix)
+ for (const std::string &iter : current_program_space->deleted_solibs)
{
if (!self->regex
- || self->compiled->exec (iter, 0, NULL, 0) == 0)
+ || self->compiled->exec (iter.c_str (), 0, NULL, 0) == 0)
return;
}
}
"catch unload". */
static void
-catch_load_or_unload (char *arg, int from_tty, int is_load,
+catch_load_or_unload (const char *arg, int from_tty, int is_load,
struct cmd_list_element *command)
{
int tempflag;
}
static void
-catch_load_command_1 (char *arg, int from_tty,
+catch_load_command_1 (const char *arg, int from_tty,
struct cmd_list_element *command)
{
catch_load_or_unload (arg, from_tty, 1, command);
}
static void
-catch_unload_command_1 (char *arg, int from_tty,
+catch_unload_command_1 (const char *arg, int from_tty,
struct cmd_list_element *command)
{
catch_load_or_unload (arg, from_tty, 0, command);
set_tracepoint_count (breakpoint_count);
if (!internal)
mention (b);
- observer_notify_breakpoint_created (b);
+ gdb::observers::breakpoint_created.notify (b);
if (update_gll)
update_global_location_list (UGLL_MAY_INSERT);
static int
breakpoint_hit_catch_exec (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner;
SAL. If FRAME_ID is valid, the breakpoint is restricted to that
frame. */
-struct breakpoint *
+breakpoint_up
set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
struct frame_id frame_id, enum bptype type)
{
update_global_location_list_nothrow (UGLL_MAY_INSERT);
- return b;
+ return breakpoint_up (b);
}
/* Make a momentary breakpoint based on the master breakpoint ORIG.
return momentary_breakpoint_from_master (orig, orig->type, orig->ops, 0);
}
-struct breakpoint *
+breakpoint_up
set_momentary_breakpoint_at_pc (struct gdbarch *gdbarch, CORE_ADDR pc,
enum bptype type)
{
loc->requested_address = sal->pc;
loc->address = adjusted_address;
loc->pspace = sal->pspace;
- loc->probe.probe = sal->probe;
+ loc->probe.prob = sal->prob;
loc->probe.objfile = sal->objfile;
gdb_assert (loc->pspace != NULL);
loc->section = sal->section;
loc->gdbarch = loc_gdbarch;
loc->line_number = sal->line;
loc->symtab = sal->symtab;
+ loc->symbol = sal->symbol;
set_breakpoint_location_function (loc,
sal->explicit_pc || sal->explicit_line);
current style settings. */
static void
-update_dprintf_commands (char *args, int from_tty,
+update_dprintf_commands (const char *args, int from_tty,
struct cmd_list_element *c)
{
struct breakpoint *b;
const char *p
= &event_location_to_string (b->location.get ())[3];
const char *endp;
- char *marker_str;
p = skip_spaces (p);
endp = skip_to_space (p);
- marker_str = savestring (p, endp - p);
- t->static_trace_marker_id = marker_str;
+ t->static_trace_marker_id.assign (p, endp - p);
printf_filtered (_("Probed static tracepoint "
"marker \"%s\"\n"),
- t->static_trace_marker_id);
+ t->static_trace_marker_id.c_str ());
}
else if (target_static_tracepoint_marker_at (sal.pc, &marker))
{
- t->static_trace_marker_id = xstrdup (marker.str_id);
- release_static_tracepoint_marker (&marker);
+ t->static_trace_marker_id = std::move (marker.str_id);
printf_filtered (_("Probed static tracepoint "
"marker \"%s\"\n"),
- t->static_trace_marker_id);
+ t->static_trace_marker_id.c_str ());
}
else
warning (_("Couldn't determine the static "
if (event_location_type (location) == LINESPEC_LOCATION)
{
- const char *address = get_linespec_location (location);
+ const char *spec = get_linespec_location (location)->spec_string;
- if (address == NULL)
+ if (spec == NULL)
{
/* The last displayed codepoint, if it's valid, is our default
breakpoint address. */
cursal = get_current_source_symtab_and_line ();
if (last_displayed_sal_is_valid ())
{
- const char *address = NULL;
+ const char *spec = NULL;
if (event_location_type (location) == LINESPEC_LOCATION)
- address = get_linespec_location (location);
+ spec = get_linespec_location (location)->spec_string;
if (!cursal.symtab
- || (address != NULL
- && strchr ("+-", address[0]) != NULL
- && address[1] != '['))
+ || (spec != NULL
+ && strchr ("+-", spec[0]) != NULL
+ && spec[1] != '['))
{
decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
get_last_displayed_symtab (),
check_fast_tracepoint_sals (struct gdbarch *gdbarch,
gdb::array_view<const symtab_and_line> sals)
{
- int rslt;
- char *msg;
- struct cleanup *old_chain;
-
for (const auto &sal : sals)
{
struct gdbarch *sarch;
associated with SAL. */
if (sarch == NULL)
sarch = gdbarch;
- rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal.pc, &msg);
- old_chain = make_cleanup (xfree, msg);
-
- if (!rslt)
+ std::string msg;
+ if (!gdbarch_fast_tracepoint_valid_at (sarch, sal.pc, &msg))
error (_("May not have a fast tracepoint at %s%s"),
- paddress (sarch, sal.pc), (msg ? msg : ""));
-
- do_cleanups (old_chain);
+ paddress (sarch, sal.pc), msg.c_str ());
}
}
static std::vector<symtab_and_line>
decode_static_tracepoint_spec (const char **arg_p)
{
- VEC(static_tracepoint_marker_p) *markers = NULL;
- struct cleanup *old_chain;
const char *p = &(*arg_p)[3];
const char *endp;
- char *marker_str;
- int i;
p = skip_spaces (p);
endp = skip_to_space (p);
- marker_str = savestring (p, endp - p);
- old_chain = make_cleanup (xfree, marker_str);
+ std::string marker_str (p, endp - p);
- markers = target_static_tracepoint_markers_by_strid (marker_str);
- if (VEC_empty(static_tracepoint_marker_p, markers))
- error (_("No known static tracepoint marker named %s"), marker_str);
+ std::vector<static_tracepoint_marker> markers
+ = target_static_tracepoint_markers_by_strid (marker_str.c_str ());
+ if (markers.empty ())
+ error (_("No known static tracepoint marker named %s"),
+ marker_str.c_str ());
std::vector<symtab_and_line> sals;
- sals.reserve (VEC_length(static_tracepoint_marker_p, markers));
+ sals.reserve (markers.size ());
- for (i = 0; i < VEC_length(static_tracepoint_marker_p, markers); i++)
+ for (const static_tracepoint_marker &marker : markers)
{
- struct static_tracepoint_marker *marker;
-
- marker = VEC_index (static_tracepoint_marker_p, markers, i);
-
- symtab_and_line sal = find_pc_line (marker->address, 0);
- sal.pc = marker->address;
+ symtab_and_line sal = find_pc_line (marker.address, 0);
+ sal.pc = marker.address;
sals.push_back (sal);
-
- release_static_tracepoint_marker (marker);
- }
-
- do_cleanups (old_chain);
+ }
*arg_p = endp;
return sals;
and BP_TEMPFLAG. */
static void
-break_command_1 (char *arg, int flag, int from_tty)
+break_command_1 (const char *arg, int flag, int from_tty)
{
int tempflag = flag & BP_TEMPFLAG;
enum bptype type_wanted = (flag & BP_HARDWAREFLAG
}
void
-break_command (char *arg, int from_tty)
+break_command (const char *arg, int from_tty)
{
break_command_1 (arg, 0, from_tty);
}
void
-tbreak_command (char *arg, int from_tty)
+tbreak_command (const char *arg, int from_tty)
{
break_command_1 (arg, BP_TEMPFLAG, from_tty);
}
static void
-hbreak_command (char *arg, int from_tty)
+hbreak_command (const char *arg, int from_tty)
{
break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
}
static void
-thbreak_command (char *arg, int from_tty)
+thbreak_command (const char *arg, int from_tty)
{
break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
}
static void
-stop_command (char *arg, int from_tty)
+stop_command (const char *arg, int from_tty)
{
printf_filtered (_("Specify the type of breakpoint to set.\n\
Usage: stop in <function | address>\n\
}
static void
-stopin_command (char *arg, int from_tty)
+stopin_command (const char *arg, int from_tty)
{
int badInput = 0;
badInput = 1;
else if (*arg != '*')
{
- char *argptr = arg;
+ const char *argptr = arg;
int hasColon = 0;
/* Look for a ':'. If this is a line number specification, then
}
static void
-stopat_command (char *arg, int from_tty)
+stopat_command (const char *arg, int from_tty)
{
int badInput = 0;
badInput = 1;
else
{
- char *argptr = arg;
+ const char *argptr = arg;
int hasColon = 0;
/* Look for a ':'. If there is a '::' then get out, otherwise
line. */
static void
-dprintf_command (char *arg, int from_tty)
+dprintf_command (const char *arg, int from_tty)
{
event_location_up location = string_to_event_location (&arg, current_language);
}
static void
-agent_printf_command (char *arg, int from_tty)
+agent_printf_command (const char *arg, int from_tty)
{
error (_("May only run agent-printf on the target"));
}
static int
breakpoint_hit_ranged_breakpoint (const struct bp_location *bl,
- struct address_space *aspace,
+ const address_space *aspace,
CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
/* Implement the "break-range" CLI command. */
static void
-break_range_command (char *arg, int from_tty)
+break_range_command (const char *arg, int from_tty)
{
- char *arg_start, *addr_string_start;
+ const char *arg_start;
struct linespec_result canonical_start, canonical_end;
int bp_count, can_use_bp, length;
CORE_ADDR end;
struct breakpoint *b;
- struct cleanup *cleanup_bkpt;
/* We don't support software ranged breakpoints. */
if (target_ranged_break_num_registers () < 0)
error (_("Cannot create a ranged breakpoint with multiple locations."));
const symtab_and_line &sal_start = lsal_start.sals[0];
- addr_string_start = savestring (arg_start, arg - arg_start);
- cleanup_bkpt = make_cleanup (xfree, addr_string_start);
+ std::string addr_string_start (arg_start, arg - arg_start);
arg++; /* Skip the comma. */
arg = skip_spaces (arg);
{
/* This range is simple enough to be handled by
the `hbreak' command. */
- hbreak_command (addr_string_start, 1);
-
- do_cleanups (cleanup_bkpt);
+ hbreak_command (&addr_string_start[0], 1);
return;
}
b->location_range_end = std::move (end_location);
b->loc->length = length;
- do_cleanups (cleanup_bkpt);
-
mention (b);
- observer_notify_breakpoint_created (b);
+ gdb::observers::breakpoint_created.notify (b);
update_global_location_list (UGLL_MAY_INSERT);
}
case TERNOP_SLICE:
case OP_LONG:
- case OP_DOUBLE:
- case OP_DECFLOAT:
+ case OP_FLOAT:
case OP_LAST:
case OP_COMPLEX:
case OP_STRING:
{
xfree (this->exp_string);
xfree (this->exp_string_reparse);
- value_free (this->val);
}
/* Implement the "re_set" breakpoint_ops method for watchpoints. */
static int
breakpoint_hit_watchpoint (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
struct breakpoint *b = bl->owner;
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;
the hardware watchpoint. */
int use_mask = 0;
CORE_ADDR mask = 0;
- char *expression;
- struct cleanup *back_to;
/* Make sure that we actually have parameters to parse. */
if (arg != NULL && arg[0] != '\0')
/* Parse the rest of the arguments. From here on out, everything
is in terms of a newly allocated string instead of the original
ARG. */
- innermost_block = NULL;
- expression = savestring (arg, exp_end - arg);
- back_to = make_cleanup (xfree, expression);
- exp_start = arg = expression;
+ innermost_block.reset ();
+ std::string expression (arg, exp_end - arg);
+ exp_start = arg = expression.c_str ();
expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
exp_end = arg;
/* Remove trailing whitespace from the expression before saving it.
error (_("Cannot watch constant value `%.*s'."), len, exp_start);
}
- exp_valid_block = innermost_block;
+ 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);
toklen = end_tok - tok;
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
{
- innermost_block = NULL;
+ innermost_block.reset ();
tok = cond_start = end_tok + 1;
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;
+ cond_exp_valid_block = innermost_block.block ();
cond_end = 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 ();
update_watchpoint (w.get (), 1);
install_breakpoint (internal, std::move (w), 1);
- do_cleanups (back_to);
}
/* Return count of debug registers needed to watch the given expression.
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))
}
void
-watch_command_wrapper (char *arg, int from_tty, int internal)
+watch_command_wrapper (const char *arg, int from_tty, int internal)
{
watch_command_1 (arg, hw_write, from_tty, 0, internal);
}
calls watch_command_1. */
static void
-watch_maybe_just_location (char *arg, int accessflag, int from_tty)
+watch_maybe_just_location (const char *arg, int accessflag, int from_tty)
{
int just_location = 0;
}
static void
-watch_command (char *arg, int from_tty)
+watch_command (const char *arg, int from_tty)
{
watch_maybe_just_location (arg, hw_write, from_tty);
}
void
-rwatch_command_wrapper (char *arg, int from_tty, int internal)
+rwatch_command_wrapper (const char *arg, int from_tty, int internal)
{
watch_command_1 (arg, hw_read, from_tty, 0, internal);
}
static void
-rwatch_command (char *arg, int from_tty)
+rwatch_command (const char *arg, int from_tty)
{
watch_maybe_just_location (arg, hw_read, from_tty);
}
void
-awatch_command_wrapper (char *arg, int from_tty, int internal)
+awatch_command_wrapper (const char *arg, int from_tty, int internal)
{
watch_command_1 (arg, hw_access, from_tty, 0, internal);
}
static void
-awatch_command (char *arg, int from_tty)
+awatch_command (const char *arg, int from_tty)
{
watch_maybe_just_location (arg, hw_access, from_tty);
}
static struct until_break_fsm *
new_until_break_fsm (struct interp *cmd_interp, int thread,
- struct breakpoint *location_breakpoint,
- struct breakpoint *caller_breakpoint)
+ breakpoint_up &&location_breakpoint,
+ breakpoint_up &&caller_breakpoint)
{
struct until_break_fsm *sm;
thread_fsm_ctor (&sm->thread_fsm, &until_break_fsm_ops, cmd_interp);
sm->thread = thread;
- sm->location_breakpoint = location_breakpoint;
- sm->caller_breakpoint = caller_breakpoint;
+ sm->location_breakpoint = location_breakpoint.release ();
+ sm->caller_breakpoint = caller_breakpoint.release ();
return sm;
}
}
void
-until_break_command (char *arg, int from_tty, int anywhere)
+until_break_command (const char *arg, int from_tty, int anywhere)
{
struct frame_info *frame;
struct gdbarch *frame_gdbarch;
struct frame_id stack_frame_id;
struct frame_id caller_frame_id;
- struct breakpoint *location_breakpoint;
- struct breakpoint *caller_breakpoint = NULL;
struct cleanup *old_chain;
int thread;
struct thread_info *tp;
/* Keep within the current frame, or in frames called by the current
one. */
+ breakpoint_up caller_breakpoint;
if (frame_id_p (caller_frame_id))
{
struct symtab_and_line sal2;
sal2,
caller_frame_id,
bp_until);
- make_cleanup_delete_breakpoint (caller_breakpoint);
set_longjmp_breakpoint (tp, caller_frame_id);
make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
/* set_momentary_breakpoint could invalidate FRAME. */
frame = NULL;
+ breakpoint_up location_breakpoint;
if (anywhere)
/* If the user told us to continue until a specified location,
we don't specify a frame at which we need to stop. */
only at the very same frame. */
location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
stack_frame_id, bp_until);
- make_cleanup_delete_breakpoint (location_breakpoint);
sm = new_until_break_fsm (command_interp (), tp->global_num,
- location_breakpoint, caller_breakpoint);
+ std::move (location_breakpoint),
+ std::move (caller_breakpoint));
tp->thread_fsm = &sm->thread_fsm;
discard_cleanups (old_chain);
catch_fork_kind;
static void
-catch_fork_command_1 (char *arg_entry, int from_tty,
+catch_fork_command_1 (const char *arg, int from_tty,
struct cmd_list_element *command)
{
- const char *arg = arg_entry;
struct gdbarch *gdbarch = get_current_arch ();
const char *cond_string = NULL;
catch_fork_kind fork_kind;
}
static void
-catch_exec_command_1 (char *arg_entry, int from_tty,
+catch_exec_command_1 (const char *arg, int from_tty,
struct cmd_list_element *command)
{
- const char *arg = arg_entry;
struct gdbarch *gdbarch = get_current_arch ();
int tempflag;
const char *cond_string = NULL;
init_ada_exception_breakpoint (struct breakpoint *b,
struct gdbarch *gdbarch,
struct symtab_and_line sal,
- char *addr_string,
+ const char *addr_string,
const struct breakpoint_ops *ops,
int tempflag,
int enabled,
}
static void
-catch_command (char *arg, int from_tty)
+catch_command (const char *arg, int from_tty)
{
error (_("Catch requires an event name."));
}
\f
static void
-tcatch_command (char *arg, int from_tty)
+tcatch_command (const char *arg, int from_tty)
{
error (_("Catch requires an event name."));
}
-/* A qsort comparison function that sorts breakpoints in order. */
+/* Compare two breakpoints and return a strcmp-like result. */
static int
-compare_breakpoints (const void *a, const void *b)
+compare_breakpoints (const breakpoint *a, const breakpoint *b)
{
- const breakpoint_p *ba = (const breakpoint_p *) a;
- uintptr_t ua = (uintptr_t) *ba;
- const breakpoint_p *bb = (const breakpoint_p *) b;
- uintptr_t ub = (uintptr_t) *bb;
+ uintptr_t ua = (uintptr_t) a;
+ uintptr_t ub = (uintptr_t) b;
- if ((*ba)->number < (*bb)->number)
+ if (a->number < b->number)
return -1;
- else if ((*ba)->number > (*bb)->number)
+ else if (a->number > b->number)
return 1;
/* Now sort by address, in case we see, e..g, two breakpoints with
/* Delete breakpoints by address or line. */
static void
-clear_command (char *arg, int from_tty)
+clear_command (const char *arg, int from_tty)
{
- struct breakpoint *b, *prev;
- VEC(breakpoint_p) *found = 0;
- int ix;
+ struct breakpoint *b;
int default_match;
- int i;
- struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
std::vector<symtab_and_line> decoded_sals;
symtab_and_line last_sal;
from_tty is forced true if we delete more than one
breakpoint. */
- found = NULL;
- make_cleanup (VEC_cleanup (breakpoint_p), &found);
+ std::vector<struct breakpoint *> found;
for (const auto &sal : sals)
{
const char *sal_fullname;
}
if (match)
- VEC_safe_push(breakpoint_p, found, b);
+ found.push_back (b);
}
}
/* Now go thru the 'found' chain and delete them. */
- if (VEC_empty(breakpoint_p, found))
+ if (found.empty ())
{
if (arg)
error (_("No breakpoint at %s."), arg);
}
/* Remove duplicates from the vec. */
- qsort (VEC_address (breakpoint_p, found),
- VEC_length (breakpoint_p, found),
- sizeof (breakpoint_p),
- compare_breakpoints);
- prev = VEC_index (breakpoint_p, found, 0);
- for (ix = 1; VEC_iterate (breakpoint_p, found, ix, b); ++ix)
- {
- if (b == prev)
- {
- VEC_ordered_remove (breakpoint_p, found, ix);
- --ix;
- }
- }
+ std::sort (found.begin (), found.end (),
+ [] (const breakpoint *a, const breakpoint *b)
+ {
+ return compare_breakpoints (a, b) < 0;
+ });
+ found.erase (std::unique (found.begin (), found.end (),
+ [] (const breakpoint *a, const breakpoint *b)
+ {
+ return compare_breakpoints (a, b) == 0;
+ }),
+ found.end ());
- if (VEC_length(breakpoint_p, found) > 1)
+ if (found.size () > 1)
from_tty = 1; /* Always report if deleted more than one. */
if (from_tty)
{
- if (VEC_length(breakpoint_p, found) == 1)
+ if (found.size () == 1)
printf_unfiltered (_("Deleted breakpoint "));
else
printf_unfiltered (_("Deleted breakpoints "));
}
- for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++)
+ for (breakpoint *iter : found)
{
if (from_tty)
- printf_unfiltered ("%d ", b->number);
- delete_breakpoint (b);
+ printf_unfiltered ("%d ", iter->number);
+ delete_breakpoint (iter);
}
if (from_tty)
putchar_unfiltered ('\n');
-
- do_cleanups (cleanups);
}
\f
/* Delete breakpoint in BS if they are `delete' breakpoints and
t = (struct tracepoint *) b;
t->number_on_target = b->number;
if (bp_location_downloaded)
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
}
{
struct breakpoint *b;
struct bp_location **locp, *loc;
- struct cleanup *cleanups;
/* Last breakpoint location address that was marked for update. */
CORE_ADDR last_addr = 0;
/* Last breakpoint location program space that was marked for update. */
/* Saved former bp_locations array which we compare against the newly
built bp_locations from the current state of ALL_BREAKPOINTS. */
- struct bp_location **old_locations, **old_locp;
+ struct bp_location **old_locp;
unsigned old_locations_count;
+ gdb::unique_xmalloc_ptr<struct bp_location *> old_locations (bp_locations);
- old_locations = bp_locations;
old_locations_count = bp_locations_count;
bp_locations = NULL;
bp_locations_count = 0;
- cleanups = make_cleanup (xfree, old_locations);
ALL_BREAKPOINTS (b)
for (loc = b->loc; loc; loc = loc->next)
and former bp_location array state respectively. */
locp = bp_locations;
- for (old_locp = old_locations;
- old_locp < old_locations + old_locations_count;
+ for (old_locp = old_locations.get ();
+ old_locp < old_locations.get () + old_locations_count;
old_locp++)
{
struct bp_location *old_loc = *old_locp;
if (insert_mode != UGLL_DONT_INSERT)
download_tracepoint_locations ();
-
- do_cleanups (cleanups);
}
void
breakpoint::~breakpoint ()
{
- decref_counted_command_line (&this->commands);
xfree (this->cond_string);
xfree (this->extra_string);
xfree (this->filter);
static int
base_breakpoint_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace,
+ const address_space *aspace,
CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
static int
bkpt_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
if (ws->kind != TARGET_WAITKIND_STOPPED
static int
dprintf_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
if (dprintf_style == dprintf_style_agent
{
/* The insertion was successful, now let's set the probe's semaphore
if needed. */
- if (bl->probe.probe->pops->set_semaphore != NULL)
- bl->probe.probe->pops->set_semaphore (bl->probe.probe,
- bl->probe.objfile,
- bl->gdbarch);
+ bl->probe.prob->set_semaphore (bl->probe.objfile, bl->gdbarch);
}
return v;
enum remove_bp_reason reason)
{
/* Let's clear the semaphore before removing the location. */
- if (bl->probe.probe->pops->clear_semaphore != NULL)
- bl->probe.probe->pops->clear_semaphore (bl->probe.probe,
- bl->probe.objfile,
- bl->gdbarch);
+ bl->probe.prob->clear_semaphore (bl->probe.objfile, bl->gdbarch);
return bkpt_remove_location (bl, reason);
}
static int
tracepoint_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
+ const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
/* By definition, the inferior does not report stops at
struct ui_out *uiout)
{
struct tracepoint *tp = (struct tracepoint *) self;
- if (tp->static_trace_marker_id)
+ if (!tp->static_trace_marker_id.empty ())
{
gdb_assert (self->type == bp_static_tracepoint);
static void
dprintf_after_condition_true (struct bpstats *bs)
{
- struct cleanup *old_chain;
- struct bpstats tmp_bs = { NULL };
+ struct bpstats tmp_bs;
struct bpstats *tmp_bs_p = &tmp_bs;
/* dprintf's never cause a stop. This wasn't set in the
commands here throws. */
tmp_bs.commands = bs->commands;
bs->commands = NULL;
- old_chain = make_cleanup_decref_counted_command_line (&tmp_bs.commands);
bpstat_do_actions_1 (&tmp_bs_p);
/* 'tmp_bs.commands' will usually be NULL by now, but
bpstat_do_actions_1 may return early without processing the whole
list. */
- do_cleanups (old_chain);
}
/* The breakpoint_ops structure to be used on static tracepoints with
{
struct linespec_sals lsal;
const char *arg_start, *arg;
- char *str;
- struct cleanup *cleanup;
- arg = arg_start = get_linespec_location (location);
+ arg = arg_start = get_linespec_location (location)->spec_string;
lsal.sals = decode_static_tracepoint_spec (&arg);
- str = savestring (arg_start, arg - arg_start);
- cleanup = make_cleanup (xfree, str);
- canonical->location = new_linespec_location (&str);
- do_cleanups (cleanup);
+ std::string str (arg_start, arg - arg_start);
+ const char *ptr = str.c_str ();
+ canonical->location
+ = new_linespec_location (&ptr, symbol_name_match_type::FULL);
lsal.canonical
= xstrdup (event_location_to_string (canonical->location.get ()));
struct program_space *search_pspace)
{
struct tracepoint *tp = (struct tracepoint *) b;
- const char *s = get_linespec_location (location);
+ const char *s = get_linespec_location (location)->spec_string;
std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
if (sals.size () > tp->static_trace_marker_id_idx)
return sals;
}
else
- error (_("marker %s not found"), tp->static_trace_marker_id);
+ error (_("marker %s not found"), tp->static_trace_marker_id.c_str ());
}
static struct breakpoint_ops strace_marker_breakpoint_ops;
a problem in that process, we'll be asked to delete the half-created
watchpoint. In that case, don't announce the deletion. */
if (bpt->number)
- observer_notify_breakpoint_deleted (bpt);
+ gdb::observers::breakpoint_deleted.notify (bpt);
if (breakpoint_chain == bpt)
breakpoint_chain = bpt->next;
delete bpt;
}
-static void
-do_delete_breakpoint_cleanup (void *b)
-{
- delete_breakpoint ((struct breakpoint *) b);
-}
-
-struct cleanup *
-make_cleanup_delete_breakpoint (struct breakpoint *b)
-{
- return make_cleanup (do_delete_breakpoint_cleanup, b);
-}
-
/* Iterator function to call a user-provided callback function once
for each of B and its related breakpoints. */
static void
iterate_over_related_breakpoints (struct breakpoint *b,
- void (*function) (struct breakpoint *,
- void *),
- void *data)
+ gdb::function_view<void (breakpoint *)> function)
{
struct breakpoint *related;
if (next == related)
{
/* RELATED is the last ring entry. */
- function (related, data);
+ function (related);
/* FUNCTION may have deleted it, so we'd never reach back to
B. There's nothing left to do anyway, so just break
break;
}
else
- function (related, data);
+ function (related);
related = next;
}
}
static void
-do_delete_breakpoint (struct breakpoint *b, void *ignore)
-{
- delete_breakpoint (b);
-}
-
-/* A callback for map_breakpoint_numbers that calls
- delete_breakpoint. */
-
-static void
-do_map_delete_breakpoint (struct breakpoint *b, void *ignore)
-{
- iterate_over_related_breakpoints (b, do_delete_breakpoint, NULL);
-}
-
-void
-delete_command (char *arg, int from_tty)
+delete_command (const char *arg, int from_tty)
{
struct breakpoint *b, *b_tmp;
}
}
else
- map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
+ map_breakpoint_numbers
+ (arg, [&] (breakpoint *b)
+ {
+ iterate_over_related_breakpoints (b, delete_breakpoint);
+ });
}
/* Return true if all locations of B bound to PSPACE are pending. If
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)
{
if (target_static_tracepoint_marker_at (pc, &marker))
{
- if (strcmp (tp->static_trace_marker_id, marker.str_id) != 0)
+ if (tp->static_trace_marker_id != marker.str_id)
warning (_("static tracepoint %d changed probed marker from %s to %s"),
- b->number,
- tp->static_trace_marker_id, marker.str_id);
+ b->number, tp->static_trace_marker_id.c_str (),
+ marker.str_id.c_str ());
- xfree (tp->static_trace_marker_id);
- tp->static_trace_marker_id = xstrdup (marker.str_id);
- release_static_tracepoint_marker (&marker);
+ tp->static_trace_marker_id = std::move (marker.str_id);
return sal;
}
if (!sal.explicit_pc
&& sal.line != 0
&& sal.symtab != NULL
- && tp->static_trace_marker_id != NULL)
+ && !tp->static_trace_marker_id.empty ())
{
- VEC(static_tracepoint_marker_p) *markers;
+ std::vector<static_tracepoint_marker> markers
+ = target_static_tracepoint_markers_by_strid
+ (tp->static_trace_marker_id.c_str ());
- markers
- = target_static_tracepoint_markers_by_strid (tp->static_trace_marker_id);
-
- if (!VEC_empty(static_tracepoint_marker_p, markers))
+ if (!markers.empty ())
{
struct symbol *sym;
struct static_tracepoint_marker *tpmarker;
struct ui_out *uiout = current_uiout;
struct explicit_location explicit_loc;
- tpmarker = VEC_index (static_tracepoint_marker_p, markers, 0);
+ tpmarker = &markers[0];
- xfree (tp->static_trace_marker_id);
- tp->static_trace_marker_id = xstrdup (tpmarker->str_id);
+ tp->static_trace_marker_id = std::move (tpmarker->str_id);
warning (_("marker for static tracepoint %d (%s) not "
"found at previous line number"),
- b->number, tp->static_trace_marker_id);
+ b->number, tp->static_trace_marker_id.c_str ());
symtab_and_line sal2 = find_pc_line (tpmarker->address, 0);
sym = find_pc_sect_function (tpmarker->address, NULL);
/* Might be nice to check if function changed, and warn if
so. */
-
- release_static_tracepoint_marker (tpmarker);
}
}
return sal;
gdb::array_view<const symtab_and_line> sals,
gdb::array_view<const symtab_and_line> sals_end)
{
- int i;
struct bp_location *existing_locations;
if (!sals_end.empty () && (sals.size () != 1 || sals_end.size () != 1))
}
if (!locations_are_equal (existing_locations, b->loc))
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
/* Find the SaL locations corresponding to the given LOCATION.
return {};
}
-/* Prepare the global context for a re-set of breakpoint B. */
+/* Reset a breakpoint. */
-static struct cleanup *
-prepare_re_set_context (struct breakpoint *b)
+static void
+breakpoint_re_set_one (breakpoint *b)
{
input_radix = b->input_radix;
set_language (b->language);
- return make_cleanup (null_cleanup, NULL);
-}
-
-/* Reset a breakpoint given it's struct breakpoint * BINT.
- The value we return ends up being the return value from catch_errors.
- Unused in this case. */
-
-static int
-breakpoint_re_set_one (void *bint)
-{
- /* Get past catch_errs. */
- struct breakpoint *b = (struct breakpoint *) bint;
- struct cleanup *cleanups;
-
- cleanups = prepare_re_set_context (b);
b->ops->re_set (b);
- do_cleanups (cleanups);
- return 0;
}
/* Re-set breakpoint locations for the current program space.
breakpoint_re_set (void)
{
struct breakpoint *b, *b_tmp;
- enum language save_language;
- int save_input_radix;
-
- save_language = current_language->la_language;
- save_input_radix = input_radix;
{
+ scoped_restore_current_language save_language;
+ scoped_restore save_input_radix = make_scoped_restore (&input_radix);
scoped_restore_current_pspace_and_thread restore_pspace_thread;
/* Note: we must not try to insert locations until after all
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
- /* Format possible error msg. */
- char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
- b->number);
- struct cleanup *cleanups = make_cleanup (xfree, message);
- catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
- do_cleanups (cleanups);
+ TRY
+ {
+ breakpoint_re_set_one (b);
+ }
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ exception_fprintf (gdb_stderr, ex,
+ "Error in re-setting breakpoint %d: ",
+ b->number);
+ }
+ END_CATCH
}
- set_language (save_language);
- input_radix = save_input_radix;
jit_breakpoint_re_set ();
}
"crossings of breakpoint %d."),
count, bptnum);
}
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
return;
}
/* Command to set ignore-count of breakpoint N to COUNT. */
static void
-ignore_command (char *args, int from_tty)
+ignore_command (const char *args, int from_tty)
{
- char *p = args;
+ const char *p = args;
int num;
if (p == 0)
printf_filtered ("\n");
}
\f
-/* Call FUNCTION on each of the breakpoints
- whose numbers are given in ARGS. */
+
+/* Call FUNCTION on each of the breakpoints with numbers in the range
+ defined by BP_NUM_RANGE (an inclusive range). */
static void
-map_breakpoint_numbers (const char *args,
- void (*function) (struct breakpoint *,
- void *),
- void *data)
+map_breakpoint_number_range (std::pair<int, int> bp_num_range,
+ gdb::function_view<void (breakpoint *)> function)
{
- int num;
- struct breakpoint *b, *tmp;
-
- if (args == 0 || *args == '\0')
- error_no_arg (_("one or more breakpoint numbers"));
-
- number_or_range_parser parser (args);
-
- while (!parser.finished ())
+ if (bp_num_range.first == 0)
+ {
+ warning (_("bad breakpoint number at or near '%d'"),
+ bp_num_range.first);
+ }
+ else
{
- const char *p = parser.cur_tok ();
- bool match = false;
+ struct breakpoint *b, *tmp;
- num = parser.get_number ();
- if (num == 0)
- {
- warning (_("bad breakpoint number at or near '%s'"), p);
- }
- else
+ for (int i = bp_num_range.first; i <= bp_num_range.second; i++)
{
+ bool match = false;
+
ALL_BREAKPOINTS_SAFE (b, tmp)
- if (b->number == num)
+ if (b->number == i)
{
match = true;
- function (b, data);
+ function (b);
break;
}
if (!match)
- printf_unfiltered (_("No breakpoint number %d.\n"), num);
+ printf_unfiltered (_("No breakpoint number %d.\n"), i);
}
}
}
+/* Call FUNCTION on each of the breakpoints whose numbers are given in
+ ARGS. */
+
+static void
+map_breakpoint_numbers (const char *args,
+ gdb::function_view<void (breakpoint *)> function)
+{
+ if (args == NULL || *args == '\0')
+ error_no_arg (_("one or more breakpoint numbers"));
+
+ number_or_range_parser parser (args);
+
+ while (!parser.finished ())
+ {
+ int num = parser.get_number ();
+ map_breakpoint_number_range (std::make_pair (num, num), function);
+ }
+}
+
+/* Return the breakpoint location structure corresponding to the
+ BP_NUM and LOC_NUM values. */
+
static struct bp_location *
-find_location_by_number (const char *number)
+find_location_by_number (int bp_num, int loc_num)
{
- const char *p1;
- int bp_num;
- int loc_num;
struct breakpoint *b;
- struct bp_location *loc;
-
- p1 = number;
- bp_num = get_number_trailer (&p1, '.');
- if (bp_num == 0 || p1[0] != '.')
- error (_("Bad breakpoint number '%s'"), number);
ALL_BREAKPOINTS (b)
if (b->number == bp_num)
}
if (!b || b->number != bp_num)
- error (_("Bad breakpoint number '%s'"), number);
+ error (_("Bad breakpoint number '%d'"), bp_num);
- /* Skip the dot. */
- ++p1;
- const char *save = p1;
- loc_num = get_number (&p1);
if (loc_num == 0)
- error (_("Bad breakpoint location number '%s'"), number);
+ error (_("Bad breakpoint location number '%d'"), loc_num);
- --loc_num;
- loc = b->loc;
- for (;loc_num && loc; --loc_num, loc = loc->next)
- ;
- if (!loc)
- error (_("Bad breakpoint location number '%s'"), save);
-
- return loc;
+ int n = 0;
+ for (bp_location *loc = b->loc; loc != NULL; loc = loc->next)
+ if (++n == loc_num)
+ return loc;
+
+ error (_("Bad breakpoint location number '%d'"), loc_num);
+}
+
+/* Modes of operation for extract_bp_num. */
+enum class extract_bp_kind
+{
+ /* Extracting a breakpoint number. */
+ bp,
+
+ /* Extracting a location number. */
+ loc,
+};
+
+/* Extract a breakpoint or location number (as determined by KIND)
+ from the string starting at START. TRAILER is a character which
+ can be found after the number. If you don't want a trailer, use
+ '\0'. If END_OUT is not NULL, it is set to point after the parsed
+ string. This always returns a positive integer. */
+
+static int
+extract_bp_num (extract_bp_kind kind, const char *start,
+ int trailer, const char **end_out = NULL)
+{
+ const char *end = start;
+ int num = get_number_trailer (&end, trailer);
+ if (num < 0)
+ error (kind == extract_bp_kind::bp
+ ? _("Negative breakpoint number '%.*s'")
+ : _("Negative breakpoint location number '%.*s'"),
+ int (end - start), start);
+ if (num == 0)
+ error (kind == extract_bp_kind::bp
+ ? _("Bad breakpoint number '%.*s'")
+ : _("Bad breakpoint location number '%.*s'"),
+ int (end - start), start);
+
+ if (end_out != NULL)
+ *end_out = end;
+ return num;
+}
+
+/* Extract a breakpoint or location range (as determined by KIND) in
+ the form NUM1-NUM2 stored at &ARG[arg_offset]. Returns a std::pair
+ representing the (inclusive) range. The returned pair's elements
+ are always positive integers. */
+
+static std::pair<int, int>
+extract_bp_or_bp_range (extract_bp_kind kind,
+ const std::string &arg,
+ std::string::size_type arg_offset)
+{
+ std::pair<int, int> range;
+ const char *bp_loc = &arg[arg_offset];
+ std::string::size_type dash = arg.find ('-', arg_offset);
+ if (dash != std::string::npos)
+ {
+ /* bp_loc is a range (x-z). */
+ if (arg.length () == dash + 1)
+ error (kind == extract_bp_kind::bp
+ ? _("Bad breakpoint number at or near: '%s'")
+ : _("Bad breakpoint location number at or near: '%s'"),
+ bp_loc);
+
+ const char *end;
+ const char *start_first = bp_loc;
+ const char *start_second = &arg[dash + 1];
+ range.first = extract_bp_num (kind, start_first, '-');
+ range.second = extract_bp_num (kind, start_second, '\0', &end);
+
+ if (range.first > range.second)
+ error (kind == extract_bp_kind::bp
+ ? _("Inverted breakpoint range at '%.*s'")
+ : _("Inverted breakpoint location range at '%.*s'"),
+ int (end - start_first), start_first);
+ }
+ else
+ {
+ /* bp_loc is a single value. */
+ range.first = extract_bp_num (kind, bp_loc, '\0');
+ range.second = range.first;
+ }
+ return range;
}
+/* Extract the breakpoint/location range specified by ARG. Returns
+ the breakpoint range in BP_NUM_RANGE, and the location range in
+ BP_LOC_RANGE.
+
+ ARG may be in any of the following forms:
+
+ x where 'x' is a breakpoint number.
+ x-y where 'x' and 'y' specify a breakpoint numbers range.
+ x.y where 'x' is a breakpoint number and 'y' a location number.
+ x.y-z where 'x' is a breakpoint number and 'y' and 'z' specify a
+ location number range.
+*/
+
+static void
+extract_bp_number_and_location (const std::string &arg,
+ std::pair<int, int> &bp_num_range,
+ std::pair<int, int> &bp_loc_range)
+{
+ std::string::size_type dot = arg.find ('.');
+
+ if (dot != std::string::npos)
+ {
+ /* Handle 'x.y' and 'x.y-z' cases. */
+
+ if (arg.length () == dot + 1 || dot == 0)
+ error (_("Bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+ bp_num_range.first
+ = extract_bp_num (extract_bp_kind::bp, arg.c_str (), '.');
+ bp_num_range.second = bp_num_range.first;
+
+ bp_loc_range = extract_bp_or_bp_range (extract_bp_kind::loc,
+ arg, dot + 1);
+ }
+ else
+ {
+ /* Handle x and x-y cases. */
+
+ bp_num_range = extract_bp_or_bp_range (extract_bp_kind::bp, arg, 0);
+ bp_loc_range.first = 0;
+ bp_loc_range.second = 0;
+ }
+}
+
+/* Enable or disable a breakpoint location BP_NUM.LOC_NUM. ENABLE
+ specifies whether to enable or disable. */
+
+static void
+enable_disable_bp_num_loc (int bp_num, int loc_num, bool enable)
+{
+ struct bp_location *loc = find_location_by_number (bp_num, loc_num);
+ if (loc != NULL)
+ {
+ if (loc->enabled != enable)
+ {
+ loc->enabled = enable;
+ mark_breakpoint_location_modified (loc);
+ }
+ if (target_supports_enable_disable_tracepoint ()
+ && current_trace_status ()->running && loc->owner
+ && is_tracepoint (loc->owner))
+ target_disable_tracepoint (loc);
+ }
+ update_global_location_list (UGLL_DONT_INSERT);
+}
+
+/* Enable or disable a range of breakpoint locations. BP_NUM is the
+ number of the breakpoint, and BP_LOC_RANGE specifies the
+ (inclusive) range of location numbers of that breakpoint to
+ enable/disable. ENABLE specifies whether to enable or disable the
+ location. */
+
+static void
+enable_disable_breakpoint_location_range (int bp_num,
+ std::pair<int, int> &bp_loc_range,
+ bool enable)
+{
+ for (int i = bp_loc_range.first; i <= bp_loc_range.second; i++)
+ enable_disable_bp_num_loc (bp_num, i, enable);
+}
/* Set ignore-count of breakpoint number BPTNUM to COUNT.
If from_tty is nonzero, it prints a message to that effect,
update_global_location_list (UGLL_DONT_INSERT);
- observer_notify_breakpoint_modified (bpt);
-}
-
-/* A callback for iterate_over_related_breakpoints. */
-
-static void
-do_disable_breakpoint (struct breakpoint *b, void *ignore)
-{
- disable_breakpoint (b);
+ gdb::observers::breakpoint_modified.notify (bpt);
}
-/* A callback for map_breakpoint_numbers that calls
- disable_breakpoint. */
-
-static void
-do_map_disable_breakpoint (struct breakpoint *b, void *ignore)
-{
- iterate_over_related_breakpoints (b, do_disable_breakpoint, NULL);
-}
+/* Enable or disable the breakpoint(s) or breakpoint location(s)
+ specified in ARGS. ARGS may be in any of the formats handled by
+ extract_bp_number_and_location. ENABLE specifies whether to enable
+ or disable the breakpoints/locations. */
static void
-disable_command (char *args, int from_tty)
+enable_disable_command (const char *args, int from_tty, bool enable)
{
if (args == 0)
{
ALL_BREAKPOINTS (bpt)
if (user_breakpoint_p (bpt))
- disable_breakpoint (bpt);
+ {
+ if (enable)
+ enable_breakpoint (bpt);
+ else
+ disable_breakpoint (bpt);
+ }
}
else
{
while (!num.empty ())
{
- if (num.find ('.') != std::string::npos)
- {
- struct bp_location *loc = find_location_by_number (num.c_str ());
+ std::pair<int, int> bp_num_range, bp_loc_range;
- if (loc)
- {
- if (loc->enabled)
- {
- loc->enabled = 0;
- mark_breakpoint_location_modified (loc);
- }
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && loc->owner
- && is_tracepoint (loc->owner))
- target_disable_tracepoint (loc);
- }
- update_global_location_list (UGLL_DONT_INSERT);
+ extract_bp_number_and_location (num, bp_num_range, bp_loc_range);
+
+ if (bp_loc_range.first == bp_loc_range.second
+ && bp_loc_range.first == 0)
+ {
+ /* Handle breakpoint ids with formats 'x' or 'x-z'. */
+ map_breakpoint_number_range (bp_num_range,
+ enable
+ ? enable_breakpoint
+ : disable_breakpoint);
}
else
- map_breakpoint_numbers (num.c_str (), do_map_disable_breakpoint,
- NULL);
+ {
+ /* Handle breakpoint ids with formats 'x.y' or
+ 'x.y-z'. */
+ enable_disable_breakpoint_location_range
+ (bp_num_range.first, bp_loc_range, enable);
+ }
num = extract_arg (&args);
}
}
}
+/* The disable command disables the specified breakpoints/locations
+ (or all defined breakpoints) so they're no longer effective in
+ stopping the inferior. ARGS may be in any of the forms defined in
+ extract_bp_number_and_location. */
+
+static void
+disable_command (const char *args, int from_tty)
+{
+ enable_disable_command (args, from_tty, false);
+}
+
static void
enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
int count)
bpt->enable_count = count;
update_global_location_list (UGLL_MAY_INSERT);
- observer_notify_breakpoint_modified (bpt);
+ gdb::observers::breakpoint_modified.notify (bpt);
}
enable_breakpoint_disp (bpt, bpt->disposition, 0);
}
-static void
-do_enable_breakpoint (struct breakpoint *bpt, void *arg)
-{
- enable_breakpoint (bpt);
-}
-
-/* A callback for map_breakpoint_numbers that calls
- enable_breakpoint. */
-
-static void
-do_map_enable_breakpoint (struct breakpoint *b, void *ignore)
-{
- iterate_over_related_breakpoints (b, do_enable_breakpoint, NULL);
-}
-
-/* The enable command enables the specified breakpoints (or all defined
- breakpoints) so they once again become (or continue to be) effective
- in stopping the inferior. */
-
-static void
-enable_command (char *args, int from_tty)
-{
- if (args == 0)
- {
- struct breakpoint *bpt;
-
- ALL_BREAKPOINTS (bpt)
- if (user_breakpoint_p (bpt))
- enable_breakpoint (bpt);
- }
- else
- {
- std::string num = extract_arg (&args);
-
- while (!num.empty ())
- {
- if (num.find ('.') != std::string::npos)
- {
- struct bp_location *loc = find_location_by_number (num.c_str ());
-
- if (loc)
- {
- if (!loc->enabled)
- {
- loc->enabled = 1;
- mark_breakpoint_location_modified (loc);
- }
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && loc->owner
- && is_tracepoint (loc->owner))
- target_enable_tracepoint (loc);
- }
- update_global_location_list (UGLL_MAY_INSERT);
- }
- else
- map_breakpoint_numbers (num.c_str (), do_map_enable_breakpoint,
- NULL);
- num = extract_arg (&args);
- }
- }
-}
-
-/* This struct packages up disposition data for application to multiple
- breakpoints. */
-
-struct disp_data
-{
- enum bpdisp disp;
- int count;
-};
-
-static void
-do_enable_breakpoint_disp (struct breakpoint *bpt, void *arg)
-{
- struct disp_data disp_data = *(struct disp_data *) arg;
-
- enable_breakpoint_disp (bpt, disp_data.disp, disp_data.count);
-}
-
-static void
-do_map_enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
-{
- struct disp_data disp = { disp_disable, 1 };
-
- iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
-}
+/* The enable command enables the specified breakpoints/locations (or
+ all defined breakpoints) so they once again become (or continue to
+ be) effective in stopping the inferior. ARGS may be in any of the
+ forms defined in extract_bp_number_and_location. */
static void
-enable_once_command (char *args, int from_tty)
+enable_command (const char *args, int from_tty)
{
- map_breakpoint_numbers (args, do_map_enable_once_breakpoint, NULL);
+ enable_disable_command (args, from_tty, true);
}
static void
-do_map_enable_count_breakpoint (struct breakpoint *bpt, void *countptr)
+enable_once_command (const char *args, int from_tty)
{
- struct disp_data disp = { disp_disable, *(int *) countptr };
-
- iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
+ map_breakpoint_numbers
+ (args, [&] (breakpoint *b)
+ {
+ iterate_over_related_breakpoints
+ (b, [&] (breakpoint *bpt)
+ {
+ enable_breakpoint_disp (bpt, disp_disable, 1);
+ });
+ });
}
static void
-enable_count_command (char *args, int from_tty)
+enable_count_command (const char *args, int from_tty)
{
int count;
count = get_number (&args);
- map_breakpoint_numbers (args, do_map_enable_count_breakpoint, &count);
-}
-
-static void
-do_map_enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
-{
- struct disp_data disp = { disp_del, 1 };
-
- iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
+ map_breakpoint_numbers
+ (args, [&] (breakpoint *b)
+ {
+ iterate_over_related_breakpoints
+ (b, [&] (breakpoint *bpt)
+ {
+ enable_breakpoint_disp (bpt, disp_disable, count);
+ });
+ });
}
static void
-enable_delete_command (char *args, int from_tty)
+enable_delete_command (const char *args, int from_tty)
{
- map_breakpoint_numbers (args, do_map_enable_delete_breakpoint, NULL);
+ map_breakpoint_numbers
+ (args, [&] (breakpoint *b)
+ {
+ iterate_over_related_breakpoints
+ (b, [&] (breakpoint *bpt)
+ {
+ enable_breakpoint_disp (bpt, disp_del, 1);
+ });
+ });
}
\f
static void
-set_breakpoint_cmd (char *args, int from_tty)
+set_breakpoint_cmd (const char *args, int from_tty)
{
}
static void
-show_breakpoint_cmd (char *args, int from_tty)
+show_breakpoint_cmd (const char *args, int from_tty)
{
}
{
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;
}
void
insert_single_step_breakpoint (struct gdbarch *gdbarch,
- struct address_space *aspace,
+ const address_space *aspace,
CORE_ADDR next_pc)
{
struct thread_info *tp = inferior_thread ();
if (!next_pcs.empty ())
{
struct frame_info *frame = get_current_frame ();
- struct address_space *aspace = get_frame_address_space (frame);
+ const address_space *aspace = get_frame_address_space (frame);
for (CORE_ADDR pc : next_pcs)
insert_single_step_breakpoint (gdbarch, aspace, pc);
int
breakpoint_has_location_inserted_here (struct breakpoint *bp,
- struct address_space *aspace,
+ const address_space *aspace,
CORE_ADDR pc)
{
struct bp_location *loc;
PC. */
int
-single_step_breakpoint_inserted_here_p (struct address_space *aspace,
+single_step_breakpoint_inserted_here_p (const address_space *aspace,
CORE_ADDR pc)
{
struct breakpoint *bpt;
}
static void
-trace_command (char *arg, int from_tty)
+trace_command (const char *arg, int from_tty)
{
struct breakpoint_ops *ops;
}
static void
-ftrace_command (char *arg, int from_tty)
+ftrace_command (const char *arg, int from_tty)
{
event_location_up location = string_to_event_location (&arg,
current_language);
/* strace command implementation. Creates a static tracepoint. */
static void
-strace_command (char *arg, int from_tty)
+strace_command (const char *arg, int from_tty)
{
struct breakpoint_ops *ops;
event_location_up location;
- struct cleanup *back_to;
/* Decide if we are dealing with a static tracepoint marker (`-m'),
or with a normal static tracepoint. */
if (arg && startswith (arg, "-m") && isspace (arg[2]))
{
ops = &strace_marker_breakpoint_ops;
- location = new_linespec_location (&arg);
+ location = new_linespec_location (&arg, symbol_name_match_type::FULL);
}
else
{
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;
}
struct tracepoint *
create_tracepoint_from_upload (struct uploaded_tp *utp)
{
- char *addr_str, small_buf[100];
+ const char *addr_str;
+ char small_buf[100];
struct tracepoint *tp;
if (utp->at_string)
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;
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);
omitted. */
static void
-info_tracepoints_command (char *args, int from_tty)
+info_tracepoints_command (const char *args, int from_tty)
{
struct ui_out *uiout = current_uiout;
int num_printed;
/* The 'enable trace' command enables tracepoints.
Not supported by all targets. */
static void
-enable_trace_command (char *args, int from_tty)
+enable_trace_command (const char *args, int from_tty)
{
enable_command (args, from_tty);
}
/* The 'disable trace' command disables tracepoints.
Not supported by all targets. */
static void
-disable_trace_command (char *args, int from_tty)
+disable_trace_command (const char *args, int from_tty)
{
disable_command (args, from_tty);
}
/* Remove a tracepoint (or all if no argument). */
static void
-delete_trace_command (char *arg, int from_tty)
+delete_trace_command (const char *arg, int from_tty)
{
struct breakpoint *b, *b_tmp;
}
}
else
- map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
+ map_breakpoint_numbers
+ (arg, [&] (breakpoint *b)
+ {
+ iterate_over_related_breakpoints (b, delete_breakpoint);
+ });
}
/* Helper function for trace_pass_command. */
trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
{
tp->pass_count = count;
- observer_notify_breakpoint_modified (tp);
+ gdb::observers::breakpoint_modified.notify (tp);
if (from_tty)
printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
tp->number, count);
Also accepts special argument "all". */
static void
-trace_pass_command (char *args, int from_tty)
+trace_pass_command (const char *args, int from_tty)
{
struct tracepoint *t1;
- unsigned int count;
+ ULONGEST count;
if (args == 0 || *args == 0)
error (_("passcount command requires an "
"argument (count + optional TP num)"));
- count = strtoul (args, &args, 10); /* Count comes first, then TP num. */
+ count = strtoulst (args, &args, 10); /* Count comes first, then TP num. */
args = skip_spaces (args);
if (*args && strncasecmp (args, "all", 3) == 0)
(tracepoint_count) is returned. */
struct tracepoint *
-get_tracepoint_by_number (char **arg,
+get_tracepoint_by_number (const char **arg,
number_or_range_parser *parser)
{
struct breakpoint *t;
int tpnum;
- char *instring = arg == NULL ? NULL : *arg;
+ const char *instring = arg == NULL ? NULL : *arg;
if (parser != NULL)
{
non-zero. */
static void
-save_breakpoints (char *filename, int from_tty,
+save_breakpoints (const char *filename, int from_tty,
int (*filter) (const struct breakpoint *))
{
struct breakpoint *tp;
current_uiout->redirect (&fp);
TRY
{
- print_command_lines (current_uiout, tp->commands->commands, 2);
+ print_command_lines (current_uiout, tp->commands.get (), 2);
}
CATCH (ex, RETURN_MASK_ALL)
{
/* The `save breakpoints' command. */
static void
-save_breakpoints_command (char *args, int from_tty)
+save_breakpoints_command (const char *args, int from_tty)
{
save_breakpoints (args, from_tty, NULL);
}
/* The `save tracepoints' command. */
static void
-save_tracepoints_command (char *args, int from_tty)
+save_tracepoints_command (const char *args, int from_tty)
{
save_breakpoints (args, from_tty, is_tracepoint);
}
syntax to specify location parameters.\n\
Example: To specify the start of the label named \"the_top\" in the\n\
function \"fact\" in the file \"factorial.c\", use \"-source factorial.c\n\
--function fact -label the_top\".\n"
+-function fact -label the_top\".\n\
+\n\
+By default, a specified function is matched against the program's\n\
+functions in all scopes. For C++, this means in all namespaces and\n\
+classes. For Ada, this means in all packages. E.g., in C++,\n\
+\"func()\" matches \"A::func()\", \"A::B::func()\", etc. The\n\
+\"-qualified\" flag overrides this behavior, making GDB interpret the\n\
+specified name as a complete fully-qualified name instead.\n"
/* This help string is used for the break, hbreak, tbreak and thbreak
commands. It is defined as a macro to prevent duplication.
void
add_catch_command (const char *name, const char *docstring,
- cmd_sfunc_ftype *sfunc,
+ cmd_const_sfunc_ftype *sfunc,
completer_ftype *completer,
void *user_data_catch,
void *user_data_tcatch)
{
struct cmd_list_element *command;
- command = add_cmd (name, class_breakpoint, NULL, docstring,
+ command = add_cmd (name, class_breakpoint, docstring,
&catch_cmdlist);
set_cmd_sfunc (command, sfunc);
set_cmd_context (command, user_data_catch);
set_cmd_completer (command, completer);
- command = add_cmd (name, class_breakpoint, NULL, docstring,
+ command = add_cmd (name, class_breakpoint, docstring,
&tcatch_cmdlist);
set_cmd_sfunc (command, sfunc);
set_cmd_context (command, user_data_tcatch);
}
static void
-save_command (char *arg, int from_tty)
+save_command (const char *arg, int from_tty)
{
printf_unfiltered (_("\"save\" must be followed by "
"the name of a save subcommand.\n"));
have been inlined. */
int
-pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc,
+pc_at_non_inline_function (const address_space *aspace, CORE_ADDR pc,
const struct target_waitstatus *ws)
{
struct breakpoint *b;
initialize_breakpoint_ops ();
- observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
- observer_attach_free_objfile (disable_breakpoints_in_freed_objfile);
- observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
+ gdb::observers::solib_unloaded.attach (disable_breakpoints_in_unloaded_shlib);
+ gdb::observers::free_objfile.attach (disable_breakpoints_in_freed_objfile);
+ gdb::observers::memory_changed.attach (invalidate_bp_value_on_memory_change);
breakpoint_objfile_key
- = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
+ = register_objfile_data_with_cleanup (NULL, free_breakpoint_objfile_data);
breakpoint_chain = 0;
/* Don't bother to call set_breakpoint_count. $bpnum isn't useful
automatic_hardware_breakpoints = 1;
- observer_attach_about_to_proceed (breakpoint_about_to_proceed);
- observer_attach_thread_exit (remove_threaded_breakpoints);
+ gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed);
+ gdb::observers::thread_exit.attach (remove_threaded_breakpoints);
}