blob: 78fffd34e9eb7233b75c67c29831444210b5617c [file] [log] [blame]
/* Everything about breakpoints, for GDB.
Copyright (C) 1986-2012 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 "gdbthread.h"
#include "target.h"
#include "language.h"
#include "gdb_string.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 "gdb.h"
#include "ui-out.h"
#include "cli/cli-script.h"
#include "gdb_assert.h"
#include "block.h"
#include "solib.h"
#include "solist.h"
#include "observer.h"
#include "exceptions.h"
#include "memattr.h"
#include "ada-lang.h"
#include "top.h"
#include "valprint.h"
#include "jit.h"
#include "xml-syscall.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 "gdb_regex.h"
#include "ax-gdb.h"
#include "dummy-frame.h"
#include "format.h"
/* readline include files */
#include "readline/readline.h"
#include "readline/history.h"
/* readline defines this. */
#undef savestring
#include "mi/mi-common.h"
#include "python/python.h"
/* Prototypes for local functions. */
static void enable_delete_command (char *, int);
static void enable_once_command (char *, int);
static void enable_count_command (char *, int);
static void disable_command (char *, int);
static void enable_command (char *, int);
static void map_breakpoint_numbers (char *, void (*) (struct breakpoint *,
void *),
void *);
static void ignore_command (char *, int);
static int breakpoint_re_set_one (void *);
static void breakpoint_re_set_default (struct breakpoint *);
static void create_sals_from_address_default (char **,
struct linespec_result *,
enum bptype, char *,
char **);
static void create_breakpoints_sal_default (struct gdbarch *,
struct linespec_result *,
struct linespec_sals *,
char *, char *, enum bptype,
enum bpdisp, int, int,
int,
const struct breakpoint_ops *,
int, int, int, unsigned);
static void decode_linespec_default (struct breakpoint *, char **,
struct symtabs_and_lines *);
static void clear_command (char *, int);
static void catch_command (char *, int);
static int can_use_hardware_watchpoint (struct value *);
static void break_command_1 (char *, int, int);
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);
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 breakpoint_address_match (struct address_space *aspace1,
CORE_ADDR addr1,
struct address_space *aspace2,
CORE_ADDR addr2);
static int watchpoint_locations_match (struct bp_location *loc1,
struct bp_location *loc2);
static int breakpoint_location_address_match (struct bp_location *bl,
struct address_space *aspace,
CORE_ADDR addr);
static void breakpoints_info (char *, int);
static void watchpoints_info (char *, int);
static int breakpoint_1 (char *, int,
int (*) (const struct breakpoint *));
static int breakpoint_cond_eval (void *);
static void cleanup_executing_breakpoints (void *);
static void commands_command (char *, int);
static void condition_command (char *, int);
typedef enum
{
mark_inserted,
mark_uninserted
}
insertion_state_t;
static int remove_breakpoint (struct bp_location *, insertion_state_t);
static int remove_breakpoint_1 (struct bp_location *, insertion_state_t);
static enum print_stop_action print_bp_stop_message (bpstat bs);
static int watchpoint_check (void *);
static void maintenance_info_breakpoints (char *, int);
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 hbreak_command (char *, int);
static void thbreak_command (char *, int);
static void enable_breakpoint_disp (struct breakpoint *, enum bpdisp,
int count);
static void stop_command (char *arg, int from_tty);
static void stopin_command (char *arg, int from_tty);
static void stopat_command (char *arg, int from_tty);
static char *ep_parse_optional_if_clause (char **arg);
static void catch_exception_command_1 (enum exception_event_kind ex_event,
char *arg, int tempflag, int from_tty);
static void tcatch_command (char *arg, int from_tty);
static void detach_single_step_breakpoints (void);
static int single_step_breakpoint_inserted_here_p (struct address_space *,
CORE_ADDR pc);
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);
static void update_global_location_list (int);
static void update_global_location_list_nothrow (int);
static int is_hardware_watchpoint (const struct breakpoint *bpt);
static void insert_breakpoint_locations (void);
static int syscall_catchpoint_p (struct breakpoint *b);
static void tracepoints_info (char *, int);
static void delete_trace_command (char *, int);
static void enable_trace_command (char *, int);
static void disable_trace_command (char *, int);
static void trace_pass_command (char *, int);
static int 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);
static void init_catchpoint (struct breakpoint *b,
struct gdbarch *gdbarch, int tempflag,
char *cond_string,
const struct breakpoint_ops *ops);
/* The abstract base class all breakpoint_ops structures inherit
from. */
static struct breakpoint_ops base_breakpoint_ops;
/* 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;
/* Momentary breakpoints for bp_longjmp and bp_exception class type. */
static struct breakpoint_ops longjmp_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. */
static 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;
/* A reference-counted struct command_line. This lets multiple
breakpoints share a single command list. */
struct counted_command_line
{
/* The reference count. */
int refc;
/* The command list. */
struct command_line *commands;
};
struct command_line *
breakpoint_commands (struct breakpoint *b)
{
return b->commands ? b->commands->commands : 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 will keep breakpoints inserted even as inferior is
stopped, and immediately insert any new breakpoints. If off, gdb
will insert breakpoints into inferior only when resuming it, and
will remove breakpoints upon stop. If auto, GDB will behave as ON
if in non-stop mode, and as OFF if all-stop mode.*/
static enum auto_boolean always_inserted_mode = AUTO_BOOLEAN_AUTO;
static void
show_always_inserted_mode (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
if (always_inserted_mode == AUTO_BOOLEAN_AUTO)
fprintf_filtered (file,
_("Always inserted breakpoint "
"mode is %s (currently %s).\n"),
value,
breakpoints_always_inserted_mode () ? "on" : "off");
else
fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"),
value);
}
int
breakpoints_always_inserted_mode (void)
{
return (always_inserted_mode == AUTO_BOOLEAN_TRUE
|| (always_inserted_mode == AUTO_BOOLEAN_AUTO && non_stop));
}
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);
}
void _initialize_breakpoint (void);
/* 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_location; \
BP_TMP < bp_location + bp_location_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_location + bp_location_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_location_compare - primarily by the ADDRESS. */
static struct bp_location **bp_location;
/* Number of elements of BP_LOCATION. */
static unsigned bp_location_count;
/* Maximum alignment offset between bp_target_info.PLACED_ADDRESS and
ADDRESS for the current elements of BP_LOCATION which get a valid
result from bp_location_has_shadow. You can use it for roughly
limiting the subrange of BP_LOCATION to scan for shadow bytes for
an address you need to read. */
static CORE_ADDR bp_location_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_LOCATION which get a valid result from bp_location_has_shadow.
You can use it for roughly limiting the subrange of BP_LOCATION to
scan for shadow bytes for an address you need to read. */
static CORE_ADDR bp_location_shadow_len_after_address_max;
/* The locations that no longer correspond to any breakpoint, unlinked
from bp_location array, but for which a hit may still be reported
by a target. */
VEC(bp_location_p) *moribund_locations = NULL;
/* 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;
/* 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. */
void
start_rbreak_breakpoints (void)
{
rbreak_start_breakpoint_count = breakpoint_count;
}
/* Called at the end of an "rbreak" command to record the last
breakpoint made. */
void
end_rbreak_breakpoints (void)
{
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;
}
/* Allocate a new counted_command_line with reference count of 1.
The new structure owns COMMANDS. */
static struct counted_command_line *
alloc_counted_command_line (struct command_line *commands)
{
struct counted_command_line *result
= xmalloc (sizeof (struct counted_command_line));
result->refc = 1;
result->commands = commands;
return result;
}
/* Increment reference count. This does nothing if CMD is NULL. */
static void
incref_counted_command_line (struct counted_command_line *cmd)
{
if (cmd)
++cmd->refc;
}
/* Decrement reference count. If the reference count reaches 0,
destroy the counted_command_line. Sets *CMDP to NULL. This does
nothing if *CMDP is NULL. */
static void
decref_counted_command_line (struct counted_command_line **cmdp)
{
if (*cmdp)
{
if (--(*cmdp)->refc == 0)
{
free_command_lines (&(*cmdp)->commands);
xfree (*cmdp);
}
*cmdp = NULL;
}
}
/* A cleanup function that calls decref_counted_command_line. */
static void
do_cleanup_counted_command_line (void *arg)
{
decref_counted_command_line (arg);
}
/* Create a cleanup that calls decref_counted_command_line on the
argument. */
static struct cleanup *
make_cleanup_decref_counted_command_line (struct counted_command_line **cmdp)
{
return make_cleanup (do_cleanup_counted_command_line, cmdp);
}
/* 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 (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 (1);
}
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_location_compare function. */
static int
bp_location_compare_addrs (const void *ap, const void *bp)
{
struct bp_location *a = *(void **) ap;
struct bp_location *b = *(void **) 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. */
memset (&dummy_loc, 0, sizeof (struct bp_location));
dummy_loc.address = address;
/* Find a close match to the first location at ADDRESS. */
locp_found = bsearch (&dummy_locp, bp_location, bp_location_count,
sizeof (struct bp_location **),
bp_location_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_location
&& (*(locp_found - 1))->address == address)
locp_found--;
return locp_found;
}
void
set_breakpoint_condition (struct breakpoint *b, char *exp,
int from_tty)
{
xfree (b->cond_string);
b->cond_string = NULL;
if (is_watchpoint (b))
{
struct watchpoint *w = (struct watchpoint *) b;
xfree (w->cond_exp);
w->cond_exp = NULL;
}
else
{
struct bp_location *loc;
for (loc = b->loc; loc; loc = loc->next)
{
xfree (loc->cond);
loc->cond = NULL;
/* 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
{
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 = NULL;
arg = exp;
w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
if (*arg)
error (_("Junk at end of expression"));
w->cond_exp_valid_block = innermost_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);
breakpoints_changed ();
observer_notify_breakpoint_modified (b);
}
/* Completion for the "condition" command. */
static VEC (char_ptr) *
condition_completer (struct cmd_list_element *cmd, char *text, char *word)
{
char *space;
text = skip_spaces (text);
space = skip_to_space (text);
if (*space == '\0')
{
int len;
struct breakpoint *b;
VEC (char_ptr) *result = NULL;
if (text[0] == '$')
{
/* We don't support completion of history indices. */
if (isdigit (text[1]))
return NULL;
return complete_internalvar (&text[1]);
}
/* We're completing the breakpoint number. */
len = strlen (text);
ALL_BREAKPOINTS (b)
{
int single = b->loc->next == NULL;
struct bp_location *loc;
int count = 1;
for (loc = b->loc; loc; loc = loc->next)
{
char location[50];
if (single)
sprintf (location, "%d", b->number);
else
sprintf (location, "%d.%d", b->number, count);
if (strncmp (location, text, len) == 0)
VEC_safe_push (char_ptr, result, xstrdup (location));
++count;
}
}
return result;
}
/* We're completing the expression part. */
text = skip_spaces (space);
return expression_completer (cmd, text, word);
}
/* condition N EXP -- set break condition of breakpoint N to EXP. */
static void
condition_command (char *arg, int from_tty)
{
struct breakpoint *b;
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 Python object assigned to
it, and if it has a definition of the "stop"
method. This method and conditions entered into GDB from
the CLI are mutually exclusive. */
if (b->py_bp_object
&& gdbpy_breakpoint_has_py_cond (b->py_bp_object))
error (_("Cannot set a condition where a Python 'stop' "
"method has been defined in the breakpoint."));
set_breakpoint_condition (b, p, from_tty);
if (is_breakpoint (b))
update_global_location_list (1);
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)
{
int i;
if (c->control_type == while_stepping_control)
error (_("The 'while-stepping' command can "
"only be used for tracepoints"));
for (i = 0; i < c->body_count; ++i)
check_no_tracepoint_commands ((c->body_list)[i]);
/* 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"));
}
}
/* Encapsulate tests for different types of tracepoints. */
static int
is_tracepoint_type (enum bptype type)
{
return (type == bp_tracepoint
|| type == bp_fast_tracepoint
|| type == bp_static_tracepoint);
}
int
is_tracepoint (const struct breakpoint *b)
{
return is_tracepoint_type (b->type);
}
/* 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))
{
/* 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 while-stepping's body has
valid tracing commands excluding nested while-stepping. */
struct command_line *c;
struct command_line *while_stepping = 0;
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;
}
}
if (while_stepping)
{
struct command_line *c2;
gdb_assert (while_stepping->body_count == 1);
c2 = while_stepping->body_list[0];
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. */
VEC(breakpoint_p) *
static_tracepoints_here (CORE_ADDR addr)
{
struct breakpoint *b;
VEC(breakpoint_p) *found = 0;
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)
VEC_safe_push(breakpoint_p, found, 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,
struct command_line *commands)
{
validate_commands_for_breakpoint (b, commands);
decref_counted_command_line (&b->commands);
b->commands = alloc_counted_command_line (commands);
breakpoints_changed ();
observer_notify_breakpoint_modified (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)
observer_notify_breakpoint_modified (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)
observer_notify_breakpoint_modified (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)
observer_notify_breakpoint_modified (b);
}
void
check_tracepoint_command (char *line, void *closure)
{
struct breakpoint *b = closure;
validate_actionline (&line, b);
}
/* A structure used to pass information through
map_breakpoint_numbers. */
struct commands_info
{
/* True if the command was typed at a tty. */
int from_tty;
/* The breakpoint range spec. */
char *arg;
/* Non-NULL if the body of the commands are being read from this
already-parsed command. */
struct command_line *control;
/* The command lines read from the user, or NULL if they have not
yet been read. */
struct counted_command_line *cmd;
};
/* A callback for map_breakpoint_numbers that sets the commands for
commands_command. */
static void
do_map_commands_command (struct breakpoint *b, void *data)
{
struct commands_info *info = data;
if (info->cmd == NULL)
{
struct command_line *l;
if (info->control != NULL)
l = copy_command_lines (info->control->body_list[0]);
else
{
struct cleanup *old_chain;
char *str;
str = xstrprintf (_("Type commands for breakpoint(s) "
"%s, one per line."),
info->arg);
old_chain = make_cleanup (xfree, str);
l = read_command_lines (str,
info->from_tty, 1,
(is_tracepoint (b)
? check_tracepoint_command : 0),
b);
do_cleanups (old_chain);
}
info->cmd = alloc_counted_command_line (l);
}
/* If a breakpoint was on the list more than once, we don't need to
do anything. */
if (b->commands != info->cmd)
{
validate_commands_for_breakpoint (b, info->cmd->commands);
incref_counted_command_line (info->cmd);
decref_counted_command_line (&b->commands);
b->commands = info->cmd;
breakpoints_changed ();
observer_notify_breakpoint_modified (b);
}
}
static void
commands_command_1 (char *arg, int from_tty,
struct command_line *control)
{
struct cleanup *cleanups;
struct commands_info info;
info.from_tty = from_tty;
info.control = control;
info.cmd = NULL;
/* If we read command lines from the user, then `info' will hold an
extra reference to the commands that we must clean up. */
cleanups = make_cleanup_decref_counted_command_line (&info.cmd);
if (arg == NULL || !*arg)
{
if (breakpoint_count - prev_breakpoint_count > 1)
arg = xstrprintf ("%d-%d", prev_breakpoint_count + 1,
breakpoint_count);
else if (breakpoint_count > 0)
arg = xstrprintf ("%d", breakpoint_count);
else
{
/* So that we don't try to free the incoming non-NULL
argument in the cleanup below. Mapping breakpoint
numbers will fail in this case. */
arg = NULL;
}
}
else
/* The command loop has some static state, so we need to preserve
our argument. */
arg = xstrdup (arg);
if (arg != NULL)
make_cleanup (xfree, arg);
info.arg = arg;
map_breakpoint_numbers (arg, do_map_commands_command, &info);
if (info.cmd == NULL)
error (_("No breakpoints specified."));
do_cleanups (cleanups);
}
static void
commands_command (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 (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 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_location_placed_address_before_address_max
up to bl->address + bp_location_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_location_placed_address_before_address_max)
and:
bl->address + bp_location_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_location_count;
while (bc_l + 1 < bc_r)
{
struct bp_location *bl;
bc = (bc_l + bc_r) / 2;
bl = bp_location[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_LOCATION_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_location_shadow_len_after_address_max
>= bl->address)
&& (bl->address + bp_location_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_location[bc_l]->address == bp_location[bc_l - 1]->address)
bc_l--;
/* Now do full processing of the found relevant range of elements. */
for (bc = bc_l; bc < bp_location_count; bc++)
{
struct bp_location *bl = bp_location[bc];
CORE_ADDR bp_addr = 0;
int bp_size = 0;
int bptoffset = 0;
/* 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_location_placed_address_before_address_max
&& memaddr + len <= (bl->address
- bp_location_placed_address_before_address_max))
break;
if (!bp_location_has_shadow (bl))
continue;
if (!breakpoint_address_match (bl->target_info.placed_address_space, 0,
current_program_space->aspace, 0))
continue;
/* Addresses and length of the part of the breakpoint that
we need to copy. */
bp_addr = bl->target_info.placed_address;
bp_size = bl->target_info.shadow_len;
if (bp_addr + bp_size <= memaddr)
/* The breakpoint is entirely before the chunk of memory we
are reading. */
continue;
if (bp_addr >= memaddr + len)
/* The breakpoint is entirely after the chunk of memory we are
reading. */
continue;
/* 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 (bl->target_info.shadow_contents >= readbuf + len
|| readbuf >= (bl->target_info.shadow_contents
+ bl->target_info.shadow_len));
/* Update the read buffer with this inserted breakpoint's
shadow. */
memcpy (readbuf + bp_addr - memaddr,
bl->target_info.shadow_contents + bptoffset, bp_size);
}
else
{
struct gdbarch *gdbarch = bl->gdbarch;
const unsigned char *bp;
CORE_ADDR placed_address = bl->target_info.placed_address;
unsigned placed_size = bl->target_info.placed_size;
/* Update the shadow with what we want to write to memory. */
memcpy (bl->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, &placed_address, &placed_size);
/* Update the final write buffer with this inserted
breakpoint's INSN. */
memcpy (writebuf + bp_addr - memaddr, bp + bptoffset, bp_size);
}
}
}
/* Return true if BPT is either a software breakpoint or a hardware
breakpoint. */
int
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 int
is_hardware_watchpoint (const struct breakpoint *bpt)
{
return (bpt->type == bp_hardware_watchpoint
|| bpt->type == bp_read_watchpoint
|| bpt->type == bp_access_watchpoint);
}
/* Return true if BPT is of any watchpoint kind, hardware or
software. */
int
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->base.pspace == current_program_space
&& (ptid_equal (b->watchpoint_thread, null_ptid)
|| (ptid_equal (inferior_ptid, b->watchpoint_thread)
&& !is_executing (inferior_ptid))));
}
/* 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)
{
struct breakpoint *b = &w->base;
if (b->related_breakpoint != b)
{
gdb_assert (b->related_breakpoint->type == bp_watchpoint_scope);
gdb_assert (b->related_breakpoint->related_breakpoint == b);
b->related_breakpoint->disposition = disp_del_at_next_stop;
b->related_breakpoint->related_breakpoint = b->related_breakpoint;
b->related_breakpoint = b;
}
b->disposition = disp_del_at_next_stop;
}
/* 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->base.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 in a function epilogue, unwinding may not work
properly, so do not attempt to recreate locations at this
point. See similar comments in watchpoint_check. */
if (gdbarch_in_function_epilogue_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->base.loc = NULL;
if (within_current_scope && reparse)
{
char *s;
if (b->exp)
{
xfree (b->exp);
b->exp = NULL;
}
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. */
value_free (b->val);
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->base.cond_string != NULL)
{
if (b->cond_exp != NULL)
{
xfree (b->cond_exp);
b->cond_exp = NULL;
}
s = b->base.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. */
}
else if (within_current_scope && b->exp)
{
int pc = 0;
struct value *val_chain, *v, *result, *next;
struct program_space *frame_pspace;
fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain);
/* 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->base))
{
b->val = v;
b->val_valid = 1;
}
frame_pspace = get_frame_program_space (get_selected_frame (NULL));
/* Look at each value on the value chain. */
for (v = val_chain; v; v = value_next (v))
{
/* If it's a memory location, and GDB actually needed
its contents to evaluate the expression, then we
must watch it. If the first value returned is
still lazy, that means an error occurred reading it;
watch it anyway in case it becomes readable. */
if (VALUE_LVAL (v) == lval_memory
&& (v == val_chain || ! value_lazy (v)))
{
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;
int len, type;
struct bp_location *loc, **tmp;
addr = value_address (v);
len = TYPE_LENGTH (value_type (v));
type = hw_write;
if (b->base.type == bp_read_watchpoint)
type = hw_read;
else if (b->base.type == bp_access_watchpoint)
type = hw_access;
loc = allocate_bp_location (&b->base);
for (tmp = &(b->base.loc); *tmp != NULL; tmp = &((*tmp)->next))
;
*tmp = loc;
loc->gdbarch = get_type_arch (value_type (v));
loc->pspace = frame_pspace;
loc->address = addr;
loc->length = len;
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->base.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->base, type, &other_type_used);
/* Add in the resources needed for B. */
i += hw_watchpoint_use_count (&b->base);
target_resources_ok
= target_can_use_hardware_watchpoint (type, i, other_type_used);
if (target_resources_ok <= 0)
{
int sw_mode = b->base.ops->works_in_software_mode (&b->base);
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->base.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->base.type = type;
}
}
else if (!b->base.ops->works_in_software_mode (&b->base))
error (_("Expression cannot be implemented with "
"read/access watchpoint."));
else
b->base.type = bp_watchpoint;
loc_type = (b->base.type == bp_watchpoint? bp_loc_other
: bp_loc_hardware_watchpoint);
for (bl = b->base.loc; bl; bl = bl->next)
bl->loc_type = loc_type;
}
for (v = val_chain; v; v = next)
{
next = value_next (v);
if (v != b->val)
value_free (v);
}
/* If a software watchpoint is not watching any memory, then the
above left it without any location set up. But,
bpstat_stop_status requires a location to be able to report
stops, so make sure there's at least a dummy one. */
if (b->base.type == bp_watchpoint && b->base.loc == NULL)
{
struct breakpoint *base = &b->base;
base->loc = allocate_bp_location (base);
base->loc->pspace = frame_pspace;
base->loc->address = -1;
base->loc->length = -1;
base->loc->watchpoint_type = -1;
}
}
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->base.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;
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 struct agent_expr *
parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
{
struct agent_expr *aexpr = NULL;
struct cleanup *old_chain = NULL;
volatile struct gdb_exception ex;
if (!cond)
return NULL;
/* We don't want to stop processing, so catch any errors
that may show up. */
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
aexpr = gen_eval_for_expr (scope, cond);
}
if (ex.reason < 0)
{
/* 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. */
return NULL;
}
/* 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;
/* 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)
{
struct agent_expr *aexpr;
/* 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. */
aexpr = parse_cond_to_aexpr (bl->address, loc->cond);
loc->cond_bytecode = aexpr;
/* Check if we managed to parse the conditional expression
correctly. If not, we will not send this condition
to the target. */
if (aexpr)
continue;
}
/* 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;
free_agent_expr (loc->cond_bytecode);
loc->cond_bytecode = NULL;
}
}
}
/* 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. */
VEC_safe_push (agent_expr_p, bl->target_info.conditions,
loc->cond_bytecode);
}
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 struct agent_expr *
parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd)
{
struct cleanup *old_cleanups = 0;
struct expression *expr, **argvec;
struct agent_expr *aexpr = NULL;
struct cleanup *old_chain = NULL;
volatile struct gdb_exception ex;
char *cmdrest;
char *format_start, *format_end;
struct format_piece *fpieces;
int nargs;
struct gdbarch *gdbarch = get_current_arch ();
if (!cmd)
return NULL;
cmdrest = cmd;
if (*cmdrest == ',')
++cmdrest;
cmdrest = skip_spaces (cmdrest);
if (*cmdrest++ != '"')
error (_("No format string following the location"));
format_start = cmdrest;
fpieces = parse_format_string (&cmdrest);
old_cleanups = make_cleanup (free_format_pieces_cleanup, &fpieces);
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. */
argvec = (struct expression **) alloca (strlen (cmd)
* sizeof (struct expression *));
nargs = 0;
while (*cmdrest != '\0')
{
char *cmd1;
cmd1 = cmdrest;
expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
argvec[nargs++] = expr;
cmdrest = cmd1;
if (*cmdrest == ',')
++cmdrest;
}
/* We don't want to stop processing, so catch any errors
that may show up. */
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
aexpr = gen_printf (scope, gdbarch, 0, 0,
format_start, format_end - format_start,
fpieces, nargs, argvec);
}
if (ex.reason < 0)
{
/* 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. */
return NULL;
}
do_cleanups (old_cleanups);
/* 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;
/* For now, limit to agent-style dprintf breakpoints. */
if (bl->owner->type != bp_dprintf
|| strcmp (dprintf_style, dprintf_style_agent) != 0)
return;
if (!target_can_run_breakpoint_commands ())
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)
{
struct agent_expr *aexpr;
/* 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. */
aexpr = parse_cmd_to_aexpr (bl->address,
loc->owner->extra_string);
loc->cmd_bytecode = aexpr;
if (!aexpr)
continue;
}
/* 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->cond_bytecode)
return;
free_agent_expr (loc->cond_bytecode);
loc->cond_bytecode = NULL;
}
}
}
/* 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. */
VEC_safe_push (agent_expr_p, bl->target_info.tcommands,
loc->cmd_bytecode);
}
bl->target_info.persist = 0;
/* Maybe flag this location as persistent. */
if (bl->owner->type == bp_dprintf && disconnected_dprintf)
bl->target_info.persist = 1;
}
/* 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 val = 0;
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.placed_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.placed_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)
warning (_("cannot set software breakpoint "
"at readonly address %s"),
paddress (bl->gdbarch, bl->address));
}
}
/* 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. */
val = bl->owner->ops->insert_location (bl);
}
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.placed_address = addr;
val = target_insert_breakpoint (bl->gdbarch,
&bl->overlay_target_info);
if (val != 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. */
val = bl->owner->ops->insert_location (bl);
}
else
{
/* No. This breakpoint will not be inserted.
No error, but do not mark the bp as 'inserted'. */
return 0;
}
}
if (val)
{
/* Can't set the breakpoint. */
if (solib_name_from_address (bl->pspace, bl->address))
{
/* See also: disable_breakpoints_in_shlibs. */
val = 0;
bl->shlib_disabled = 1;
observer_notify_breakpoint_modified (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);
}
else
{
if (bl->loc_type == bp_loc_hardware_breakpoint)
{
*hw_breakpoint_error = 1;
fprintf_unfiltered (tmp_error_stream,
"Cannot insert hardware "
"breakpoint %d.\n",
bl->owner->number);
}
else
{
fprintf_unfiltered (tmp_error_stream,
"Cannot insert breakpoint %d.\n",
bl->owner->number);
fprintf_filtered (tmp_error_stream,
"Error accessing memory address ");
fputs_filtered (paddress (bl->gdbarch, bl->address),
tmp_error_stream);
fprintf_filtered (tmp_error_stream, ": %s.\n",
safe_strerror (val));
}
}
}
else
bl->inserted = 1;
return val;
}
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)
{
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)
{
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 (0);
}
/* 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. */);
}
update_global_location_list (1);
/* update_global_location_list does not insert breakpoints when
always_inserted_mode is not enabled. Explicitly insert them
now. */
if (!breakpoints_always_inserted_mode ())
insert_breakpoint_locations ();
}
/* 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;
struct ui_file *tmp_error_stream = mem_fileopen ();
struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
/* Explicitly mark the warning -- this will only be printed if
there was an error. */
fprintf_unfiltered (tmp_error_stream, "Warning:\n");
save_current_space_and_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->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)
&& ptid_equal (inferior_ptid, null_ptid))
continue;
val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
&hw_breakpoint_error);
if (val)
error_flag = val;
}
if (error_flag)
{
target_terminal_ours_for_output ();
error_stream (tmp_error_stream);
}
do_cleanups (cleanups);
}
/* 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;
struct ui_file *tmp_error_stream = mem_fileopen ();
struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
/* Explicitly mark the warning -- this will only be printed if
there was an error. */
fprintf_unfiltered (tmp_error_stream, "Warning:\n");
save_current_space_and_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_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)
&& ptid_equal (inferior_ptid, null_ptid))
continue;
val = insert_bp_location (bl, tmp_error_stream, &disabled_breaks,
&hw_breakpoint_error);
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, mark_uninserted);
hw_breakpoint_error = 1;
fprintf_unfiltered (tmp_error_stream,
"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)
{
fprintf_unfiltered (tmp_error_stream,
"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);
}
do_cleanups (cleanups);
}
/* 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, mark_uninserted);
}
return val;
}
/* Remove breakpoints of process PID. */
int
remove_breakpoints_pid (int pid)
{
struct bp_location *bl, **blp_tmp;
int val;
struct inferior *inf = find_inferior_pid (pid);
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->pspace != inf->pspace)
continue;
if (bl->owner->type == bp_dprintf)
continue;
if (bl->inserted)
{
val = remove_breakpoint (bl, mark_uninserted);
if (val != 0)
return val;
}
}
return 0;
}
int
reattach_breakpoints (int pid)
{
struct cleanup *old_chain;
struct bp_location *bl, **blp_tmp;
int val;
struct ui_file *tmp_error_stream;
int dummy1 = 0, dummy2 = 0;
struct inferior *inf;
struct thread_info *tp;
tp = any_live_thread_of_process (pid);
if (tp == NULL)
return 1;
inf = find_inferior_pid (pid);
old_chain = save_inferior_ptid ();
inferior_ptid = tp->ptid;
tmp_error_stream = mem_fileopen ();
make_cleanup_ui_file_delete (tmp_error_stream);
ALL_BP_LOCATIONS (bl, blp_tmp)
{
if (bl->pspace != inf->pspace)
continue;
if (bl->inserted)
{
bl->inserted = 0;
val = insert_bp_location (bl, tmp_error_stream, &dummy1, &dummy2);
if (val != 0)
{
do_cleanups (old_chain);
return val;
}
}
}
do_cleanups (old_chain);
return 0;
}
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)
{
struct symtab_and_line sal;
struct breakpoint *b;
init_sal (&sal); /* Initialize to zeroes. */
sal.pc = address;
sal.section = find_pc_overlay (sal.pc);
sal.pspace = current_program_space;
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 minimal_symbol *overlay_msym;
/* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */
struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
/* True if we have looked for longjmp probes. */
int longjmp_searched;
/* SystemTap probe points for longjmp (if any). */
VEC (probe_p) *longjmp_probes;
/* Minimal symbol for "std::terminate()" (if any). */
struct minimal_symbol *terminate_msym;
/* Minimal symbol for "_Unwind_DebugHook" (if any). */
struct minimal_symbol *exception_msym;
/* True if we have looked for exception probes. */
int exception_searched;
/* SystemTap probe points for unwinding (if any). */
VEC (probe_p) *exception_probes;
};
static const struct 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 = objfile_data (objfile, breakpoint_objfile_key);
if (bp_objfile_data == NULL)
{
bp_objfile_data = obstack_alloc (&objfile->objfile_obstack,
sizeof (*bp_objfile_data));
memset (bp_objfile_data, 0, sizeof (*bp_objfile_data));
set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
}
return bp_objfile_data;
}
static void
free_breakpoint_probes (struct objfile *obj, void *data)
{
struct breakpoint_objfile_data *bp_objfile_data = data;
VEC_free (probe_p, bp_objfile_data->longjmp_probes);
VEC_free (probe_p, bp_objfile_data->exception_probes);
}
static void
create_overlay_event_breakpoint (void)
{
struct objfile *objfile;
const char *const func_name = "_ovly_debug_event";
ALL_OBJFILES (objfile)
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
if (msym_not_found_p (bp_objfile_data->overlay_msym))
continue;
if (bp_objfile_data->overlay_msym == NULL)
{
struct minimal_symbol *m;
m = lookup_minimal_symbol_text (func_name, objfile);
if (m == NULL)
{
/* Avoid future lookups in this objfile. */
bp_objfile_data->overlay_msym = &msym_not_found;
continue;
}
bp_objfile_data->overlay_msym = m;
}
addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym);
b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
bp_overlay_event,
&internal_breakpoint_ops);
b->addr_string = xstrdup (func_name);
if (overlay_debugging == ovly_auto)
{
b->enable_state = bp_enabled;
overlay_events_enabled = 1;
}
else
{
b->enable_state = bp_disabled;
overlay_events_enabled = 0;
}
}
update_global_location_list (1);
}
static void
create_longjmp_master_breakpoint (void)
{
struct program_space *pspace;
struct cleanup *old_chain;
old_chain = save_current_program_space ();
ALL_PSPACES (pspace)
{
struct objfile *objfile;
set_current_program_space (pspace);
ALL_OBJFILES (objfile)
{
int i;
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
gdbarch = get_objfile_arch (objfile);
if (!gdbarch_get_longjmp_target_p (gdbarch))
continue;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
if (!bp_objfile_data->longjmp_searched)
{
bp_objfile_data->longjmp_probes
= find_probes_in_objfile (objfile, "libc", "longjmp");
bp_objfile_data->longjmp_searched = 1;
}
if (bp_objfile_data->longjmp_probes != NULL)
{
int i;
struct probe *probe;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
for (i = 0;
VEC_iterate (probe_p,
bp_objfile_data->longjmp_probes,
i, probe);
++i)
{
struct breakpoint *b;
b = create_internal_breakpoint (gdbarch, probe->address,
bp_longjmp_master,
&internal_breakpoint_ops);
b->addr_string = xstrdup ("-probe-stap libc:longjmp");
b->enable_state = bp_disabled;
}
continue;
}
for (i = 0; i < NUM_LONGJMP_NAMES; i++)
{
struct breakpoint *b;
const char *func_name;
CORE_ADDR addr;
if (msym_not_found_p (bp_objfile_data->longjmp_msym[i]))
continue;
func_name = longjmp_names[i];
if (bp_objfile_data->longjmp_msym[i] == NULL)
{
struct minimal_symbol *m;
m = lookup_minimal_symbol_text (func_name, objfile);
if (m == NULL)
{
/* Prevent future lookups in this objfile. */
bp_objfile_data->longjmp_msym[i] = &msym_not_found;
continue;
}
bp_objfile_data->longjmp_msym[i] = m;
}
addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
&internal_breakpoint_ops);
b->addr_string = xstrdup (func_name);
b->enable_state = bp_disabled;
}
}
}
update_global_location_list (1);
do_cleanups (old_chain);
}
/* Create a master std::terminate breakpoint. */
static void
create_std_terminate_master_breakpoint (void)
{
struct program_space *pspace;
struct cleanup *old_chain;
const char *const func_name = "std::terminate()";
old_chain = save_current_program_space ();
ALL_PSPACES (pspace)
{
struct objfile *objfile;
CORE_ADDR addr;
set_current_program_space (pspace);
ALL_OBJFILES (objfile)
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
if (msym_not_found_p (bp_objfile_data->terminate_msym))
continue;
if (bp_objfile_data->terminate_msym == NULL)
{
struct minimal_symbol *m;
m = lookup_minimal_symbol (func_name, NULL, objfile);
if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
&& MSYMBOL_TYPE (m) != mst_file_text))
{
/* Prevent future lookups in this objfile. */
bp_objfile_data->terminate_msym = &msym_not_found;
continue;
}
bp_objfile_data->terminate_msym = m;
}
addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
bp_std_terminate_master,
&internal_breakpoint_ops);
b->addr_string = xstrdup (func_name);
b->enable_state = bp_disabled;
}
}
update_global_location_list (1);
do_cleanups (old_chain);
}
/* Install a master breakpoint on the unwinder's debug hook. */
static void
create_exception_master_breakpoint (void)
{
struct objfile *objfile;
const char *const func_name = "_Unwind_DebugHook";
ALL_OBJFILES (objfile)
{
struct breakpoint *b;
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
/* We prefer the SystemTap probe point if it exists. */
if (!bp_objfile_data->exception_searched)
{
bp_objfile_data->exception_probes
= find_probes_in_objfile (objfile, "libgcc", "unwind");
bp_objfile_data->exception_searched = 1;
}
if (bp_objfile_data->exception_probes != NULL)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
int i;
struct probe *probe;
for (i = 0;
VEC_iterate (probe_p,
bp_objfile_data->exception_probes,
i, probe);
++i)
{
struct breakpoint *b;
b = create_internal_breakpoint (gdbarch, probe->address,
bp_exception_master,
&internal_breakpoint_ops);
b->addr_string = xstrdup ("-probe-stap libgcc:unwind");
b->enable_state = bp_disabled;
}
continue;