Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
15950 lines (13377 sloc) 457 KB
/* Everything about breakpoints, for GDB.
Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "arch-utils.h"
#include <ctype.h>
#include "hashtab.h"
#include "symtab.h"
#include "frame.h"
#include "breakpoint.h"
#include "tracepoint.h"
#include "gdbtypes.h"
#include "expression.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "value.h"
#include "command.h"
#include "inferior.h"
#include "infrun.h"
#include "gdbthread.h"
#include "target.h"
#include "language.h"
#include "gdb-demangle.h"
#include "filenames.h"
#include "annotate.h"
#include "symfile.h"
#include "objfiles.h"
#include "source.h"
#include "linespec.h"
#include "completer.h"
#include "ui-out.h"
#include "cli/cli-script.h"
#include "block.h"
#include "solib.h"
#include "solist.h"
#include "observable.h"
#include "memattr.h"
#include "ada-lang.h"
#include "top.h"
#include "valprint.h"
#include "jit.h"
#include "parser-defs.h"
#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 "gdbsupport/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"
#include "readline/history.h"
/* readline defines this. */
#undef savestring
#include "mi/mi-common.h"
#include "extension.h"
#include <algorithm>
#include "progspace-and-thread.h"
#include "gdbsupport/array-view.h"
#include "gdbsupport/gdb_optional.h"
/* Prototypes for local functions. */
static void map_breakpoint_numbers (const char *,
gdb::function_view<void (breakpoint *)>);
static void breakpoint_re_set_default (struct breakpoint *);
static void
create_sals_from_location_default (const struct event_location *location,
struct linespec_result *canonical,
enum bptype type_wanted);
static void create_breakpoints_sal_default (struct gdbarch *,
struct linespec_result *,
gdb::unique_xmalloc_ptr<char>,
gdb::unique_xmalloc_ptr<char>,
enum bptype,
enum bpdisp, int, int,
int,
const struct breakpoint_ops *,
int, int, int, unsigned);
static std::vector<symtab_and_line> decode_location_default
(struct breakpoint *b, const struct event_location *location,
struct program_space *search_pspace);
static int can_use_hardware_watchpoint
(const std::vector<value_ref_ptr> &vals);
static void mention (struct breakpoint *);
static struct breakpoint *set_raw_breakpoint_without_location (struct gdbarch *,
enum bptype,
const struct breakpoint_ops *);
static struct bp_location *add_location_to_breakpoint (struct breakpoint *,
const struct symtab_and_line *);
/* This function is used in gdbtk sources and thus can not be made
static. */
struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
struct symtab_and_line,
enum bptype,
const struct breakpoint_ops *);
static struct breakpoint *
momentary_breakpoint_from_master (struct breakpoint *orig,
enum bptype type,
const struct breakpoint_ops *ops,
int loc_enabled);
static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);
static CORE_ADDR adjust_breakpoint_address (struct gdbarch *gdbarch,
CORE_ADDR bpaddr,
enum bptype bptype);
static void describe_other_breakpoints (struct gdbarch *,
struct program_space *, CORE_ADDR,
struct obj_section *, int);
static int watchpoint_locations_match (struct bp_location *loc1,
struct bp_location *loc2);
static int breakpoint_location_address_match (struct bp_location *bl,
const struct address_space *aspace,
CORE_ADDR addr);
static int breakpoint_location_address_range_overlap (struct bp_location *,
const address_space *,
CORE_ADDR, int);
static int remove_breakpoint (struct bp_location *);
static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
static enum print_stop_action print_bp_stop_message (bpstat bs);
static int hw_breakpoint_used_count (void);
static int hw_watchpoint_use_count (struct breakpoint *);
static int hw_watchpoint_used_count_others (struct breakpoint *except,
enum bptype type,
int *other_type_used);
static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
int count);
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 struct bp_location *allocate_bp_location (struct breakpoint *bpt);
/* update_global_location_list's modes of operation wrt to whether to
insert locations now. */
enum ugll_insert_mode
{
/* Don't insert any breakpoint locations into the inferior, only
remove already-inserted locations that no longer should be
inserted. Functions that delete a breakpoint or breakpoints
should specify this mode, so that deleting a breakpoint doesn't
have the side effect of inserting the locations of other
breakpoints that are marked not-inserted, but should_be_inserted
returns true on them.
This behavior is useful is situations close to tear-down -- e.g.,
after an exec, while the target still has execution, but
breakpoint shadows of the previous executable image should *NOT*
be restored to the new image; or before detaching, where the
target still has execution and wants to delete breakpoints from
GDB's lists, and all breakpoints had already been removed from
the inferior. */
UGLL_DONT_INSERT,
/* May insert breakpoints iff breakpoints_should_be_inserted_now
claims breakpoints should be inserted now. */
UGLL_MAY_INSERT,
/* Insert locations now, irrespective of
breakpoints_should_be_inserted_now. E.g., say all threads are
stopped right now, and the user did "continue". We need to
insert breakpoints _before_ resuming the target, but
UGLL_MAY_INSERT wouldn't insert them, because
breakpoints_should_be_inserted_now returns false at that point,
as no thread is running yet. */
UGLL_INSERT
};
static void update_global_location_list (enum ugll_insert_mode);
static void update_global_location_list_nothrow (enum ugll_insert_mode);
static void insert_breakpoint_locations (void);
static void trace_pass_command (const char *, int);
static void set_tracepoint_count (int num);
static bool is_masked_watchpoint (const struct breakpoint *b);
static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address);
/* Return 1 if B refers to a static tracepoint set by marker ("-m"), zero
otherwise. */
static int strace_marker_p (struct breakpoint *b);
/* The breakpoint_ops structure to be inherited by all breakpoint_ops
that are implemented on top of software or hardware breakpoints
(user breakpoints, internal and momentary breakpoints, etc.). */
static struct breakpoint_ops bkpt_base_breakpoint_ops;
/* Internal breakpoints class type. */
static struct breakpoint_ops internal_breakpoint_ops;
/* Momentary breakpoints class type. */
static struct breakpoint_ops momentary_breakpoint_ops;
/* The breakpoint_ops structure to be used in regular user created
breakpoints. */
struct breakpoint_ops bkpt_breakpoint_ops;
/* Breakpoints set on probes. */
static struct breakpoint_ops bkpt_probe_breakpoint_ops;
/* Dynamic printf class type. */
struct breakpoint_ops dprintf_breakpoint_ops;
/* The style in which to perform a dynamic printf. This is a user
option because different output options have different tradeoffs;
if GDB does the printing, there is better error handling if there
is a problem with any of the arguments, but using an inferior
function lets you have special-purpose printers and sending of
output to the same place as compiled-in print functions. */
static const char dprintf_style_gdb[] = "gdb";
static const char dprintf_style_call[] = "call";
static const char dprintf_style_agent[] = "agent";
static const char *const dprintf_style_enums[] = {
dprintf_style_gdb,
dprintf_style_call,
dprintf_style_agent,
NULL
};
static const char *dprintf_style = dprintf_style_gdb;
/* The function to use for dynamic printf if the preferred style is to
call into the inferior. The value is simply a string that is
copied into the command, so it can be anything that GDB can
evaluate to a callable address, not necessarily a function name. */
static char *dprintf_function;
/* The channel to use for dynamic printf if the preferred style is to
call into the inferior; if a nonempty string, it will be passed to
the call as the first argument, with the format string as the
second. As with the dprintf function, this can be anything that
GDB knows how to evaluate, so in addition to common choices like
"stderr", this could be an app-specific expression like
"mystreams[curlogger]". */
static char *dprintf_channel;
/* True if dprintf commands should continue to operate even if GDB
has disconnected. */
static int disconnected_dprintf = 1;
struct command_line *
breakpoint_commands (struct breakpoint *b)
{
return b->commands ? b->commands.get () : NULL;
}
/* Flag indicating that a command has proceeded the inferior past the
current breakpoint. */
static int breakpoint_proceeded;
const char *
bpdisp_text (enum bpdisp disp)
{
/* NOTE: the following values are a part of MI protocol and
represent values of 'disp' field returned when inferior stops at
a breakpoint. */
static const char * const bpdisps[] = {"del", "dstp", "dis", "keep"};
return bpdisps[(int) disp];
}
/* Prototypes for exported functions. */
/* If FALSE, gdb will not use hardware support for watchpoints, even
if such is available. */
static int can_use_hw_watchpoints;
static void
show_can_use_hw_watchpoints (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *value)
{
fprintf_filtered (file,
_("Debugger's willingness to use "
"watchpoint hardware is %s.\n"),
value);
}
/* If AUTO_BOOLEAN_FALSE, gdb will not attempt to create pending breakpoints.
If AUTO_BOOLEAN_TRUE, gdb will automatically create pending breakpoints
for unrecognized breakpoint locations.
If AUTO_BOOLEAN_AUTO, gdb will query when breakpoints are unrecognized. */
static enum auto_boolean pending_break_support;
static void
show_pending_break_support (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *value)
{
fprintf_filtered (file,
_("Debugger's behavior regarding "
"pending breakpoints is %s.\n"),
value);
}
/* If 1, gdb will automatically use hardware breakpoints for breakpoints
set with "break" but falling in read-only memory.
If 0, gdb will warn about such breakpoints, but won't automatically
use hardware breakpoints. */
static int automatic_hardware_breakpoints;
static void
show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *value)
{
fprintf_filtered (file,
_("Automatic usage of hardware breakpoints is %s.\n"),
value);
}
/* If on, GDB keeps breakpoints inserted even if the inferior is
stopped, and immediately inserts any new breakpoints as soon as
they're created. If off (default), GDB keeps breakpoints off of
the target as long as possible. That is, it delays inserting
breakpoints until the next resume, and removes them again when the
target fully stops. This is a bit safer in case GDB crashes while
processing user input. */
static int always_inserted_mode = 0;
static void
show_always_inserted_mode (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"),
value);
}
/* See breakpoint.h. */
int
breakpoints_should_be_inserted_now (void)
{
if (gdbarch_has_global_breakpoints (target_gdbarch ()))
{
/* If breakpoints are global, they should be inserted even if no
thread under gdb's control is running, or even if there are
no threads under GDB's control yet. */
return 1;
}
else if (target_has_execution)
{
if (always_inserted_mode)
{
/* The user wants breakpoints inserted even if all threads
are stopped. */
return 1;
}
if (threads_are_executing ())
return 1;
/* Don't remove breakpoints yet if, even though all threads are
stopped, we still have events to process. */
for (thread_info *tp : all_non_exited_threads ())
if (tp->resumed
&& tp->suspend.waitstatus_pending_p)
return 1;
}
return 0;
}
static const char condition_evaluation_both[] = "host or target";
/* Modes for breakpoint condition evaluation. */
static const char condition_evaluation_auto[] = "auto";
static const char condition_evaluation_host[] = "host";
static const char condition_evaluation_target[] = "target";
static const char *const condition_evaluation_enums[] = {
condition_evaluation_auto,
condition_evaluation_host,
condition_evaluation_target,
NULL
};
/* Global that holds the current mode for breakpoint condition evaluation. */
static const char *condition_evaluation_mode_1 = condition_evaluation_auto;
/* Global that we use to display information to the user (gets its value from
condition_evaluation_mode_1. */
static const char *condition_evaluation_mode = condition_evaluation_auto;
/* Translate a condition evaluation mode MODE into either "host"
or "target". This is used mostly to translate from "auto" to the
real setting that is being used. It returns the translated
evaluation mode. */
static const char *
translate_condition_evaluation_mode (const char *mode)
{
if (mode == condition_evaluation_auto)
{
if (target_supports_evaluation_of_breakpoint_conditions ())
return condition_evaluation_target;
else
return condition_evaluation_host;
}
else
return mode;
}
/* Discovers what condition_evaluation_auto translates to. */
static const char *
breakpoint_condition_evaluation_mode (void)
{
return translate_condition_evaluation_mode (condition_evaluation_mode);
}
/* Return true if GDB should evaluate breakpoint conditions or false
otherwise. */
static int
gdb_evaluates_breakpoint_condition_p (void)
{
const char *mode = breakpoint_condition_evaluation_mode ();
return (mode == condition_evaluation_host);
}
/* Are we executing breakpoint commands? */
static int executing_breakpoint_commands;
/* Are overlay event breakpoints enabled? */
static int overlay_events_enabled;
/* See description in breakpoint.h. */
int target_exact_watchpoints = 0;
/* Walk the following statement or block through all breakpoints.
ALL_BREAKPOINTS_SAFE does so even if the statement deletes the
current breakpoint. */
#define ALL_BREAKPOINTS(B) for (B = breakpoint_chain; B; B = B->next)
#define ALL_BREAKPOINTS_SAFE(B,TMP) \
for (B = breakpoint_chain; \
B ? (TMP=B->next, 1): 0; \
B = TMP)
/* Similar iterator for the low-level breakpoints. SAFE variant is
not provided so update_global_location_list must not be called
while executing the block of ALL_BP_LOCATIONS. */
#define ALL_BP_LOCATIONS(B,BP_TMP) \
for (BP_TMP = bp_locations; \
BP_TMP < bp_locations + bp_locations_count && (B = *BP_TMP);\
BP_TMP++)
/* Iterates through locations with address ADDRESS for the currently selected
program space. BP_LOCP_TMP points to each object. BP_LOCP_START points
to where the loop should start from.
If BP_LOCP_START is a NULL pointer, the macro automatically seeks the
appropriate location to start with. */
#define ALL_BP_LOCATIONS_AT_ADDR(BP_LOCP_TMP, BP_LOCP_START, ADDRESS) \
for (BP_LOCP_START = BP_LOCP_START == NULL ? get_first_locp_gte_addr (ADDRESS) : BP_LOCP_START, \
BP_LOCP_TMP = BP_LOCP_START; \
BP_LOCP_START \
&& (BP_LOCP_TMP < bp_locations + bp_locations_count \
&& (*BP_LOCP_TMP)->address == ADDRESS); \
BP_LOCP_TMP++)
/* Iterator for tracepoints only. */
#define ALL_TRACEPOINTS(B) \
for (B = breakpoint_chain; B; B = B->next) \
if (is_tracepoint (B))
/* Chains of all breakpoints defined. */
struct breakpoint *breakpoint_chain;
/* Array is sorted by bp_locations_compare - primarily by the ADDRESS. */
static struct bp_location **bp_locations;
/* Number of elements of BP_LOCATIONS. */
static unsigned bp_locations_count;
/* Maximum alignment offset between bp_target_info.PLACED_ADDRESS and
ADDRESS for the current elements of BP_LOCATIONS which get a valid
result from bp_location_has_shadow. You can use it for roughly
limiting the subrange of BP_LOCATIONS to scan for shadow bytes for
an address you need to read. */
static CORE_ADDR bp_locations_placed_address_before_address_max;
/* Maximum offset plus alignment between bp_target_info.PLACED_ADDRESS
+ bp_target_info.SHADOW_LEN and ADDRESS for the current elements of
BP_LOCATIONS which get a valid result from bp_location_has_shadow.
You can use it for roughly limiting the subrange of BP_LOCATIONS to
scan for shadow bytes for an address you need to read. */
static CORE_ADDR bp_locations_shadow_len_after_address_max;
/* 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. */
static std::vector<bp_location *> moribund_locations;
/* Number of last breakpoint made. */
static int breakpoint_count;
/* The value of `breakpoint_count' before the last command that
created breakpoints. If the last (break-like) command created more
than one breakpoint, then the difference between BREAKPOINT_COUNT
and PREV_BREAKPOINT_COUNT is more than one. */
static int prev_breakpoint_count;
/* Number of last tracepoint made. */
static int tracepoint_count;
static struct cmd_list_element *breakpoint_set_cmdlist;
static struct cmd_list_element *breakpoint_show_cmdlist;
struct cmd_list_element *save_cmdlist;
/* See declaration at breakpoint.h. */
struct breakpoint *
breakpoint_find_if (int (*func) (struct breakpoint *b, void *d),
void *user_data)
{
struct breakpoint *b = NULL;
ALL_BREAKPOINTS (b)
{
if (func (b, user_data) != 0)
break;
}
return b;
}
/* Return whether a breakpoint is an active enabled breakpoint. */
static int
breakpoint_enabled (struct breakpoint *b)
{
return (b->enable_state == bp_enabled);
}
/* Set breakpoint count to NUM. */
static void
set_breakpoint_count (int num)
{
prev_breakpoint_count = breakpoint_count;
breakpoint_count = num;
set_internalvar_integer (lookup_internalvar ("bpnum"), num);
}
/* Used by `start_rbreak_breakpoints' below, to record the current
breakpoint count before "rbreak" creates any breakpoint. */
static int rbreak_start_breakpoint_count;
/* Called at the start an "rbreak" command to record the first
breakpoint made. */
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. */
scoped_rbreak_breakpoints::~scoped_rbreak_breakpoints ()
{
prev_breakpoint_count = rbreak_start_breakpoint_count;
}
/* Used in run_command to zero the hit count when a new run starts. */
void
clear_breakpoint_hit_counts (void)
{
struct breakpoint *b;
ALL_BREAKPOINTS (b)
b->hit_count = 0;
}
/* Return the breakpoint with the specified number, or NULL
if the number does not refer to an existing breakpoint. */
struct breakpoint *
get_breakpoint (int num)
{
struct breakpoint *b;
ALL_BREAKPOINTS (b)
if (b->number == num)
return b;
return NULL;
}
/* Mark locations as "conditions have changed" in case the target supports
evaluating conditions on its side. */
static void
mark_breakpoint_modified (struct breakpoint *b)
{
struct bp_location *loc;
/* This is only meaningful if the target is
evaluating conditions and if the user has
opted for condition evaluation on the target's
side. */
if (gdb_evaluates_breakpoint_condition_p ()
|| !target_supports_evaluation_of_breakpoint_conditions ())
return;
if (!is_breakpoint (b))
return;
for (loc = b->loc; loc; loc = loc->next)
loc->condition_changed = condition_modified;
}
/* Mark location as "conditions have changed" in case the target supports
evaluating conditions on its side. */
static void
mark_breakpoint_location_modified (struct bp_location *loc)
{
/* This is only meaningful if the target is
evaluating conditions and if the user has
opted for condition evaluation on the target's
side. */
if (gdb_evaluates_breakpoint_condition_p ()
|| !target_supports_evaluation_of_breakpoint_conditions ())
return;
if (!is_breakpoint (loc->owner))
return;
loc->condition_changed = condition_modified;
}
/* Sets the condition-evaluation mode using the static global
condition_evaluation_mode. */
static void
set_condition_evaluation_mode (const char *args, int from_tty,
struct cmd_list_element *c)
{
const char *old_mode, *new_mode;
if ((condition_evaluation_mode_1 == condition_evaluation_target)
&& !target_supports_evaluation_of_breakpoint_conditions ())
{
condition_evaluation_mode_1 = condition_evaluation_mode;
warning (_("Target does not support breakpoint condition evaluation.\n"
"Using host evaluation mode instead."));
return;
}
new_mode = translate_condition_evaluation_mode (condition_evaluation_mode_1);
old_mode = translate_condition_evaluation_mode (condition_evaluation_mode);
/* Flip the switch. Flip it even if OLD_MODE == NEW_MODE as one of the
settings was "auto". */
condition_evaluation_mode = condition_evaluation_mode_1;
/* Only update the mode if the user picked a different one. */
if (new_mode != old_mode)
{
struct bp_location *loc, **loc_tmp;
/* If the user switched to a different evaluation mode, we
need to synch the changes with the target as follows:
"host" -> "target": Send all (valid) conditions to the target.
"target" -> "host": Remove all the conditions from the target.
*/
if (new_mode == condition_evaluation_target)
{
/* Mark everything modified and synch conditions with the
target. */
ALL_BP_LOCATIONS (loc, loc_tmp)
mark_breakpoint_location_modified (loc);
}
else
{
/* Manually mark non-duplicate locations to synch conditions
with the target. We do this to remove all the conditions the
target knows about. */
ALL_BP_LOCATIONS (loc, loc_tmp)
if (is_breakpoint (loc->owner) && loc->inserted)
loc->needs_update = 1;
}
/* Do the update. */
update_global_location_list (UGLL_MAY_INSERT);
}
return;
}
/* Shows the current mode of breakpoint condition evaluation. Explicitly shows
what "auto" is translating to. */
static void
show_condition_evaluation_mode (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
if (condition_evaluation_mode == condition_evaluation_auto)
fprintf_filtered (file,
_("Breakpoint condition evaluation "
"mode is %s (currently %s).\n"),
value,
breakpoint_condition_evaluation_mode ());
else
fprintf_filtered (file, _("Breakpoint condition evaluation mode is %s.\n"),
value);
}
/* 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. */
static int
bp_locations_compare_addrs (const void *ap, const void *bp)
{
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 0;
else
return ((a->address > b->address) - (a->address < b->address));
}
/* Helper function to skip all bp_locations with addresses
less than ADDRESS. It returns the first bp_location that
is greater than or equal to ADDRESS. If none is found, just
return NULL. */
static struct bp_location **
get_first_locp_gte_addr (CORE_ADDR address)
{
struct bp_location dummy_loc;
struct bp_location *dummy_locp = &dummy_loc;
struct bp_location **locp_found = NULL;
/* Initialize the dummy location's address field. */
dummy_loc.address = address;
/* Find a close match to the first location at ADDRESS. */
locp_found = ((struct bp_location **)
bsearch (&dummy_locp, bp_locations, bp_locations_count,
sizeof (struct bp_location **),
bp_locations_compare_addrs));
/* Nothing was found, nothing left to do. */
if (locp_found == NULL)
return NULL;
/* We may have found a location that is at ADDRESS but is not the first in the
location's list. Go backwards (if possible) and locate the first one. */
while ((locp_found - 1) >= bp_locations
&& (*(locp_found - 1))->address == address)
locp_found--;
return locp_found;
}
void
set_breakpoint_condition (struct breakpoint *b, const char *exp,
int from_tty)
{
xfree (b->cond_string);
b->cond_string = NULL;
if (is_watchpoint (b))
{
struct watchpoint *w = (struct watchpoint *) b;
w->cond_exp.reset ();
}
else
{
struct bp_location *loc;
for (loc = b->loc; loc; loc = loc->next)
{
loc->cond.reset ();
/* No need to free the condition agent expression
bytecode (if we have one). We will handle this
when we go through update_global_location_list. */
}
}
if (*exp == 0)
{
if (from_tty)
printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number);
}
else
{
const char *arg = exp;
/* I don't know if it matters whether this is the string the user
typed in or the decompiled expression. */
b->cond_string = xstrdup (arg);
b->condition_not_parsed = 0;
if (is_watchpoint (b))
{
struct watchpoint *w = (struct watchpoint *) b;
innermost_block_tracker tracker;
arg = exp;
w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
if (*arg)
error (_("Junk at end of expression"));
w->cond_exp_valid_block = tracker.block ();
}
else
{
struct bp_location *loc;
for (loc = b->loc; loc; loc = loc->next)
{
arg = exp;
loc->cond =
parse_exp_1 (&arg, loc->address,
block_for_pc (loc->address), 0);
if (*arg)
error (_("Junk at end of expression"));
}
}
}
mark_breakpoint_modified (b);
gdb::observers::breakpoint_modified.notify (b);
}
/* Completion for the "condition" command. */
static void
condition_completer (struct cmd_list_element *cmd,
completion_tracker &tracker,
const char *text, const char *word)
{
const char *space;
text = skip_spaces (text);
space = skip_to_space (text);
if (*space == '\0')
{
int len;
struct breakpoint *b;
if (text[0] == '$')
{
/* We don't support completion of history indices. */
if (!isdigit (text[1]))
complete_internalvar (tracker, &text[1]);
return;
}
/* We're completing the breakpoint number. */
len = strlen (text);
ALL_BREAKPOINTS (b)
{
char number[50];
xsnprintf (number, sizeof (number), "%d", b->number);
if (strncmp (number, text, len) == 0)
tracker.add_completion (make_unique_xstrdup (number));
}
return;
}
/* We're completing the expression part. */
text = skip_spaces (space);
expression_completer (cmd, tracker, text, word);
}
/* condition N EXP -- set break condition of breakpoint N to EXP. */
static void
condition_command (const char *arg, int from_tty)
{
struct breakpoint *b;
const char *p;
int bnum;
if (arg == 0)
error_no_arg (_("breakpoint number"));
p = arg;
bnum = get_number (&p);
if (bnum == 0)
error (_("Bad breakpoint argument: '%s'"), arg);
ALL_BREAKPOINTS (b)
if (b->number == bnum)
{
/* Check if this breakpoint has a "stop" method implemented in an
extension language. This method and conditions entered into GDB
from the CLI are mutually exclusive. */
const struct extension_language_defn *extlang
= get_breakpoint_cond_ext_lang (b, EXT_LANG_NONE);
if (extlang != NULL)
{
error (_("Only one stop condition allowed. There is currently"
" a %s stop condition defined for this breakpoint."),
ext_lang_capitalized_name (extlang));
}
set_breakpoint_condition (b, p, from_tty);
if (is_breakpoint (b))
update_global_location_list (UGLL_MAY_INSERT);
return;
}
error (_("No breakpoint number %d."), bnum);
}
/* Check that COMMAND do not contain commands that are suitable
only for tracepoints and not suitable for ordinary breakpoints.
Throw if any such commands is found. */
static void
check_no_tracepoint_commands (struct command_line *commands)
{
struct command_line *c;
for (c = commands; c; c = c->next)
{
if (c->control_type == while_stepping_control)
error (_("The 'while-stepping' command can "
"only be used for tracepoints"));
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
command directly. */
if (strstr (c->line, "collect ") == c->line)
error (_("The 'collect' command can only be used for tracepoints"));
if (strstr (c->line, "teval ") == c->line)
error (_("The 'teval' command can only be used for tracepoints"));
}
}
struct longjmp_breakpoint : public breakpoint
{
~longjmp_breakpoint () override;
};
/* Encapsulate tests for different types of tracepoints. */
static bool
is_tracepoint_type (bptype type)
{
return (type == bp_tracepoint
|| type == bp_fast_tracepoint
|| type == bp_static_tracepoint);
}
static bool
is_longjmp_type (bptype type)
{
return type == bp_longjmp || type == bp_exception;
}
/* See breakpoint.h. */
bool
is_tracepoint (const struct breakpoint *b)
{
return is_tracepoint_type (b->type);
}
/* Factory function to create an appropriate instance of breakpoint given
TYPE. */
static std::unique_ptr<breakpoint>
new_breakpoint_from_type (bptype type)
{
breakpoint *b;
if (is_tracepoint_type (type))
b = new tracepoint ();
else if (is_longjmp_type (type))
b = new longjmp_breakpoint ();
else
b = new breakpoint ();
return std::unique_ptr<breakpoint> (b);
}
/* A helper function that validates that COMMANDS are valid for a
breakpoint. This function will throw an exception if a problem is
found. */
static void
validate_commands_for_breakpoint (struct breakpoint *b,
struct command_line *commands)
{
if (is_tracepoint (b))
{
struct tracepoint *t = (struct tracepoint *) b;
struct command_line *c;
struct command_line *while_stepping = 0;
/* Reset the while-stepping step count. The previous commands
might have included a while-stepping action, while the new
ones might not. */
t->step_count = 0;
/* We need to verify that each top-level element of commands is
valid for tracepoints, that there's at most one
while-stepping element, and that the while-stepping's body
has valid tracing commands excluding nested while-stepping.
We also need to validate the tracepoint action line in the
context of the tracepoint --- validate_actionline actually
has side effects, like setting the tracepoint's
while-stepping STEP_COUNT, in addition to checking if the
collect/teval actions parse and make sense in the
tracepoint's context. */
for (c = commands; c; c = c->next)
{
if (c->control_type == while_stepping_control)
{
if (b->type == bp_fast_tracepoint)
error (_("The 'while-stepping' command "
"cannot be used for fast tracepoint"));
else if (b->type == bp_static_tracepoint)
error (_("The 'while-stepping' command "
"cannot be used for static tracepoint"));
if (while_stepping)
error (_("The 'while-stepping' command "
"can be used only once"));
else
while_stepping = c;
}
validate_actionline (c->line, b);
}
if (while_stepping)
{
struct command_line *c2;
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)
error (_("The 'while-stepping' command cannot be nested"));
}
}
}
else
{
check_no_tracepoint_commands (commands);
}
}
/* Return a vector of all the static tracepoints set at ADDR. The
caller is responsible for releasing the vector. */
std::vector<breakpoint *>
static_tracepoints_here (CORE_ADDR addr)
{
struct breakpoint *b;
std::vector<breakpoint *> found;
struct bp_location *loc;
ALL_BREAKPOINTS (b)
if (b->type == bp_static_tracepoint)
{
for (loc = b->loc; loc; loc = loc->next)
if (loc->address == addr)
found.push_back (b);
}
return found;
}
/* Set the command list of B to COMMANDS. If breakpoint is tracepoint,
validate that only allowed commands are included. */
void
breakpoint_set_commands (struct breakpoint *b,
counted_command_line &&commands)
{
validate_commands_for_breakpoint (b, commands.get ());
b->commands = std::move (commands);
gdb::observers::breakpoint_modified.notify (b);
}
/* Set the internal `silent' flag on the breakpoint. Note that this
is not the same as the "silent" that may appear in the breakpoint's
commands. */
void
breakpoint_set_silent (struct breakpoint *b, int silent)
{
int old_silent = b->silent;
b->silent = silent;
if (old_silent != silent)
gdb::observers::breakpoint_modified.notify (b);
}
/* Set the thread for this breakpoint. If THREAD is -1, make the
breakpoint work for any thread. */
void
breakpoint_set_thread (struct breakpoint *b, int thread)
{
int old_thread = b->thread;
b->thread = thread;
if (old_thread != thread)
gdb::observers::breakpoint_modified.notify (b);
}
/* Set the task for this breakpoint. If TASK is 0, make the
breakpoint work for any task. */
void
breakpoint_set_task (struct breakpoint *b, int task)
{
int old_task = b->task;
b->task = task;
if (old_task != task)
gdb::observers::breakpoint_modified.notify (b);
}
static void
commands_command_1 (const char *arg, int from_tty,
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;
if (arg == NULL || !*arg)
{
if (breakpoint_count - prev_breakpoint_count > 1)
new_arg = string_printf ("%d-%d", prev_breakpoint_count + 1,
breakpoint_count);
else if (breakpoint_count > 0)
new_arg = string_printf ("%d", breakpoint_count);
arg = new_arg.c_str ();
}
map_breakpoint_numbers
(arg, [&] (breakpoint *b)
{
if (!cmd_read)
{
gdb_assert (cmd == NULL);
if (control != NULL)
cmd = control->body_list_0;
else
{
std::string str
= string_printf (_("Type commands for breakpoint(s) "
"%s, one per line."),
arg);
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
do anything. */
if (b->commands != cmd)
{
validate_commands_for_breakpoint (b, cmd.get ());
b->commands = cmd;
gdb::observers::breakpoint_modified.notify (b);
}
});
}
static void
commands_command (const char *arg, int from_tty)
{
commands_command_1 (arg, from_tty, NULL);
}
/* Like commands_command, but instead of reading the commands from
input stream, takes them from an already parsed command structure.
This is used by cli-script.c to DTRT with breakpoint commands
that are part of if and while bodies. */
enum command_control_type
commands_from_control_command (const char *arg, struct command_line *cmd)
{
commands_command_1 (arg, 0, cmd);
return simple_control;
}
/* Return non-zero if BL->TARGET_INFO contains valid information. */
static int
bp_location_has_shadow (struct bp_location *bl)
{
if (bl->loc_type != bp_loc_software_breakpoint)
return 0;
if (!bl->inserted)
return 0;
if (bl->target_info.shadow_len == 0)
/* BL isn't valid, or doesn't shadow memory. */
return 0;
return 1;
}
/* Update BUF, which is LEN bytes read from the target address
MEMADDR, by replacing a memory breakpoint with its shadowed
contents.
If READBUF is not NULL, this buffer must not overlap with the of
the breakpoint location's shadow_contents buffer. Otherwise, a
failed assertion internal error will be raised. */
static void
one_breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
const gdb_byte *writebuf_org,
ULONGEST memaddr, LONGEST len,
struct bp_target_info *target_info,
struct gdbarch *gdbarch)
{
/* Now do full processing of the found relevant range of elements. */
CORE_ADDR bp_addr = 0;
int bp_size = 0;
int bptoffset = 0;
if (!breakpoint_address_match (target_info->placed_address_space, 0,
current_program_space->aspace, 0))
{
/* The breakpoint is inserted in a different address space. */
return;
}
/* Addresses and length of the part of the breakpoint that
we need to copy. */
bp_addr = target_info->placed_address;
bp_size = target_info->shadow_len;
if (bp_addr + bp_size <= memaddr)
{
/* The breakpoint is entirely before the chunk of memory we are
reading. */
return;
}
if (bp_addr >= memaddr + len)
{
/* The breakpoint is entirely after the chunk of memory we are
reading. */
return;
}
/* Offset within shadow_contents. */
if (bp_addr < memaddr)
{
/* Only copy the second part of the breakpoint. */
bp_size -= memaddr - bp_addr;
bptoffset = memaddr - bp_addr;
bp_addr = memaddr;
}
if (bp_addr + bp_size > memaddr + len)
{
/* Only copy the first part of the breakpoint. */
bp_size -= (bp_addr + bp_size) - (memaddr + len);
}
if (readbuf != NULL)
{
/* Verify that the readbuf buffer does not overlap with the
shadow_contents buffer. */
gdb_assert (target_info->shadow_contents >= readbuf + len
|| readbuf >= (target_info->shadow_contents
+ target_info->shadow_len));
/* Update the read buffer with this inserted breakpoint's
shadow. */
memcpy (readbuf + bp_addr - memaddr,
target_info->shadow_contents + bptoffset, bp_size);
}
else
{
const unsigned char *bp;
CORE_ADDR addr = target_info->reqstd_address;
int placed_size;
/* Update the shadow with what we want to write to memory. */
memcpy (target_info->shadow_contents + bptoffset,
writebuf_org + bp_addr - memaddr, bp_size);
/* Determine appropriate breakpoint contents and size for this
address. */
bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &placed_size);
/* Update the final write buffer with this inserted
breakpoint's INSN. */
memcpy (writebuf + bp_addr - memaddr, bp + bptoffset, bp_size);
}
}
/* Update BUF, which is LEN bytes read from the target address MEMADDR,
by replacing any memory breakpoints with their shadowed contents.
If READBUF is not NULL, this buffer must not overlap with any of
the breakpoint location's shadow_contents buffers. Otherwise,
a failed assertion internal error will be raised.
The range of shadowed area by each bp_location is:
bl->address - bp_locations_placed_address_before_address_max
up to bl->address + bp_locations_shadow_len_after_address_max
The range we were requested to resolve shadows for is:
memaddr ... memaddr + len
Thus the safe cutoff boundaries for performance optimization are
memaddr + len <= (bl->address
- bp_locations_placed_address_before_address_max)
and:
bl->address + bp_locations_shadow_len_after_address_max <= memaddr */
void
breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
const gdb_byte *writebuf_org,
ULONGEST memaddr, LONGEST len)
{
/* Left boundary, right boundary and median element of our binary
search. */
unsigned bc_l, bc_r, bc;
/* Find BC_L which is a leftmost element which may affect BUF
content. It is safe to report lower value but a failure to
report higher one. */
bc_l = 0;
bc_r = bp_locations_count;
while (bc_l + 1 < bc_r)
{
struct bp_location *bl;
bc = (bc_l + bc_r) / 2;
bl = bp_locations[bc];
/* Check first BL->ADDRESS will not overflow due to the added
constant. Then advance the left boundary only if we are sure
the BC element can in no way affect the BUF content (MEMADDR
to MEMADDR + LEN range).
Use the BP_LOCATIONS_SHADOW_LEN_AFTER_ADDRESS_MAX safety
offset so that we cannot miss a breakpoint with its shadow
range tail still reaching MEMADDR. */
if ((bl->address + bp_locations_shadow_len_after_address_max
>= bl->address)
&& (bl->address + bp_locations_shadow_len_after_address_max
<= memaddr))
bc_l = bc;
else
bc_r = bc;
}
/* Due to the binary search above, we need to make sure we pick the
first location that's at BC_L's address. E.g., if there are
multiple locations at the same address, BC_L may end up pointing
at a duplicate location, and miss the "master"/"inserted"
location. Say, given locations L1, L2 and L3 at addresses A and
B:
L1@A, L2@A, L3@B, ...
BC_L could end up pointing at location L2, while the "master"
location could be L1. Since the `loc->inserted' flag is only set
on "master" locations, we'd forget to restore the shadow of L1
and L2. */
while (bc_l > 0
&& bp_locations[bc_l]->address == bp_locations[bc_l - 1]->address)
bc_l--;
/* Now do full processing of the found relevant range of elements. */
for (bc = bc_l; bc < bp_locations_count; bc++)
{
struct bp_location *bl = bp_locations[bc];
/* bp_location array has BL->OWNER always non-NULL. */
if (bl->owner->type == bp_none)
warning (_("reading through apparently deleted breakpoint #%d?"),
bl->owner->number);
/* Performance optimization: any further element can no longer affect BUF
content. */
if (bl->address >= bp_locations_placed_address_before_address_max
&& memaddr + len <= (bl->address
- bp_locations_placed_address_before_address_max))
break;
if (!bp_location_has_shadow (bl))
continue;
one_breakpoint_xfer_memory (readbuf, writebuf, writebuf_org,
memaddr, len, &bl->target_info, bl->gdbarch);
}
}
/* See breakpoint.h. */
bool
is_breakpoint (const struct breakpoint *bpt)
{
return (bpt->type == bp_breakpoint
|| bpt->type == bp_hardware_breakpoint
|| bpt->type == bp_dprintf);
}
/* Return true if BPT is of any hardware watchpoint kind. */
static bool
is_hardware_watchpoint (const struct breakpoint *bpt)
{
return (bpt->type == bp_hardware_watchpoint
|| bpt->type == bp_read_watchpoint
|| bpt->type == bp_access_watchpoint);
}
/* See breakpoint.h. */
bool
is_watchpoint (const struct breakpoint *bpt)
{
return (is_hardware_watchpoint (bpt)
|| bpt->type == bp_watchpoint);
}
/* Returns true if the current thread and its running state are safe
to evaluate or update watchpoint B. Watchpoints on local
expressions need to be evaluated in the context of the thread that
was current when the watchpoint was created, and, that thread needs
to be stopped to be able to select the correct frame context.
Watchpoints on global expressions can be evaluated on any thread,
and in any state. It is presently left to the target allowing
memory accesses when threads are running. */
static int
watchpoint_in_thread_scope (struct watchpoint *b)
{
return (b->pspace == current_program_space
&& (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
associated bp_watchpoint_scope breakpoint. */
static void
watchpoint_del_at_next_stop (struct watchpoint *w)
{
if (w->related_breakpoint != w)
{
gdb_assert (w->related_breakpoint->type == bp_watchpoint_scope);
gdb_assert (w->related_breakpoint->related_breakpoint == w);
w->related_breakpoint->disposition = disp_del_at_next_stop;
w->related_breakpoint->related_breakpoint = w->related_breakpoint;
w->related_breakpoint = w;
}
w->disposition = disp_del_at_next_stop;
}
/* Extract a bitfield value from value VAL using the bit parameters contained in
watchpoint W. */
static struct value *
extract_bitfield_from_watchpoint_value (struct watchpoint *w, struct value *val)
{
struct value *bit_val;
if (val == NULL)
return NULL;
bit_val = allocate_value (value_type (val));
unpack_value_bitfield (bit_val,
w->val_bitpos,
w->val_bitsize,
value_contents_for_printing (val),
value_offset (val),
val);
return bit_val;
}
/* Allocate a dummy location and add it to B, which must be a software
watchpoint. This is required because even if a software watchpoint
is not watching any memory, bpstat_stop_status requires a location
to be able to report stops. */
static void
software_watchpoint_add_no_memory_location (struct breakpoint *b,
struct program_space *pspace)
{
gdb_assert (b->type == bp_watchpoint && b->loc == NULL);
b->loc = allocate_bp_location (b);
b->loc->pspace = pspace;
b->loc->address = -1;
b->loc->length = -1;
}
/* Returns true if B is a software watchpoint that is not watching any
memory (e.g., "watch $pc"). */
static bool
is_no_memory_software_watchpoint (struct breakpoint *b)
{
return (b->type == bp_watchpoint
&& b->loc != NULL
&& b->loc->next == NULL
&& b->loc->address == -1
&& b->loc->length == -1);
}
/* Assuming that B is a watchpoint:
- Reparse watchpoint expression, if REPARSE is non-zero
- Evaluate expression and store the result in B->val
- Evaluate the condition if there is one, and store the result
in b->loc->cond.
- Update the list of values that must be watched in B->loc.
If the watchpoint disposition is disp_del_at_next_stop, then do
nothing. If this is local watchpoint that is out of scope, delete
it.
Even with `set breakpoint always-inserted on' the watchpoints are
removed + inserted on each stop here. Normal breakpoints must
never be removed because they might be missed by a running thread
when debugging in non-stop mode. On the other hand, hardware
watchpoints (is_hardware_watchpoint; processed here) are specific
to each LWP since they are stored in each LWP's hardware debug
registers. Therefore, such LWP must be stopped first in order to
be able to modify its hardware watchpoints.
Hardware watchpoints must be reset exactly once after being
presented to the user. It cannot be done sooner, because it would
reset the data used to present the watchpoint hit to the user. And
it must not be done later because it could display the same single
watchpoint hit during multiple GDB stops. Note that the latter is
relevant only to the hardware watchpoint types bp_read_watchpoint
and bp_access_watchpoint. False hit by bp_hardware_watchpoint is
not user-visible - its hit is suppressed if the memory content has
not changed.
The following constraints influence the location where we can reset
hardware watchpoints:
* target_stopped_by_watchpoint and target_stopped_data_address are
called several times when GDB stops.
[linux]
* Multiple hardware watchpoints can be hit at the same time,
causing GDB to stop. GDB only presents one hardware watchpoint
hit at a time as the reason for stopping, and all the other hits
are presented later, one after the other, each time the user
requests the execution to be resumed. Execution is not resumed
for the threads still having pending hit event stored in
LWP_INFO->STATUS. While the watchpoint is already removed from
the inferior on the first stop the thread hit event is kept being
reported from its cached value by linux_nat_stopped_data_address
until the real thread resume happens after the watchpoint gets
presented and thus its LWP_INFO->STATUS gets reset.
Therefore the hardware watchpoint hit can get safely reset on the
watchpoint removal from inferior. */
static void
update_watchpoint (struct watchpoint *b, int reparse)
{
int within_current_scope;
struct frame_id saved_frame_id;
int frame_saved;
/* If this is a local watchpoint, we only want to check if the
watchpoint frame is in scope if the current thread is the thread
that was used to create the watchpoint. */
if (!watchpoint_in_thread_scope (b))
return;
if (b->disposition == disp_del_at_next_stop)
return;
frame_saved = 0;
/* Determine if the watchpoint is within scope. */
if (b->exp_valid_block == NULL)
within_current_scope = 1;
else
{
struct frame_info *fi = get_current_frame ();
struct gdbarch *frame_arch = get_frame_arch (fi);
CORE_ADDR frame_pc = get_frame_pc (fi);
/* If we're at a point where the stack has been destroyed
(e.g. in a function epilogue), unwinding may not work
properly. Do not attempt to recreate locations at this
point. See similar comments in watchpoint_check. */
if (gdbarch_stack_frame_destroyed_p (frame_arch, frame_pc))
return;
/* Save the current frame's ID so we can restore it after
evaluating the watchpoint expression on its own frame. */
/* FIXME drow/2003-09-09: It would be nice if evaluate_expression
took a frame parameter, so that we didn't have to change the
selected frame. */
frame_saved = 1;
saved_frame_id = get_frame_id (get_selected_frame (NULL));
fi = frame_find_by_id (b->watchpoint_frame);
within_current_scope = (fi != NULL);
if (within_current_scope)
select_frame (fi);
}
/* We don't free locations. They are stored in the bp_location array
and update_global_location_list will eventually delete them and
remove breakpoints if needed. */
b->loc = NULL;
if (within_current_scope && reparse)
{
const char *s;
b->exp.reset ();
s = b->exp_string_reparse ? b->exp_string_reparse : b->exp_string;
b->exp = parse_exp_1 (&s, 0, b->exp_valid_block, 0);
/* If the meaning of expression itself changed, the old value is
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. */
b->val = NULL;
b->val_valid = 0;
/* Note that unlike with breakpoints, the watchpoint's condition
expression is stored in the breakpoint object, not in the
locations (re)created below. */
if (b->cond_string != NULL)
{
b->cond_exp.reset ();
s = b->cond_string;
b->cond_exp = parse_exp_1 (&s, 0, b->cond_exp_valid_block, 0);
}
}
/* If we failed to parse the expression, for example because
it refers to a global variable in a not-yet-loaded shared library,
don't try to insert watchpoint. We don't automatically delete
such watchpoint, though, since failure to parse expression
is different from out-of-scope watchpoint. */
if (!target_has_execution)
{
/* Without execution, memory can't change. No use to try and
set watchpoint locations. The watchpoint will be reset when
the target gains execution, through breakpoint_re_set. */
if (!can_use_hw_watchpoints)
{
if (b->ops->works_in_software_mode (b))
b->type = bp_watchpoint;
else
error (_("Can't set read/access watchpoint when "
"hardware watchpoints are disabled."));
}
}
else if (within_current_scope && b->exp)
{
int pc = 0;
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);
/* Avoid setting b->val if it's already set. The meaning of
b->val is 'the last value' user saw, and we should update
it only if we reported that last value to user. As it
happens, the code that reports it updates b->val directly.
We don't keep track of the memory value for masked
watchpoints. */
if (!b->val_valid && !is_masked_watchpoint (b))
{
if (b->val_bitsize != 0)
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. */
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[0] || ! value_lazy (v)))
{
struct type *vtype = check_typedef (value_type (v));
/* We only watch structs and arrays if user asked
for it explicitly, never if they just happen to
appear in the middle of some value chain. */
if (v == result
|| (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
&& TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
{
CORE_ADDR addr;
enum target_hw_bp_type type;
struct bp_location *loc, **tmp;
int bitpos = 0, bitsize = 0;
if (value_bitsize (v) != 0)
{
/* Extract the bit parameters out from the bitfield
sub-expression. */
bitpos = value_bitpos (v);
bitsize = value_bitsize (v);
}
else if (v == result && b->val_bitsize != 0)
{
/* If VAL_BITSIZE != 0 then RESULT is actually a bitfield
lvalue whose bit parameters are saved in the fields
VAL_BITPOS and VAL_BITSIZE. */
bitpos = b->val_bitpos;
bitsize = b->val_bitsize;
}
addr = value_address (v);
if (bitsize != 0)
{
/* Skip the bytes that don't contain the bitfield. */
addr += bitpos / 8;
}
type = hw_write;
if (b->type == bp_read_watchpoint)
type = hw_read;
else if (b->type == bp_access_watchpoint)
type = hw_access;
loc = allocate_bp_location (b);
for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
;
*tmp = loc;
loc->gdbarch = get_type_arch (value_type (v));
loc->pspace = frame_pspace;
loc->address = address_significant (loc->gdbarch, addr);
if (bitsize != 0)
{
/* Just cover the bytes that make up the bitfield. */
loc->length = ((bitpos % 8) + bitsize + 7) / 8;
}
else
loc->length = TYPE_LENGTH (value_type (v));
loc->watchpoint_type = type;
}
}
}
/* Change the type of breakpoint between hardware assisted or
an ordinary watchpoint depending on the hardware support
and free hardware slots. REPARSE is set when the inferior
is started. */
if (reparse)
{
int reg_cnt;
enum bp_loc_type loc_type;
struct bp_location *bl;
reg_cnt = can_use_hardware_watchpoint (val_chain);
if (reg_cnt)
{
int i, target_resources_ok, other_type_used;
enum bptype type;
/* Use an exact watchpoint when there's only one memory region to be
watched, and only one debug register is needed to watch it. */
b->exact = target_exact_watchpoints && reg_cnt == 1;
/* We need to determine how many resources are already
used for all other hardware watchpoints plus this one
to see if we still have enough resources to also fit
this watchpoint in as well. */
/* If this is a software watchpoint, we try to turn it
to a hardware one -- count resources as if B was of
hardware watchpoint type. */
type = b->type;
if (type == bp_watchpoint)
type = bp_hardware_watchpoint;
/* This watchpoint may or may not have been placed on
the list yet at this point (it won't be in the list
if we're trying to create it for the first time,
through watch_command), so always account for it
manually. */
/* Count resources used by all watchpoints except B. */
i = hw_watchpoint_used_count_others (b, type, &other_type_used);
/* Add in the resources needed for B. */
i += hw_watchpoint_use_count (b);
target_resources_ok
= target_can_use_hardware_watchpoint (type, i, other_type_used);
if (target_resources_ok <= 0)
{
int sw_mode = b->ops->works_in_software_mode (b);
if (target_resources_ok == 0 && !sw_mode)
error (_("Target does not support this type of "
"hardware watchpoint."));
else if (target_resources_ok < 0 && !sw_mode)
error (_("There are not enough available hardware "
"resources for this watchpoint."));
/* Downgrade to software watchpoint. */
b->type = bp_watchpoint;
}
else
{
/* If this was a software watchpoint, we've just
found we have enough resources to turn it to a
hardware watchpoint. Otherwise, this is a
nop. */
b->type = type;
}
}
else if (!b->ops->works_in_software_mode (b))
{
if (!can_use_hw_watchpoints)
error (_("Can't set read/access watchpoint when "
"hardware watchpoints are disabled."));
else
error (_("Expression cannot be implemented with "
"read/access watchpoint."));
}
else
b->type = bp_watchpoint;
loc_type = (b->type == bp_watchpoint? bp_loc_other
: bp_loc_hardware_watchpoint);
for (bl = b->loc; bl; bl = bl->next)
bl->loc_type = loc_type;
}
/* 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
stops, so make sure there's at least a dummy one. */
if (b->type == bp_watchpoint && b->loc == NULL)
software_watchpoint_add_no_memory_location (b, frame_pspace);
}
else if (!within_current_scope)
{
printf_filtered (_("\
Watchpoint %d deleted because the program has left the block\n\
in which its expression is valid.\n"),
b->number);
watchpoint_del_at_next_stop (b);
}
/* Restore the selected frame. */
if (frame_saved)
select_frame (frame_find_by_id (saved_frame_id));
}
/* Returns 1 iff breakpoint location should be
inserted in the inferior. We don't differentiate the type of BL's owner
(breakpoint vs. tracepoint), although insert_location in tracepoint's
breakpoint_ops is not defined, because in insert_bp_location,
tracepoint's insert_location will not be called. */
static int
should_be_inserted (struct bp_location *bl)
{
if (bl->owner == NULL || !breakpoint_enabled (bl->owner))
return 0;
if (bl->owner->disposition == disp_del_at_next_stop)
return 0;
if (!bl->enabled || bl->shlib_disabled || bl->duplicate)
return 0;
if (user_breakpoint_p (bl->owner) && bl->pspace->executing_startup)
return 0;
/* This is set for example, when we're attached to the parent of a
vfork, and have detached from the child. The child is running
free, and we expect it to do an exec or exit, at which point the
OS makes the parent schedulable again (and the target reports
that the vfork is done). Until the child is done with the shared
memory region, do not insert breakpoints in the parent, otherwise
the child could still trip on the parent's breakpoints. Since
the parent is blocked anyway, it won't miss any breakpoint. */
if (bl->pspace->breakpoints_not_allowed)
return 0;
/* Don't insert a breakpoint if we're trying to step past its
location, except if the breakpoint is a single-step breakpoint,
and the breakpoint's thread is the thread which is stepping past
a breakpoint. */
if ((bl->loc_type == bp_loc_software_breakpoint
|| bl->loc_type == bp_loc_hardware_breakpoint)
&& stepping_past_instruction_at (bl->pspace->aspace,
bl->address)
/* The single-step breakpoint may be inserted at the location
we're trying to step if the instruction branches to itself.
However, the instruction won't be executed at all and it may
break the semantics of the instruction, for example, the
instruction is a conditional branch or updates some flags.
We can't fix it unless GDB is able to emulate the instruction
or switch to displaced stepping. */
&& !(bl->owner->type == bp_single_step
&& thread_is_stepping_over_breakpoint (bl->owner->thread)))
{
if (debug_infrun)
{
fprintf_unfiltered (gdb_stdlog,
"infrun: skipping breakpoint: "
"stepping past insn at: %s\n",
paddress (bl->gdbarch, bl->address));
}
return 0;
}
/* Don't insert watchpoints if we're trying to step past the
instruction that triggered one. */
if ((bl->loc_type == bp_loc_hardware_watchpoint)
&& stepping_past_nonsteppable_watchpoint ())
{
if (debug_infrun)
{
fprintf_unfiltered (gdb_stdlog,
"infrun: stepping past non-steppable watchpoint. "
"skipping watchpoint at %s:%d\n",
paddress (bl->gdbarch, bl->address),
bl->length);
}
return 0;
}
return 1;
}
/* Same as should_be_inserted but does the check assuming
that the location is not duplicated. */
static int
unduplicated_should_be_inserted (struct bp_location *bl)
{
int result;
const int save_duplicate = bl->duplicate;
bl->duplicate = 0;
result = should_be_inserted (bl);
bl->duplicate = save_duplicate;
return result;
}
/* Parses a conditional described by an expression COND into an
agent expression bytecode suitable for evaluation
by the bytecode interpreter. Return NULL if there was
any error during parsing. */
static agent_expr_up
parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
{
if (cond == NULL)
return NULL;
agent_expr_up aexpr;
/* We don't want to stop processing, so catch any errors
that may show up. */
try
{
aexpr = gen_eval_for_expr (scope, cond);
}
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. */
}
/* We have a valid agent expression. */
return aexpr;
}
/* Based on location BL, create a list of breakpoint conditions to be
passed on to the target. If we have duplicated locations with different
conditions, we will add such conditions to the list. The idea is that the
target will evaluate the list of conditions and will only notify GDB when
one of them is true. */
static void
build_target_condition_list (struct bp_location *bl)
{
struct bp_location **locp = NULL, **loc2p;
int null_condition_or_parse_error = 0;
int modified = bl->needs_update;
struct bp_location *loc;
/* Release conditions left over from a previous insert. */
bl->target_info.conditions.clear ();
/* This is only meaningful if the target is
evaluating conditions and if the user has
opted for condition evaluation on the target's
side. */
if (gdb_evaluates_breakpoint_condition_p ()
|| !target_supports_evaluation_of_breakpoint_conditions ())
return;
/* Do a first pass to check for locations with no assigned
conditions or conditions that fail to parse to a valid agent expression
bytecode. If any of these happen, then it's no use to send conditions
to the target since this location will always trigger and generate a
response back to GDB. */
ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
{
loc = (*loc2p);
if (is_breakpoint (loc->owner) && loc->pspace->num == bl->pspace->num)
{
if (modified)
{
/* Re-parse the conditions since something changed. In that
case we already freed the condition bytecodes (see
force_breakpoint_reinsertion). We just
need to parse the condition to bytecodes again. */
loc->cond_bytecode = parse_cond_to_aexpr (bl->address,
loc->cond.get ());
}
/* If we have a NULL bytecode expression, it means something
went wrong or we have a null condition expression. */
if (!loc->cond_bytecode)
{
null_condition_or_parse_error = 1;
break;
}
}
}
/* If any of these happened, it means we will have to evaluate the conditions
for the location's address on gdb's side. It is no use keeping bytecodes
for all the other duplicate locations, thus we free all of them here.
This is so we have a finer control over which locations' conditions are
being evaluated by GDB or the remote stub. */
if (null_condition_or_parse_error)
{
ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
{
loc = (*loc2p);
if (is_breakpoint (loc->owner) && loc->pspace->num == bl->pspace->num)
{
/* Only go as far as the first NULL bytecode is
located. */
if (!loc->cond_bytecode)
return;
loc->cond_bytecode.reset ();
}
}
}
/* No NULL conditions or failed bytecode generation. Build a condition list
for this location's address. */
ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
{
loc = (*loc2p);
if (loc->cond
&& is_breakpoint (loc->owner)
&& loc->pspace->num == bl->pspace->num
&& loc->owner->enable_state == bp_enabled
&& loc->enabled)
{
/* Add the condition to the vector. This will be used later
to send the conditions to the target. */
bl->target_info.conditions.push_back (loc->cond_bytecode.get ());
}
}
return;
}
/* Parses a command described by string CMD into an agent expression
bytecode suitable for evaluation by the bytecode interpreter.
Return NULL if there was any error during parsing. */
static agent_expr_up
parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
{
const char *cmdrest;
const char *format_start, *format_end;
struct gdbarch *gdbarch = get_current_arch ();
if (cmd == NULL)
return NULL;
cmdrest = cmd;
if (*cmdrest == ',')
++cmdrest;
cmdrest = skip_spaces (cmdrest);
if (*cmdrest++ != '"')
error (_("No format string following the location"));
format_start = cmdrest;
format_pieces fpieces (&cmdrest);
format_end = cmdrest;
if (*cmdrest++ != '"')
error (_("Bad format string, non-terminated '\"'."));
cmdrest = skip_spaces (cmdrest);
if (!(*cmdrest == ',' || *cmdrest == '\0'))
error (_("Invalid argument syntax"));
if (*cmdrest == ',')
cmdrest++;
cmdrest = skip_spaces (cmdrest);
/* For each argument, make an expression. */
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.push_back (expr.release ());
cmdrest = cmd1;
if (*cmdrest == ',')
++cmdrest;
}
agent_expr_up aexpr;
/* We don't want to stop processing, so catch any errors
that may show up. */
try
{
aexpr = gen_printf (scope, gdbarch, 0, 0,
format_start, format_end - format_start,
argvec.size (), argvec.data ());
}
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. */
}
/* We have a valid agent expression, return it. */
return aexpr;
}
/* Based on location BL, create a list of breakpoint commands to be
passed on to the target. If we have duplicated locations with
different commands, we will add any such to the list. */
static void
build_target_command_list (struct bp_location *bl)
{
struct bp_location **locp = NULL, **loc2p;
int null_command_or_parse_error = 0;
int modified = bl->needs_update;
struct bp_location *loc;
/* Clear commands left over from a previous insert. */
bl->target_info.tcommands.clear ();
if (!target_can_run_breakpoint_commands ())
return;
/* For now, limit to agent-style dprintf breakpoints. */
if (dprintf_style != dprintf_style_agent)
return;
/* For now, if we have any duplicate location that isn't a dprintf,
don't install the target-side commands, as that would make the
breakpoint not be reported to the core, and we'd lose
control. */
ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
{
loc = (*loc2p);
if (is_breakpoint (loc->owner)
&& loc->pspace->num == bl->pspace->num
&& loc->owner->type != bp_dprintf)
return;
}
/* Do a first pass to check for locations with no assigned
conditions or conditions that fail to parse to a valid agent expression
bytecode. If any of these happen, then it's no use to send conditions
to the target since this location will always trigger and generate a
response back to GDB. */
ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
{
loc = (*loc2p);
if (is_breakpoint (loc->owner) && loc->pspace->num == bl->pspace->num)
{
if (modified)
{
/* Re-parse the commands since something changed. In that
case we already freed the command bytecodes (see
force_breakpoint_reinsertion). We just
need to parse the command to bytecodes again. */
loc->cmd_bytecode
= parse_cmd_to_aexpr (bl->address,
loc->owner->extra_string);
}
/* If we have a NULL bytecode expression, it means something
went wrong or we have a null command expression. */
if (!loc->cmd_bytecode)
{
null_command_or_parse_error = 1;
break;
}
}
}
/* If anything failed, then we're not doing target-side commands,
and so clean up. */
if (null_command_or_parse_error)
{
ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
{
loc = (*loc2p);
if (is_breakpoint (loc->owner)
&& loc->pspace->num == bl->pspace->num)
{
/* Only go as far as the first NULL bytecode is
located. */
if (loc->cmd_bytecode == NULL)
return;
loc->cmd_bytecode.reset ();
}
}
}
/* No NULL commands or failed bytecode generation. Build a command list
for this location's address. */
ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address)
{
loc = (*loc2p);
if (loc->owner->extra_string
&& is_breakpoint (loc->owner)
&& loc->pspace->num == bl->pspace->num
&& loc->owner->enable_state == bp_enabled
&& loc->enabled)
{
/* Add the command to the vector. This will be used later
to send the commands to the target. */
bl->target_info.tcommands.push_back (loc->cmd_bytecode.get ());
}
}
bl->target_info.persist = 0;
/* Maybe flag this location as persistent. */
if (bl->owner->type == bp_dprintf && disconnected_dprintf)
bl->target_info.persist = 1;
}
/* Return the kind of breakpoint on address *ADDR. Get the kind
of breakpoint according to ADDR except single-step breakpoint.
Get the kind of single-step breakpoint according to the current
registers state. */
static int
breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr)
{
if (bl->owner->type == bp_single_step)
{
struct thread_info *thr = find_thread_global_id (bl->owner->thread);
struct regcache *regcache;
regcache = get_thread_regcache (thr);
return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
regcache, addr);
}
else
return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr);
}
/* Insert a low-level "breakpoint" of some type. BL is the breakpoint
location. Any error messages are printed to TMP_ERROR_STREAM; and
DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems.
Returns 0 for success, 1 if the bp_location type is not supported or
-1 for failure.
NOTE drow/2003-09-09: This routine could be broken down to an
object-style method for each breakpoint or catchpoint type. */
static int
insert_bp_location (struct bp_location *bl,
struct ui_file *tmp_error_stream,
int *disabled_breaks,
int *hw_breakpoint_error,
int *hw_bp_error_explained_already)
{
gdb_exception bp_excpt;
if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
return 0;
/* Note we don't initialize bl->target_info, as that wipes out
the breakpoint location's shadow_contents if the breakpoint
is still inserted at that location. This in turn breaks
target_read_memory which depends on these buffers when
a memory read is requested at the breakpoint location:
Once the target_info has been wiped, we fail to see that
we have a breakpoint inserted at that address and thus
read the breakpoint instead of returning the data saved in
the breakpoint location's shadow contents. */
bl->target_info.reqstd_address = bl->address;
bl->target_info.placed_address_space = bl->pspace->aspace;
bl->target_info.length = bl->length;
/* When working with target-side conditions, we must pass all the conditions
for the same breakpoint address down to the target since GDB will not
insert those locations. With a list of breakpoint conditions, the target
can decide when to stop and notify GDB. */
if (is_breakpoint (bl->owner))
{
build_target_condition_list (bl);
build_target_command_list (bl);
/* Reset the modification marker. */
bl->needs_update = 0;
}
if (bl->loc_type == bp_loc_software_breakpoint
|| bl->loc_type == bp_loc_hardware_breakpoint)
{
if (bl->owner->type != bp_hardware_breakpoint)
{
/* If the explicitly specified breakpoint type
is not hardware breakpoint, check the memory map to see
if the breakpoint address is in read only memory or not.
Two important cases are:
- location type is not hardware breakpoint, memory
is readonly. We change the type of the location to
hardware breakpoint.
- location type is hardware breakpoint, memory is
read-write. This means we've previously made the
location hardware one, but then the memory map changed,
so we undo.
When breakpoints are removed, remove_breakpoints will use
location types we've just set here, the only possible
problem is that memory map has changed during running
program, but it's not going to work anyway with current
gdb. */
struct mem_region *mr
= lookup_mem_region (bl->target_info.reqstd_address);
if (mr)
{
if (automatic_hardware_breakpoints)
{
enum bp_loc_type new_type;
if (mr->attrib.mode != MEM_RW)
new_type = bp_loc_hardware_breakpoint;
else
new_type = bp_loc_software_breakpoint;
if (new_type != bl->loc_type)
{
static int said = 0;
bl->loc_type = new_type;
if (!said)
{
fprintf_filtered (gdb_stdout,
_("Note: automatically using "
"hardware breakpoints for "
"read-only addresses.\n"));
said = 1;
}
}
}
else if (bl->loc_type == bp_loc_software_breakpoint
&& mr->attrib.mode != MEM_RW)
{
fprintf_unfiltered (tmp_error_stream,
_("Cannot insert breakpoint %d.\n"
"Cannot set software breakpoint "
"at read-only address %s\n"),
bl->owner->number,
paddress (bl->gdbarch, bl->address));
return 1;
}
}
}
/* First check to see if we have to handle an overlay. */
if (overlay_debugging == ovly_off
|| bl->section == NULL
|| !(section_is_overlay (bl->section)))
{
/* No overlay handling: just set the breakpoint. */
try
{
int val;
val = bl->owner->ops->insert_location (bl);
if (val)
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
catch (gdb_exception &e)
{
bp_excpt = std::move (e);
}
}
else
{
/* This breakpoint is in an overlay section.
Shall we set a breakpoint at the LMA? */
if (!overlay_events_enabled)
{
/* Yes -- overlay event support is not active,
so we must try to set a breakpoint at the LMA.
This will not work for a hardware breakpoint. */
if (bl->loc_type == bp_loc_hardware_breakpoint)
warning (_("hardware breakpoint %d not supported in overlay!"),
bl->owner->number);
else
{
CORE_ADDR addr = overlay_unmapped_address (bl->address,
bl->section);
/* Set a software (trap) breakpoint at the LMA. */
bl->overlay_target_info = bl->target_info;
bl->overlay_target_info.reqstd_address = addr;
/* No overlay handling: just set the breakpoint. */
try
{
int val;
bl->overlay_target_info.kind
= breakpoint_kind (bl, &addr);
bl->overlay_target_info.placed_address = addr;
val = target_insert_breakpoint (bl->gdbarch,
&bl->overlay_target_info);
if (val)
bp_excpt
= gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
catch (gdb_exception &e)
{
bp_excpt = std::move (e);
}
if (bp_excpt.reason != 0)
fprintf_unfiltered (tmp_error_stream,
"Overlay breakpoint %d "
"failed: in ROM?\n",
bl->owner->number);
}
}
/* Shall we set a breakpoint at the VMA? */
if (section_is_mapped (bl->section))
{
/* Yes. This overlay section is mapped into memory. */
try
{
int val;
val = bl->owner->ops->insert_location (bl);
if (val)
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
catch (gdb_exception &e)
{
bp_excpt = std::move (e);
}
}
else
{
/* No. This breakpoint will not be inserted.
No error, but do not mark the bp as 'inserted'. */
return 0;
}
}
if (bp_excpt.reason != 0)
{
/* Can't set the breakpoint. */
/* In some cases, we might not be able to insert a
breakpoint in a shared library that has already been
removed, but we have not yet processed the shlib unload
event. Unfortunately, some targets that implement
breakpoint insertion themselves can't tell why the
breakpoint insertion failed (e.g., the remote target
doesn't define error codes), so we must treat generic
errors as memory errors. */
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,
bl->address)))
{
/* See also: disable_breakpoints_in_shlibs. */
bl->shlib_disabled = 1;
gdb::observers::breakpoint_modified.notify (bl->owner);
if (!*disabled_breaks)
{
fprintf_unfiltered (tmp_error_stream,
"Cannot insert breakpoint %d.\n",
bl->owner->number);
fprintf_unfiltered (tmp_error_stream,
"Temporarily disabling shared "
"library breakpoints:\n");
}
*disabled_breaks = 1;
fprintf_unfiltered (tmp_error_stream,
"breakpoint #%d\n", bl->owner->number);
return 0;
}
else
{
if (bl->loc_type == bp_loc_hardware_breakpoint)
{
*hw_breakpoint_error = 1;
*hw_bp_error_explained_already = bp_excpt.message != NULL;
fprintf_unfiltered (tmp_error_stream,
"Cannot insert hardware breakpoint %d%s",
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_excpt.message == NULL)
{
std::string message
= memory_error_message (TARGET_XFER_E_IO,
bl->gdbarch, bl->address);
fprintf_unfiltered (tmp_error_stream,
"Cannot insert breakpoint %d.\n"
"%s\n",
bl->owner->number, message.c_str ());
}
else
{
fprintf_unfiltered (tmp_error_stream,
"Cannot insert breakpoint %d: %s\n",
bl->owner->number,
bp_excpt.what ());
}
}
return 1;
}
}
else
bl->inserted = 1;
return 0;
}
else if (bl->loc_type == bp_loc_hardware_watchpoint
/* NOTE drow/2003-09-08: This state only exists for removing
watchpoints. It's not clear that it's necessary... */
&& bl->owner->disposition != disp_del_at_next_stop)
{
int val;
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->insert_location != NULL);
val = bl->owner->ops->insert_location (bl);
/* If trying to set a read-watchpoint, and it turns out it's not
supported, try emulating one with an access watchpoint. */
if (val == 1 && bl->watchpoint_type == hw_read)
{
struct bp_location *loc, **loc_temp;
/* But don't try to insert it, if there's already another
hw_access location that would be considered a duplicate
of this one. */
ALL_BP_LOCATIONS (loc, loc_temp)
if (loc != bl
&& loc->watchpoint_type == hw_access
&& watchpoint_locations_match (bl, loc))
{
bl->duplicate = 1;
bl->inserted = 1;
bl->target_info = loc->target_info;
bl->watchpoint_type = hw_access;
val = 0;
break;
}
if (val == 1)
{
bl->watchpoint_type = hw_access;
val = bl->owner->ops->insert_location (bl);
if (val)
/* Back to the original value. */
bl->watchpoint_type = hw_read;
}
}
bl->inserted = (val == 0);
}
else if (bl->owner->type == bp_catchpoint)
{
int val;
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->insert_location != NULL);
val = bl->owner->ops->insert_location (bl);
if (val)
{
bl->owner->enable_state = bp_disabled;
if (val == 1)
warning (_("\
Error inserting catchpoint %d: Your system does not support this type\n\
of catchpoint."), bl->owner->number);
else
warning (_("Error inserting catchpoint %d."), bl->owner->number);
}
bl->inserted = (val == 0);
/* We've already printed an error message if there was a problem
inserting this catchpoint, and we've disabled the catchpoint,
so just return success. */
return 0;
}
return 0;
}
/* This function is called when program space PSPACE is about to be
deleted. It takes care of updating breakpoints to not reference
PSPACE anymore. */
void
breakpoint_program_space_exit (struct program_space *pspace)
{
struct breakpoint *b, *b_temp;
struct bp_location *loc, **loc_temp;
/* Remove any breakpoint that was set through this program space. */
ALL_BREAKPOINTS_SAFE (b, b_temp)
{
if (b->pspace == pspace)
delete_breakpoint (b);
}
/* Breakpoints set through other program spaces could have locations
bound to PSPACE as well. Remove those. */
ALL_BP_LOCATIONS (loc, loc_temp)
{
struct bp_location *tmp;
if (loc->pspace == pspace)
{
/* ALL_BP_LOCATIONS bp_location has LOC->OWNER always non-NULL. */
if (loc->owner->loc == loc)
loc->owner->loc = loc->next;
else
for (tmp = loc->owner->loc; tmp->next != NULL; tmp = tmp->next)
if (tmp->next == loc)
{
tmp->next = loc->next;
break;
}
}
}
/* Now update the global location list to permanently delete the
removed locations above. */
update_global_location_list (UGLL_DONT_INSERT);
}
/* Make sure all breakpoints are inserted in inferior.
Throws exception on any error.
A breakpoint that is already inserted won't be inserted
again, so calling this function twice is safe. */
void
insert_breakpoints (void)
{
struct breakpoint *bpt;
ALL_BREAKPOINTS (bpt)
if (is_hardware_watchpoint (bpt))
{
struct watchpoint *w = (struct watchpoint *) bpt;
update_watchpoint (w, 0 /* don't reparse. */);
}
/* Updating watchpoints creates new locations, so update the global
location list. Explicitly tell ugll to insert locations and
ignore breakpoints_always_inserted_mode. */
update_global_location_list (UGLL_INSERT);
}
/* Invoke CALLBACK for each of bp_location. */
void
iterate_over_bp_locations (walk_bp_location_callback callback)
{
struct bp_location *loc, **loc_tmp;
ALL_BP_LOCATIONS (loc, loc_tmp)
{
callback (loc, NULL);
}
}
/* This is used when we need to synch breakpoint conditions between GDB and the
target. It is the case with deleting and disabling of breakpoints when using
always-inserted mode. */
static void
update_inserted_breakpoint_locations (void)
{
struct bp_location *bl, **blp_tmp;
int error_flag = 0;
int val = 0;
int disabled_breaks = 0;
int hw_breakpoint_error = 0;
int hw_bp_details_reported = 0;
string_file tmp_error_stream;
/* Explicitly mark the warning -- this will only be printed if
there was an error. */
tmp_error_stream.puts ("Warning:\n");
scoped_restore_current_pspace_and_thread restore_pspace_thread;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
/* We only want to update software breakpoints and hardware
breakpoints. */
if (!is_breakpoint (bl->owner))
continue;
/* 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->needs_update)
continue;
switch_to_program_space_and_thread (bl->pspace);
/* For targets that support global breakpoints, there's no need
to select an inferior to insert breakpoint to. In fact, even
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)
continue;
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
&hw_breakpoint_error, &hw_bp_details_reported);
if (val)
error_flag = val;
}
if (error_flag)
{
target_terminal::ours_for_output ();
error_stream (tmp_error_stream);
}
}
/* Used when starting or continuing the program. */
static void
insert_breakpoint_locations (void)
{
struct breakpoint *bpt;
struct bp_location *bl, **blp_tmp;
int error_flag = 0;
int val = 0;
int disabled_breaks = 0;
int hw_breakpoint_error = 0;
int hw_bp_error_explained_already = 0;
string_file tmp_error_stream;
/* Explicitly mark the warning -- this will only be printed if
there was an error. */
tmp_error_stream.puts ("Warning:\n");
scoped_restore_current_pspace_and_thread restore_pspace_thread;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
continue;
/* There is no point inserting thread-specific breakpoints if
the thread no longer exists. ALL_BP_LOCATIONS bp_location
has BL->OWNER always non-NULL. */
if (bl->owner->thread != -1
&& !valid_global_thread_id (bl->owner->thread))
continue;
switch_to_program_space_and_thread (bl->pspace);
/* For targets that support global breakpoints, there's no need
to select an inferior to insert breakpoint to. In fact, even
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)
continue;
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
&hw_breakpoint_error, &hw_bp_error_explained_already);
if (val)
error_flag = val;
}
/* If we failed to insert all locations of a watchpoint, remove
them, as half-inserted watchpoint is of limited use. */
ALL_BREAKPOINTS (bpt)
{
int some_failed = 0;
struct bp_location *loc;
if (!is_hardware_watchpoint (bpt))
continue;
if (!breakpoint_enabled (bpt))
continue;
if (bpt->disposition == disp_del_at_next_stop)
continue;
for (loc = bpt->loc; loc; loc = loc->next)
if (!loc->inserted && should_be_inserted (loc))
{
some_failed = 1;
break;
}
if (some_failed)
{
for (loc = bpt->loc; loc; loc = loc->next)
if (loc->inserted)
remove_breakpoint (loc);
hw_breakpoint_error = 1;
tmp_error_stream.printf ("Could not insert "
"hardware watchpoint %d.\n",
bpt->number);
error_flag = -1;
}
}
if (error_flag)
{
/* If a hardware breakpoint or watchpoint was inserted, add a
message about possibly exhausted resources. */
if (hw_breakpoint_error && !hw_bp_error_explained_already)
{
tmp_error_stream.printf ("Could not insert hardware breakpoints:\n\
You may have requested too many hardware breakpoints/watchpoints.\n");
}
target_terminal::ours_for_output ();
error_stream (tmp_error_stream);
}
}
/* Used when the program stops.
Returns zero if successful, or non-zero if there was a problem
removing a breakpoint location. */
int
remove_breakpoints (void)
{
struct bp_location *bl, **blp_tmp;
int val = 0;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->inserted && !is_tracepoint (bl->owner))
val |= remove_breakpoint (bl);
}
return val;
}
/* When a thread exits, remove breakpoints that are related to
that thread. */
static void
remove_threaded_breakpoints (struct thread_info *tp, int silent)
{
struct breakpoint *b, *b_tmp;
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
if (b->thread == tp->global_num && user_breakpoint_p (b))
{
b->disposition = disp_del_at_next_stop;
printf_filtered (_("\
Thread-specific breakpoint %d deleted - thread %s no longer in the thread list.\n"),
b->number, print_thread_id (tp));
/* Hide it from the user. */
b->number = 0;
}
}
}
/* See breakpoint.h. */
void
remove_breakpoints_inf (inferior *inf)
{
struct bp_location *bl, **blp_tmp;
int val;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->pspace != inf->pspace)
continue;
if (bl->inserted && !bl->target_info.persist)
{
val = remove_breakpoint (bl);
if (val != 0)
return;
}
}
}
static int internal_breakpoint_number = -1;
/* Set the breakpoint number of B, depending on the value of INTERNAL.
If INTERNAL is non-zero, the breakpoint number will be populated
from internal_breakpoint_number and that variable decremented.
Otherwise the breakpoint number will be populated from
breakpoint_count and that value incremented. Internal breakpoints
do not set the internal var bpnum. */
static void
set_breakpoint_number (int internal, struct breakpoint *b)
{
if (internal)
b->number = internal_breakpoint_number--;
else
{
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
}
}
static struct breakpoint *
create_internal_breakpoint (struct gdbarch *gdbarch,
CORE_ADDR address, enum bptype type,
const struct breakpoint_ops *ops)
{
symtab_and_line sal;
sal.pc = address;
sal.section = find_pc_overlay (sal.pc);
sal.pspace = current_program_space;
breakpoint *b = set_raw_breakpoint (gdbarch, sal, type, ops);
b->number = internal_breakpoint_number--;
b->disposition = disp_donttouch;
return b;
}
static const char *const longjmp_names[] =
{
"longjmp", "_longjmp", "siglongjmp", "_siglongjmp"
};
#define NUM_LONGJMP_NAMES ARRAY_SIZE(longjmp_names)
/* Per-objfile data private to breakpoint.c. */
struct breakpoint_objfile_data
{
/* Minimal symbol for "_ovly_debug_event" (if any). */
struct bound_minimal_symbol overlay_msym {};
/* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */
struct bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES] {};
/* True if we have looked for longjmp probes. */
int longjmp_searched = 0;
/* 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 {};
/* Minimal symbol for "_Unwind_DebugHook" (if any). */
struct bound_minimal_symbol exception_msym {};
/* True if we have looked for exception probes. */
int exception_searched = 0;
/* SystemTap probe points for unwinding (if any). These are non-owning
references. */
std::vector<probe *> exception_probes;
};
static const struct objfile_key<breakpoint_objfile_data>
breakpoint_objfile_key;
/* Minimal symbol not found sentinel. */
static struct minimal_symbol msym_not_found;
/* Returns TRUE if MSYM point to the "not found" sentinel. */
static int
msym_not_found_p (const struct minimal_symbol *msym)
{
return msym == &msym_not_found;
}
/* Return per-objfile data needed by breakpoint.c.
Allocate the data if necessary. */
static struct breakpoint_objfile_data *
get_breakpoint_objfile_data (struct objfile *objfile)
{
struct breakpoint_objfile_data *bp_objfile_data;
bp_objfile_data = breakpoint_objfile_key.get (objfile);
if (bp_objfile_data == NULL)
bp_objfile_data = breakpoint_objfile_key.emplace (objfile);
return bp_objfile_data;
}
static void
create_overlay_event_breakpoint (void)
{
const char *const func_name = "_ovly_debug_event";
for (objfile *objfile : current_program_space->objfiles ())
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
if (msym_not_found_p (bp_objfile_data->overlay_msym.minsym))
continue;
if (bp_objfile_data->overlay_msym.minsym == NULL)
{
struct bound_minimal_symbol m;
m = lookup_minimal_symbol_text (func_name, objfile);
if (m.minsym == NULL)
{
/* Avoid future lookups in this objfile. */
bp_objfile_data->overlay_msym.minsym = &msym_not_found;
continue;
}
bp_objfile_data->overlay_msym = m;
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym);
b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
bp_overlay_event,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
explicit_loc.function_name = ASTRDUP (func_name);
b->location = new_explicit_location (&explicit_loc);
if (overlay_debugging == ovly_auto)
{
b->enable_state = bp_enabled;
overlay_events_enabled = 1;
}
else
{
b->enable_state = bp_disabled;
overlay_events_enabled = 0;
}
}
}
static void
create_longjmp_master_breakpoint (void)
{
struct program_space *pspace;
scoped_restore_current_program_space restore_pspace;
ALL_PSPACES (pspace)
{
set_current_program_space (pspace);
for (objfile *objfile : current_program_space->objfiles ())
{
int i;
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
gdbarch = get_objfile_arch (objfile);
bp_objfile_data = get_breakpoint_objfile_data (objfile);
if (!bp_objfile_data->longjmp_searched)
{
std::vector<probe *> ret
= find_probes_in_objfile (objfile, "libc", "longjmp");
if (!ret.empty ())
{
/* We are only interested in checking one element. */
probe *p = ret[0];
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 (!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;
}
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;
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;
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;
}
}
}
}
/* Create a master std::terminate breakpoint. */
static void
create_std_terminate_master_breakpoint (void)
{
struct program_space *pspace;
const char *const func_name = "std::terminate()";
scoped_restore_current_program_space restore_pspace;
ALL_PSPACES (pspace)
{
CORE_ADDR addr;
set_current_program_space (pspace);
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);
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;
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;
}
}
}
/* Install a master breakpoint on the unwinder's debug hook. */
static void
create_exception_master_breakpoint (void)
{
const char *const func_name = "_Unwind_DebugHook";
for (objfile *objfile : current_program_space->objfiles ())
{
struct breakpoint *b;
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
/* We prefer the SystemTap probe point if it exists. */
if (!bp_objfile_data->exception_searched)
{
std::vector<probe *> ret
= find_probes_in_objfile (objfile, "libgcc", "unwind");
if (!ret.empty ())
{
/* We are only interested in checking one element. */
probe *p = ret[0];
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->exception_probes = ret;
bp_objfile_data->exception_searched = 1;
}
if (!bp_objfile_data->exception_probes.empty ())
{
gdbarch = get_objfile_arch (objfile);
for (probe *p : bp_objfile_data->exception_probes)
{
b = create_internal_breakpoint (gdbarch,
p->get_relocated_address (objfile),
bp_exception_master,
&internal_breakpoint_ops);
b->location = new_probe_location ("-probe-stap libgcc:unwind");
b->enable_state = bp_disabled;
}
continue;
}
/* Otherwise, try the hook function. */
if (msym_not_found_p (bp_objfile_data->exception_msym.minsym))
continue;
gdbarch = get_objfile_arch (objfile);
if (bp_objfile_data->exception_msym.minsym == NULL)
{
struct bound_minimal_symbol debug_hook;
debug_hook = lookup_minimal_symbol (func_name, NULL, objfile);
if (debug_hook.minsym == NULL)
{
bp_objfile_data->exception_msym.minsym = &msym_not_found;
continue;
}
bp_objfile_data->exception_msym = debug_hook;
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
current_top_target ());
b = create_internal_breakpoint (gdbarch, addr, bp_exception_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;
}
}
/* Does B have a location spec? */
static int
breakpoint_event_location_empty_p (const struct breakpoint *b)
{
return b->location != NULL && event_location_empty_p (b->location.get ());
}
void
update_breakpoints_after_exec (void)
{
struct breakpoint *b, *b_tmp;
struct bp_location *bploc, **bplocp_tmp;
/* We're about to delete breakpoints from GDB's lists. If the
INSERTED flag is true, GDB will try to lift the breakpoints by
writing the breakpoints' "shadow contents" back into memory. The
"shadow contents" are NOT valid after an exec, so GDB should not
do that. Instead, the target is responsible from marking
breakpoints out as soon as it detects an exec. We don't do that
here instead, because there may be other attempts to delete
breakpoints after detecting an exec and before reaching here. */
ALL_BP_LOCATIONS (bploc, bplocp_tmp)
if (bploc->pspace == current_program_space)
gdb_assert (!bploc->inserted);
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
if (b->pspace != current_program_space)
continue;
/* Solib breakpoints must be explicitly reset after an exec(). */
if (b->type == bp_shlib_event)
{
delete_breakpoint (b);
continue;
}
/* JIT breakpoints must be explicitly reset after an exec(). */
if (b->type == bp_jit_event)
{
delete_breakpoint (b);
continue;
}
/* Thread event breakpoints must be set anew after an exec(),
as must overlay event and longjmp master breakpoints. */
if (b->type == bp_thread_event || b->type == bp_overlay_event
|| b->type == bp_longjmp_master || b->type == bp_std_terminate_master
|| b->type == bp_exception_master)
{
delete_breakpoint (b);
continue;
}
/* Step-resume breakpoints are meaningless after an exec(). */
if (b->type == bp_step_resume || b->type == bp_hp_step_resume)
{
delete_breakpoint (b);
continue;
}
/* Just like single-step breakpoints. */
if (b->type == bp_single_step)
{
delete_breakpoint (b);
continue;
}
/* Longjmp and longjmp-resume breakpoints are also meaningless
after an exec. */
if (b->type == bp_longjmp || b->type == bp_longjmp_resume
|| b->type == bp_longjmp_call_dummy
|| b->type == bp_exception || b->type == bp_exception_resume)
{
delete_breakpoint (b);
continue;
}
if (b->type == bp_catchpoint)
{
/* For now, none of the bp_catchpoint breakpoints need to
do anything at this point. In the future, if some of
the catchpoints need to something, we will need to add
a new method, and call this method from here. */
continue;
}
/* bp_finish is a special case. The only way we ought to be able
to see one of these when an exec() has happened, is if the user
caught a vfork, and then said "finish". Ordinarily a finish just
carries them to the call-site of the current callee, by setting
a temporary bp there and resuming. But in this case, the finish
will carry them entirely through the vfork & exec.
We don't want to allow a bp_finish to remain inserted now. But
we can't safely delete it, 'cause finish_command has a handle to
the bp on a bpstat, and will later want to delete it. There's a
chance (and I've seen it happen) that if we delete the bp_finish
here, that its storage will get reused by the time finish_command
gets 'round to deleting the "use to be a bp_finish" breakpoint.
We really must allow finish_command to delete a bp_finish.
In the absence of a general solution for the "how do we know
it's safe to delete something others may have handles to?"
problem, what we'll do here is just uninsert the bp_finish, and
let finish_command delete it.
(We know the bp_finish is "doomed" in the sense that it's
momentary, and will be deleted as soon as finish_command sees
the inferior stopped. So it doesn't matter that the bp's
address is probably bogus in the new a.out, unlike e.g., the
solib breakpoints.) */
if (b->type == bp_finish)
{
continue;
}
/* Without a symbolic address, we have little hope of the
pre-exec() address meaning the same thing in the post-exec()
a.out. */
if (breakpoint_event_location_empty_p (b))
{
delete_breakpoint (b);
continue;
}
}
}
int
detach_breakpoints (ptid_t ptid)
{
struct bp_location *bl, **blp_tmp;
int val = 0;
scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
struct inferior *inf = current_inferior ();
if (ptid.pid () == inferior_ptid.pid ())
error (_("Cannot detach breakpoints of inferior_ptid"));
/* Set inferior_ptid; remove_breakpoint_1 uses this global. */
inferior_ptid = ptid;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->pspace != inf->pspace)
continue;
/* This function must physically remove breakpoints locations
from the specified ptid, without modifying the breakpoint
package's state. Locations of type bp_loc_other are only
maintained at GDB side. So, there is no need to remove
these bp_loc_other locations. Moreover, removing these
would modify the breakpoint package's state. */
if (bl->loc_type == bp_loc_other)
continue;
if (bl->inserted)
val |= remove_breakpoint_1 (bl, DETACH_BREAKPOINT);
}
return val;
}
/* Remove the breakpoint location BL from the current address space.
Note that this is used to detach breakpoints from a child fork.
When we get here, the child isn't in the inferior list, and neither
do we have objects to represent its address space --- we should
*not* look at bl->pspace->aspace here. */
static int
remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
{
int val;
/* BL is never in moribund_locations by our callers. */
gdb_assert (bl->owner != NULL);
/* The type of none suggests that owner is actually deleted.
This should not ever happen. */
gdb_assert (bl->owner->type != bp_none);
if (bl->loc_type == bp_loc_software_breakpoint
|| bl->loc_type == bp_loc_hardware_breakpoint)
{
/* "Normal" instruction breakpoint: either the standard
trap-instruction bp (bp_breakpoint), or a
bp_hardware_breakpoint. */
/* First check to see if we have to handle an overlay. */
if (overlay_debugging == ovly_off
|| bl->section == NULL
|| !(section_is_overlay (bl->section)))
{
/* No overlay handling: just remove the breakpoint. */
/* If we're trying to uninsert a memory breakpoint that we
know is set in a dynamic object that is marked
shlib_disabled, then either the dynamic object was
removed with "remove-symbol-file" or with
"nosharedlibrary". In the former case, we don't know
whether another dynamic object might have loaded over the
breakpoint's address -- the user might well let us know
about it next with add-symbol-file (the whole point of
add-symbol-file is letting the user manually maintain a
list of dynamically loaded objects). If we have the
breakpoint's shadow memory, that is, this is a software
breakpoint managed by GDB, check whether the breakpoint
is still inserted in memory, to avoid overwriting wrong
code with stale saved shadow contents. Note that HW
breakpoints don't have shadow memory, as they're
implemented using a mechanism that is not dependent on
being able to modify the target's memory, and as such
they should always be removed. */
if (bl->shlib_disabled
&& bl->target_info.shadow_len != 0
&& !memory_validate_breakpoint (bl->gdbarch, &bl->target_info))
val = 0;
else
val = bl->owner->ops->remove_location (bl, reason);
}
else
{
/* This breakpoint is in an overlay section.
Did we set a breakpoint at the LMA? */
if (!overlay_events_enabled)
{
/* Yes -- overlay event support is not active, so we
should have set a breakpoint at the LMA. Remove it.
*/
/* Ignore any failures: if the LMA is in ROM, we will
have already warned when we failed to insert it. */
if (bl->loc_type == bp_loc_hardware_breakpoint)
target_remove_hw_breakpoint (bl->gdbarch,
&bl->overlay_target_info);
else
target_remove_breakpoint (bl->gdbarch,
&bl->overlay_target_info,
reason);
}
/* Did we set a breakpoint at the VMA?
If so, we will have marked the breakpoint 'inserted'. */
if (bl->inserted)
{
/* Yes -- remove it. Previously we did not bother to
remove the breakpoint if the section had been
unmapped, but let's not rely on that being safe. We
don't know what the overlay manager might do. */
/* However, we should remove *software* breakpoints only
if the section is still mapped, or else we overwrite
wrong code with the saved shadow contents. */
if (bl->loc_type == bp_loc_hardware_breakpoint
|| section_is_mapped (bl->section))
val = bl->owner->ops->remove_location (bl, reason);
else
val = 0;
}
else
{
/* No -- not inserted, so no need to remove. No error. */
val = 0;
}
}
/* In some cases, we might not be able to remove a breakpoint in
a shared library that has already been removed, but we have
not yet processed the shlib unload event. Similarly for an
unloaded add-symbol-file object - the user might not yet have
had the chance to remove-symbol-file it. shlib_disabled will
be set if the library/object has already been removed, but
the breakpoint hasn't been uninserted yet, e.g., after
"nosharedlibrary" or "remove-symbol-file" with breakpoints
always-inserted mode. */
if (val
&& (bl->loc_type == bp_loc_software_breakpoint
&& (bl->shlib_disabled
|| solib_name_from_address (bl->pspace, bl->address)
|| shared_objfile_contains_address_p (bl->pspace,
bl->address))))
val = 0;
if (val)
return val;
bl->inserted = (reason == DETACH_BREAKPOINT);
}
else if (bl->loc_type == bp_loc_hardware_watchpoint)
{
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->remove_location != NULL);
bl->inserted = (reason == DETACH_BREAKPOINT);
bl->owner->ops->remove_location (bl, reason);
/* Failure to remove any of the hardware watchpoints comes here. */
if (reason == REMOVE_BREAKPOINT && bl->inserted)
warning (_("Could not remove hardware watchpoint %d."),
bl->owner->number);
}
else if (bl->owner->type == bp_catchpoint
&& breakpoint_enabled (bl->owner)
&& !bl->duplicate)
{
gdb_assert (bl->owner->ops != NULL
&& bl->owner->ops->remove_location != NULL);
val = bl->owner->ops->remove_location (bl, reason);
if (val)
return val;
bl->inserted = (reason == DETACH_BREAKPOINT);
}
return 0;
}
static int
remove_breakpoint (struct bp_location *bl)
{
/* BL is never in moribund_locations by our callers. */
gdb_assert (bl->owner != NULL);
/* The type of none suggests that owner is actually deleted.
This should not ever happen. */
gdb_assert (bl->owner->type != bp_none);
scoped_restore_current_pspace_and_thread restore_pspace_thread;
switch_to_program_space_and_thread (bl->pspace);
return remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
}
/* Clear the "inserted" flag in all breakpoints. */
void
mark_breakpoints_out (void)
{
struct bp_location *bl, **blp_tmp;
ALL_BP_LOCATIONS (bl, blp_tmp)
if (bl->pspace == current_program_space)
bl->inserted = 0;
}
/* Clear the "inserted" flag in all breakpoints and delete any
breakpoints which should go away between runs of the program.
Plus other such housekeeping that has to be done for breakpoints
between runs.
Note: this function gets called at the end of a run (by
generic_mourn_inferior) and when a run begins (by
init_wait_for_inferior). */
void
breakpoint_init_inferior (enum inf_context context)
{
struct breakpoint *b, *b_tmp;
struct program_space *pspace = current_program_space;
/* If breakpoint locations are shared across processes, then there's
nothing to do. */
if (gdbarch_has_global_breakpoints (target_gdbarch ()))
return;
mark_breakpoints_out ();
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
if (b->loc && b->loc->pspace != pspace)
continue;
switch (b->type)
{
case bp_call_dummy:
case bp_longjmp_call_dummy:
/* If the call dummy breakpoint is at the entry point it will
cause problems when the inferior is rerun, so we better get
rid of it. */
case bp_watchpoint_scope:
/* Also get rid of scope breakpoints. */
case bp_shlib_event:
/* Also remove solib event breakpoints. Their addresses may
have changed since the last time we ran the program.
Actually we may now be debugging against different target;
and so the solib backend that installed this breakpoint may
not be used in by the target. E.g.,
(gdb) file prog-linux
(gdb) run # native linux target
...
(gdb) kill
(gdb) file prog-win.exe
(gdb) tar rem :9999 # remote Windows gdbserver.
*/
case bp_step_resume:
/* Also remove step-resume breakpoints. */
case bp_single_step:
/* Also remove single-step breakpoints. */
delete_breakpoint (b);
break;
case bp_watchpoint:
case bp_hardware_watchpoint:
case bp_read_watchpoint:
case bp_access_watchpoint:
{
struct watchpoint *w = (struct watchpoint *) b;
/* Likewise for watchpoints on local expressions. */
if (w->exp_valid_block != NULL)
delete_breakpoint (b);
else
{
/* Get rid of existing locations, which are no longer
valid. New ones will be created in
update_watchpoint, when the inferior is restarted.
The next update_global_location_list call will
garbage collect them. */
b->loc = NULL;
if (context == inf_starting)
{
/* Reset val field to force reread of starting value in
insert_breakpoints. */
w->val.reset (nullptr);
w->val_valid = 0;
}
}
}
break;
default:
break;
}
}
/* Get rid of the moribund locations. */
for (bp_location *bl : moribund_locations)
decref_bp_location (&bl);
moribund_locations.clear ();
}
/* These functions concern about actual breakpoints inserted in the
target --- to e.g. check if we need to do decr_pc adjustment or if
we need to hop over the bkpt --- so we check for address space
match, not program space. */
/* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint
exists at PC. It returns ordinary_breakpoint_here if it's an
ordinary breakpoint, or permanent_breakpoint_here if it's a
permanent breakpoint.
- When continuing from a location with an ordinary breakpoint, we
actually single step once before calling insert_breakpoints.
- When continuing from a location with a permanent breakpoint, we
need to use the `SKIP_PERMANENT_BREAKPOINT' macro, provided by
the target, to advance the PC past the breakpoint. */
enum breakpoint_here
breakpoint_here_p (const address_space *aspace, CORE_ADDR pc)
{
struct bp_location *bl, **blp_tmp;
int any_breakpoint_here = 0;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->loc_type != bp_loc_software_breakpoint
&& bl->loc_type != bp_loc_hardware_breakpoint)
continue;
/* ALL_BP_LOCATIONS bp_location has BL->OWNER always non-NULL. */
if ((breakpoint_enabled (bl->owner)
|| bl->permanent)
&& breakpoint_location_address_match (bl, aspace, pc))
{
if (overlay_debugging
&& section_is_overlay (bl->section)
&& !section_is_mapped (bl->section))
continue; /* unmapped overlay -- can't be a match */
else if (bl->permanent)
return permanent_breakpoint_here;
else
any_breakpoint_here = 1;
}
}
return any_breakpoint_here ? ordinary_breakpoint_here : no_breakpoint_here;
}
/* See breakpoint.h. */
int
breakpoint_in_range_p (const address_space *aspace,
CORE_ADDR addr, ULONGEST len)
{
struct bp_location *bl, **blp_tmp;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->loc_type != bp_loc_software_breakpoint
&& bl->loc_type != bp_loc_hardware_breakpoint)
continue;
if ((breakpoint_enabled (bl->owner)
|| bl->permanent)
&& breakpoint_location_address_range_overlap (bl, aspace,
addr, len))
{
if (overlay_debugging
&& section_is_overlay (bl->section)
&& !section_is_mapped (bl->section))
{
/* Unmapped overlay -- can't be a match. */
continue;
}
return 1;
}