/* Everything about breakpoints, for GDB.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_regex.h"
#include "probe.h"
#include "cli/cli-utils.h"
-#include "continuations.h"
#include "stack.h"
-#include "skip.h"
#include "ax-gdb.h"
#include "dummy-frame.h"
#include "interps.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"
-#include "readline/history.h"
+#include "readline/tilde.h"
/* readline defines this. */
#undef savestring
/* Breakpoints set on probes. */
static struct breakpoint_ops bkpt_probe_breakpoint_ops;
+/* Tracepoints set on probes. */
+static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
+
/* Dynamic printf class type. */
struct breakpoint_ops dprintf_breakpoint_ops;
no threads under GDB's control yet. */
return 1;
}
- else if (target_has_execution)
+ else
{
if (always_inserted_mode)
{
return 1;
}
- if (threads_are_executing ())
- return 1;
+ for (inferior *inf : all_inferiors ())
+ if (inf->has_execution ()
+ && threads_are_executing (inf->process_target ()))
+ return 1;
/* Don't remove breakpoints yet if, even though all threads are
stopped, we still have events to process. */
/* Chains of all breakpoints defined. */
-struct breakpoint *breakpoint_chain;
+static struct breakpoint *breakpoint_chain;
-/* Array is sorted by bp_locations_compare - primarily by the ADDRESS. */
+/* Array is sorted by bp_location_is_less_than - primarily by the ADDRESS. */
static struct bp_location **bp_locations;
/* A comparison function for bp_location AP and BP that is used by
bsearch. This comparison function only cares about addresses, unlike
- the more general bp_locations_compare function. */
+ the more general bp_location_is_less_than function. */
static int
bp_locations_compare_addrs (const void *ap, const void *bp)
if we aren't attached to any process yet, we should still
insert breakpoints. */
if (!gdbarch_has_global_breakpoints (target_gdbarch ())
- && inferior_ptid == null_ptid)
+ && (inferior_ptid == null_ptid || !target_has_execution))
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 ())
- && inferior_ptid == null_ptid)
+ && (inferior_ptid == null_ptid || !target_has_execution))
continue;
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym);
- b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
+ b = create_internal_breakpoint (objfile->arch (), addr,
bp_overlay_event,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
- gdbarch = get_objfile_arch (objfile);
+ gdbarch = objfile->arch ();
bp_objfile_data = get_breakpoint_objfile_data (objfile);
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
- b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
+ b = create_internal_breakpoint (objfile->arch (), addr,
bp_std_terminate_master,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
if (!bp_objfile_data->exception_probes.empty ())
{
- gdbarch = get_objfile_arch (objfile);
+ gdbarch = objfile->arch ();
for (probe *p : bp_objfile_data->exception_probes)
{
if (msym_not_found_p (bp_objfile_data->exception_msym.minsym))
continue;
- gdbarch = get_objfile_arch (objfile);
+ gdbarch = objfile->arch ();
if (bp_objfile_data->exception_msym.minsym == NULL)
{
if (sym)
{
uiout->text ("in ");
- uiout->field_string ("func", SYMBOL_PRINT_NAME (sym),
+ uiout->field_string ("func", sym->print_name (),
function_name_style.style ());
uiout->text (" ");
uiout->wrap_hint (wrap_indent_at_field (uiout, "what"));
{
struct breakpoint *b = loc->owner;
- function_name = MSYMBOL_LINKAGE_NAME (loc->msymbol);
+ function_name = loc->msymbol->linkage_name ();
if (b->type == bp_breakpoint && b->loc == loc
&& loc->next == NULL && b->related_breakpoint == b)
get_sal_arch (struct symtab_and_line sal)
{
if (sal.section)
- return get_objfile_arch (sal.section->objfile);
+ return sal.section->objfile->arch ();
if (sal.symtab)
- return get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
+ return SYMTAB_OBJFILE (sal.symtab)->arch ();
return NULL;
}
}
\f
-static int bp_loc_is_permanent (struct bp_location *loc);
+static bool bp_loc_is_permanent (struct bp_location *loc);
static struct bp_location *
add_location_to_breakpoint (struct breakpoint *b,
}
\f
-/* See breakpoint.h. */
-
-int
-program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address)
-{
- int len;
- CORE_ADDR addr;
- const gdb_byte *bpoint;
- gdb_byte *target_mem;
-
- addr = address;
- bpoint = gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);
-
- /* Software breakpoints unsupported? */
- if (bpoint == NULL)
- return 0;
-
- target_mem = (gdb_byte *) alloca (len);
-
- /* Enable the automatic memory restoration from breakpoints while
- we read the memory. Otherwise we could say about our temporary
- breakpoints they are permanent. */
- scoped_restore restore_memory
- = make_scoped_restore_show_memory_breakpoints (0);
-
- if (target_read_memory (address, target_mem, len) == 0
- && memcmp (target_mem, bpoint, len) == 0)
- return 1;
-
- return 0;
-}
-
-/* Return 1 if LOC is pointing to a permanent breakpoint,
- return 0 otherwise. */
+/* Return true if LOC is pointing to a permanent breakpoint,
+ return false otherwise. */
-static int
+static bool
bp_loc_is_permanent (struct bp_location *loc)
{
gdb_assert (loc != NULL);
/* If we have a non-breakpoint-backed catchpoint or a software
watchpoint, just return 0. We should not attempt to read from
the addresses the locations of these breakpoint types point to.
- program_breakpoint_here_p, below, will attempt to read
+ gdbarch_program_breakpoint_here_p, below, will attempt to read
memory. */
if (!bl_address_is_meaningful (loc))
- return 0;
+ return false;
scoped_restore_current_pspace_and_thread restore_pspace_thread;
switch_to_program_space_and_thread (loc->pspace);
- return program_breakpoint_here_p (loc->gdbarch, loc->address);
+ return gdbarch_program_breakpoint_here_p (loc->gdbarch, loc->address);
}
/* Build a command list for the dprintf corresponding to the current
return sals;
}
+/* Returns the breakpoint ops appropriate for use with with LOCATION_TYPE and
+ according to IS_TRACEPOINT. */
+
+static const struct breakpoint_ops *
+breakpoint_ops_for_event_location_type (enum event_location_type location_type,
+ bool is_tracepoint)
+{
+ if (is_tracepoint)
+ {
+ if (location_type == PROBE_LOCATION)
+ return &tracepoint_probe_breakpoint_ops;
+ else
+ return &tracepoint_breakpoint_ops;
+ }
+ else
+ {
+ if (location_type == PROBE_LOCATION)
+ return &bkpt_probe_breakpoint_ops;
+ else
+ return &bkpt_breakpoint_ops;
+ }
+}
+
+/* See breakpoint.h. */
+
+const struct breakpoint_ops *
+breakpoint_ops_for_event_location (const struct event_location *location,
+ bool is_tracepoint)
+{
+ if (location != nullptr)
+ return breakpoint_ops_for_event_location_type
+ (event_location_type (location), is_tracepoint);
+ return is_tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
+}
+
/* See breakpoint.h. */
int
enum bptype type_wanted = (flag & BP_HARDWAREFLAG
? bp_hardware_breakpoint
: bp_breakpoint);
- struct breakpoint_ops *ops;
event_location_up location = string_to_event_location (&arg, current_language);
-
- /* Matching breakpoints on probes. */
- if (location != NULL
- && event_location_type (location.get ()) == PROBE_LOCATION)
- ops = &bkpt_probe_breakpoint_ops;
- else
- ops = &bkpt_breakpoint_ops;
+ const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
+ (location.get (), false /* is_tracepoint */);
create_breakpoint (get_current_arch (),
location.get (),
print_recreate_masked_watchpoint (struct breakpoint *b, struct ui_file *fp)
{
struct watchpoint *w = (struct watchpoint *) b;
- char tmp[40];
switch (b->type)
{
_("Invalid hardware watchpoint type."));
}
- sprintf_vma (tmp, w->hw_wp_mask);
- fprintf_unfiltered (fp, " %s mask 0x%s", w->exp_string, tmp);
+ fprintf_unfiltered (fp, " %s mask 0x%s", w->exp_string,
+ phex (w->hw_wp_mask, sizeof (CORE_ADDR)));
print_recreate_thread (b, fp);
}
b->language = language_ada;
}
-static void
-catch_command (const char *arg, int from_tty)
-{
- error (_("Catch requires an event name."));
-}
\f
-static void
-tcatch_command (const char *arg, int from_tty)
-{
- error (_("Catch requires an event name."));
-}
-
/* Compare two breakpoints and return a strcmp-like result. */
static int
}
/* A comparison function for bp_location AP and BP being interfaced to
- qsort. Sort elements primarily by their ADDRESS (no matter what
+ std::sort. Sort elements primarily by their ADDRESS (no matter what
bl_address_is_meaningful says), secondarily by ordering first
permanent elements and terciarily just ensuring the array is sorted
- stable way despite qsort being an unstable algorithm. */
+ stable way despite std::sort being an unstable algorithm. */
static int
-bp_locations_compare (const void *ap, const void *bp)
+bp_location_is_less_than (const bp_location *a, const bp_location *b)
{
- const struct bp_location *a = *(const struct bp_location **) ap;
- const struct bp_location *b = *(const struct bp_location **) bp;
-
if (a->address != b->address)
- return (a->address > b->address) - (a->address < b->address);
+ return a->address < b->address;
/* Sort locations at the same address by their pspace number, keeping
locations of the same inferior (in a multi-inferior environment)
grouped. */
if (a->pspace->num != b->pspace->num)
- return ((a->pspace->num > b->pspace->num)
- - (a->pspace->num < b->pspace->num));
+ return a->pspace->num < b->pspace->num;
/* Sort permanent breakpoints first. */
if (a->permanent != b->permanent)
- return (a->permanent < b->permanent) - (a->permanent > b->permanent);
+ return a->permanent > b->permanent;
/* Make the internal GDB representation stable across GDB runs
where A and B memory inside GDB can differ. Breakpoint locations of
the same type at the same address can be sorted in arbitrary order. */
if (a->owner->number != b->owner->number)
- return ((a->owner->number > b->owner->number)
- - (a->owner->number < b->owner->number));
+ return a->owner->number < b->owner->number;
- return (a > b) - (a < b);
+ return a < b;
}
/* Set bp_locations_placed_address_before_address_max and
ALL_BREAKPOINTS (b)
for (loc = b->loc; loc; loc = loc->next)
*locp++ = loc;
- qsort (bp_locations, bp_locations_count, sizeof (*bp_locations),
- bp_locations_compare);
+ std::sort (bp_locations, bp_locations + bp_locations_count,
+ bp_location_is_less_than);
bp_locations_target_extensions_update ();
around. We simply always ignore hardware watchpoint
traps we can no longer explain. */
- old_loc->events_till_retirement = 3 * (thread_count () + 1);
+ process_stratum_target *proc_target = nullptr;
+ for (inferior *inf : all_inferiors ())
+ if (inf->pspace == old_loc->pspace)
+ {
+ proc_target = inf->process_target ();
+ break;
+ }
+ if (proc_target != nullptr)
+ old_loc->events_till_retirement
+ = 3 * (thread_count (proc_target) + 1);
+ else
+ old_loc->events_till_retirement = 1;
old_loc->owner = NULL;
moribund_locations.push_back (old_loc);
struct breakpoint_ops tracepoint_breakpoint_ops;
-/* The breakpoint_ops structure to be use on tracepoints placed in a
- static probe. */
+/* Virtual table for tracepoints on static probes. */
static void
tracepoint_probe_create_sals_from_location
return bkpt_probe_decode_location (b, location, search_pspace);
}
-static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
-
/* Dprintf breakpoint_ops methods. */
static void
uiout->text ("Now in ");
if (sym)
{
- uiout->field_string ("func", SYMBOL_PRINT_NAME (sym),
+ uiout->field_string ("func", sym->print_name (),
function_name_style.style ());
uiout->text (" at ");
}
});
}
\f
-static void
-set_breakpoint_cmd (const char *args, int from_tty)
-{
-}
-
-static void
-show_breakpoint_cmd (const char *args, int from_tty)
-{
-}
-
/* Invalidate last known value of any hardware watchpoint if
the memory which that value represents has been written to by
GDB itself. */
static void
trace_command (const char *arg, int from_tty)
{
- struct breakpoint_ops *ops;
-
event_location_up location = string_to_event_location (&arg,
current_language);
- if (location != NULL
- && event_location_type (location.get ()) == PROBE_LOCATION)
- ops = &tracepoint_probe_breakpoint_ops;
- else
- ops = &tracepoint_breakpoint_ops;
+ const struct breakpoint_ops *ops = breakpoint_ops_for_event_location
+ (location.get (), true /* is_tracepoint */);
create_breakpoint (get_current_arch (),
location.get (),
set_cmd_completer (command, completer);
}
-static void
-save_command (const char *arg, int from_tty)
-{
- printf_unfiltered (_("\"save\" must be followed by "
- "the name of a save subcommand.\n"));
- help_list (save_cmdlist, "save ", all_commands, gdb_stdout);
-}
-
struct breakpoint *
-iterate_over_breakpoints (int (*callback) (struct breakpoint *, void *),
- void *data)
+iterate_over_breakpoints (gdb::function_view<bool (breakpoint *)> callback)
{
struct breakpoint *b, *b_tmp;
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
- if ((*callback) (b, data))
+ if (callback (b))
return b;
}
cmd_list_element *commands_cmd_element = nullptr;
+void _initialize_breakpoint ();
void
-_initialize_breakpoint (void)
+_initialize_breakpoint ()
{
struct cmd_list_element *c;
breakpoint set."),
&maintenanceinfolist);
- add_prefix_cmd ("catch", class_breakpoint, catch_command, _("\
+ add_basic_prefix_cmd ("catch", class_breakpoint, _("\
Set catchpoints to catch events."),
- &catch_cmdlist, "catch ",
- 0/*allow-unknown*/, &cmdlist);
+ &catch_cmdlist, "catch ",
+ 0/*allow-unknown*/, &cmdlist);
- add_prefix_cmd ("tcatch", class_breakpoint, tcatch_command, _("\
+ add_basic_prefix_cmd ("tcatch", class_breakpoint, _("\
Set temporary catchpoints to catch events."),
- &tcatch_cmdlist, "tcatch ",
- 0/*allow-unknown*/, &cmdlist);
+ &tcatch_cmdlist, "tcatch ",
+ 0/*allow-unknown*/, &cmdlist);
add_catch_command ("fork", _("Catch calls to fork."),
catch_fork_command_1,
Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
if TPNUM is omitted, passcount refers to the last tracepoint defined."));
- add_prefix_cmd ("save", class_breakpoint, save_command,
- _("Save breakpoint definitions as a script."),
- &save_cmdlist, "save ",
- 0/*allow-unknown*/, &cmdlist);
+ add_basic_prefix_cmd ("save", class_breakpoint,
+ _("Save breakpoint definitions as a script."),
+ &save_cmdlist, "save ",
+ 0/*allow-unknown*/, &cmdlist);
c = add_cmd ("breakpoints", class_breakpoint, save_breakpoints_command, _("\
Save current breakpoint definitions as a script.\n\
c = add_com_alias ("save-tracepoints", "save tracepoints", class_trace, 0);
deprecate_cmd (c, "save tracepoints");
- add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, _("\
+ add_basic_prefix_cmd ("breakpoint", class_maintenance, _("\
Breakpoint specific settings.\n\
Configure various breakpoint-specific variables such as\n\
pending breakpoint behavior."),
- &breakpoint_set_cmdlist, "set breakpoint ",
- 0/*allow-unknown*/, &setlist);
- add_prefix_cmd ("breakpoint", class_maintenance, show_breakpoint_cmd, _("\
+ &breakpoint_set_cmdlist, "set breakpoint ",
+ 0/*allow-unknown*/, &setlist);
+ add_show_prefix_cmd ("breakpoint", class_maintenance, _("\
Breakpoint specific settings.\n\
Configure various breakpoint-specific variables such as\n\
pending breakpoint behavior."),
- &breakpoint_show_cmdlist, "show breakpoint ",
- 0/*allow-unknown*/, &showlist);
+ &breakpoint_show_cmdlist, "show breakpoint ",
+ 0/*allow-unknown*/, &showlist);
add_setshow_auto_boolean_cmd ("pending", no_class,
&pending_break_support, _("\