/* 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,
watchpoint_value_print (struct value *val, struct ui_file *stream)
{
if (val == NULL)
- fprintf_unfiltered (stream, _("<unreadable>"));
+ fprintf_styled (stream, metadata_style.style (), _("<unreadable>"));
else
{
struct value_print_options opts;
if (uiout->is_mi_like_p ())
uiout->field_string
("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
- uiout->text ("\nWatchpoint ");
- uiout->field_signed ("wpnum", b->number);
- uiout->text (" deleted because the program has left the block in\n"
- "which its expression is valid.\n");
+ uiout->message ("\nWatchpoint %pF deleted because the program has "
+ "left the block in\n"
+ "which its expression is valid.\n",
+ signed_field ("wpnum", b->number));
}
/* Make sure the watchpoint's commands aren't executed. */
if (sym)
{
uiout->text ("in ");
- uiout->field_string ("func", SYMBOL_PRINT_NAME (sym),
- ui_out_style_kind::FUNCTION);
+ uiout->field_string ("func", sym->print_name (),
+ function_name_style.style ());
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),
- ui_out_style_kind::FILE);
+ file_name_style.style ());
uiout->text (":");
if (uiout->is_mi_like_p ())
{
annotate_field (4);
if (header_of_multiple)
- uiout->field_string ("addr", "<MULTIPLE>");
+ uiout->field_string ("addr", "<MULTIPLE>",
+ metadata_style.style ());
else if (b->loc == NULL || loc->shlib_disabled)
- uiout->field_string ("addr", "<PENDING>");
+ uiout->field_string ("addr", "<PENDING>",
+ metadata_style.style ());
else
uiout->field_core_addr ("addr",
loc->gdbarch, loc->address);
&& breakpoint_condition_evaluation_mode ()
== condition_evaluation_target)
{
- uiout->text (" (");
- uiout->field_string ("evaluated-by",
- bp_condition_evaluator (b));
- uiout->text (" evals)");
+ uiout->message (" (%pF evals)",
+ string_field ("evaluated-by",
+ bp_condition_evaluator (b)));
}
uiout->text ("\n");
}
if (!part_of_multiple && b->ignore_count)
{
annotate_field (8);
- uiout->text ("\tignore next ");
- uiout->field_signed ("ignore", b->ignore_count);
- uiout->text (" hits\n");
+ uiout->message ("\tignore next %pF hits\n",
+ signed_field ("ignore", b->ignore_count));
}
/* Note that an enable count of 1 corresponds to "enable once"
(others > 1) ? ","
: ((others == 1) ? " and" : ""));
}
- printf_filtered (_("also set at pc "));
- fputs_styled (paddress (gdbarch, pc), address_style.style (), gdb_stdout);
- printf_filtered (".\n");
+ current_uiout->message (_("also set at pc %ps.\n"),
+ styled_string (address_style.style (),
+ paddress (gdbarch, pc)));
}
}
\f
{
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)
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 (),
}
/* 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);
else
{
if (opts.addressprint || b->loc->symtab == NULL)
- {
- printf_filtered (" at ");
- fputs_styled (paddress (b->loc->gdbarch, b->loc->address),
- address_style.style (),
- gdb_stdout);
- }
+ printf_filtered (" at %ps",
+ styled_string (address_style.style (),
+ paddress (b->loc->gdbarch,
+ b->loc->address)));
if (b->loc->symtab != NULL)
{
/* If there is a single location, we can print the location
more nicely. */
if (b->loc->next == NULL)
{
- puts_filtered (": file ");
- fputs_styled (symtab_to_filename_for_display (b->loc->symtab),
- file_name_style.style (),
- gdb_stdout);
- printf_filtered (", line %d.",
+ const char *filename
+ = symtab_to_filename_for_display (b->loc->symtab);
+ printf_filtered (": file %ps, line %d.",
+ styled_string (file_name_style.style (),
+ filename),
b->loc->line_number);
}
else
annotate_breakpoint (b->number);
maybe_print_thread_hit_breakpoint (uiout);
- if (bp_temp)
- uiout->text ("Temporary breakpoint ");
- else
- uiout->text ("Breakpoint ");
if (uiout->is_mi_like_p ())
{
uiout->field_string ("reason",
async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
uiout->field_string ("disp", bpdisp_text (b->disposition));
}
- uiout->field_signed ("bkptno", b->number);
- uiout->text (", ");
+ if (bp_temp)
+ uiout->message ("Temporary breakpoint %pF, ",
+ signed_field ("bkptno", b->number));
+ else
+ uiout->message ("Breakpoint %pF, ",
+ signed_field ("bkptno", b->number));
return PRINT_SRC_AND_LOC;
}
{
gdb_assert (self->type == bp_static_tracepoint);
- uiout->text ("\tmarker id is ");
- uiout->field_string ("static-tracepoint-marker-string-id",
- tp->static_trace_marker_id);
- uiout->text ("\n");
+ uiout->message ("\tmarker id is %pF\n",
+ string_field ("static-tracepoint-marker-string-id",
+ tp->static_trace_marker_id.c_str ()));
}
}
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),
- ui_out_style_kind::FUNCTION);
+ uiout->field_string ("func", sym->print_name (),
+ function_name_style.style ());
uiout->text (" at ");
}
uiout->field_string ("file",
symtab_to_filename_for_display (sal2.symtab),
- ui_out_style_kind::FILE);
+ file_name_style.style ());
uiout->text (":");
if (uiout->is_mi_like_p ())
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 (),
}
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;
}