/* Everything about breakpoints, for GDB.
- Copyright (C) 1986-2018 Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "format.h"
#include "thread-fsm.h"
#include "tid-parse.h"
+#include "cli/cli-style.h"
/* readline include files */
#include "readline/readline.h"
}
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. */
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"));
/* 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;
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 = control->body_list_0;
else
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
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)
+ && (b->watchpoint_thread == null_ptid
+ || (inferior_ptid == b->watchpoint_thread
&& !inferior_thread ()->executing)));
}
{
int pc = 0;
std::vector<value_ref_ptr> val_chain;
- struct value *v, *result, *next;
+ struct value *v, *result;
struct program_space *frame_pspace;
fetch_subexp_value (b->exp.get (), &pc, &v, &result, &val_chain, 0);
/* 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,
static void
create_overlay_event_breakpoint (void)
{
- struct objfile *objfile;
const char *const func_name = "_ovly_debug_event";
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : all_objfiles (current_program_space))
{
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;
-
- gdbarch = get_objfile_arch (objfile);
+ for (objfile *objfile : all_objfiles (current_program_space))
+ {
+ int i;
+ struct gdbarch *gdbarch;
+ struct breakpoint_objfile_data *bp_objfile_data;
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
+ gdbarch = get_objfile_arch (objfile);
- if (!bp_objfile_data->longjmp_searched)
- {
- std::vector<probe *> ret
- = find_probes_in_objfile (objfile, "libc", "longjmp");
+ bp_objfile_data = get_breakpoint_objfile_data (objfile);
- if (!ret.empty ())
- {
- /* We are only interested in checking one element. */
- probe *p = ret[0];
+ if (!bp_objfile_data->longjmp_searched)
+ {
+ std::vector<probe *> ret
+ = find_probes_in_objfile (objfile, "libc", "longjmp");
- 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;
- }
+ if (!ret.empty ())
+ {
+ /* We are only interested in checking one element. */
+ probe *p = ret[0];
- if (!bp_objfile_data->longjmp_probes.empty ())
- {
- 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 (probe *p : bp_objfile_data->longjmp_probes)
- {
- 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,
- 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;
- }
+ 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 : all_objfiles (current_program_space))
+ {
+ 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 : all_objfiles (current_program_space))
{
struct breakpoint *b;
struct gdbarch *gdbarch;
if (!bp_objfile_data->exception_probes.empty ())
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ gdbarch = get_objfile_arch (objfile);
for (probe *p : bp_objfile_data->exception_probes)
{
- struct breakpoint *b;
-
b = create_internal_breakpoint (gdbarch,
p->get_relocated_address (objfile),
bp_exception_master,
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
}
/* 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
int
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 void
breakpoint_about_to_proceed (void)
{
- if (!ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid != null_ptid)
{
struct thread_info *tp = inferior_thread ();
if (!target_supports_stopped_by_sw_breakpoint ()
|| !target_supports_stopped_by_hw_breakpoint ())
{
- bp_location *loc;
-
- for (int 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))
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 ())
/* 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;
std::vector<int> inf_nums;
int mi_only = 1;
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_inferiors ())
{
if (inf->pspace == loc->pspace)
inf_nums.push_back (inf->num);
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", c->forked_inferior_pid.pid ());
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", c->forked_inferior_pid.pid ());
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");
}
if (badInput)
- printf_filtered (_("Usage: stop at <line>\n"));
+ printf_filtered (_("Usage: stop at LINE\n"));
else
break_command_1 (arg, 0, from_tty);
}
{
struct breakpoint *scope_breakpoint = NULL;
const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
- struct value *mark, *result;
+ struct value *result;
int saved_bitpos = 0, saved_bitsize = 0;
const char *exp_start = NULL;
const char *exp_end = NULL;
}
exp_valid_block = innermost_block.block ();
- mark = value_mark ();
+ struct value *mark = value_mark ();
struct value *val_as_value = nullptr;
fetch_subexp_value (exp.get (), &pc, &val_as_value, &result, NULL,
just_location);
/* 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 ());
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
/* 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
}
else
map_breakpoint_numbers
- (arg, [&] (breakpoint *b)
+ (arg, [&] (breakpoint *br)
{
- iterate_over_related_breakpoints (b, delete_breakpoint);
+ iterate_over_related_breakpoints (br, delete_breakpoint);
});
}
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 ())
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
if (next_cmd < this_utp->cmd_strings.size ())
{
- rslt = this_utp->cmd_strings[next_cmd];
+ rslt = this_utp->cmd_strings[next_cmd].get ();
next_cmd++;
}
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 */,
}
else
map_breakpoint_numbers
- (arg, [&] (breakpoint *b)
+ (arg, [&] (breakpoint *br)
{
- iterate_over_related_breakpoints (b, delete_breakpoint);
+ iterate_over_related_breakpoints (br, delete_breakpoint);
});
}
/* 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;
static struct cmd_list_element *enablebreaklist = NULL;
+/* See breakpoint.h. */
+
+cmd_list_element *commands_cmd_element = nullptr;
+
void
_initialize_breakpoint (void)
{
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\