/* Everything about breakpoints, for GDB.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
#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"
#include "ax-gdb.h"
#include "dummy-frame.h"
#include "interps.h"
-#include "format.h"
+#include "common/format.h"
#include "thread-fsm.h"
#include "tid-parse.h"
+#include "cli/cli-style.h"
+#include "mi/mi-main.h"
/* readline include files */
#include "readline/readline.h"
/* Prototypes for local functions. */
-static void disable_command (char *, int);
-
-static void enable_command (char *, int);
-
static void map_breakpoint_numbers (const char *,
gdb::function_view<void (breakpoint *)>);
-static void ignore_command (char *, int);
-
static void breakpoint_re_set_default (struct breakpoint *);
static void
(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 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 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);
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 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 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);
}
else if (target_has_execution)
{
- struct thread_info *tp;
-
if (always_inserted_mode)
{
/* The user wants breakpoints inserted even if all threads
/* Don't remove breakpoints yet if, even though all threads are
stopped, we still have events to process. */
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
if (tp->resumed
&& tp->suspend.waitstatus_pending_p)
return 1;
/* The locations that no longer correspond to any breakpoint, unlinked
from the bp_locations array, but for which a hit may still be
reported by a target. */
-VEC(bp_location_p) *moribund_locations = NULL;
+static std::vector<bp_location *> moribund_locations;
/* Number of last breakpoint made. */
/* 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;
}
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_tracker tracker;
arg = exp;
- w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
+ w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
if (*arg)
error (_("Junk at end of expression"));
- w->cond_exp_valid_block = innermost_block;
+ w->cond_exp_valid_block = tracker.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)
for (c = commands; c; c = c->next)
{
- int i;
-
if (c->control_type == while_stepping_control)
error (_("The 'while-stepping' command can "
"only be used for tracepoints"));
- for (i = 0; i < c->body_count; ++i)
- check_no_tracepoint_commands ((c->body_list)[i]);
+ check_no_tracepoint_commands (c->body_list_0.get ());
+ check_no_tracepoint_commands (c->body_list_1.get ());
/* Not that command parsing removes leading whitespace and comment
lines and also empty lines. So, we only need to check for
{
struct command_line *c2;
- gdb_assert (while_stepping->body_count == 1);
- c2 = while_stepping->body_list[0];
+ gdb_assert (while_stepping->body_list_1 == nullptr);
+ c2 = while_stepping->body_list_0.get ();
for (; c2; c2 = c2->next)
{
if (c2->control_type == while_stepping_control)
/* Return a vector of all the static tracepoints set at ADDR. The
caller is responsible for releasing the vector. */
-VEC(breakpoint_p) *
+std::vector<breakpoint *>
static_tracepoints_here (CORE_ADDR addr)
{
struct breakpoint *b;
- VEC(breakpoint_p) *found = 0;
+ std::vector<breakpoint *> found;
struct bp_location *loc;
ALL_BREAKPOINTS (b)
{
for (loc = b->loc; loc; loc = loc->next)
if (loc->address == addr)
- VEC_safe_push(breakpoint_p, found, b);
+ found.push_back (b);
}
return found;
void
breakpoint_set_commands (struct breakpoint *b,
- command_line_up &&commands)
+ counted_command_line &&commands)
{
validate_commands_for_breakpoint (b, commands.get ());
b->commands = std::move (commands);
- observer_notify_breakpoint_modified (b);
+ 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);
-}
-
-void
-check_tracepoint_command (char *line, void *closure)
-{
- struct breakpoint *b = (struct breakpoint *) closure;
-
- validate_actionline (line, b);
+ gdb::observers::breakpoint_modified.notify (b);
}
static void
struct command_line *control)
{
counted_command_line cmd;
+ /* cmd_read will be true once we have read cmd. Note that cmd might still be
+ NULL after the call to read_command_lines if the user provides an empty
+ list of command by just typing "end". */
+ bool cmd_read = false;
std::string new_arg;
map_breakpoint_numbers
(arg, [&] (breakpoint *b)
{
- if (cmd == NULL)
+ if (!cmd_read)
{
+ gdb_assert (cmd == NULL);
if (control != NULL)
- cmd = copy_command_lines (control->body_list[0]);
+ cmd = control->body_list_0;
else
{
std::string str
"%s, one per line."),
arg);
- cmd = read_command_lines (&str[0],
- from_tty, 1,
- (is_tracepoint (b)
- ? check_tracepoint_command : 0),
- b);
+ auto do_validate = [=] (const char *line)
+ {
+ validate_actionline (line, b);
+ };
+ gdb::function_view<void (const char *)> validator;
+ if (is_tracepoint (b))
+ validator = do_validate;
+
+ cmd = read_command_lines (str.c_str (), from_tty, 1, validator);
}
+ cmd_read = true;
}
/* If a breakpoint was on the list more than once, we don't need to
{
validate_commands_for_breakpoint (b, cmd.get ());
b->commands = cmd;
- observer_notify_breakpoint_modified (b);
+ gdb::observers::breakpoint_modified.notify (b);
}
});
-
- if (cmd == NULL)
- error (_("No breakpoints specified."));
}
static void
-commands_command (char *arg, int from_tty)
+commands_command (const char *arg, int from_tty)
{
commands_command_1 (arg, from_tty, NULL);
}
watchpoint_in_thread_scope (struct watchpoint *b)
{
return (b->pspace == current_program_space
- && (ptid_equal (b->watchpoint_thread, null_ptid)
- || (ptid_equal (inferior_ptid, b->watchpoint_thread)
- && !is_executing (inferior_ptid))));
+ && (b->watchpoint_thread == null_ptid
+ || (inferior_ptid == b->watchpoint_thread
+ && !inferior_thread ()->executing)));
}
/* Set watchpoint B to disp_del_at_next_stop, even including its possible
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;
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
/* We don't want to stop processing, so catch any errors
that may show up. */
- TRY
+ try
{
aexpr = gen_eval_for_expr (scope, cond);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
/* If we got here, it means the condition could not be parsed to a valid
bytecode expression and thus can't be evaluated on the target's side.
It's no use iterating through the conditions. */
}
- END_CATCH
/* We have a valid agent expression. */
return aexpr;
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;
/* We don't want to stop processing, so catch any errors
that may show up. */
- TRY
+ try
{
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)
+ catch (const gdb_exception_error &ex)
{
/* If we got here, it means the command could not be parsed to a valid
bytecode expression and thus can't be evaluated on the target's side.
It's no use iterating through the other commands. */
}
- END_CATCH
-
- do_cleanups (old_cleanups);
/* We have a valid agent expression, return it. */
return aexpr;
struct thread_info *thr = find_thread_global_id (bl->owner->thread);
struct regcache *regcache;
- regcache = get_thread_regcache (thr->ptid);
+ regcache = get_thread_regcache (thr);
return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
regcache, addr);
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;
|| !(section_is_overlay (bl->section)))
{
/* No overlay handling: just set the breakpoint. */
- TRY
+ try
{
int val;
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)
+ catch (const gdb_exception &e)
{
- bp_err = e.error;
- bp_err_message = e.message;
+ bp_excpt = e;
}
- END_CATCH
}
else
{
bl->overlay_target_info.reqstd_address = addr;
/* No overlay handling: just set the breakpoint. */
- TRY
+ try
{
int val;
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)
+ catch (const gdb_exception &e)
{
- 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",
if (section_is_mapped (bl->section))
{
/* Yes. This overlay section is mapped into memory. */
- TRY
+ try
{
int val;
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)
+ catch (const gdb_exception &e)
{
- bp_err = e.error;
- bp_err_message = e.message;
+ bp_excpt = e;
}
- END_CATCH
}
else
{
}
}
- 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.what ());
}
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.what ());
}
}
return 1;
/* We only want to update locations that are already inserted
and need updating. This is to avoid unwanted insertion during
deletion of breakpoints. */
- if (!bl->inserted || (bl->inserted && !bl->needs_update))
+ if (!bl->inserted || !bl->needs_update)
continue;
switch_to_program_space_and_thread (bl->pspace);
if we aren't attached to any process yet, we should still
insert breakpoints. */
if (!gdbarch_has_global_breakpoints (target_gdbarch ())
- && ptid_equal (inferior_ptid, null_ptid))
+ && inferior_ptid == null_ptid)
continue;
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
if we aren't attached to any process yet, we should still
insert breakpoints. */
if (!gdbarch_has_global_breakpoints (target_gdbarch ())
- && ptid_equal (inferior_ptid, null_ptid))
+ && inferior_ptid == null_ptid)
continue;
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
}
}
-/* Remove breakpoints of process PID. */
+/* Remove breakpoints of inferior INF. */
int
-remove_breakpoints_pid (int pid)
+remove_breakpoints_inf (inferior *inf)
{
struct bp_location *bl, **blp_tmp;
int val;
- struct inferior *inf = find_inferior_pid (pid);
ALL_BP_LOCATIONS (bl, blp_tmp)
{
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
create_overlay_event_breakpoint (void)
{
- struct objfile *objfile;
const char *const func_name = "_ovly_debug_event";
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
ALL_PSPACES (pspace)
{
- struct objfile *objfile;
-
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- int i;
- struct gdbarch *gdbarch;
- struct breakpoint_objfile_data *bp_objfile_data;
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ int i;
+ struct gdbarch *gdbarch;
+ struct breakpoint_objfile_data *bp_objfile_data;
- gdbarch = get_objfile_arch (objfile);
+ gdbarch = get_objfile_arch (objfile);
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
+ bp_objfile_data = get_breakpoint_objfile_data (objfile);
- if (!bp_objfile_data->longjmp_searched)
- {
- VEC (probe_p) *ret;
-
- ret = find_probes_in_objfile (objfile, "libc", "longjmp");
- if (ret != NULL)
- {
- /* We are only interested in checking one element. */
- struct probe *p = VEC_index (probe_p, ret, 0);
+ if (!bp_objfile_data->longjmp_searched)
+ {
+ std::vector<probe *> ret
+ = find_probes_in_objfile (objfile, "libc", "longjmp");
- if (!can_evaluate_probe_arguments (p))
- {
- /* We cannot use the probe interface here, because it does
- not know how to evaluate arguments. */
- VEC_free (probe_p, ret);
- ret = NULL;
- }
- }
- bp_objfile_data->longjmp_probes = ret;
- bp_objfile_data->longjmp_searched = 1;
- }
+ if (!ret.empty ())
+ {
+ /* We are only interested in checking one element. */
+ probe *p = ret[0];
- if (bp_objfile_data->longjmp_probes != NULL)
- {
- int i;
- struct probe *probe;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ if (!p->can_evaluate_arguments ())
+ {
+ /* We cannot use the probe interface here, because it does
+ not know how to evaluate arguments. */
+ ret.clear ();
+ }
+ }
+ bp_objfile_data->longjmp_probes = ret;
+ bp_objfile_data->longjmp_searched = 1;
+ }
- for (i = 0;
- VEC_iterate (probe_p,
- bp_objfile_data->longjmp_probes,
- i, probe);
- ++i)
- {
- struct breakpoint *b;
+ if (!bp_objfile_data->longjmp_probes.empty ())
+ {
+ for (probe *p : bp_objfile_data->longjmp_probes)
+ {
+ struct breakpoint *b;
+
+ b = create_internal_breakpoint (gdbarch,
+ p->get_relocated_address (objfile),
+ bp_longjmp_master,
+ &internal_breakpoint_ops);
+ b->location = new_probe_location ("-probe-stap libc:longjmp");
+ b->enable_state = bp_disabled;
+ }
- b = create_internal_breakpoint (gdbarch,
- get_probe_address (probe,
- objfile),
- bp_longjmp_master,
- &internal_breakpoint_ops);
- b->location = new_probe_location ("-probe-stap libc:longjmp");
- b->enable_state = bp_disabled;
- }
+ continue;
+ }
+ if (!gdbarch_get_longjmp_target_p (gdbarch))
continue;
- }
- if (!gdbarch_get_longjmp_target_p (gdbarch))
- continue;
-
- for (i = 0; i < NUM_LONGJMP_NAMES; i++)
- {
- struct breakpoint *b;
- const char *func_name;
- CORE_ADDR addr;
- struct explicit_location explicit_loc;
+ for (i = 0; i < NUM_LONGJMP_NAMES; i++)
+ {
+ struct breakpoint *b;
+ const char *func_name;
+ CORE_ADDR addr;
+ struct explicit_location explicit_loc;
- if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
- continue;
+ if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
+ continue;
- func_name = longjmp_names[i];
- if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
- {
- struct bound_minimal_symbol m;
+ func_name = longjmp_names[i];
+ if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
+ {
+ struct bound_minimal_symbol m;
- m = lookup_minimal_symbol_text (func_name, objfile);
- if (m.minsym == NULL)
- {
- /* Prevent future lookups in this objfile. */
- bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
- continue;
- }
- bp_objfile_data->longjmp_msym[i] = m;
- }
+ m = lookup_minimal_symbol_text (func_name, objfile);
+ if (m.minsym == NULL)
+ {
+ /* Prevent future lookups in this objfile. */
+ bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
+ continue;
+ }
+ bp_objfile_data->longjmp_msym[i] = m;
+ }
- addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
- b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
- &internal_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
- b->enable_state = bp_disabled;
- }
- }
+ addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
+ b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
+ &internal_breakpoint_ops);
+ initialize_explicit_location (&explicit_loc);
+ explicit_loc.function_name = ASTRDUP (func_name);
+ b->location = new_explicit_location (&explicit_loc);
+ b->enable_state = bp_disabled;
+ }
+ }
}
}
ALL_PSPACES (pspace)
{
- struct objfile *objfile;
CORE_ADDR addr;
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- struct breakpoint *b;
- struct breakpoint_objfile_data *bp_objfile_data;
- struct explicit_location explicit_loc;
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ struct breakpoint *b;
+ struct breakpoint_objfile_data *bp_objfile_data;
+ struct explicit_location explicit_loc;
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
+ bp_objfile_data = get_breakpoint_objfile_data (objfile);
- if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
- continue;
+ if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
+ continue;
- if (bp_objfile_data->terminate_msym.minsym == NULL)
- {
- struct bound_minimal_symbol m;
+ if (bp_objfile_data->terminate_msym.minsym == NULL)
+ {
+ struct bound_minimal_symbol m;
- m = lookup_minimal_symbol (func_name, NULL, objfile);
- if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
- && MSYMBOL_TYPE (m.minsym) != mst_file_text))
- {
- /* Prevent future lookups in this objfile. */
- bp_objfile_data->terminate_msym.minsym = &msym_not_found;
- continue;
- }
- bp_objfile_data->terminate_msym = m;
- }
+ m = lookup_minimal_symbol (func_name, NULL, objfile);
+ if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
+ && MSYMBOL_TYPE (m.minsym) != mst_file_text))
+ {
+ /* Prevent future lookups in this objfile. */
+ bp_objfile_data->terminate_msym.minsym = &msym_not_found;
+ continue;
+ }
+ bp_objfile_data->terminate_msym = m;
+ }
- addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
- b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
- bp_std_terminate_master,
- &internal_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
- b->enable_state = bp_disabled;
- }
+ addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
+ b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
+ bp_std_terminate_master,
+ &internal_breakpoint_ops);
+ initialize_explicit_location (&explicit_loc);
+ explicit_loc.function_name = ASTRDUP (func_name);
+ b->location = new_explicit_location (&explicit_loc);
+ b->enable_state = bp_disabled;
+ }
}
}
static void
create_exception_master_breakpoint (void)
{
- struct objfile *objfile;
const char *const func_name = "_Unwind_DebugHook";
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
struct breakpoint *b;
struct gdbarch *gdbarch;
/* 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;
+ gdbarch = get_objfile_arch (objfile);
- 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");
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
- ¤t_target);
+ current_top_target ());
b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
struct inferior *inf = current_inferior ();
- if (ptid_get_pid (ptid) == ptid_get_pid (inferior_ptid))
+ if (ptid.pid () == inferior_ptid.pid ())
error (_("Cannot detach breakpoints of inferior_ptid"));
/* Set inferior_ptid; remove_breakpoint_1 uses this global. */
breakpoint_init_inferior (enum inf_context context)
{
struct breakpoint *b, *b_tmp;
- struct bp_location *bl;
- int ix;
struct program_space *pspace = current_program_space;
/* If breakpoint locations are shared across processes, then there's
{
/* 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;
}
}
}
/* Get rid of the moribund locations. */
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, bl); ++ix)
+ for (bp_location *bl : moribund_locations)
decref_bp_location (&bl);
- VEC_free (bp_location_p, moribund_locations);
+ moribund_locations.clear ();
}
/* These functions concern about actual breakpoints inserted in the
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;
-
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ for (bp_location *loc : moribund_locations)
if (breakpoint_location_address_match (loc, aspace, pc))
return 1;
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;
bpstats::~bpstats ()
{
- if (old_val != NULL)
- value_free (old_val);
if (bp_location_at != NULL)
decref_bp_location (&bp_location_at);
}
bp_location_at (other.bp_location_at),
breakpoint_at (other.breakpoint_at),
commands (other.commands),
- old_val (other.old_val),
print (other.print),
stop (other.stop),
print_it (other.print_it)
{
- if (old_val != NULL)
- {
- old_val = value_copy (old_val);
- release_value (old_val);
- }
+ if (other.old_val != NULL)
+ old_val = release_value (value_copy (other.old_val.get ()));
incref_bp_location (bp_location_at);
}
void
bpstat_clear_actions (void)
{
- struct thread_info *tp;
bpstat bs;
- if (ptid_equal (inferior_ptid, null_ptid))
- return;
-
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
+ if (inferior_ptid == null_ptid)
return;
+ thread_info *tp = inferior_thread ();
for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
{
bs->commands = NULL;
-
- if (bs->old_val != NULL)
- {
- value_free (bs->old_val);
- bs->old_val = NULL;
- }
+ bs->old_val.reset (nullptr);
}
}
static void
breakpoint_about_to_proceed (void)
{
- if (!ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid != null_ptid)
{
struct thread_info *tp = inferior_thread ();
return again;
}
+/* Helper for bpstat_do_actions. Get the current thread, if there's
+ one, is alive and has execution. Return NULL otherwise. */
+
+static thread_info *
+get_bpstat_thread ()
+{
+ if (inferior_ptid == null_ptid || !target_has_execution)
+ return NULL;
+
+ thread_info *tp = inferior_thread ();
+ if (tp->state == THREAD_EXITED || tp->executing)
+ return NULL;
+ return tp;
+}
+
void
bpstat_do_actions (void)
{
- struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
+ auto cleanup_if_error = make_scope_exit (bpstat_clear_actions);
+ thread_info *tp;
/* Do any commands attached to breakpoint we are stopped at. */
- while (!ptid_equal (inferior_ptid, null_ptid)
- && target_has_execution
- && !is_exited (inferior_ptid)
- && !is_executing (inferior_ptid))
- /* Since in sync mode, bpstat_do_actions may resume the inferior,
- and only return when it is stopped at the next breakpoint, we
- keep doing breakpoint actions until it returns false to
- indicate the inferior was not resumed. */
- if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
- break;
+ while ((tp = get_bpstat_thread ()) != NULL)
+ {
+ /* Since in sync mode, bpstat_do_actions may resume the
+ inferior, and only return when it is stopped at the next
+ breakpoint, we keep doing breakpoint actions until it returns
+ false to indicate the inferior was not resumed. */
+ if (!bpstat_do_actions_1 (&tp->control.stop_bpstat))
+ break;
+ }
- discard_cleanups (cleanup_if_error);
+ cleanup_if_error.release ();
}
/* Print out the (old or new) value associated with a watchpoint. */
static void
print_solib_event (int is_catchpoint)
{
- int any_deleted
- = !VEC_empty (char_ptr, current_program_space->deleted_solibs);
- int any_added
- = !VEC_empty (so_list_ptr, current_program_space->added_solibs);
+ bool any_deleted = !current_program_space->deleted_solibs.empty ();
+ bool any_added = !current_program_space->added_solibs.empty ();
if (!is_catchpoint)
{
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);
if (any_added)
{
- struct so_list *iter;
- int ix;
-
current_uiout->text (_(" Inferior loaded "));
ui_out_emit_list list_emitter (current_uiout, "added");
- for (ix = 0;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
+ bool first = true;
+ for (so_list *iter : current_program_space->added_solibs)
{
- if (ix > 0)
+ if (!first)
current_uiout->text (" ");
+ first = false;
current_uiout->field_string ("library", iter->so_name);
current_uiout->text ("\n");
}
bp_location_at (bl),
breakpoint_at (bl->owner),
commands (NULL),
- old_val (NULL),
print (0),
stop (0),
print_it (print_it_normal)
bp_location_at (NULL),
breakpoint_at (NULL),
commands (NULL),
- old_val (NULL),
print (0),
stop (0),
print_it (print_it_normal)
int
watchpoints_triggered (struct target_waitstatus *ws)
{
- int stopped_by_watchpoint = target_stopped_by_watchpoint ();
+ bool stopped_by_watchpoint = target_stopped_by_watchpoint ();
CORE_ADDR addr;
struct breakpoint *b;
return 0;
}
- if (!target_stopped_data_address (¤t_target, &addr))
+ if (!target_stopped_data_address (current_top_target (), &addr))
{
/* We were stopped by a watchpoint, but we don't know where.
Mark all watchpoints as unknown. */
}
}
/* Exact match not required. Within range is sufficient. */
- else if (target_watchpoint_addr_within_range (¤t_target,
+ else if (target_watchpoint_addr_within_range (current_top_target (),
addr, loc->address,
loc->length))
{
the address of the array instead of its contents. This is
not what we want. */
if ((b->val != NULL) != (new_val != NULL)
- || (b->val != NULL && !value_equal_contents (b->val, new_val)))
+ || (b->val != NULL && !value_equal_contents (b->val.get (),
+ new_val)))
{
- if (new_val != NULL)
- {
- release_value (new_val);
- value_free_to_mark (mark);
- }
bs->old_val = b->val;
- b->val = new_val;
+ b->val = release_value (new_val);
b->val_valid = 1;
+ if (new_val != NULL)
+ value_free_to_mark (mark);
return WP_VALUE_CHANGED;
}
else
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;
{
wp_check_result e;
- TRY
+ try
{
e = watchpoint_check (bs);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error evaluating expression "
watchpoint_del_at_next_stop (b);
e = WP_DELETED;
}
- END_CATCH
switch (e)
{
breakpoint, set BS->stop to 0. */
static void
-bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
+bpstat_check_breakpoint_conditions (bpstat bs, thread_info *thread)
{
const struct bp_location *bl;
struct breakpoint *b;
/* If this is a thread/task-specific breakpoint, don't waste cpu
evaluating the condition if this isn't the specified
thread/task. */
- if ((b->thread != -1 && b->thread != ptid_to_global_thread_id (ptid))
- || (b->task != 0 && b->task != ada_get_task_number (ptid)))
-
+ if ((b->thread != -1 && b->thread != thread->global_num)
+ || (b->task != 0 && b->task != ada_get_task_number (thread)))
{
bs->stop = 0;
return;
}
if (within_current_scope)
{
- TRY
+ try
{
condition_result = breakpoint_cond_eval (cond);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error in testing breakpoint condition:\n");
}
- END_CATCH
}
else
{
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);
}
}
&& !target_supports_stopped_by_hw_breakpoint ()));
}
-
-/* Get a bpstat associated with having just stopped at address
- BP_ADDR in thread PTID.
-
- Determine whether we stopped at a breakpoint, etc, or whether we
- don't understand this stop. Result is a chain of bpstat's such
- that:
-
- if we don't understand the stop, the result is a null pointer.
-
- if we understand why we stopped, the result is not null.
-
- Each element of the chain refers to a particular breakpoint or
- watchpoint at which we have stopped. (We may have stopped for
- several reasons concurrently.)
-
- Each element of the chain has valid next, breakpoint_at,
- commands, FIXME??? fields. */
+/* See breakpoint.h. */
bpstat
-bpstat_stop_status (struct address_space *aspace,
- CORE_ADDR bp_addr, ptid_t ptid,
+build_bpstat_chain (const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
- struct breakpoint *b = NULL;
- struct bp_location *bl;
- struct bp_location *loc;
- /* First item of allocated bpstat's. */
+ struct breakpoint *b;
bpstat bs_head = NULL, *bs_link = &bs_head;
- /* Pointer to the last thing in the chain currently. */
- bpstat bs;
- int ix;
- int need_remove_insert;
- int removed_any;
-
- /* First, build the bpstat chain with locations that explain a
- target stop, while being careful to not set the target running,
- as that may invalidate locations (in particular watchpoint
- locations are recreated). Resuming will happen here with
- breakpoint conditions or watchpoint expressions that include
- inferior function calls. */
ALL_BREAKPOINTS (b)
{
if (!breakpoint_enabled (b))
continue;
- for (bl = b->loc; bl != NULL; bl = bl->next)
+ for (bp_location *bl = b->loc; bl != NULL; bl = bl->next)
{
/* For hardware watchpoints, we look only at the first
location. The watchpoint_check function will work on the
/* Come here if it's a watchpoint, or if the break address
matches. */
- bs = new bpstats (bl, &bs_link); /* Alloc a bpstat to
- explain stop. */
+ bpstat bs = new bpstats (bl, &bs_link); /* Alloc a bpstat to
+ explain stop. */
/* Assume we stop. Should we find a watchpoint that is not
actually triggered, or if the condition of the breakpoint
if (!target_supports_stopped_by_sw_breakpoint ()
|| !target_supports_stopped_by_hw_breakpoint ())
{
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ for (bp_location *loc : moribund_locations)
{
if (breakpoint_location_address_match (loc, aspace, bp_addr)
&& need_moribund_for_location_type (loc))
{
- bs = new bpstats (loc, &bs_link);
+ bpstat bs = new bpstats (loc, &bs_link);
/* For hits of moribund locations, we should just proceed. */
bs->stop = 0;
bs->print = 0;
}
}
+ return bs_head;
+}
+
+/* See breakpoint.h. */
+
+bpstat
+bpstat_stop_status (const address_space *aspace,
+ CORE_ADDR bp_addr, thread_info *thread,
+ const struct target_waitstatus *ws,
+ bpstat stop_chain)
+{
+ struct breakpoint *b = NULL;
+ /* First item of allocated bpstat's. */
+ bpstat bs_head = stop_chain;
+ bpstat bs;
+ int need_remove_insert;
+ int removed_any;
+
+ /* First, build the bpstat chain with locations that explain a
+ target stop, while being careful to not set the target running,
+ as that may invalidate locations (in particular watchpoint
+ locations are recreated). Resuming will happen here with
+ breakpoint conditions or watchpoint expressions that include
+ inferior function calls. */
+ if (bs_head == NULL)
+ bs_head = build_bpstat_chain (aspace, bp_addr, ws);
+
/* A bit of special processing for shlib breakpoints. We need to
process solib loading here, so that the lists of loaded and
unloaded libraries are correct before we handle "catch load" and
b->ops->check_status (bs);
if (bs->stop)
{
- bpstat_check_breakpoint_conditions (bs, ptid);
+ bpstat_check_breakpoint_conditions (bs, thread);
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)
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)
{
uiout->text ("in ");
- uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+ uiout->field_string ("func", SYMBOL_PRINT_NAME (sym),
+ ui_out_style_kind::FUNCTION);
uiout->text (" ");
uiout->wrap_hint (wrap_indent_at_field (uiout, "what"));
uiout->text ("at ");
}
uiout->field_string ("file",
- symtab_to_filename_for_display (loc->symtab));
+ symtab_to_filename_for_display (loc->symtab),
+ ui_out_style_kind::FILE);
uiout->text (":");
if (uiout->is_mi_like_p ())
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]));
}
}
}
/* 1 */
annotate_field (0);
if (part_of_multiple)
- {
- char *formatted;
- formatted = xstrprintf ("%d.%d", b->number, loc_number);
- uiout->field_string ("number", formatted);
- xfree (formatted);
- }
+ uiout->field_fmt ("number", "%d.%d", b->number, loc_number);
else
- {
- uiout->field_int ("number", b->number);
- }
+ uiout->field_int ("number", b->number);
/* 2 */
annotate_field (1);
else
uiout->field_string ("disp", bpdisp_text (b->disposition));
-
/* 4 */
annotate_field (3);
if (part_of_multiple)
uiout->field_string ("enabled", loc->enabled ? "y" : "n");
else
uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]);
- uiout->spaces (2);
-
/* 5 and 6 */
if (b->ops != NULL && b->ops->print_one != NULL)
{
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)
+ for (inferior *inf : all_inferiors ())
{
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)
int allflag)
{
struct ui_out *uiout = current_uiout;
+ bool use_fixed_output = mi_multi_location_breakpoint_output_fixed (uiout);
- {
- ui_out_emit_tuple tuple_emitter (uiout, "bkpt");
+ gdb::optional<ui_out_emit_tuple> bkpt_tuple_emitter (gdb::in_place, uiout, "bkpt");
+ print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
- print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
- }
+ /* The mi2 broken format: the main breakpoint tuple ends here, the locations
+ are outside. */
+ if (!use_fixed_output)
+ bkpt_tuple_emitter.reset ();
/* If this breakpoint has custom print function,
it's already printed. Otherwise, print individual
&& !is_hardware_watchpoint (b)
&& (b->loc->next || !b->loc->enabled))
{
- struct bp_location *loc;
- int n = 1;
+ gdb::optional<ui_out_emit_list> locations_list;
+
+ /* For MI version <= 2, keep the behavior where GDB outputs an invalid
+ MI record. For later versions, place breakpoint locations in a
+ list. */
+ if (uiout->is_mi_like_p () && use_fixed_output)
+ locations_list.emplace (uiout, "locations");
- for (loc = b->loc; loc; loc = loc->next, ++n)
+ int n = 1;
+ for (bp_location *loc = b->loc; loc != NULL; loc = loc->next, ++n)
{
- ui_out_emit_tuple tuple_emitter (uiout, NULL);
+ ui_out_emit_tuple loc_tuple_emitter (uiout, NULL);
print_one_breakpoint_location (b, loc, n, last_loc, allflag);
}
}
}
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;
: ((others == 1) ? " and" : ""));
}
printf_filtered (_("also set at pc "));
- fputs_filtered (paddress (gdbarch, pc), gdb_stdout);
+ fputs_styled (paddress (gdbarch, pc), address_style.style (), gdb_stdout);
printf_filtered (".\n");
}
}
/* 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;
+
+ 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);
+ }
- /* 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
}
}
-bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner)
+bp_location::bp_location (breakpoint *owner)
{
bp_location *loc = this;
- gdb_assert (ops != NULL);
-
- loc->ops = ops;
loc->owner = owner;
loc->cond_bytecode = NULL;
loc->shlib_disabled = 0;
static void
free_bp_location (struct bp_location *loc)
{
- loc->ops->dtor (loc);
delete loc;
}
|| loc->owner->type == bp_hardware_breakpoint
|| is_tracepoint (loc->owner))
{
- int is_gnu_ifunc;
const char *function_name;
- CORE_ADDR func_addr;
- find_pc_partial_function_gnu_ifunc (loc->address, &function_name,
- &func_addr, NULL, &is_gnu_ifunc);
-
- if (is_gnu_ifunc && !explicit_loc)
+ if (loc->msymbol != NULL
+ && (MSYMBOL_TYPE (loc->msymbol) == mst_text_gnu_ifunc
+ || MSYMBOL_TYPE (loc->msymbol) == mst_data_gnu_ifunc)
+ && !explicit_loc)
{
struct breakpoint *b = loc->owner;
- gdb_assert (loc->pspace == current_program_space);
- if (gnu_ifunc_resolve_name (function_name,
- &loc->requested_address))
- {
- /* Recalculate ADDRESS based on new REQUESTED_ADDRESS. */
- loc->address = adjust_breakpoint_address (loc->gdbarch,
- loc->requested_address,
- b->type);
- }
- else if (b->type == bp_breakpoint && b->loc == loc
- && loc->next == NULL && b->related_breakpoint == b)
+ function_name = MSYMBOL_LINKAGE_NAME (loc->msymbol);
+
+ if (b->type == bp_breakpoint && b->loc == loc
+ && loc->next == NULL && b->related_breakpoint == b)
{
/* Create only the whole new breakpoint of this type but do not
mess more complicated breakpoints with multiple locations. */
b->type = bp_gnu_ifunc_resolver;
/* Remember the resolver's address for use by the return
breakpoint. */
- loc->related_address = func_addr;
+ loc->related_address = loc->address;
}
}
+ else
+ find_pc_partial_function (loc->address, &function_name, NULL, NULL);
if (function_name)
loc->function_name = xstrdup (function_name);
new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
&momentary_breakpoint_ops,
1);
- new_b->thread = ptid_to_global_thread_id (inferior_ptid);
+ new_b->thread = inferior_thread ()->global_num;
/* Link NEW_B into the chain of RETVAL breakpoints. */
|| frame_find_by_id (dummy_b->frame_id) != NULL)
continue;
- dummy_frame_discard (dummy_b->frame_id, tp->ptid);
+ dummy_frame_discard (dummy_b->frame_id, tp);
while (b->related_breakpoint != b)
{
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
insert_catch_fork (struct bp_location *bl)
{
- return target_insert_fork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_insert_fork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "remove" breakpoint_ops method for fork
static int
remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason)
{
- return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_remove_fork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "breakpoint_hit" breakpoint_ops method for fork
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;
}
uiout->field_int ("bkptno", b->number);
uiout->text (" (forked process ");
- uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("newpid", c->forked_inferior_pid.pid ());
uiout->text ("), ");
return PRINT_SRC_AND_LOC;
}
uiout->field_skip ("addr");
annotate_field (5);
uiout->text ("fork");
- if (!ptid_equal (c->forked_inferior_pid, null_ptid))
+ if (c->forked_inferior_pid != null_ptid)
{
uiout->text (", process ");
- uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("what", c->forked_inferior_pid.pid ());
uiout->spaces (1);
}
static int
insert_catch_vfork (struct bp_location *bl)
{
- return target_insert_vfork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_insert_vfork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "remove" breakpoint_ops method for vfork
static int
remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason)
{
- return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_remove_vfork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "breakpoint_hit" breakpoint_ops method for vfork
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;
}
uiout->field_int ("bkptno", b->number);
uiout->text (" (vforked process ");
- uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("newpid", c->forked_inferior_pid.pid ());
uiout->text ("), ");
return PRINT_SRC_AND_LOC;
}
uiout->field_skip ("addr");
annotate_field (5);
uiout->text ("vfork");
- if (!ptid_equal (c->forked_inferior_pid, null_ptid))
+ if (c->forked_inferior_pid != null_ptid)
{
uiout->text (", process ");
- uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("what", c->forked_inferior_pid.pid ());
uiout->spaces (1);
}
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;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
+ for (so_list *iter : current_program_space->added_solibs)
{
if (!self->regex
|| self->compiled->exec (iter->so_name, 0, NULL, 0) == 0)
}
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;
}
}
struct solib_catchpoint *self = (struct solib_catchpoint *) b;
struct value_print_options opts;
struct ui_out *uiout = current_uiout;
- char *msg;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
uiout->field_skip ("addr");
}
+ std::string msg;
annotate_field (5);
if (self->is_load)
{
if (self->regex)
- msg = xstrprintf (_("load of library matching %s"), self->regex);
+ msg = string_printf (_("load of library matching %s"), self->regex);
else
- msg = xstrdup (_("load of library"));
+ msg = _("load of library");
}
else
{
if (self->regex)
- msg = xstrprintf (_("unload of library matching %s"), self->regex);
+ msg = string_printf (_("unload of library matching %s"), self->regex);
else
- msg = xstrdup (_("unload of library"));
+ msg = _("unload of library");
}
uiout->field_string ("what", msg);
- xfree (msg);
if (uiout->is_mi_like_p ())
uiout->field_string ("catch-type", self->is_load ? "load" : "unload");
"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
insert_catch_exec (struct bp_location *bl)
{
- return target_insert_exec_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_insert_exec_catchpoint (inferior_ptid.pid ());
}
static int
remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason)
{
- return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_remove_exec_catchpoint (inferior_ptid.pid ());
}
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)
{
b->disposition = disp_donttouch;
b->frame_id = frame_id;
- /* If we're debugging a multi-threaded program, then we want
- momentary breakpoints to be active in only a single thread of
- control. */
- if (in_thread_list (inferior_ptid))
- b->thread = ptid_to_global_thread_id (inferior_ptid);
+ b->thread = inferior_thread ()->global_num;
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)
{
mention (struct breakpoint *b)
{
b->ops->print_mention (b);
- if (current_uiout->is_mi_like_p ())
- return;
- printf_filtered ("\n");
+ current_uiout->text ("\n");
}
\f
loc->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;
+ loc->msymbol = sal->msymbol;
+ loc->objfile = sal->objfile;
set_breakpoint_location_function (loc,
sal->explicit_pc || sal->explicit_line);
_("Invalid dprintf style."));
gdb_assert (printf_line != NULL);
- /* Manufacture a printf sequence. */
- {
- struct command_line *printf_cmd_line = XNEW (struct command_line);
- printf_cmd_line->control_type = simple_control;
- printf_cmd_line->body_count = 0;
- printf_cmd_line->body_list = NULL;
- printf_cmd_line->next = NULL;
- printf_cmd_line->line = printf_line;
-
- breakpoint_set_commands (b, command_line_up (printf_cmd_line));
- }
+ /* Manufacture a printf sequence. */
+ struct command_line *printf_cmd_line
+ = new struct command_line (simple_control, printf_line);
+ breakpoint_set_commands (b, counted_command_line (printf_cmd_line,
+ command_lines_deleter ()));
}
/* Update all dprintf commands, making their command lists reflect
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;
const char *p = &(*arg_p)[3];
const char *endp;
- int i;
p = skip_spaces (p);
std::string marker_str (p, endp - p);
- markers = target_static_tracepoint_markers_by_strid (marker_str.c_str ());
- if (VEC_empty(static_tracepoint_marker_p, markers))
+ 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);
- }
+ }
*arg_p = endp;
return sals;
unsigned flags)
{
struct linespec_result canonical;
- struct cleanup *bkpt_chain = NULL;
int pending = 0;
int task = 0;
int prev_bkpt_count = breakpoint_count;
if (extra_string != NULL && *extra_string == '\0')
extra_string = NULL;
- TRY
+ try
{
ops->create_sals_from_location (location, &canonical, type_wanted);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
/* If caller is interested in rc value from parse, set
value. */
error. */
if (pending_break_support == AUTO_BOOLEAN_FALSE)
- throw_exception (e);
+ throw;
exception_print (gdb_stderr, e);
pending = 1;
}
else
- throw_exception (e);
+ throw;
}
- END_CATCH
if (!pending && canonical.lsals.empty ())
return 0;
- /* ----------------------------- SNIP -----------------------------
- Anything added to the cleanup chain beyond this point is assumed
- to be part of a breakpoint. If the breakpoint create succeeds
- then the memory is not reclaimed. */
- bkpt_chain = make_cleanup (null_cleanup, 0);
-
/* Resolve all line numbers to PC's and verify that the addresses
are ok for the target. */
if (!pending)
prev_breakpoint_count = prev_bkpt_count;
}
- /* That's it. Discard the cleanups for data inserted into the
- breakpoint. */
- discard_cleanups (bkpt_chain);
-
- /* error call may happen here - have BKPT_CHAIN already discarded. */
update_global_location_list (UGLL_MAY_INSERT);
return 1;
}
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\
}
if (badInput)
- printf_filtered (_("Usage: stop at <line>\n"));
+ printf_filtered (_("Usage: stop at LINE\n"));
else
break_command_1 (arg, 0, from_tty);
}
line. */
static void
-dprintf_command (char *arg_in, int from_tty)
+dprintf_command (const char *arg, int from_tty)
{
- const char *arg = arg_in;
event_location_up location = string_to_event_location (&arg, current_language);
/* If non-NULL, ARG should have been advanced past the location;
}
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)
{
gdb_assert (bl);
gdb_assert (b->type == bp_hardware_breakpoint);
- if (uiout->is_mi_like_p ())
- return;
-
- printf_filtered (_("Hardware assisted ranged breakpoint %d from %s to %s."),
- b->number, paddress (bl->gdbarch, bl->address),
- paddress (bl->gdbarch, bl->address + bl->length - 1));
+ uiout->message (_("Hardware assisted ranged breakpoint %d from %s to %s."),
+ b->number, paddress (bl->gdbarch, bl->address),
+ paddress (bl->gdbarch, bl->address + bl->length - 1));
}
/* Implement the "print_recreate" breakpoint_ops method for
/* Implement the "break-range" CLI command. */
static void
-break_range_command (char *arg_in, int from_tty)
+break_range_command (const char *arg, int from_tty)
{
- const char *arg = arg_in;
const char *arg_start;
struct linespec_result canonical_start, canonical_end;
int bp_count, can_use_bp, length;
b->loc->length = length;
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 *result;
int saved_bitpos = 0, saved_bitsize = 0;
const char *exp_start = NULL;
const char *exp_end = NULL;
/* 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;
std::string expression (arg, exp_end - arg);
exp_start = arg = expression.c_str ();
- expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
+ innermost_block_tracker tracker;
+ expression_up exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
exp_end = arg;
/* Remove trailing whitespace from the expression before saving it.
This makes the eventual display of the expression string a bit
error (_("Cannot watch constant value `%.*s'."), len, exp_start);
}
- exp_valid_block = innermost_block;
- mark = value_mark ();
- fetch_subexp_value (exp.get (), &pc, &val, &result, NULL, just_location);
+ exp_valid_block = tracker.block ();
+ struct value *mark = value_mark ();
+ 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;
tok = cond_start = end_tok + 1;
- parse_exp_1 (&tok, 0, 0, 0);
+ innermost_block_tracker if_tracker;
+ parse_exp_1 (&tok, 0, 0, 0, &if_tracker);
/* 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 = if_tracker.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 ();
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))
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);
}
}
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);
}
}
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);
}
in infcmd.c. Here because it uses the mechanisms of
breakpoints. */
-struct until_break_fsm
+struct until_break_fsm : public thread_fsm
{
- /* The base class. */
- struct thread_fsm thread_fsm;
-
- /* The thread that as current when the command was executed. */
+ /* The thread that was current when the command was executed. */
int thread;
/* The breakpoint set at the destination location. */
- struct breakpoint *location_breakpoint;
+ breakpoint_up location_breakpoint;
/* Breakpoint set at the return address in the caller frame. May be
NULL. */
- struct breakpoint *caller_breakpoint;
-};
-
-static void until_break_fsm_clean_up (struct thread_fsm *self,
- struct thread_info *thread);
-static int until_break_fsm_should_stop (struct thread_fsm *self,
- struct thread_info *thread);
-static enum async_reply_reason
- until_break_fsm_async_reply_reason (struct thread_fsm *self);
-
-/* until_break_fsm's vtable. */
+ breakpoint_up caller_breakpoint;
+
+ until_break_fsm (struct interp *cmd_interp, int thread,
+ breakpoint_up &&location_breakpoint,
+ breakpoint_up &&caller_breakpoint)
+ : thread_fsm (cmd_interp),
+ thread (thread),
+ location_breakpoint (std::move (location_breakpoint)),
+ caller_breakpoint (std::move (caller_breakpoint))
+ {
+ }
-static struct thread_fsm_ops until_break_fsm_ops =
-{
- NULL, /* dtor */
- until_break_fsm_clean_up,
- until_break_fsm_should_stop,
- NULL, /* return_value */
- until_break_fsm_async_reply_reason,
+ void clean_up (struct thread_info *thread) override;
+ bool should_stop (struct thread_info *thread) override;
+ enum async_reply_reason do_async_reply_reason () override;
};
-/* Allocate a new until_break_command_fsm. */
-
-static struct until_break_fsm *
-new_until_break_fsm (struct interp *cmd_interp, int thread,
- struct breakpoint *location_breakpoint,
- struct breakpoint *caller_breakpoint)
-{
- struct until_break_fsm *sm;
-
- sm = XCNEW (struct until_break_fsm);
- 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;
-
- return sm;
-}
-
/* Implementation of the 'should_stop' FSM method for the
until(location)/advance commands. */
-static int
-until_break_fsm_should_stop (struct thread_fsm *self,
- struct thread_info *tp)
+bool
+until_break_fsm::should_stop (struct thread_info *tp)
{
- struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
if (bpstat_find_breakpoint (tp->control.stop_bpstat,
- sm->location_breakpoint) != NULL
- || (sm->caller_breakpoint != NULL
+ location_breakpoint.get ()) != NULL
+ || (caller_breakpoint != NULL
&& bpstat_find_breakpoint (tp->control.stop_bpstat,
- sm->caller_breakpoint) != NULL))
- thread_fsm_set_finished (self);
+ caller_breakpoint.get ()) != NULL))
+ set_finished ();
- return 1;
+ return true;
}
/* Implementation of the 'clean_up' FSM method for the
until(location)/advance commands. */
-static void
-until_break_fsm_clean_up (struct thread_fsm *self,
- struct thread_info *thread)
+void
+until_break_fsm::clean_up (struct thread_info *)
{
- struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
/* Clean up our temporary breakpoints. */
- if (sm->location_breakpoint != NULL)
- {
- delete_breakpoint (sm->location_breakpoint);
- sm->location_breakpoint = NULL;
- }
- if (sm->caller_breakpoint != NULL)
- {
- delete_breakpoint (sm->caller_breakpoint);
- sm->caller_breakpoint = NULL;
- }
- delete_longjmp_breakpoint (sm->thread);
+ location_breakpoint.reset ();
+ caller_breakpoint.reset ();
+ delete_longjmp_breakpoint (thread);
}
/* Implementation of the 'async_reply_reason' FSM method for the
until(location)/advance commands. */
-static enum async_reply_reason
-until_break_fsm_async_reply_reason (struct thread_fsm *self)
+enum async_reply_reason
+until_break_fsm::do_async_reply_reason ()
{
return EXEC_ASYNC_LOCATION_REACHED;
}
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;
- struct until_break_fsm *sm;
clear_proceed_status (0);
tp = inferior_thread ();
thread = tp->global_num;
- old_chain = make_cleanup (null_cleanup, NULL);
-
/* Note linespec handling above invalidates the frame chain.
Installing a breakpoint also invalidates the frame chain (as it
may need to switch threads), so do any frame handling before
/* Keep within the current frame, or in frames called by the current
one. */
+ breakpoint_up caller_breakpoint;
+
+ gdb::optional<delete_longjmp_breakpoint_cleanup> lj_deleter;
+
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);
+ lj_deleter.emplace (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);
- tp->thread_fsm = &sm->thread_fsm;
+ tp->thread_fsm = new until_break_fsm (command_interp (), tp->global_num,
+ std::move (location_breakpoint),
+ std::move (caller_breakpoint));
- discard_cleanups (old_chain);
+ if (lj_deleter)
+ lj_deleter->release ();
proceed (-1, GDB_SIGNAL_DEFAULT);
}
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;
}
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."));
}
/* 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;
int default_match;
- int i;
std::vector<symtab_and_line> decoded_sals;
symtab_and_line last_sal;
/* Remove duplicates from the vec. */
std::sort (found.begin (), found.end (),
- [] (const breakpoint *a, const breakpoint *b)
+ [] (const breakpoint *bp_a, const breakpoint *bp_b)
{
- return compare_breakpoints (a, b) < 0;
+ return compare_breakpoints (bp_a, bp_b) < 0;
});
found.erase (std::unique (found.begin (), found.end (),
- [] (const breakpoint *a, const breakpoint *b)
+ [] (const breakpoint *bp_a, const breakpoint *bp_b)
{
- return compare_breakpoints (a, b) == 0;
+ return compare_breakpoints (bp_a, bp_b) == 0;
}),
found.end ());
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);
}
}
old_loc->events_till_retirement = 3 * (thread_count () + 1);
old_loc->owner = NULL;
- VEC_safe_push (bp_location_p, moribund_locations, old_loc);
+ moribund_locations.push_back (old_loc);
}
else
{
void
breakpoint_retire_moribund (void)
{
- struct bp_location *loc;
- int ix;
-
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
- if (--(loc->events_till_retirement) == 0)
- {
- decref_bp_location (&loc);
- VEC_unordered_remove (bp_location_p, moribund_locations, ix);
- --ix;
- }
+ for (int ix = 0; ix < moribund_locations.size (); ++ix)
+ {
+ struct bp_location *loc = moribund_locations[ix];
+ if (--(loc->events_till_retirement) == 0)
+ {
+ decref_bp_location (&loc);
+ unordered_remove (moribund_locations, ix);
+ --ix;
+ }
+ }
}
static void
update_global_location_list_nothrow (enum ugll_insert_mode insert_mode)
{
- TRY
+ try
{
update_global_location_list (insert_mode);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
}
- END_CATCH
}
/* Clear BKP from a BPS. */
if (opts.addressprint || b->loc->symtab == NULL)
{
printf_filtered (" at ");
- fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
- gdb_stdout);
+ fputs_styled (paddress (b->loc->gdbarch, b->loc->address),
+ address_style.style (),
+ gdb_stdout);
}
if (b->loc->symtab != NULL)
{
/* If there is a single location, we can print the location
more nicely. */
if (b->loc->next == NULL)
- printf_filtered (": file %s, line %d.",
- symtab_to_filename_for_display (b->loc->symtab),
- b->loc->line_number);
+ {
+ puts_filtered (": file ");
+ fputs_styled (symtab_to_filename_for_display (b->loc->symtab),
+ file_name_style.style (),
+ gdb_stdout);
+ printf_filtered (", line %d.",
+ b->loc->line_number);
+ }
else
/* This is not ideal, but each location may have a
different file name, and this at least reflects the
}
}
-/* Default bp_location_ops methods. */
-
-static void
-bp_location_dtor (struct bp_location *self)
+bp_location::~bp_location ()
{
- xfree (self->function_name);
+ xfree (function_name);
}
-static const struct bp_location_ops bp_location_ops =
-{
- bp_location_dtor
-};
-
/* Destructor for the breakpoint base class. */
breakpoint::~breakpoint ()
static struct bp_location *
base_breakpoint_allocate_location (struct breakpoint *self)
{
- return new bp_location (&bp_location_ops, self);
+ return new bp_location (self);
}
static void
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);
struct linespec_sals lsal;
const char *arg_start, *arg;
- arg = arg_start = get_linespec_location (location);
+ arg = arg_start = get_linespec_location (location)->spec_string;
lsal.sals = decode_static_tracepoint_spec (&arg);
std::string str (arg_start, arg - arg_start);
const char *ptr = str.c_str ();
- canonical->location = new_linespec_location (&ptr);
+ 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
-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, [&] (breakpoint *b)
+ (arg, [&] (breakpoint *br)
{
- iterate_over_related_breakpoints (b, delete_breakpoint);
+ iterate_over_related_breakpoints (br, delete_breakpoint);
});
}
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;
-
- markers
- = target_static_tracepoint_markers_by_strid (tp->static_trace_marker_id);
+ std::vector<static_tracepoint_marker> markers
+ = target_static_tracepoint_markers_by_strid
+ (tp->static_trace_marker_id.c_str ());
- 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);
uiout->text ("Now in ");
if (sym)
{
- uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+ uiout->field_string ("func", SYMBOL_PRINT_NAME (sym),
+ ui_out_style_kind::FUNCTION);
uiout->text (" at ");
}
uiout->field_string ("file",
- symtab_to_filename_for_display (sal2.symtab));
+ symtab_to_filename_for_display (sal2.symtab),
+ ui_out_style_kind::FILE);
uiout->text (":");
if (uiout->is_mi_like_p ())
/* 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))
const char *s;
s = b->cond_string;
- TRY
+ try
{
new_loc->cond = parse_exp_1 (&s, sal.pc,
block_for_pc (sal.pc),
0);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
warning (_("failed to reevaluate condition "
"for breakpoint %d: %s"),
- b->number, e.message);
+ b->number, e.what ());
new_loc->enabled = 0;
}
- END_CATCH
}
if (!sals_end.empty ())
}
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.
std::vector<symtab_and_line> sals;
- TRY
+ try
{
sals = b->ops->decode_location (b, location, search_pspace);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
int not_found_and_ok = 0;
happens only when a binary has changed, I don't know
which approach is better. */
b->enable_state = bp_disabled;
- throw_exception (e);
+ throw;
}
}
- END_CATCH
if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR)
{
return {};
}
-/* Prepare the global context for a re-set of breakpoint B. */
-
-static struct cleanup *
-prepare_re_set_context (struct breakpoint *b)
-{
- input_radix = b->input_radix;
- set_language (b->language);
-
- return make_cleanup (null_cleanup, NULL);
-}
-
/* Reset a breakpoint. */
static void
breakpoint_re_set_one (breakpoint *b)
{
- struct cleanup *cleanups;
+ input_radix = b->input_radix;
+ set_language (b->language);
- cleanups = prepare_re_set_context (b);
b->ops->re_set (b);
- do_cleanups (cleanups);
}
/* 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;
+ /* breakpoint_re_set_one sets the current_language to the language
+ of the breakpoint it is resetting (see prepare_re_set_context)
+ before re-evaluating the breakpoint's location. This change can
+ unfortunately get undone by accident if the language_mode is set
+ to auto, and we either switch frames, or more likely in this context,
+ we select the current frame.
+
+ We prevent this by temporarily turning the language_mode to
+ language_mode_manual. We restore it once all breakpoints
+ have been reset. */
+ scoped_restore save_language_mode = make_scoped_restore (&language_mode);
+ language_mode = language_mode_manual;
+
/* Note: we must not try to insert locations until after all
breakpoints have been re-set. Otherwise, e.g., when re-setting
breakpoint 1, we'd insert the locations of breakpoint 2, which
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
- TRY
+ try
{
breakpoint_re_set_one (b);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
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 ();
}
{
if (b->thread != -1)
{
- if (in_thread_list (inferior_ptid))
- b->thread = ptid_to_global_thread_id (inferior_ptid);
+ b->thread = inferior_thread ()->global_num;
/* We're being called after following a fork. The new fork is
selected as current, and unless this was a vfork will have a
"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,
- gdb::function_view<void (breakpoint *)> function)
+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)
{
- const char *p = parser.cur_tok ();
- bool match = false;
+ warning (_("bad breakpoint number at or near '%d'"),
+ bp_num_range.first);
+ }
+ else
+ {
+ 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);
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);
+
+ gdb::observers::breakpoint_modified.notify (loc->owner);
}
+/* 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);
+ gdb::observers::breakpoint_modified.notify (bpt);
}
+/* 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 (), [&] (breakpoint *b)
- {
- iterate_over_related_breakpoints (b, disable_breakpoint);
- });
+ {
+ /* 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)
/* Initialize it just to avoid a GCC false warning. */
enum enable_state orig_enable_state = bp_disabled;
- TRY
+ try
{
struct watchpoint *w = (struct watchpoint *) bpt;
bpt->enable_state = bp_enabled;
update_watchpoint (w, 1 /* reparse */);
}
- CATCH (e, RETURN_MASK_ALL)
+ catch (const gdb_exception &e)
{
bpt->enable_state = orig_enable_state;
exception_fprintf (gdb_stderr, e, _("Cannot enable watchpoint %d: "),
bpt->number);
return;
}
- END_CATCH
}
bpt->enable_state = bp_enabled;
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);
}
-/* 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. */
+/* 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_command (char *args, int from_tty)
+enable_command (const 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 (), [&] (breakpoint *b)
- {
- iterate_over_related_breakpoints (b, enable_breakpoint);
- });
- num = extract_arg (&args);
- }
- }
+ enable_disable_command (args, from_tty, true);
}
static void
}
\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_in, int from_tty)
+trace_command (const char *arg, int from_tty)
{
- const char *arg = arg_in;
struct breakpoint_ops *ops;
event_location_up location = string_to_event_location (&arg,
}
static void
-ftrace_command (char *arg_in, int from_tty)
+ftrace_command (const char *arg, int from_tty)
{
- const char *arg = arg_in;
event_location_up location = string_to_event_location (&arg,
current_language);
create_breakpoint (get_current_arch (),
/* strace command implementation. Creates a static tracepoint. */
static void
-strace_command (char *arg_in, int from_tty)
+strace_command (const char *arg, int from_tty)
{
- const char *arg = arg_in;
struct breakpoint_ops *ops;
event_location_up location;
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].get ();
+ next_cmd++;
+ }
return rslt;
}
struct tracepoint *tp;
if (utp->at_string)
- addr_str = utp->at_string;
+ addr_str = utp->at_string.get ();
else
{
/* In the absence of a source location, fall back to raw
current_language);
if (!create_breakpoint (get_current_arch (),
location.get (),
- utp->cond_string, -1, addr_str,
+ utp->cond_string.get (), -1, addr_str,
0 /* parse cond/thread */,
0 /* tempflag */,
utp->type /* type_wanted */,
special-purpose "reader" function and call the usual command line
reader, then pass the result to the breakpoint command-setting
function. */
- if (!VEC_empty (char_ptr, utp->cmd_strings))
+ if (!utp->cmd_strings.empty ())
{
- command_line_up cmd_list;
+ counted_command_line cmd_list;
this_utp = utp;
next_cmd = 0;
- cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
+ cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL);
breakpoint_set_commands (tp, std::move (cmd_list));
}
- else if (!VEC_empty (char_ptr, utp->actions)
- || !VEC_empty (char_ptr, utp->step_actions))
+ else if (!utp->actions.empty ()
+ || !utp->step_actions.empty ())
warning (_("Uploaded tracepoint %d actions "
"have no source form, ignoring them"),
utp->number);
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);
}
}
else
map_breakpoint_numbers
- (arg, [&] (breakpoint *b)
+ (arg, [&] (breakpoint *br)
{
- iterate_over_related_breakpoints (b, delete_breakpoint);
+ iterate_over_related_breakpoints (br, delete_breakpoint);
});
}
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)
{
fp.puts (" commands\n");
current_uiout->redirect (&fp);
- TRY
+ try
{
print_command_lines (current_uiout, tp->commands.get (), 2);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
current_uiout->redirect (NULL);
- throw_exception (ex);
+ throw;
}
- END_CATCH
current_uiout->redirect (NULL);
fp.puts (" end\n");
/* Create a vector of all tracepoints. */
-VEC(breakpoint_p) *
+std::vector<breakpoint *>
all_tracepoints (void)
{
- VEC(breakpoint_p) *tp_vec = 0;
+ std::vector<breakpoint *> tp_vec;
struct breakpoint *tp;
ALL_TRACEPOINTS (tp)
{
- VEC_safe_push (breakpoint_p, tp_vec, tp);
+ tp_vec.push_back (tp);
}
return tp_vec;
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)
}
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;
static struct cmd_list_element *enablebreaklist = NULL;
+/* See breakpoint.h. */
+
+cmd_list_element *commands_cmd_element = nullptr;
+
void
_initialize_breakpoint (void)
{
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
Set ignore-count of breakpoint number N to COUNT.\n\
Usage is `ignore N COUNT'."));
- add_com ("commands", class_breakpoint, commands_command, _("\
+ commands_cmd_element = add_com ("commands", class_breakpoint,
+ commands_command, _("\
Set commands to be executed when the given breakpoints are hit.\n\
Give a space-separated breakpoint list as argument after \"commands\".\n\
A list element can be a breakpoint number (e.g. `5') or a range of numbers\n\
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);
}