gdb/breakpoint.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #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 "gdb.h"
- #include "ui-out.h"
- #include "cli/cli-script.h"
- #include "block.h"
- #include "solib.h"
- #include "solist.h"
- #include "observer.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 "ax-gdb.h"
- #include "dummy-frame.h"
- #include "format.h"
- #include "readline/readline.h"
- #include "readline/history.h"
- #undef savestring
- #include "mi/mi-common.h"
- #include "extension.h"
- enum exception_event_kind
- {
- EX_EVENT_THROW,
- EX_EVENT_RETHROW,
- EX_EVENT_CATCH
- };
- 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 *,
- 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 *);
- 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,
- 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 void tcatch_command (char *arg, int from_tty);
- 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);
- enum ugll_insert_mode
- {
-
- UGLL_DONT_INSERT,
-
- UGLL_MAY_INSERT,
-
- UGLL_INSERT
- };
- static void update_global_location_list (enum ugll_insert_mode);
- static void update_global_location_list_nothrow (enum ugll_insert_mode);
- 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 void set_tracepoint_count (int num);
- static int is_masked_watchpoint (const struct breakpoint *b);
- static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address);
- static int strace_marker_p (struct breakpoint *b);
- struct breakpoint_ops base_breakpoint_ops;
- static struct breakpoint_ops bkpt_base_breakpoint_ops;
- static struct breakpoint_ops internal_breakpoint_ops;
- static struct breakpoint_ops momentary_breakpoint_ops;
- static struct breakpoint_ops longjmp_breakpoint_ops;
- struct breakpoint_ops bkpt_breakpoint_ops;
- static struct breakpoint_ops bkpt_probe_breakpoint_ops;
- struct breakpoint_ops dprintf_breakpoint_ops;
- 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;
- static char *dprintf_function = "";
- static char *dprintf_channel = "";
- static int disconnected_dprintf = 1;
- struct counted_command_line
- {
-
- int refc;
-
- struct command_line *commands;
- };
- struct command_line *
- breakpoint_commands (struct breakpoint *b)
- {
- return b->commands ? b->commands->commands : NULL;
- }
- static int breakpoint_proceeded;
- const char *
- bpdisp_text (enum bpdisp disp)
- {
-
- static const char * const bpdisps[] = {"del", "dstp", "dis", "keep"};
- return bpdisps[(int) disp];
- }
- 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);
- }
- 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);
- }
- 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);
- }
- 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);
- }
- int
- breakpoints_should_be_inserted_now (void)
- {
- if (gdbarch_has_global_breakpoints (target_gdbarch ()))
- {
-
- return 1;
- }
- else if (target_has_execution)
- {
- if (always_inserted_mode)
- {
-
- return 1;
- }
- if (threads_are_executing ())
- return 1;
- }
- return 0;
- }
- static const char condition_evaluation_both[] = "host or target";
- 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
- };
- static const char *condition_evaluation_mode_1 = condition_evaluation_auto;
- static const char *condition_evaluation_mode = condition_evaluation_auto;
- 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;
- }
- static const char *
- breakpoint_condition_evaluation_mode (void)
- {
- return translate_condition_evaluation_mode (condition_evaluation_mode);
- }
- static int
- gdb_evaluates_breakpoint_condition_p (void)
- {
- const char *mode = breakpoint_condition_evaluation_mode ();
- return (mode == condition_evaluation_host);
- }
- void _initialize_breakpoint (void);
- static int executing_breakpoint_commands;
- static int overlay_events_enabled;
- int target_exact_watchpoints = 0;
- #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)
- #define ALL_BP_LOCATIONS(B,BP_TMP) \
- for (BP_TMP = bp_location; \
- BP_TMP < bp_location + bp_location_count && (B = *BP_TMP); \
- BP_TMP++)
- #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++)
- #define ALL_TRACEPOINTS(B) \
- for (B = breakpoint_chain; B; B = B->next) \
- if (is_tracepoint (B))
- struct breakpoint *breakpoint_chain;
- static struct bp_location **bp_location;
- static unsigned bp_location_count;
- static CORE_ADDR bp_location_placed_address_before_address_max;
- static CORE_ADDR bp_location_shadow_len_after_address_max;
- VEC(bp_location_p) *moribund_locations = NULL;
- static int breakpoint_count;
- static int prev_breakpoint_count;
- 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;
- static int
- breakpoint_enabled (struct breakpoint *b)
- {
- return (b->enable_state == bp_enabled);
- }
- static void
- set_breakpoint_count (int num)
- {
- prev_breakpoint_count = breakpoint_count;
- breakpoint_count = num;
- set_internalvar_integer (lookup_internalvar ("bpnum"), num);
- }
- static int rbreak_start_breakpoint_count;
- void
- start_rbreak_breakpoints (void)
- {
- rbreak_start_breakpoint_count = breakpoint_count;
- }
- void
- end_rbreak_breakpoints (void)
- {
- prev_breakpoint_count = rbreak_start_breakpoint_count;
- }
- void
- clear_breakpoint_hit_counts (void)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- b->hit_count = 0;
- }
- 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;
- }
- static void
- incref_counted_command_line (struct counted_command_line *cmd)
- {
- if (cmd)
- ++cmd->refc;
- }
- 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;
- }
- }
- static void
- do_cleanup_counted_command_line (void *arg)
- {
- decref_counted_command_line (arg);
- }
- static struct cleanup *
- make_cleanup_decref_counted_command_line (struct counted_command_line **cmdp)
- {
- return make_cleanup (do_cleanup_counted_command_line, cmdp);
- }
- struct breakpoint *
- get_breakpoint (int num)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- if (b->number == num)
- return b;
- return NULL;
- }
- static void
- mark_breakpoint_modified (struct breakpoint *b)
- {
- struct bp_location *loc;
-
- 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;
- }
- static void
- mark_breakpoint_location_modified (struct bp_location *loc)
- {
-
- if (gdb_evaluates_breakpoint_condition_p ()
- || !target_supports_evaluation_of_breakpoint_conditions ())
- return;
- if (!is_breakpoint (loc->owner))
- return;
- loc->condition_changed = condition_modified;
- }
- 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);
-
- condition_evaluation_mode = condition_evaluation_mode_1;
-
- if (new_mode != old_mode)
- {
- struct bp_location *loc, **loc_tmp;
-
- if (new_mode == condition_evaluation_target)
- {
-
- ALL_BP_LOCATIONS (loc, loc_tmp)
- mark_breakpoint_location_modified (loc);
- }
- else
- {
-
- ALL_BP_LOCATIONS (loc, loc_tmp)
- if (is_breakpoint (loc->owner) && loc->inserted)
- loc->needs_update = 1;
- }
-
- update_global_location_list (UGLL_MAY_INSERT);
- }
- return;
- }
- 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);
- }
- 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));
- }
- 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;
-
- memset (&dummy_loc, 0, sizeof (struct bp_location));
- dummy_loc.address = address;
-
- locp_found = bsearch (&dummy_locp, bp_location, bp_location_count,
- sizeof (struct bp_location **),
- bp_location_compare_addrs);
-
- if (locp_found == NULL)
- return NULL;
-
- 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;
-
- }
- }
- if (*exp == 0)
- {
- if (from_tty)
- printf_filtered (_("Breakpoint %d now unconditional.\n"), b->number);
- }
- else
- {
- const char *arg = exp;
-
- 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);
- observer_notify_breakpoint_modified (b);
- }
- static VEC (char_ptr) *
- condition_completer (struct cmd_list_element *cmd,
- const char *text, const char *word)
- {
- const char *space;
- text = skip_spaces_const (text);
- space = skip_to_space_const (text);
- if (*space == '\0')
- {
- int len;
- struct breakpoint *b;
- VEC (char_ptr) *result = NULL;
- if (text[0] == '$')
- {
-
- if (isdigit (text[1]))
- return NULL;
- return complete_internalvar (&text[1]);
- }
-
- len = strlen (text);
- ALL_BREAKPOINTS (b)
- {
- char number[50];
- xsnprintf (number, sizeof (number), "%d", b->number);
- if (strncmp (number, text, len) == 0)
- VEC_safe_push (char_ptr, result, xstrdup (number));
- }
- return result;
- }
-
- text = skip_spaces_const (space);
- return expression_completer (cmd, text, word);
- }
- 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)
- {
-
- 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);
- }
- 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]);
-
- 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"));
- }
- }
- 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);
- }
- 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;
-
- t->step_count = 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;
- }
- validate_actionline (c->line, b);
- }
- 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);
- }
- }
- 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;
- }
- 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);
- observer_notify_breakpoint_modified (b);
- }
- 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);
- }
- 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);
- }
- 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);
- }
- struct commands_info
- {
-
- int from_tty;
-
- char *arg;
-
- struct command_line *control;
-
- struct counted_command_line *cmd;
- };
- 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 (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;
- 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;
-
- 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
- {
-
- arg = NULL;
- }
- }
- else
-
- 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);
- }
- enum command_control_type
- commands_from_control_command (char *arg, struct command_line *cmd)
- {
- commands_command_1 (arg, 0, cmd);
- return simple_control;
- }
- 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)
-
- return 0;
- return 1;
- }
- 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)
- {
-
- 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))
- {
-
- return;
- }
-
- bp_addr = target_info->placed_address;
- bp_size = target_info->shadow_len;
- if (bp_addr + bp_size <= memaddr)
- {
-
- return;
- }
- if (bp_addr >= memaddr + len)
- {
-
- return;
- }
-
- if (bp_addr < memaddr)
- {
-
- bp_size -= memaddr - bp_addr;
- bptoffset = memaddr - bp_addr;
- bp_addr = memaddr;
- }
- if (bp_addr + bp_size > memaddr + len)
- {
-
- bp_size -= (bp_addr + bp_size) - (memaddr + len);
- }
- if (readbuf != NULL)
- {
-
- gdb_assert (target_info->shadow_contents >= readbuf + len
- || readbuf >= (target_info->shadow_contents
- + target_info->shadow_len));
-
- 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;
-
- memcpy (target_info->shadow_contents + bptoffset,
- writebuf_org + bp_addr - memaddr, bp_size);
-
- bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &placed_size);
-
- memcpy (writebuf + bp_addr - memaddr, bp + bptoffset, bp_size);
- }
- }
- void
- breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf,
- const gdb_byte *writebuf_org,
- ULONGEST memaddr, LONGEST len)
- {
-
- unsigned bc_l, bc_r, bc;
- size_t i;
-
- 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];
-
- 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;
- }
-
- while (bc_l > 0
- && bp_location[bc_l]->address == bp_location[bc_l - 1]->address)
- bc_l--;
-
- 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;
-
- if (bl->owner->type == bp_none)
- warning (_("reading through apparently deleted breakpoint #%d?"),
- bl->owner->number);
-
- 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;
- one_breakpoint_xfer_memory (readbuf, writebuf, writebuf_org,
- memaddr, len, &bl->target_info, bl->gdbarch);
- }
- }
- int
- is_breakpoint (const struct breakpoint *bpt)
- {
- return (bpt->type == bp_breakpoint
- || bpt->type == bp_hardware_breakpoint
- || bpt->type == bp_dprintf);
- }
- 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);
- }
- int
- is_watchpoint (const struct breakpoint *bpt)
- {
- return (is_hardware_watchpoint (bpt)
- || bpt->type == bp_watchpoint);
- }
- 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))));
- }
- 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;
- }
- 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;
- }
- static void
- update_watchpoint (struct watchpoint *b, int reparse)
- {
- int within_current_scope;
- struct frame_id saved_frame_id;
- int frame_saved;
-
- if (!watchpoint_in_thread_scope (b))
- return;
- if (b->base.disposition == disp_del_at_next_stop)
- return;
- frame_saved = 0;
-
- 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 (gdbarch_in_function_epilogue_p (frame_arch, frame_pc))
- return;
-
- FIXME
- 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);
- }
-
- b->base.loc = NULL;
- if (within_current_scope && reparse)
- {
- const 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);
-
- value_free (b->val);
- b->val = NULL;
- b->val_valid = 0;
-
- 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 (!target_has_execution)
- {
-
- if (!can_use_hw_watchpoints)
- {
- if (b->base.ops->works_in_software_mode (&b->base))
- b->base.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;
- struct value *val_chain, *v, *result, *next;
- struct program_space *frame_pspace;
- fetch_subexp_value (b->exp, &pc, &v, &result, &val_chain, 0);
-
- if (!b->val_valid && !is_masked_watchpoint (&b->base))
- {
- if (b->val_bitsize != 0)
- {
- v = extract_bitfield_from_watchpoint_value (b, v);
- if (v != NULL)
- release_value (v);
- }
- b->val = v;
- b->val_valid = 1;
- }
- frame_pspace = get_frame_program_space (get_selected_frame (NULL));
-
- for (v = val_chain; v; v = value_next (v))
- {
-
- if (VALUE_LVAL (v) == lval_memory
- && (v == val_chain || ! value_lazy (v)))
- {
- struct type *vtype = check_typedef (value_type (v));
-
- if (v == result
- || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
- && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
- {
- CORE_ADDR addr;
- int type;
- struct bp_location *loc, **tmp;
- int bitpos = 0, bitsize = 0;
- if (value_bitsize (v) != 0)
- {
-
- bitpos = value_bitpos (v);
- bitsize = value_bitsize (v);
- }
- else if (v == result && b->val_bitsize != 0)
- {
-
- bitpos = b->val_bitpos;
- bitsize = b->val_bitsize;
- }
- addr = value_address (v);
- if (bitsize != 0)
- {
-
- addr += bitpos / 8;
- }
- 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;
- if (bitsize != 0)
- {
-
- loc->length = ((bitpos % 8) + bitsize + 7) / 8;
- }
- else
- loc->length = TYPE_LENGTH (value_type (v));
- loc->watchpoint_type = type;
- }
- }
- }
-
- 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;
-
- b->exact = target_exact_watchpoints && reg_cnt == 1;
-
-
- type = b->base.type;
- if (type == bp_watchpoint)
- type = bp_hardware_watchpoint;
-
-
- i = hw_watchpoint_used_count_others (&b->base, type, &other_type_used);
-
- 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."));
-
- b->base.type = bp_watchpoint;
- }
- else
- {
-
- b->base.type = type;
- }
- }
- else if (!b->base.ops->works_in_software_mode (&b->base))
- {
- 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->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 (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);
- }
-
- if (frame_saved)
- select_frame (frame_find_by_id (saved_frame_id));
- }
- 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;
-
- if (bl->pspace->breakpoints_not_allowed)
- return 0;
-
- if ((bl->loc_type == bp_loc_software_breakpoint
- || bl->loc_type == bp_loc_hardware_breakpoint)
- && stepping_past_instruction_at (bl->pspace->aspace,
- bl->address))
- {
- if (debug_infrun)
- {
- fprintf_unfiltered (gdb_stdlog,
- "infrun: skipping breakpoint: "
- "stepping past insn at: %s\n",
- paddress (bl->gdbarch, bl->address));
- }
- return 0;
- }
-
- 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;
- }
- 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;
- }
- static struct agent_expr *
- parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond)
- {
- struct agent_expr *aexpr = NULL;
- volatile struct gdb_exception ex;
- if (!cond)
- return NULL;
-
- TRY_CATCH (ex, RETURN_MASK_ERROR)
- {
- aexpr = gen_eval_for_expr (scope, cond);
- }
- if (ex.reason < 0)
- {
-
- return NULL;
- }
-
- return aexpr;
- }
- 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;
-
- VEC_free (agent_expr_p, bl->target_info.conditions);
-
- if (gdb_evaluates_breakpoint_condition_p ()
- || !target_supports_evaluation_of_breakpoint_conditions ())
- return;
-
- 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;
-
- aexpr = parse_cond_to_aexpr (bl->address, loc->cond);
- loc->cond_bytecode = aexpr;
-
- if (aexpr)
- continue;
- }
-
- if (!loc->cond_bytecode)
- {
- null_condition_or_parse_error = 1;
- break;
- }
- }
- }
-
- 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)
- {
-
- if (!loc->cond_bytecode)
- return;
- free_agent_expr (loc->cond_bytecode);
- loc->cond_bytecode = NULL;
- }
- }
- }
-
- 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)
-
- VEC_safe_push (agent_expr_p, bl->target_info.conditions,
- loc->cond_bytecode);
- }
- return;
- }
- 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;
- volatile struct gdb_exception ex;
- const char *cmdrest;
- const 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_const (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_const (cmdrest);
- if (!(*cmdrest == ',' || *cmdrest == '\0'))
- error (_("Invalid argument syntax"));
- if (*cmdrest == ',')
- cmdrest++;
- cmdrest = skip_spaces_const (cmdrest);
-
- argvec = (struct expression **) alloca (strlen (cmd)
- * sizeof (struct expression *));
- nargs = 0;
- while (*cmdrest != '\0')
- {
- const char *cmd1;
- cmd1 = cmdrest;
- expr = parse_exp_1 (&cmd1, scope, block_for_pc (scope), 1);
- argvec[nargs++] = expr;
- cmdrest = cmd1;
- if (*cmdrest == ',')
- ++cmdrest;
- }
-
- TRY_CATCH (ex, RETURN_MASK_ERROR)
- {
- aexpr = gen_printf (scope, gdbarch, 0, 0,
- format_start, format_end - format_start,
- fpieces, nargs, argvec);
- }
- do_cleanups (old_cleanups);
- if (ex.reason < 0)
- {
-
- return NULL;
- }
-
- return aexpr;
- }
- 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;
-
- VEC_free (agent_expr_p, bl->target_info.tcommands);
- if (!target_can_run_breakpoint_commands ())
- return;
-
- if (dprintf_style != dprintf_style_agent)
- return;
-
- 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;
- }
-
- 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;
-
- aexpr = parse_cmd_to_aexpr (bl->address,
- loc->owner->extra_string);
- loc->cmd_bytecode = aexpr;
- if (!aexpr)
- continue;
- }
-
- if (!loc->cmd_bytecode)
- {
- null_command_or_parse_error = 1;
- break;
- }
- }
- }
-
- 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)
- {
-
- if (loc->cmd_bytecode == NULL)
- return;
- free_agent_expr (loc->cmd_bytecode);
- loc->cmd_bytecode = NULL;
- }
- }
- }
-
- 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)
-
- VEC_safe_push (agent_expr_p, bl->target_info.tcommands,
- loc->cmd_bytecode);
- }
- bl->target_info.persist = 0;
-
- if (bl->owner->type == bp_dprintf && disconnected_dprintf)
- bl->target_info.persist = 1;
- }
- 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)
- {
- enum errors bp_err = GDB_NO_ERROR;
- const char *bp_err_message = NULL;
- volatile struct gdb_exception e;
- if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
- return 0;
-
- bl->target_info.reqstd_address = bl->address;
- bl->target_info.placed_address_space = bl->pspace->aspace;
- bl->target_info.length = bl->length;
-
- if (is_breakpoint (bl->owner))
- {
- build_target_condition_list (bl);
- build_target_command_list (bl);
-
- 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)
- {
-
- 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;
- }
- }
- }
-
- if (overlay_debugging == ovly_off
- || bl->section == NULL
- || !(section_is_overlay (bl->section)))
- {
-
- TRY_CATCH (e, RETURN_MASK_ALL)
- {
- int val;
- val = bl->owner->ops->insert_location (bl);
- if (val)
- bp_err = GENERIC_ERROR;
- }
- if (e.reason < 0)
- {
- bp_err = e.error;
- bp_err_message = e.message;
- }
- }
- else
- {
-
- if (!overlay_events_enabled)
- {
-
- 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);
-
- bl->overlay_target_info = bl->target_info;
- bl->overlay_target_info.reqstd_address = addr;
-
- TRY_CATCH (e, RETURN_MASK_ALL)
- {
- int val;
- val = target_insert_breakpoint (bl->gdbarch,
- &bl->overlay_target_info);
- if (val)
- bp_err = GENERIC_ERROR;
- }
- if (e.reason < 0)
- {
- bp_err = e.error;
- bp_err_message = e.message;
- }
- if (bp_err != GDB_NO_ERROR)
- fprintf_unfiltered (tmp_error_stream,
- "Overlay breakpoint %d "
- "failed: in ROM?\n",
- bl->owner->number);
- }
- }
-
- if (section_is_mapped (bl->section))
- {
-
- TRY_CATCH (e, RETURN_MASK_ALL)
- {
- int val;
- val = bl->owner->ops->insert_location (bl);
- if (val)
- bp_err = GENERIC_ERROR;
- }
- if (e.reason < 0)
- {
- bp_err = e.error;
- bp_err_message = e.message;
- }
- }
- else
- {
-
- return 0;
- }
- }
- if (bp_err != GDB_NO_ERROR)
- {
-
-
- if ((bp_err == GENERIC_ERROR || bp_err == 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)))
- {
-
- 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);
- return 0;
- }
- else
- {
- if (bl->loc_type == bp_loc_hardware_breakpoint)
- {
- *hw_breakpoint_error = 1;
- *hw_bp_error_explained_already = bp_err_message != NULL;
- fprintf_unfiltered (tmp_error_stream,
- "Cannot insert hardware breakpoint %d%s",
- bl->owner->number, bp_err_message ? ":" : ".\n");
- if (bp_err_message != NULL)
- fprintf_unfiltered (tmp_error_stream, "%s.\n", bp_err_message);
- }
- else
- {
- if (bp_err_message == NULL)
- {
- char *message
- = memory_error_message (TARGET_XFER_E_IO,
- bl->gdbarch, bl->address);
- struct cleanup *old_chain = make_cleanup (xfree, message);
- fprintf_unfiltered (tmp_error_stream,
- "Cannot insert breakpoint %d.\n"
- "%s\n",
- bl->owner->number, message);
- do_cleanups (old_chain);
- }
- else
- {
- fprintf_unfiltered (tmp_error_stream,
- "Cannot insert breakpoint %d: %s\n",
- bl->owner->number,
- bp_err_message);
- }
- }
- return 1;
- }
- }
- else
- bl->inserted = 1;
- return 0;
- }
- else if (bl->loc_type == bp_loc_hardware_watchpoint
-
- && 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 (val == 1 && bl->watchpoint_type == hw_read)
- {
- struct bp_location *loc, **loc_temp;
-
- 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)
-
- 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);
-
- return 0;
- }
- return 0;
- }
- void
- breakpoint_program_space_exit (struct program_space *pspace)
- {
- struct breakpoint *b, *b_temp;
- struct bp_location *loc, **loc_temp;
-
- ALL_BREAKPOINTS_SAFE (b, b_temp)
- {
- if (b->pspace == pspace)
- delete_breakpoint (b);
- }
-
- ALL_BP_LOCATIONS (loc, loc_temp)
- {
- struct bp_location *tmp;
- if (loc->pspace == pspace)
- {
-
- 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;
- }
- }
- }
-
- update_global_location_list (UGLL_DONT_INSERT);
- }
- 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 );
- }
-
- update_global_location_list (UGLL_INSERT);
- }
- 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);
- }
- }
- 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;
- struct ui_file *tmp_error_stream = mem_fileopen ();
- struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
-
- fprintf_unfiltered (tmp_error_stream, "Warning:\n");
- save_current_space_and_thread ();
- ALL_BP_LOCATIONS (bl, blp_tmp)
- {
-
- if (!is_breakpoint (bl->owner))
- continue;
-
- if (!bl->inserted || (bl->inserted && !bl->needs_update))
- continue;
- switch_to_program_space_and_thread (bl->pspace);
-
- 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, &hw_bp_details_reported);
- if (val)
- error_flag = val;
- }
- if (error_flag)
- {
- target_terminal_ours_for_output ();
- error_stream (tmp_error_stream);
- }
- do_cleanups (cleanups);
- }
- 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;
- struct ui_file *tmp_error_stream = mem_fileopen ();
- struct cleanup *cleanups = make_cleanup_ui_file_delete (tmp_error_stream);
-
- 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;
-
- if (bl->owner->thread != -1
- && !valid_thread_id (bl->owner->thread))
- continue;
- switch_to_program_space_and_thread (bl->pspace);
-
- 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, &hw_bp_error_explained_already);
- if (val)
- error_flag = val;
- }
-
- 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 (hw_breakpoint_error && !hw_bp_error_explained_already)
- {
- 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);
- }
- 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;
- }
- 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->num && user_breakpoint_p (b))
- {
- b->disposition = disp_del_at_next_stop;
- printf_filtered (_("\
- Thread-specific breakpoint %d deleted - thread %d no longer in the thread list.\n"),
- b->number, tp->num);
-
- b->number = 0;
- }
- }
- }
- 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->inserted && !bl->target_info.persist)
- {
- 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, dummy3 = 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, &dummy3);
- if (val != 0)
- {
- do_cleanups (old_chain);
- return val;
- }
- }
- }
- do_cleanups (old_chain);
- return 0;
- }
- static int internal_breakpoint_number = -1;
- 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);
- 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)
- struct breakpoint_objfile_data
- {
-
- struct bound_minimal_symbol overlay_msym;
-
- struct bound_minimal_symbol longjmp_msym[NUM_LONGJMP_NAMES];
-
- int longjmp_searched;
-
- VEC (probe_p) *longjmp_probes;
-
- struct bound_minimal_symbol terminate_msym;
-
- struct bound_minimal_symbol exception_msym;
-
- int exception_searched;
-
- VEC (probe_p) *exception_probes;
- };
- static const struct objfile_data *breakpoint_objfile_key;
- static struct minimal_symbol msym_not_found;
- static int
- msym_not_found_p (const struct minimal_symbol *msym)
- {
- return msym == &msym_not_found;
- }
- 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.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)
- {
-
- 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);
- 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 (UGLL_MAY_INSERT);
- }
- 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);
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
- if (!bp_objfile_data->longjmp_searched)
- {
- VEC (probe_p) *ret;
- ret = find_probes_in_objfile (objfile, "libc", "longjmp");
- if (ret != NULL)
- {
-
- struct probe *p = VEC_index (probe_p, ret, 0);
- if (!can_evaluate_probe_arguments (p))
- {
-
- VEC_free (probe_p, ret);
- ret = NULL;
- }
- }
- bp_objfile_data->longjmp_probes = ret;
- 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,
- get_probe_address (probe,
- objfile),
- bp_longjmp_master,
- &internal_breakpoint_ops);
- b->addr_string = xstrdup ("-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;
- 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)
- {
-
- 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);
- b->addr_string = xstrdup (func_name);
- b->enable_state = bp_disabled;
- }
- }
- }
- update_global_location_list (UGLL_MAY_INSERT);
- do_cleanups (old_chain);
- }
- 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.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))
- {
-
- 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);
- b->addr_string = xstrdup (func_name);
- b->enable_state = bp_disabled;
- }
- }
- update_global_location_list (UGLL_MAY_INSERT);
- do_cleanups (old_chain);
- }
- 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);
-
- if (!bp_objfile_data->exception_searched)
- {
- VEC (probe_p) *ret;
- ret = find_probes_in_objfile (objfile, "libgcc", "unwind");
- if (ret != NULL)
- {
-
- struct probe *p = VEC_index (probe_p, ret, 0);
- if (!can_evaluate_probe_arguments (p))
- {
-
- VEC_free (probe_p, ret);
- ret = NULL;
- }
- }
- bp_objfile_data->exception_probes = ret;
- 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,
- get_probe_address (probe,
- objfile),
- bp_exception_master,
- &internal_breakpoint_ops);
- b->addr_string = xstrdup ("-probe-stap libgcc:unwind");
- b->enable_state = bp_disabled;
- }
- continue;
- }
-
- 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,
- ¤t_target);
- b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
- &internal_breakpoint_ops);
- b->addr_string = xstrdup (func_name);
- b->enable_state = bp_disabled;
- }
- update_global_location_list (UGLL_MAY_INSERT);
- }
- void
- update_breakpoints_after_exec (void)
- {
- struct breakpoint *b, *b_tmp;
- struct bp_location *bploc, **bplocp_tmp;
-
- 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;
-
- if (b->type == bp_shlib_event)
- {
- delete_breakpoint (b);
- continue;
- }
-
- if (b->type == bp_jit_event)
- {
- delete_breakpoint (b);
- continue;
- }
-
- 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;
- }
-
- if (b->type == bp_step_resume || b->type == bp_hp_step_resume)
- {
- delete_breakpoint (b);
- continue;
- }
-
- if (b->type == bp_single_step)
- {
- delete_breakpoint (b);
- continue;
- }
-
- 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)
- {
-
- continue;
- }
-
- if (b->type == bp_finish)
- {
- continue;
- }
-
- if (b->addr_string == NULL)
- {
- delete_breakpoint (b);
- continue;
- }
- }
- }
- int
- detach_breakpoints (ptid_t ptid)
- {
- struct bp_location *bl, **blp_tmp;
- int val = 0;
- struct cleanup *old_chain = save_inferior_ptid ();
- struct inferior *inf = current_inferior ();
- if (ptid_get_pid (ptid) == ptid_get_pid (inferior_ptid))
- error (_("Cannot detach breakpoints of inferior_ptid"));
-
- inferior_ptid = ptid;
- ALL_BP_LOCATIONS (bl, blp_tmp)
- {
- if (bl->pspace != inf->pspace)
- continue;
-
- if (bl->loc_type == bp_loc_other)
- continue;
- if (bl->inserted)
- val |= remove_breakpoint_1 (bl, mark_inserted);
- }
- do_cleanups (old_chain);
- return val;
- }
- static int
- remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
- {
- int val;
-
- gdb_assert (bl->owner != NULL);
- if (bl->permanent)
-
- return 0;
-
- gdb_assert (bl->owner->type != bp_none);
- if (bl->loc_type == bp_loc_software_breakpoint
- || bl->loc_type == bp_loc_hardware_breakpoint)
- {
-
-
- if (overlay_debugging == ovly_off
- || bl->section == NULL
- || !(section_is_overlay (bl->section)))
- {
-
-
- 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);
- }
- else
- {
-
- if (!overlay_events_enabled)
- {
-
-
- 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);
- }
-
- if (bl->inserted)
- {
-
-
- if (bl->loc_type == bp_loc_hardware_breakpoint
- || section_is_mapped (bl->section))
- val = bl->owner->ops->remove_location (bl);
- else
- val = 0;
- }
- else
- {
-
- val = 0;
- }
- }
-
- 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 = (is == mark_inserted);
- }
- else if (bl->loc_type == bp_loc_hardware_watchpoint)
- {
- gdb_assert (bl->owner->ops != NULL
- && bl->owner->ops->remove_location != NULL);
- bl->inserted = (is == mark_inserted);
- bl->owner->ops->remove_location (bl);
-
- if ((is == mark_uninserted) && (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);
- if (val)
- return val;
- bl->inserted = (is == mark_inserted);
- }
- return 0;
- }
- static int
- remove_breakpoint (struct bp_location *bl, insertion_state_t is)
- {
- int ret;
- struct cleanup *old_chain;
-
- gdb_assert (bl->owner != NULL);
- if (bl->permanent)
-
- return 0;
-
- gdb_assert (bl->owner->type != bp_none);
- old_chain = save_current_space_and_thread ();
- switch_to_program_space_and_thread (bl->pspace);
- ret = remove_breakpoint_1 (bl, is);
- do_cleanups (old_chain);
- return ret;
- }
- void
- mark_breakpoints_out (void)
- {
- struct bp_location *bl, **blp_tmp;
- ALL_BP_LOCATIONS (bl, blp_tmp)
- if (bl->pspace == current_program_space
- && !bl->permanent)
- bl->inserted = 0;
- }
- void
- breakpoint_init_inferior (enum inf_context context)
- {
- struct breakpoint *b, *b_tmp;
- struct bp_location *bl, **blp_tmp;
- int ix;
- struct program_space *pspace = current_program_space;
-
- 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:
-
- case bp_watchpoint_scope:
-
- case bp_shlib_event:
-
- case bp_step_resume:
-
- case bp_single_step:
-
- 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;
-
- if (w->exp_valid_block != NULL)
- delete_breakpoint (b);
- else if (context == inf_starting)
- {
-
- if (w->val)
- value_free (w->val);
- w->val = NULL;
- w->val_valid = 0;
- }
- }
- break;
- default:
- break;
- }
- }
-
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, bl); ++ix)
- decref_bp_location (&bl);
- VEC_free (bp_location_p, moribund_locations);
- }
- enum breakpoint_here
- breakpoint_here_p (struct 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;
-
- 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;
- else if (bl->permanent)
- return permanent_breakpoint_here;
- else
- any_breakpoint_here = 1;
- }
- }
- return any_breakpoint_here ? ordinary_breakpoint_here : 0;
- }
- int
- moribund_breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc)
- {
- struct bp_location *loc;
- int ix;
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
- if (breakpoint_location_address_match (loc, aspace, pc))
- return 1;
- return 0;
- }
- static int
- bp_location_inserted_here_p (struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR pc)
- {
- if (bl->inserted
- && breakpoint_address_match (bl->pspace->aspace, bl->address,
- aspace, pc))
- {
- if (overlay_debugging
- && section_is_overlay (bl->section)
- && !section_is_mapped (bl->section))
- return 0;
- else
- return 1;
- }
- return 0;
- }
- int
- breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc)
- {
- struct bp_location **blp, **blp_tmp = NULL;
- struct bp_location *bl;
- ALL_BP_LOCATIONS_AT_ADDR (blp, blp_tmp, pc)
- {
- struct bp_location *bl = *blp;
- if (bl->loc_type != bp_loc_software_breakpoint
- && bl->loc_type != bp_loc_hardware_breakpoint)
- continue;
- if (bp_location_inserted_here_p (bl, aspace, pc))
- return 1;
- }
- return 0;
- }
- int
- software_breakpoint_inserted_here_p (struct address_space *aspace,
- CORE_ADDR pc)
- {
- struct bp_location **blp, **blp_tmp = NULL;
- struct bp_location *bl;
- ALL_BP_LOCATIONS_AT_ADDR (blp, blp_tmp, pc)
- {
- struct bp_location *bl = *blp;
- if (bl->loc_type != bp_loc_software_breakpoint)
- continue;
- if (bp_location_inserted_here_p (bl, aspace, pc))
- return 1;
- }
- return 0;
- }
- int
- hardware_breakpoint_inserted_here_p (struct address_space *aspace,
- CORE_ADDR pc)
- {
- struct bp_location **blp, **blp_tmp = NULL;
- struct bp_location *bl;
- ALL_BP_LOCATIONS_AT_ADDR (blp, blp_tmp, pc)
- {
- struct bp_location *bl = *blp;
- if (bl->loc_type != bp_loc_hardware_breakpoint)
- continue;
- if (bp_location_inserted_here_p (bl, aspace, pc))
- return 1;
- }
- return 0;
- }
- int
- hardware_watchpoint_inserted_in_range (struct address_space *aspace,
- CORE_ADDR addr, ULONGEST len)
- {
- struct breakpoint *bpt;
- ALL_BREAKPOINTS (bpt)
- {
- struct bp_location *loc;
- if (bpt->type != bp_hardware_watchpoint
- && bpt->type != bp_access_watchpoint)
- continue;
- if (!breakpoint_enabled (bpt))
- continue;
- for (loc = bpt->loc; loc; loc = loc->next)
- if (loc->pspace->aspace == aspace && loc->inserted)
- {
- CORE_ADDR l, h;
-
- l = max (loc->address, addr);
- h = min (loc->address + loc->length, addr + len);
- if (l < h)
- return 1;
- }
- }
- return 0;
- }
- int
- is_catchpoint (struct breakpoint *ep)
- {
- return (ep->type == bp_catchpoint);
- }
- static void
- bpstat_free (bpstat bs)
- {
- if (bs->old_val != NULL)
- value_free (bs->old_val);
- decref_counted_command_line (&bs->commands);
- decref_bp_location (&bs->bp_location_at);
- xfree (bs);
- }
- void
- bpstat_clear (bpstat *bsp)
- {
- bpstat p;
- bpstat q;
- if (bsp == 0)
- return;
- p = *bsp;
- while (p != NULL)
- {
- q = p->next;
- bpstat_free (p);
- p = q;
- }
- *bsp = NULL;
- }
- bpstat
- bpstat_copy (bpstat bs)
- {
- bpstat p = NULL;
- bpstat tmp;
- bpstat retval = NULL;
- if (bs == NULL)
- return bs;
- for (; bs != NULL; bs = bs->next)
- {
- tmp = (bpstat) xmalloc (sizeof (*tmp));
- memcpy (tmp, bs, sizeof (*tmp));
- incref_counted_command_line (tmp->commands);
- incref_bp_location (tmp->bp_location_at);
- if (bs->old_val != NULL)
- {
- tmp->old_val = value_copy (bs->old_val);
- release_value (tmp->old_val);
- }
- if (p == NULL)
-
- retval = tmp;
- else
- p->next = tmp;
- p = tmp;
- }
- p->next = NULL;
- return retval;
- }
- bpstat
- bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint)
- {
- if (bsp == NULL)
- return NULL;
- for (; bsp != NULL; bsp = bsp->next)
- {
- if (bsp->breakpoint_at == breakpoint)
- return bsp;
- }
- return NULL;
- }
- int
- bpstat_explains_signal (bpstat bsp, enum gdb_signal sig)
- {
- for (; bsp != NULL; bsp = bsp->next)
- {
- if (bsp->breakpoint_at == NULL)
- {
-
- if (sig == GDB_SIGNAL_TRAP)
- return 1;
- }
- else
- {
- if (bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at,
- sig))
- return 1;
- }
- }
- return 0;
- }
- int
- bpstat_num (bpstat *bsp, int *num)
- {
- struct breakpoint *b;
- if ((*bsp) == NULL)
- return 0;
-
- b = (*bsp)->breakpoint_at;
- *bsp = (*bsp)->next;
- if (b == NULL)
- return -1;
- *num = b->number;
- return 1;
- }
- void
- bpstat_clear_actions (void)
- {
- struct thread_info *tp;
- bpstat bs;
- if (ptid_equal (inferior_ptid, null_ptid))
- return;
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
- return;
- for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
- {
- decref_counted_command_line (&bs->commands);
- if (bs->old_val != NULL)
- {
- value_free (bs->old_val);
- bs->old_val = NULL;
- }
- }
- }
- static void
- breakpoint_about_to_proceed (void)
- {
- if (!ptid_equal (inferior_ptid, null_ptid))
- {
- struct thread_info *tp = inferior_thread ();
-
- if (tp->control.in_infcall)
- return;
- }
- breakpoint_proceeded = 1;
- }
- static void
- cleanup_executing_breakpoints (void *ignore)
- {
- executing_breakpoint_commands = 0;
- }
- static int
- command_line_is_silent (struct command_line *cmd)
- {
- return cmd && (strcmp ("silent", cmd->line) == 0
- || (xdb_commands && strcmp ("Q", cmd->line) == 0));
- }
- static int
- bpstat_do_actions_1 (bpstat *bsp)
- {
- bpstat bs;
- struct cleanup *old_chain;
- int again = 0;
-
- if (executing_breakpoint_commands)
- return 0;
- executing_breakpoint_commands = 1;
- old_chain = make_cleanup (cleanup_executing_breakpoints, 0);
- prevent_dont_repeat ();
-
- bs = *bsp;
- breakpoint_proceeded = 0;
- for (; bs != NULL; bs = bs->next)
- {
- struct counted_command_line *ccmd;
- struct command_line *cmd;
- struct cleanup *this_cmd_tree_chain;
-
- ccmd = bs->commands;
- bs->commands = NULL;
- this_cmd_tree_chain = make_cleanup_decref_counted_command_line (&ccmd);
- cmd = ccmd ? ccmd->commands : NULL;
- if (command_line_is_silent (cmd))
- {
-
- cmd = cmd->next;
- }
- while (cmd != NULL)
- {
- execute_control_command (cmd);
- if (breakpoint_proceeded)
- break;
- else
- cmd = cmd->next;
- }
-
- do_cleanups (this_cmd_tree_chain);
- if (breakpoint_proceeded)
- {
- if (target_can_async_p ())
-
- ;
- else
-
- again = 1;
- break;
- }
- }
- do_cleanups (old_chain);
- return again;
- }
- void
- bpstat_do_actions (void)
- {
- struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
-
- while (!ptid_equal (inferior_ptid, null_ptid)
- && target_has_execution
- && !is_exited (inferior_ptid)
- && !is_executing (inferior_ptid))
-
- if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
- break;
- discard_cleanups (cleanup_if_error);
- }
- static void
- watchpoint_value_print (struct value *val, struct ui_file *stream)
- {
- if (val == NULL)
- fprintf_unfiltered (stream, _("<unreadable>"));
- else
- {
- struct value_print_options opts;
- get_user_print_options (&opts);
- value_print (val, stream, &opts);
- }
- }
- static enum print_stop_action
- print_bp_stop_message (bpstat bs)
- {
- switch (bs->print_it)
- {
- case print_it_noop:
-
- return PRINT_UNKNOWN;
- break;
- case print_it_done:
-
- return PRINT_SRC_AND_LOC;
- break;
- case print_it_normal:
- {
- struct breakpoint *b = bs->breakpoint_at;
-
- if (b == NULL)
- return PRINT_UNKNOWN;
-
- return b->ops->print_it (bs);
- }
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("print_bp_stop_message: unrecognized enum value"));
- break;
- }
- }
- static void
- print_solib_event (int is_catchpoint)
- {
- int any_deleted
- = !VEC_empty (char_ptr, current_program_space->deleted_solibs);
- int any_added
- = !VEC_empty (so_list_ptr, current_program_space->added_solibs);
- if (!is_catchpoint)
- {
- if (any_added || any_deleted)
- ui_out_text (current_uiout,
- _("Stopped due to shared library event:\n"));
- else
- ui_out_text (current_uiout,
- _("Stopped due to shared library event (no "
- "libraries added or removed)\n"));
- }
- if (ui_out_is_mi_like_p (current_uiout))
- ui_out_field_string (current_uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
- if (any_deleted)
- {
- struct cleanup *cleanup;
- char *name;
- int ix;
- ui_out_text (current_uiout, _(" Inferior unloaded "));
- cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
- "removed");
- for (ix = 0;
- VEC_iterate (char_ptr, current_program_space->deleted_solibs,
- ix, name);
- ++ix)
- {
- if (ix > 0)
- ui_out_text (current_uiout, " ");
- ui_out_field_string (current_uiout, "library", name);
- ui_out_text (current_uiout, "\n");
- }
- do_cleanups (cleanup);
- }
- if (any_added)
- {
- struct so_list *iter;
- int ix;
- struct cleanup *cleanup;
- ui_out_text (current_uiout, _(" Inferior loaded "));
- cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
- "added");
- for (ix = 0;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
- {
- if (ix > 0)
- ui_out_text (current_uiout, " ");
- ui_out_field_string (current_uiout, "library", iter->so_name);
- ui_out_text (current_uiout, "\n");
- }
- do_cleanups (cleanup);
- }
- }
- enum print_stop_action
- bpstat_print (bpstat bs, int kind)
- {
- int val;
-
- for (; bs; bs = bs->next)
- {
- val = print_bp_stop_message (bs);
- if (val == PRINT_SRC_ONLY
- || val == PRINT_SRC_AND_LOC
- || val == PRINT_NOTHING)
- return val;
- }
-
- if (kind == TARGET_WAITKIND_LOADED)
- {
- print_solib_event (0);
- return PRINT_NOTHING;
- }
-
- return PRINT_UNKNOWN;
- }
- static int
- breakpoint_cond_eval (void *exp)
- {
- struct value *mark = value_mark ();
- int i = !value_true (evaluate_expression ((struct expression *) exp));
- value_free_to_mark (mark);
- return i;
- }
- static bpstat
- bpstat_alloc (struct bp_location *bl, bpstat **bs_link_pointer)
- {
- bpstat bs;
- bs = (bpstat) xmalloc (sizeof (*bs));
- bs->next = NULL;
- **bs_link_pointer = bs;
- *bs_link_pointer = &bs->next;
- bs->breakpoint_at = bl->owner;
- bs->bp_location_at = bl;
- incref_bp_location (bl);
-
- bs->commands = NULL;
- bs->old_val = NULL;
- bs->print_it = print_it_normal;
- return bs;
- }
- int
- watchpoints_triggered (struct target_waitstatus *ws)
- {
- int stopped_by_watchpoint = target_stopped_by_watchpoint ();
- CORE_ADDR addr;
- struct breakpoint *b;
- if (!stopped_by_watchpoint)
- {
-
- ALL_BREAKPOINTS (b)
- if (is_hardware_watchpoint (b))
- {
- struct watchpoint *w = (struct watchpoint *) b;
- w->watchpoint_triggered = watch_triggered_no;
- }
- return 0;
- }
- if (!target_stopped_data_address (¤t_target, &addr))
- {
-
- ALL_BREAKPOINTS (b)
- if (is_hardware_watchpoint (b))
- {
- struct watchpoint *w = (struct watchpoint *) b;
- w->watchpoint_triggered = watch_triggered_unknown;
- }
- return 1;
- }
-
- ALL_BREAKPOINTS (b)
- if (is_hardware_watchpoint (b))
- {
- struct watchpoint *w = (struct watchpoint *) b;
- struct bp_location *loc;
- w->watchpoint_triggered = watch_triggered_no;
- for (loc = b->loc; loc; loc = loc->next)
- {
- if (is_masked_watchpoint (b))
- {
- CORE_ADDR newaddr = addr & w->hw_wp_mask;
- CORE_ADDR start = loc->address & w->hw_wp_mask;
- if (newaddr == start)
- {
- w->watchpoint_triggered = watch_triggered_yes;
- break;
- }
- }
-
- else if (target_watchpoint_addr_within_range (¤t_target,
- addr, loc->address,
- loc->length))
- {
- w->watchpoint_triggered = watch_triggered_yes;
- break;
- }
- }
- }
- return 1;
- }
- #define WP_DELETED 1
- #define WP_VALUE_CHANGED 2
- #define WP_VALUE_NOT_CHANGED 3
- #define WP_IGNORE 4
- #define BP_TEMPFLAG 1
- #define BP_HARDWAREFLAG 2
- static int
- watchpoint_check (void *p)
- {
- bpstat bs = (bpstat) p;
- struct watchpoint *b;
- struct frame_info *fr;
- int within_current_scope;
-
- gdb_assert (bs->breakpoint_at != NULL);
- b = (struct watchpoint *) bs->breakpoint_at;
-
- if (!watchpoint_in_thread_scope (b))
- return WP_IGNORE;
- if (b->exp_valid_block == NULL)
- within_current_scope = 1;
- else
- {
- struct frame_info *frame = get_current_frame ();
- struct gdbarch *frame_arch = get_frame_arch (frame);
- CORE_ADDR frame_pc = get_frame_pc (frame);
-
- if (gdbarch_in_function_epilogue_p (frame_arch, frame_pc))
- return WP_IGNORE;
- fr = frame_find_by_id (b->watchpoint_frame);
- within_current_scope = (fr != NULL);
-
- if (within_current_scope)
- {
- struct symbol *function;
- function = get_frame_function (fr);
- if (function == NULL
- || !contained_in (b->exp_valid_block,
- SYMBOL_BLOCK_VALUE (function)))
- within_current_scope = 0;
- }
- if (within_current_scope)
-
- select_frame (fr);
- }
- if (within_current_scope)
- {
-
- int pc = 0;
- struct value *mark;
- struct value *new_val;
- if (is_masked_watchpoint (&b->base))
-
- return WP_VALUE_CHANGED;
- mark = value_mark ();
- fetch_subexp_value (b->exp, &pc, &new_val, NULL, NULL, 0);
- if (b->val_bitsize != 0)
- new_val = extract_bitfield_from_watchpoint_value (b, new_val);
-
- if ((b->val != NULL) != (new_val != NULL)
- || (b->val != NULL && !value_equal_contents (b->val, new_val)))
- {
- if (new_val != NULL)
- {
- release_value (new_val);
- value_free_to_mark (mark);
- }
- bs->old_val = b->val;
- b->val = new_val;
- b->val_valid = 1;
- return WP_VALUE_CHANGED;
- }
- else
- {
-
- value_free_to_mark (mark);
- return WP_VALUE_NOT_CHANGED;
- }
- }
- else
- {
- struct ui_out *uiout = current_uiout;
-
-
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
- ui_out_text (uiout, "\nWatchpoint ");
- ui_out_field_int (uiout, "wpnum", b->base.number);
- ui_out_text (uiout,
- " deleted because the program has left the block in\n\
- which its expression is valid.\n");
-
- decref_counted_command_line (&b->base.commands);
- watchpoint_del_at_next_stop (b);
- return WP_DELETED;
- }
- }
- static int
- bpstat_check_location (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- struct breakpoint *b = bl->owner;
-
- gdb_assert (b != NULL);
- return b->ops->breakpoint_hit (bl, aspace, bp_addr, ws);
- }
- static void
- bpstat_check_watchpoint (bpstat bs)
- {
- const struct bp_location *bl;
- struct watchpoint *b;
-
- bl = bs->bp_location_at;
- gdb_assert (bl != NULL);
- b = (struct watchpoint *) bs->breakpoint_at;
- gdb_assert (b != NULL);
- {
- int must_check_value = 0;
- if (b->base.type == bp_watchpoint)
-
- must_check_value = 1;
- else if (b->watchpoint_triggered == watch_triggered_yes)
-
- must_check_value = 1;
- else if (b->watchpoint_triggered == watch_triggered_unknown
- && b->base.type == bp_hardware_watchpoint)
-
- must_check_value = 1;
- if (must_check_value)
- {
- char *message
- = xstrprintf ("Error evaluating expression for watchpoint %d\n",
- b->base.number);
- struct cleanup *cleanups = make_cleanup (xfree, message);
- int e = catch_errors (watchpoint_check, bs, message,
- RETURN_MASK_ALL);
- do_cleanups (cleanups);
- switch (e)
- {
- case WP_DELETED:
-
- bs->print_it = print_it_done;
-
- break;
- case WP_IGNORE:
- bs->print_it = print_it_noop;
- bs->stop = 0;
- break;
- case WP_VALUE_CHANGED:
- if (b->base.type == bp_read_watchpoint)
- {
-
- int other_write_watchpoint = 0;
- if (bl->watchpoint_type == hw_read)
- {
- struct breakpoint *other_b;
- ALL_BREAKPOINTS (other_b)
- if (other_b->type == bp_hardware_watchpoint
- || other_b->type == bp_access_watchpoint)
- {
- struct watchpoint *other_w =
- (struct watchpoint *) other_b;
- if (other_w->watchpoint_triggered
- == watch_triggered_yes)
- {
- other_write_watchpoint = 1;
- break;
- }
- }
- }
- if (other_write_watchpoint
- || bl->watchpoint_type == hw_access)
- {
-
- bs->print_it = print_it_noop;
- bs->stop = 0;
- }
- }
- break;
- case WP_VALUE_NOT_CHANGED:
- if (b->base.type == bp_hardware_watchpoint
- || b->base.type == bp_watchpoint)
- {
-
- bs->print_it = print_it_noop;
- bs->stop = 0;
- }
-
- break;
- default:
-
- case 0:
-
- printf_filtered (_("Watchpoint %d deleted.\n"), b->base.number);
- watchpoint_del_at_next_stop (b);
-
- bs->print_it = print_it_done;
- break;
- }
- }
- else
- {
-
- bs->print_it = print_it_noop;
- bs->stop = 0;
- }
- }
- }
- static void
- bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
- {
- const struct bp_location *bl;
- struct breakpoint *b;
- int value_is_zero = 0;
- struct expression *cond;
- gdb_assert (bs->stop);
-
- bl = bs->bp_location_at;
- gdb_assert (bl != NULL);
- b = bs->breakpoint_at;
- gdb_assert (b != NULL);
-
- if (frame_id_p (b->frame_id)
- && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ())))
- {
- bs->stop = 0;
- return;
- }
-
- if ((b->thread != -1 && b->thread != pid_to_thread_id (ptid))
- || (b->task != 0 && b->task != ada_get_task_number (ptid)))
- {
- bs->stop = 0;
- return;
- }
-
- bs->stop = breakpoint_ext_lang_cond_says_stop (b);
- if (is_watchpoint (b))
- {
- struct watchpoint *w = (struct watchpoint *) b;
- cond = w->cond_exp;
- }
- else
- cond = bl->cond;
- if (cond && b->disposition != disp_del_at_next_stop)
- {
- int within_current_scope = 1;
- struct watchpoint * w;
-
- struct value *mark = value_mark ();
- if (is_watchpoint (b))
- w = (struct watchpoint *) b;
- else
- w = NULL;
-
- if (w == NULL || w->cond_exp_valid_block == NULL)
- select_frame (get_current_frame ());
- else
- {
- struct frame_info *frame;
-
- frame = block_innermost_frame (w->cond_exp_valid_block);
- if (frame != NULL)
- select_frame (frame);
- else
- within_current_scope = 0;
- }
- if (within_current_scope)
- value_is_zero
- = catch_errors (breakpoint_cond_eval, cond,
- "Error in testing breakpoint condition:\n",
- RETURN_MASK_ALL);
- else
- {
- warning (_("Watchpoint condition cannot be tested "
- "in the current scope"));
-
- value_is_zero = 0;
- }
- FIXME
- value_free_to_mark (mark);
- }
- if (cond && value_is_zero)
- {
- bs->stop = 0;
- }
- else if (b->ignore_count > 0)
- {
- b->ignore_count--;
- bs->stop = 0;
-
- ++(b->hit_count);
- observer_notify_breakpoint_modified (b);
- }
- }
- FIXME
- bpstat
- bpstat_stop_status (struct address_space *aspace,
- CORE_ADDR bp_addr, ptid_t ptid,
- const struct target_waitstatus *ws)
- {
- struct breakpoint *b = NULL;
- struct bp_location *bl;
- struct bp_location *loc;
-
- bpstat bs_head = NULL, *bs_link = &bs_head;
-
- bpstat bs;
- int ix;
- int need_remove_insert;
- int removed_any;
-
- ALL_BREAKPOINTS (b)
- {
- if (!breakpoint_enabled (b))
- continue;
- for (bl = b->loc; bl != NULL; bl = bl->next)
- {
-
- if (b->type == bp_hardware_watchpoint && bl != b->loc)
- break;
- if (!bl->enabled || bl->shlib_disabled)
- continue;
- if (!bpstat_check_location (bl, aspace, bp_addr, ws))
- continue;
-
- bs = bpstat_alloc (bl, &bs_link);
-
- bs->stop = 1;
- bs->print = 1;
-
- if (b->type == bp_watchpoint_scope && b->related_breakpoint != b)
- {
- struct watchpoint *w = (struct watchpoint *) b->related_breakpoint;
- w->watchpoint_triggered = watch_triggered_yes;
- }
- }
- }
-
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
- {
- if (breakpoint_location_address_match (loc, aspace, bp_addr))
- {
- bs = bpstat_alloc (loc, &bs_link);
-
- bs->stop = 0;
- bs->print = 0;
- bs->print_it = print_it_noop;
- }
- }
-
- for (bs = bs_head; bs != NULL; bs = bs->next)
- {
- if (bs->breakpoint_at && bs->breakpoint_at->type == bp_shlib_event)
- {
- handle_solib_event ();
- break;
- }
- }
-
- removed_any = 0;
- for (bs = bs_head; bs != NULL; bs = bs->next)
- {
- if (!bs->stop)
- continue;
- b = bs->breakpoint_at;
- b->ops->check_status (bs);
- if (bs->stop)
- {
- bpstat_check_breakpoint_conditions (bs, ptid);
- if (bs->stop)
- {
- ++(b->hit_count);
- observer_notify_breakpoint_modified (b);
-
- if (b->disposition == disp_disable)
- {
- --(b->enable_count);
- if (b->enable_count <= 0)
- b->enable_state = bp_disabled;
- removed_any = 1;
- }
- if (b->silent)
- bs->print = 0;
- bs->commands = b->commands;
- incref_counted_command_line (bs->commands);
- if (command_line_is_silent (bs->commands
- ? bs->commands->commands : NULL))
- bs->print = 0;
- b->ops->after_condition_true (bs);
- }
- }
-
- if (!bs->stop || !bs->print)
- bs->print_it = print_it_noop;
- }
-
- need_remove_insert = 0;
- if (! bpstat_causes_stop (bs_head))
- for (bs = bs_head; bs != NULL; bs = bs->next)
- if (!bs->stop
- && bs->breakpoint_at
- && is_hardware_watchpoint (bs->breakpoint_at))
- {
- struct watchpoint *w = (struct watchpoint *) bs->breakpoint_at;
- update_watchpoint (w, 0 );
- need_remove_insert = 1;
- }
- if (need_remove_insert)
- update_global_location_list (UGLL_MAY_INSERT);
- else if (removed_any)
- update_global_location_list (UGLL_DONT_INSERT);
- return bs_head;
- }
- static void
- handle_jit_event (void)
- {
- struct frame_info *frame;
- struct gdbarch *gdbarch;
-
- target_terminal_ours_for_output ();
- frame = get_current_frame ();
- gdbarch = get_frame_arch (frame);
- jit_event_handler (gdbarch);
- target_terminal_inferior ();
- }
- struct bpstat_what
- bpstat_what (bpstat bs_head)
- {
- struct bpstat_what retval;
- int jit_event = 0;
- bpstat bs;
- retval.main_action = BPSTAT_WHAT_KEEP_CHECKING;
- retval.call_dummy = STOP_NONE;
- retval.is_longjmp = 0;
- for (bs = bs_head; bs != NULL; bs = bs->next)
- {
-
- enum bpstat_what_main_action this_action = BPSTAT_WHAT_KEEP_CHECKING;
- enum bptype bptype;
- if (bs->breakpoint_at == NULL)
- {
-
- bptype = bp_none;
- }
- else
- bptype = bs->breakpoint_at->type;
- switch (bptype)
- {
- case bp_none:
- break;
- case bp_breakpoint:
- case bp_hardware_breakpoint:
- case bp_single_step:
- case bp_until:
- case bp_finish:
- case bp_shlib_event:
- if (bs->stop)
- {
- if (bs->print)
- this_action = BPSTAT_WHAT_STOP_NOISY;
- else
- this_action = BPSTAT_WHAT_STOP_SILENT;
- }
- else
- this_action = BPSTAT_WHAT_SINGLE;
- break;
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- case bp_read_watchpoint:
- case bp_access_watchpoint:
- if (bs->stop)
- {
- if (bs->print)
- this_action = BPSTAT_WHAT_STOP_NOISY;
- else
- this_action = BPSTAT_WHAT_STOP_SILENT;
- }
- else
- {
-
- }
- break;
- case bp_longjmp:
- case bp_longjmp_call_dummy:
- case bp_exception:
- this_action = BPSTAT_WHAT_SET_LONGJMP_RESUME;
- retval.is_longjmp = bptype != bp_exception;
- break;
- case bp_longjmp_resume:
- case bp_exception_resume:
- this_action = BPSTAT_WHAT_CLEAR_LONGJMP_RESUME;
- retval.is_longjmp = bptype == bp_longjmp_resume;
- break;
- case bp_step_resume:
- if (bs->stop)
- this_action = BPSTAT_WHAT_STEP_RESUME;
- else
- {
-
- this_action = BPSTAT_WHAT_SINGLE;
- }
- break;
- case bp_hp_step_resume:
- if (bs->stop)
- this_action = BPSTAT_WHAT_HP_STEP_RESUME;
- else
- {
-
- this_action = BPSTAT_WHAT_SINGLE;
- }
- break;
- case bp_watchpoint_scope:
- case bp_thread_event:
- case bp_overlay_event:
- case bp_longjmp_master:
- case bp_std_terminate_master:
- case bp_exception_master:
- this_action = BPSTAT_WHAT_SINGLE;
- break;
- case bp_catchpoint:
- if (bs->stop)
- {
- if (bs->print)
- this_action = BPSTAT_WHAT_STOP_NOISY;
- else
- this_action = BPSTAT_WHAT_STOP_SILENT;
- }
- else
- {
-
- }
- break;
- case bp_jit_event:
- jit_event = 1;
- this_action = BPSTAT_WHAT_SINGLE;
- break;
- case bp_call_dummy:
-
- retval.call_dummy = STOP_STACK_DUMMY;
- this_action = BPSTAT_WHAT_STOP_SILENT;
- break;
- case bp_std_terminate:
-
- retval.call_dummy = STOP_STD_TERMINATE;
- this_action = BPSTAT_WHAT_STOP_SILENT;
- break;
- case bp_tracepoint:
- case bp_fast_tracepoint:
- case bp_static_tracepoint:
-
- internal_error (__FILE__, __LINE__,
- _("bpstat_what: tracepoint encountered"));
- break;
- case bp_gnu_ifunc_resolver:
-
- this_action = BPSTAT_WHAT_SINGLE;
- break;
- case bp_gnu_ifunc_resolver_return:
-
- this_action = BPSTAT_WHAT_KEEP_CHECKING;
- break;
- case bp_dprintf:
- if (bs->stop)
- this_action = BPSTAT_WHAT_STOP_SILENT;
- else
- this_action = BPSTAT_WHAT_SINGLE;
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("bpstat_what: unhandled bptype %d"), (int) bptype);
- }
- retval.main_action = max (retval.main_action, this_action);
- }
-
- if (jit_event)
- {
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "bpstat_what: bp_jit_event\n");
- handle_jit_event ();
- }
- for (bs = bs_head; bs != NULL; bs = bs->next)
- {
- struct breakpoint *b = bs->breakpoint_at;
- if (b == NULL)
- continue;
- switch (b->type)
- {
- case bp_gnu_ifunc_resolver:
- gnu_ifunc_resolver_stop (b);
- break;
- case bp_gnu_ifunc_resolver_return:
- gnu_ifunc_resolver_return_stop (b);
- break;
- }
- }
- return retval;
- }
- int
- bpstat_should_step (void)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- if (breakpoint_enabled (b) && b->type == bp_watchpoint && b->loc != NULL)
- return 1;
- return 0;
- }
- int
- bpstat_causes_stop (bpstat bs)
- {
- for (; bs != NULL; bs = bs->next)
- if (bs->stop)
- return 1;
- return 0;
- }
- static char *
- wrap_indent_at_field (struct ui_out *uiout, const char *col_name)
- {
- static char wrap_indent[80];
- int i, total_width, width, align;
- char *text;
- total_width = 0;
- for (i = 1; ui_out_query_field (uiout, i, &width, &align, &text); i++)
- {
- if (strcmp (text, col_name) == 0)
- {
- gdb_assert (total_width < sizeof wrap_indent);
- memset (wrap_indent, ' ', total_width);
- wrap_indent[total_width] = 0;
- return wrap_indent;
- }
- total_width += width + 1;
- }
- return NULL;
- }
- static const char *
- bp_condition_evaluator (struct breakpoint *b)
- {
- struct bp_location *bl;
- char host_evals = 0;
- char target_evals = 0;
- if (!b)
- return NULL;
- if (!is_breakpoint (b))
- return NULL;
- if (gdb_evaluates_breakpoint_condition_p ()
- || !target_supports_evaluation_of_breakpoint_conditions ())
- return condition_evaluation_host;
- for (bl = b->loc; bl; bl = bl->next)
- {
- if (bl->cond_bytecode)
- target_evals++;
- else
- host_evals++;
- }
- if (host_evals && target_evals)
- return condition_evaluation_both;
- else if (target_evals)
- return condition_evaluation_target;
- else
- return condition_evaluation_host;
- }
- static const char *
- bp_location_condition_evaluator (struct bp_location *bl)
- {
- if (bl && !is_breakpoint (bl->owner))
- return NULL;
- if (gdb_evaluates_breakpoint_condition_p ()
- || !target_supports_evaluation_of_breakpoint_conditions ())
- return condition_evaluation_host;
- if (bl && bl->cond_bytecode)
- return condition_evaluation_target;
- else
- return condition_evaluation_host;
- }
- static void
- print_breakpoint_location (struct breakpoint *b,
- struct bp_location *loc)
- {
- struct ui_out *uiout = current_uiout;
- struct cleanup *old_chain = save_current_program_space ();
- if (loc != NULL && loc->shlib_disabled)
- loc = NULL;
- if (loc != NULL)
- set_current_program_space (loc->pspace);
- if (b->display_canonical)
- ui_out_field_string (uiout, "what", b->addr_string);
- else if (loc && loc->symtab)
- {
- struct symbol *sym
- = find_pc_sect_function (loc->address, loc->section);
- if (sym)
- {
- ui_out_text (uiout, "in ");
- ui_out_field_string (uiout, "func",
- SYMBOL_PRINT_NAME (sym));
- ui_out_text (uiout, " ");
- ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what"));
- ui_out_text (uiout, "at ");
- }
- ui_out_field_string (uiout, "file",
- symtab_to_filename_for_display (loc->symtab));
- ui_out_text (uiout, ":");
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "fullname",
- symtab_to_fullname (loc->symtab));
- ui_out_field_int (uiout, "line", loc->line_number);
- }
- else if (loc)
- {
- struct ui_file *stb = mem_fileopen ();
- struct cleanup *stb_chain = make_cleanup_ui_file_delete (stb);
- print_address_symbolic (loc->gdbarch, loc->address, stb,
- demangle, "");
- ui_out_field_stream (uiout, "at", stb);
- do_cleanups (stb_chain);
- }
- else
- ui_out_field_string (uiout, "pending", b->addr_string);
- if (loc && is_breakpoint (b)
- && breakpoint_condition_evaluation_mode () == condition_evaluation_target
- && bp_condition_evaluator (b) == condition_evaluation_both)
- {
- ui_out_text (uiout, " (");
- ui_out_field_string (uiout, "evaluated-by",
- bp_location_condition_evaluator (loc));
- ui_out_text (uiout, ")");
- }
- do_cleanups (old_chain);
- }
- static const char *
- bptype_string (enum bptype type)
- {
- struct ep_type_description
- {
- enum bptype type;
- char *description;
- };
- static struct ep_type_description bptypes[] =
- {
- {bp_none, "?deleted?"},
- {bp_breakpoint, "breakpoint"},
- {bp_hardware_breakpoint, "hw breakpoint"},
- {bp_single_step, "sw single-step"},
- {bp_until, "until"},
- {bp_finish, "finish"},
- {bp_watchpoint, "watchpoint"},
- {bp_hardware_watchpoint, "hw watchpoint"},
- {bp_read_watchpoint, "read watchpoint"},
- {bp_access_watchpoint, "acc watchpoint"},
- {bp_longjmp, "longjmp"},
- {bp_longjmp_resume, "longjmp resume"},
- {bp_longjmp_call_dummy, "longjmp for call dummy"},
- {bp_exception, "exception"},
- {bp_exception_resume, "exception resume"},
- {bp_step_resume, "step resume"},
- {bp_hp_step_resume, "high-priority step resume"},
- {bp_watchpoint_scope, "watchpoint scope"},
- {bp_call_dummy, "call dummy"},
- {bp_std_terminate, "std::terminate"},
- {bp_shlib_event, "shlib events"},
- {bp_thread_event, "thread events"},
- {bp_overlay_event, "overlay events"},
- {bp_longjmp_master, "longjmp master"},
- {bp_std_terminate_master, "std::terminate master"},
- {bp_exception_master, "exception master"},
- {bp_catchpoint, "catchpoint"},
- {bp_tracepoint, "tracepoint"},
- {bp_fast_tracepoint, "fast tracepoint"},
- {bp_static_tracepoint, "static tracepoint"},
- {bp_dprintf, "dprintf"},
- {bp_jit_event, "jit events"},
- {bp_gnu_ifunc_resolver, "STT_GNU_IFUNC resolver"},
- {bp_gnu_ifunc_resolver_return, "STT_GNU_IFUNC resolver return"},
- };
- if (((int) type >= (sizeof (bptypes) / sizeof (bptypes[0])))
- || ((int) type != bptypes[(int) type].type))
- internal_error (__FILE__, __LINE__,
- _("bptypes table does not describe type #%d."),
- (int) type);
- return bptypes[(int) type].description;
- }
- static void
- output_thread_groups (struct ui_out *uiout,
- const char *field_name,
- VEC(int) *inf_num,
- int mi_only)
- {
- struct cleanup *back_to;
- int is_mi = ui_out_is_mi_like_p (uiout);
- int inf;
- int i;
-
- if (!is_mi && mi_only)
- return;
- back_to = make_cleanup_ui_out_list_begin_end (uiout, field_name);
- for (i = 0; VEC_iterate (int, inf_num, i, inf); ++i)
- {
- if (is_mi)
- {
- char mi_group[10];
- xsnprintf (mi_group, sizeof (mi_group), "i%d", inf);
- ui_out_field_string (uiout, NULL, mi_group);
- }
- else
- {
- if (i == 0)
- ui_out_text (uiout, " inf ");
- else
- ui_out_text (uiout, ", ");
- ui_out_text (uiout, plongest (inf));
- }
- }
- do_cleanups (back_to);
- }
- static void
- print_one_breakpoint_location (struct breakpoint *b,
- struct bp_location *loc,
- int loc_number,
- struct bp_location **last_loc,
- int allflag)
- {
- struct command_line *l;
- static char bpenables[] = "nynny";
- struct ui_out *uiout = current_uiout;
- int header_of_multiple = 0;
- int part_of_multiple = (loc != NULL);
- struct value_print_options opts;
- get_user_print_options (&opts);
- gdb_assert (!loc || loc_number != 0);
-
- if (loc == NULL
- && (b->loc != NULL
- && (b->loc->next != NULL || !b->loc->enabled)))
- header_of_multiple = 1;
- if (loc == NULL)
- loc = b->loc;
- annotate_record ();
-
- annotate_field (0);
- if (part_of_multiple)
- {
- char *formatted;
- formatted = xstrprintf ("%d.%d", b->number, loc_number);
- ui_out_field_string (uiout, "number", formatted);
- xfree (formatted);
- }
- else
- {
- ui_out_field_int (uiout, "number", b->number);
- }
-
- annotate_field (1);
- if (part_of_multiple)
- ui_out_field_skip (uiout, "type");
- else
- ui_out_field_string (uiout, "type", bptype_string (b->type));
-
- annotate_field (2);
- if (part_of_multiple)
- ui_out_field_skip (uiout, "disp");
- else
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
-
- annotate_field (3);
- if (part_of_multiple)
- ui_out_field_string (uiout, "enabled", loc->enabled ? "y" : "n");
- else
- ui_out_field_fmt (uiout, "enabled", "%c",
- bpenables[(int) b->enable_state]);
- ui_out_spaces (uiout, 2);
-
- if (b->ops != NULL && b->ops->print_one != NULL)
- {
-
- gdb_assert (b->loc == NULL || b->loc->next == NULL);
- b->ops->print_one (b, last_loc);
- }
- else
- switch (b->type)
- {
- case bp_none:
- internal_error (__FILE__, __LINE__,
- _("print_one_breakpoint: bp_none encountered\n"));
- break;
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- case bp_read_watchpoint:
- case bp_access_watchpoint:
- {
- struct watchpoint *w = (struct watchpoint *) b;
-
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- ui_out_field_string (uiout, "what", w->exp_string);
- }
- break;
- case bp_breakpoint:
- case bp_hardware_breakpoint:
- case bp_single_step:
- case bp_until:
- case bp_finish:
- case bp_longjmp:
- case bp_longjmp_resume:
- case bp_longjmp_call_dummy:
- case bp_exception:
- case bp_exception_resume:
- case bp_step_resume:
- case bp_hp_step_resume:
- case bp_watchpoint_scope:
- case bp_call_dummy:
- case bp_std_terminate:
- case bp_shlib_event:
- case bp_thread_event:
- case bp_overlay_event:
- case bp_longjmp_master:
- case bp_std_terminate_master:
- case bp_exception_master:
- case bp_tracepoint:
- case bp_fast_tracepoint:
- case bp_static_tracepoint:
- case bp_dprintf:
- case bp_jit_event:
- case bp_gnu_ifunc_resolver:
- case bp_gnu_ifunc_resolver_return:
- if (opts.addressprint)
- {
- annotate_field (4);
- if (header_of_multiple)
- ui_out_field_string (uiout, "addr", "<MULTIPLE>");
- else if (b->loc == NULL || loc->shlib_disabled)
- ui_out_field_string (uiout, "addr", "<PENDING>");
- else
- ui_out_field_core_addr (uiout, "addr",
- loc->gdbarch, loc->address);
- }
- annotate_field (5);
- if (!header_of_multiple)
- print_breakpoint_location (b, loc);
- if (b->loc)
- *last_loc = b->loc;
- break;
- }
- if (loc != NULL && !header_of_multiple)
- {
- struct inferior *inf;
- VEC(int) *inf_num = NULL;
- int mi_only = 1;
- ALL_INFERIORS (inf)
- {
- if (inf->pspace == loc->pspace)
- VEC_safe_push (int, inf_num, inf->num);
- }
-
- if (allflag
- || (!gdbarch_has_global_breakpoints (target_gdbarch ())
- && (number_of_program_spaces () > 1
- || number_of_inferiors () > 1)
-
- && loc->owner->type != bp_catchpoint))
- mi_only = 0;
- output_thread_groups (uiout, "thread-groups", inf_num, mi_only);
- VEC_free (int, inf_num);
- }
- if (!part_of_multiple)
- {
- if (b->thread != -1)
- {
- FIXME
- ui_out_text (uiout, " thread ");
- ui_out_field_int (uiout, "thread", b->thread);
- }
- else if (b->task != 0)
- {
- ui_out_text (uiout, " task ");
- ui_out_field_int (uiout, "task", b->task);
- }
- }
- ui_out_text (uiout, "\n");
- if (!part_of_multiple)
- b->ops->print_one_detail (b, uiout);
- if (part_of_multiple && frame_id_p (b->frame_id))
- {
- annotate_field (6);
- ui_out_text (uiout, "\tstop only in stack frame at ");
- FIXME
- ui_out_field_core_addr (uiout, "frame",
- b->gdbarch, b->frame_id.stack_addr);
- ui_out_text (uiout, "\n");
- }
- if (!part_of_multiple && b->cond_string)
- {
- annotate_field (7);
- if (is_tracepoint (b))
- ui_out_text (uiout, "\ttrace only if ");
- else
- ui_out_text (uiout, "\tstop only if ");
- ui_out_field_string (uiout, "cond", b->cond_string);
-
- if (is_breakpoint (b)
- && breakpoint_condition_evaluation_mode ()
- == condition_evaluation_target)
- {
- ui_out_text (uiout, " (");
- ui_out_field_string (uiout, "evaluated-by",
- bp_condition_evaluator (b));
- ui_out_text (uiout, " evals)");
- }
- ui_out_text (uiout, "\n");
- }
- if (!part_of_multiple && b->thread != -1)
- {
- FIXME
- ui_out_text (uiout, "\tstop only in thread ");
- ui_out_field_int (uiout, "thread", b->thread);
- ui_out_text (uiout, "\n");
- }
- if (!part_of_multiple)
- {
- if (b->hit_count)
- {
- FIXME
- if (is_catchpoint (b))
- ui_out_text (uiout, "\tcatchpoint");
- else if (is_tracepoint (b))
- ui_out_text (uiout, "\ttracepoint");
- else
- ui_out_text (uiout, "\tbreakpoint");
- ui_out_text (uiout, " already hit ");
- ui_out_field_int (uiout, "times", b->hit_count);
- if (b->hit_count == 1)
- ui_out_text (uiout, " time\n");
- else
- ui_out_text (uiout, " times\n");
- }
- else
- {
-
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_int (uiout, "times", b->hit_count);
- }
- }
- if (!part_of_multiple && b->ignore_count)
- {
- annotate_field (8);
- ui_out_text (uiout, "\tignore next ");
- ui_out_field_int (uiout, "ignore", b->ignore_count);
- ui_out_text (uiout, " hits\n");
- }
-
- if (!part_of_multiple && b->enable_count > 1)
- {
- annotate_field (8);
- ui_out_text (uiout, "\tdisable after ");
-
- if (b->ignore_count)
- ui_out_text (uiout, "additional ");
- else
- ui_out_text (uiout, "next ");
- ui_out_field_int (uiout, "enable", b->enable_count);
- ui_out_text (uiout, " hits\n");
- }
- if (!part_of_multiple && is_tracepoint (b))
- {
- struct tracepoint *tp = (struct tracepoint *) b;
- if (tp->traceframe_usage)
- {
- ui_out_text (uiout, "\ttrace buffer usage ");
- ui_out_field_int (uiout, "traceframe-usage", tp->traceframe_usage);
- ui_out_text (uiout, " bytes\n");
- }
- }
- l = b->commands ? b->commands->commands : NULL;
- if (!part_of_multiple && l)
- {
- struct cleanup *script_chain;
- annotate_field (9);
- script_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "script");
- print_command_lines (uiout, l, 4);
- do_cleanups (script_chain);
- }
- if (is_tracepoint (b))
- {
- struct tracepoint *t = (struct tracepoint *) b;
- if (!part_of_multiple && t->pass_count)
- {
- annotate_field (10);
- ui_out_text (uiout, "\tpass count ");
- ui_out_field_int (uiout, "pass", t->pass_count);
- ui_out_text (uiout, " \n");
- }
-
- if (!header_of_multiple && loc != NULL && !loc->shlib_disabled)
- {
- annotate_field (11);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "installed",
- loc->inserted ? "y" : "n");
- else
- {
- if (loc->inserted)
- ui_out_text (uiout, "\t");
- else
- ui_out_text (uiout, "\tnot ");
- ui_out_text (uiout, "installed on target\n");
- }
- }
- }
- if (ui_out_is_mi_like_p (uiout) && !part_of_multiple)
- {
- if (is_watchpoint (b))
- {
- struct watchpoint *w = (struct watchpoint *) b;
- ui_out_field_string (uiout, "original-location", w->exp_string);
- }
- else if (b->addr_string)
- ui_out_field_string (uiout, "original-location", b->addr_string);
- }
- }
- static void
- print_one_breakpoint (struct breakpoint *b,
- struct bp_location **last_loc,
- int allflag)
- {
- struct cleanup *bkpt_chain;
- struct ui_out *uiout = current_uiout;
- bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt");
- print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
- do_cleanups (bkpt_chain);
-
- if (b->ops == NULL || b->ops->print_one == NULL)
- {
-
- if (b->loc
- && !is_hardware_watchpoint (b)
- && (b->loc->next || !b->loc->enabled))
- {
- struct bp_location *loc;
- int n = 1;
- for (loc = b->loc; loc; loc = loc->next, ++n)
- {
- struct cleanup *inner2 =
- make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
- print_one_breakpoint_location (b, loc, n, last_loc, allflag);
- do_cleanups (inner2);
- }
- }
- }
- }
- static int
- breakpoint_address_bits (struct breakpoint *b)
- {
- int print_address_bits = 0;
- struct bp_location *loc;
- for (loc = b->loc; loc; loc = loc->next)
- {
- int addr_bit;
-
- if (b->type == bp_watchpoint && loc->watchpoint_type == -1)
- continue;
- addr_bit = gdbarch_addr_bit (loc->gdbarch);
- if (addr_bit > print_address_bits)
- print_address_bits = addr_bit;
- }
- return print_address_bits;
- }
- struct captured_breakpoint_query_args
- {
- int bnum;
- };
- static int
- do_captured_breakpoint_query (struct ui_out *uiout, void *data)
- {
- struct captured_breakpoint_query_args *args = data;
- struct breakpoint *b;
- struct bp_location *dummy_loc = NULL;
- ALL_BREAKPOINTS (b)
- {
- if (args->bnum == b->number)
- {
- print_one_breakpoint (b, &dummy_loc, 0);
- return GDB_RC_OK;
- }
- }
- return GDB_RC_NONE;
- }
- enum gdb_rc
- gdb_breakpoint_query (struct ui_out *uiout, int bnum,
- char **error_message)
- {
- struct captured_breakpoint_query_args args;
- args.bnum = bnum;
-
- if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
- error_message, RETURN_MASK_ALL) < 0)
- return GDB_RC_FAIL;
- else
- return GDB_RC_OK;
- }
- int
- user_breakpoint_p (struct breakpoint *b)
- {
- return b->number > 0;
- }
- static int
- breakpoint_1 (char *args, int allflag,
- int (*filter) (const struct breakpoint *))
- {
- struct breakpoint *b;
- struct bp_location *last_loc = NULL;
- int nr_printable_breakpoints;
- struct cleanup *bkpttbl_chain;
- struct value_print_options opts;
- int print_address_bits = 0;
- int print_type_col_width = 14;
- struct ui_out *uiout = current_uiout;
- get_user_print_options (&opts);
-
- nr_printable_breakpoints = 0;
- ALL_BREAKPOINTS (b)
- {
-
- if (filter && !filter (b))
- continue;
-
- if (args != NULL && *args != '\0')
- {
- if (allflag && parse_and_eval_long (args) != b->number)
- continue;
- if (!allflag && !number_is_in_list (args, b->number))
- continue;
- }
- if (allflag || user_breakpoint_p (b))
- {
- int addr_bit, type_len;
- addr_bit = breakpoint_address_bits (b);
- if (addr_bit > print_address_bits)
- print_address_bits = addr_bit;
- type_len = strlen (bptype_string (b->type));
- if (type_len > print_type_col_width)
- print_type_col_width = type_len;
- nr_printable_breakpoints++;
- }
- }
- if (opts.addressprint)
- bkpttbl_chain
- = make_cleanup_ui_out_table_begin_end (uiout, 6,
- nr_printable_breakpoints,
- "BreakpointTable");
- else
- bkpttbl_chain
- = make_cleanup_ui_out_table_begin_end (uiout, 5,
- nr_printable_breakpoints,
- "BreakpointTable");
- if (nr_printable_breakpoints > 0)
- annotate_breakpoints_headers ();
- if (nr_printable_breakpoints > 0)
- annotate_field (0);
- ui_out_table_header (uiout, 7, ui_left, "number", "Num");
- if (nr_printable_breakpoints > 0)
- annotate_field (1);
- ui_out_table_header (uiout, print_type_col_width, ui_left,
- "type", "Type");
- if (nr_printable_breakpoints > 0)
- annotate_field (2);
- ui_out_table_header (uiout, 4, ui_left, "disp", "Disp");
- if (nr_printable_breakpoints > 0)
- annotate_field (3);
- ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");
- if (opts.addressprint)
- {
- if (nr_printable_breakpoints > 0)
- annotate_field (4);
- if (print_address_bits <= 32)
- ui_out_table_header (uiout, 10, ui_left,
- "addr", "Address");
- else
- ui_out_table_header (uiout, 18, ui_left,
- "addr", "Address");
- }
- if (nr_printable_breakpoints > 0)
- annotate_field (5);
- ui_out_table_header (uiout, 40, ui_noalign, "what", "What");
- ui_out_table_body (uiout);
- if (nr_printable_breakpoints > 0)
- annotate_breakpoints_table ();
- ALL_BREAKPOINTS (b)
- {
- QUIT;
-
- if (filter && !filter (b))
- continue;
-
- if (args != NULL && *args != '\0')
- {
- if (allflag)
- {
- if (parse_and_eval_long (args) != b->number)
- continue;
- }
- else
- {
- if (!number_is_in_list (args, b->number))
- continue;
- }
- }
-
- if (allflag || user_breakpoint_p (b))
- print_one_breakpoint (b, &last_loc, allflag);
- }
- do_cleanups (bkpttbl_chain);
- if (nr_printable_breakpoints == 0)
- {
-
- if (!filter)
- {
- if (args == NULL || *args == '\0')
- ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
- else
- ui_out_message (uiout, 0,
- "No breakpoint or watchpoint matching '%s'.\n",
- args);
- }
- }
- else
- {
- if (last_loc && !server_command)
- set_next_address (last_loc->gdbarch, last_loc->address);
- }
- FIXME
- annotate_breakpoints_table_end ();
- return nr_printable_breakpoints;
- }
- static void
- default_collect_info (void)
- {
- struct ui_out *uiout = current_uiout;
-
- if (!*default_collect)
- return;
-
- ui_out_text (uiout, "default collect ");
- ui_out_field_string (uiout, "default-collect", default_collect);
- ui_out_text (uiout, " \n");
- }
- static void
- breakpoints_info (char *args, int from_tty)
- {
- breakpoint_1 (args, 0, NULL);
- default_collect_info ();
- }
- static void
- watchpoints_info (char *args, int from_tty)
- {
- int num_printed = breakpoint_1 (args, 0, is_watchpoint);
- struct ui_out *uiout = current_uiout;
- if (num_printed == 0)
- {
- if (args == NULL || *args == '\0')
- ui_out_message (uiout, 0, "No watchpoints.\n");
- else
- ui_out_message (uiout, 0, "No watchpoint matching '%s'.\n", args);
- }
- }
- static void
- maintenance_info_breakpoints (char *args, int from_tty)
- {
- breakpoint_1 (args, 1, NULL);
- default_collect_info ();
- }
- static int
- breakpoint_has_pc (struct breakpoint *b,
- struct program_space *pspace,
- CORE_ADDR pc, struct obj_section *section)
- {
- struct bp_location *bl = b->loc;
- for (; bl; bl = bl->next)
- {
- if (bl->pspace == pspace
- && bl->address == pc
- && (!overlay_debugging || bl->section == section))
- return 1;
- }
- return 0;
- }
- static void
- describe_other_breakpoints (struct gdbarch *gdbarch,
- struct program_space *pspace, CORE_ADDR pc,
- struct obj_section *section, int thread)
- {
- int others = 0;
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- others += (user_breakpoint_p (b)
- && breakpoint_has_pc (b, pspace, pc, section));
- if (others > 0)
- {
- if (others == 1)
- printf_filtered (_("Note: breakpoint "));
- else
- printf_filtered (_("Note: breakpoints "));
- ALL_BREAKPOINTS (b)
- if (user_breakpoint_p (b) && breakpoint_has_pc (b, pspace, pc, section))
- {
- others--;
- printf_filtered ("%d", b->number);
- if (b->thread == -1 && thread != -1)
- printf_filtered (" (all threads)");
- else if (b->thread != -1)
- printf_filtered (" (thread %d)", b->thread);
- printf_filtered ("%s%s ",
- ((b->enable_state == bp_disabled
- || b->enable_state == bp_call_disabled)
- ? " (disabled)"
- : ""),
- (others > 1) ? ","
- : ((others == 1) ? " and" : ""));
- }
- printf_filtered (_("also set at pc "));
- fputs_filtered (paddress (gdbarch, pc), gdb_stdout);
- printf_filtered (".\n");
- }
- }
- static int
- breakpoint_address_is_meaningful (struct breakpoint *bpt)
- {
- enum bptype type = bpt->type;
- return (type != bp_watchpoint && type != bp_catchpoint);
- }
- static int
- watchpoint_locations_match (struct bp_location *loc1,
- struct bp_location *loc2)
- {
- struct watchpoint *w1 = (struct watchpoint *) loc1->owner;
- struct watchpoint *w2 = (struct watchpoint *) loc2->owner;
-
- gdb_assert (w1 != NULL);
- gdb_assert (w2 != NULL);
-
- if ((w1->cond_exp
- && target_can_accel_watchpoint_condition (loc1->address,
- loc1->length,
- loc1->watchpoint_type,
- w1->cond_exp))
- || (w2->cond_exp
- && target_can_accel_watchpoint_condition (loc2->address,
- loc2->length,
- loc2->watchpoint_type,
- w2->cond_exp)))
- return 0;
-
- return (loc1->owner->type == loc2->owner->type
- && loc1->pspace->aspace == loc2->pspace->aspace
- && loc1->address == loc2->address
- && loc1->length == loc2->length);
- }
- int
- breakpoint_address_match (struct address_space *aspace1, CORE_ADDR addr1,
- struct address_space *aspace2, CORE_ADDR addr2)
- {
- return ((gdbarch_has_global_breakpoints (target_gdbarch ())
- || aspace1 == aspace2)
- && addr1 == addr2);
- }
- static int
- breakpoint_address_match_range (struct address_space *aspace1, CORE_ADDR addr1,
- int len1, struct address_space *aspace2,
- CORE_ADDR addr2)
- {
- return ((gdbarch_has_global_breakpoints (target_gdbarch ())
- || aspace1 == aspace2)
- && addr2 >= addr1 && addr2 < addr1 + len1);
- }
- static int
- breakpoint_location_address_match (struct bp_location *bl,
- struct address_space *aspace,
- CORE_ADDR addr)
- {
- return (breakpoint_address_match (bl->pspace->aspace, bl->address,
- aspace, addr)
- || (bl->length
- && breakpoint_address_match_range (bl->pspace->aspace,
- bl->address, bl->length,
- aspace, addr)));
- }
- static int
- tracepoint_locations_match (struct bp_location *loc1,
- struct bp_location *loc2)
- {
- if (is_tracepoint (loc1->owner) && is_tracepoint (loc2->owner))
-
- return (loc1->address == loc2->address && loc1->owner == loc2->owner);
- else
- return 0;
- }
- static int
- breakpoint_locations_match (struct bp_location *loc1,
- struct bp_location *loc2)
- {
- int hw_point1, hw_point2;
-
- gdb_assert (loc1->owner != NULL);
- gdb_assert (loc2->owner != NULL);
- hw_point1 = is_hardware_watchpoint (loc1->owner);
- hw_point2 = is_hardware_watchpoint (loc2->owner);
- if (hw_point1 != hw_point2)
- return 0;
- else if (hw_point1)
- return watchpoint_locations_match (loc1, loc2);
- else if (is_tracepoint (loc1->owner) || is_tracepoint (loc2->owner))
- return tracepoint_locations_match (loc1, loc2);
- else
-
- return (breakpoint_address_match (loc1->pspace->aspace, loc1->address,
- loc2->pspace->aspace, loc2->address)
- && loc1->length == loc2->length);
- }
- static void
- breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr,
- int bnum, int have_bnum)
- {
-
- char astr1[64];
- char astr2[64];
- strcpy (astr1, hex_string_custom ((unsigned long) from_addr, 8));
- strcpy (astr2, hex_string_custom ((unsigned long) to_addr, 8));
- if (have_bnum)
- warning (_("Breakpoint %d address previously adjusted from %s to %s."),
- bnum, astr1, astr2);
- else
- warning (_("Breakpoint address adjusted from %s to %s."), astr1, astr2);
- }
- static CORE_ADDR
- adjust_breakpoint_address (struct gdbarch *gdbarch,
- CORE_ADDR bpaddr, enum bptype bptype)
- {
- if (!gdbarch_adjust_breakpoint_address_p (gdbarch))
- {
-
- return bpaddr;
- }
- else if (bptype == bp_watchpoint
- || bptype == bp_hardware_watchpoint
- || bptype == bp_read_watchpoint
- || bptype == bp_access_watchpoint
- || bptype == bp_catchpoint)
- {
-
- return bpaddr;
- }
- else if (bptype == bp_single_step)
- {
-
- return bpaddr;
- }
- else
- {
- CORE_ADDR adjusted_bpaddr;
-
- adjusted_bpaddr = gdbarch_adjust_breakpoint_address (gdbarch, bpaddr);
-
- if (adjusted_bpaddr != bpaddr)
- breakpoint_adjustment_warning (bpaddr, adjusted_bpaddr, 0, 0);
- return adjusted_bpaddr;
- }
- }
- void
- init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
- struct breakpoint *owner)
- {
- memset (loc, 0, sizeof (*loc));
- gdb_assert (ops != NULL);
- loc->ops = ops;
- loc->owner = owner;
- loc->cond = NULL;
- loc->cond_bytecode = NULL;
- loc->shlib_disabled = 0;
- loc->enabled = 1;
- switch (owner->type)
- {
- case bp_breakpoint:
- case bp_single_step:
- case bp_until:
- case bp_finish:
- case bp_longjmp:
- case bp_longjmp_resume:
- case bp_longjmp_call_dummy:
- case bp_exception:
- case bp_exception_resume:
- case bp_step_resume:
- case bp_hp_step_resume:
- case bp_watchpoint_scope:
- case bp_call_dummy:
- case bp_std_terminate:
- case bp_shlib_event:
- case bp_thread_event:
- case bp_overlay_event:
- case bp_jit_event:
- case bp_longjmp_master:
- case bp_std_terminate_master:
- case bp_exception_master:
- case bp_gnu_ifunc_resolver:
- case bp_gnu_ifunc_resolver_return:
- case bp_dprintf:
- loc->loc_type = bp_loc_software_breakpoint;
- mark_breakpoint_location_modified (loc);
- break;
- case bp_hardware_breakpoint:
- loc->loc_type = bp_loc_hardware_breakpoint;
- mark_breakpoint_location_modified (loc);
- break;
- case bp_hardware_watchpoint:
- case bp_read_watchpoint:
- case bp_access_watchpoint:
- loc->loc_type = bp_loc_hardware_watchpoint;
- break;
- case bp_watchpoint:
- case bp_catchpoint:
- case bp_tracepoint:
- case bp_fast_tracepoint:
- case bp_static_tracepoint:
- loc->loc_type = bp_loc_other;
- break;
- default:
- internal_error (__FILE__, __LINE__, _("unknown breakpoint type"));
- }
- loc->refc = 1;
- }
- static struct bp_location *
- allocate_bp_location (struct breakpoint *bpt)
- {
- return bpt->ops->allocate_location (bpt);
- }
- static void
- free_bp_location (struct bp_location *loc)
- {
- loc->ops->dtor (loc);
- xfree (loc);
- }
- static void
- incref_bp_location (struct bp_location *bl)
- {
- ++bl->refc;
- }
- static void
- decref_bp_location (struct bp_location **blp)
- {
- gdb_assert ((*blp)->refc > 0);
- if (--(*blp)->refc == 0)
- free_bp_location (*blp);
- *blp = NULL;
- }
- static void
- add_to_breakpoint_chain (struct breakpoint *b)
- {
- struct breakpoint *b1;
-
- b1 = breakpoint_chain;
- if (b1 == 0)
- breakpoint_chain = b;
- else
- {
- while (b1->next)
- b1 = b1->next;
- b1->next = b;
- }
- }
- static void
- init_raw_breakpoint_without_location (struct breakpoint *b,
- struct gdbarch *gdbarch,
- enum bptype bptype,
- const struct breakpoint_ops *ops)
- {
- memset (b, 0, sizeof (*b));
- gdb_assert (ops != NULL);
- b->ops = ops;
- b->type = bptype;
- b->gdbarch = gdbarch;
- b->language = current_language->la_language;
- b->input_radix = input_radix;
- b->thread = -1;
- b->enable_state = bp_enabled;
- b->next = 0;
- b->silent = 0;
- b->ignore_count = 0;
- b->commands = NULL;
- b->frame_id = null_frame_id;
- b->condition_not_parsed = 0;
- b->py_bp_object = NULL;
- b->related_breakpoint = b;
- }
- static struct breakpoint *
- set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
- enum bptype bptype,
- const struct breakpoint_ops *ops)
- {
- struct breakpoint *b = XNEW (struct breakpoint);
- init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
- add_to_breakpoint_chain (b);
- return b;
- }
- static void
- set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
- {
- gdb_assert (loc->owner != NULL);
- if (loc->owner->type == bp_breakpoint
- || loc->owner->type == bp_hardware_breakpoint
- || is_tracepoint (loc->owner))
- {
- int is_gnu_ifunc;
- const char *function_name;
- CORE_ADDR func_addr;
- find_pc_partial_function_gnu_ifunc (loc->address, &function_name,
- &func_addr, NULL, &is_gnu_ifunc);
- if (is_gnu_ifunc && !explicit_loc)
- {
- struct breakpoint *b = loc->owner;
- gdb_assert (loc->pspace == current_program_space);
- if (gnu_ifunc_resolve_name (function_name,
- &loc->requested_address))
- {
-
- loc->address = adjust_breakpoint_address (loc->gdbarch,
- loc->requested_address,
- b->type);
- }
- else if (b->type == bp_breakpoint && b->loc == loc
- && loc->next == NULL && b->related_breakpoint == b)
- {
-
- b->type = bp_gnu_ifunc_resolver;
-
- loc->related_address = func_addr;
- }
- }
- if (function_name)
- loc->function_name = xstrdup (function_name);
- }
- }
- struct gdbarch *
- get_sal_arch (struct symtab_and_line sal)
- {
- if (sal.section)
- return get_objfile_arch (sal.section->objfile);
- if (sal.symtab)
- return get_objfile_arch (SYMTAB_OBJFILE (sal.symtab));
- return NULL;
- }
- static void
- init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
- struct symtab_and_line sal, enum bptype bptype,
- const struct breakpoint_ops *ops)
- {
- init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
- add_location_to_breakpoint (b, &sal);
- if (bptype != bp_catchpoint)
- gdb_assert (sal.pspace != NULL);
-
- if (bptype != bp_breakpoint && bptype != bp_hardware_breakpoint)
- b->pspace = sal.pspace;
- }
- struct breakpoint *
- set_raw_breakpoint (struct gdbarch *gdbarch,
- struct symtab_and_line sal, enum bptype bptype,
- const struct breakpoint_ops *ops)
- {
- struct breakpoint *b = XNEW (struct breakpoint);
- init_raw_breakpoint (b, gdbarch, sal, bptype, ops);
- add_to_breakpoint_chain (b);
- return b;
- }
- void
- make_breakpoint_permanent (struct breakpoint *b)
- {
- struct bp_location *bl;
-
- for (bl = b->loc; bl; bl = bl->next)
- {
- bl->permanent = 1;
- bl->inserted = 1;
- }
- }
- void
- set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
- {
- struct breakpoint *b, *b_tmp;
- int thread = tp->num;
-
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->pspace == current_program_space
- && (b->type == bp_longjmp_master
- || b->type == bp_exception_master))
- {
- enum bptype type = b->type == bp_longjmp_master ? bp_longjmp : bp_exception;
- struct breakpoint *clone;
-
- clone = momentary_breakpoint_from_master (b, type,
- &longjmp_breakpoint_ops, 1);
- clone->thread = thread;
- }
- tp->initiating_frame = frame;
- }
- void
- delete_longjmp_breakpoint (int thread)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_longjmp || b->type == bp_exception)
- {
- if (b->thread == thread)
- delete_breakpoint (b);
- }
- }
- void
- delete_longjmp_breakpoint_at_next_stop (int thread)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_longjmp || b->type == bp_exception)
- {
- if (b->thread == thread)
- b->disposition = disp_del_at_next_stop;
- }
- }
- struct breakpoint *
- set_longjmp_breakpoint_for_call_dummy (void)
- {
- struct breakpoint *b, *retval = NULL;
- ALL_BREAKPOINTS (b)
- if (b->pspace == current_program_space && b->type == bp_longjmp_master)
- {
- struct breakpoint *new_b;
- new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
- &momentary_breakpoint_ops,
- 1);
- new_b->thread = pid_to_thread_id (inferior_ptid);
-
- gdb_assert (new_b->related_breakpoint == new_b);
- if (retval == NULL)
- retval = new_b;
- new_b->related_breakpoint = retval;
- while (retval->related_breakpoint != new_b->related_breakpoint)
- retval = retval->related_breakpoint;
- retval->related_breakpoint = new_b;
- }
- return retval;
- }
- void
- check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_longjmp_call_dummy && b->thread == tp->num)
- {
- struct breakpoint *dummy_b = b->related_breakpoint;
- while (dummy_b != b && dummy_b->type != bp_call_dummy)
- dummy_b = dummy_b->related_breakpoint;
- if (dummy_b->type != bp_call_dummy
- || frame_find_by_id (dummy_b->frame_id) != NULL)
- continue;
- dummy_frame_discard (dummy_b->frame_id, tp->ptid);
- while (b->related_breakpoint != b)
- {
- if (b_tmp == b->related_breakpoint)
- b_tmp = b->related_breakpoint->next;
- delete_breakpoint (b->related_breakpoint);
- }
- delete_breakpoint (b);
- }
- }
- void
- enable_overlay_breakpoints (void)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- if (b->type == bp_overlay_event)
- {
- b->enable_state = bp_enabled;
- update_global_location_list (UGLL_MAY_INSERT);
- overlay_events_enabled = 1;
- }
- }
- void
- disable_overlay_breakpoints (void)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- if (b->type == bp_overlay_event)
- {
- b->enable_state = bp_disabled;
- update_global_location_list (UGLL_DONT_INSERT);
- overlay_events_enabled = 0;
- }
- }
- void
- set_std_terminate_breakpoint (void)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->pspace == current_program_space
- && b->type == bp_std_terminate_master)
- {
- momentary_breakpoint_from_master (b, bp_std_terminate,
- &momentary_breakpoint_ops, 1);
- }
- }
- void
- delete_std_terminate_breakpoint (void)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_std_terminate)
- delete_breakpoint (b);
- }
- struct breakpoint *
- create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
- {
- struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch, address, bp_thread_event,
- &internal_breakpoint_ops);
- b->enable_state = bp_enabled;
-
- b->addr_string
- = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));
- update_global_location_list_nothrow (UGLL_MAY_INSERT);
- return b;
- }
- void
- remove_thread_event_breakpoints (void)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_thread_event
- && b->loc->pspace == current_program_space)
- delete_breakpoint (b);
- }
- struct lang_and_radix
- {
- enum language lang;
- int radix;
- };
- struct breakpoint *
- create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
- {
- struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch, address, bp_jit_event,
- &internal_breakpoint_ops);
- update_global_location_list_nothrow (UGLL_MAY_INSERT);
- return b;
- }
- void
- remove_jit_event_breakpoints (void)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_jit_event
- && b->loc->pspace == current_program_space)
- delete_breakpoint (b);
- }
- void
- remove_solib_event_breakpoints (void)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_shlib_event
- && b->loc->pspace == current_program_space)
- delete_breakpoint (b);
- }
- void
- remove_solib_event_breakpoints_at_next_stop (void)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (b->type == bp_shlib_event
- && b->loc->pspace == current_program_space)
- b->disposition = disp_del_at_next_stop;
- }
- static struct breakpoint *
- create_solib_event_breakpoint_1 (struct gdbarch *gdbarch, CORE_ADDR address,
- enum ugll_insert_mode insert_mode)
- {
- struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch, address, bp_shlib_event,
- &internal_breakpoint_ops);
- update_global_location_list_nothrow (insert_mode);
- return b;
- }
- struct breakpoint *
- create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
- {
- return create_solib_event_breakpoint_1 (gdbarch, address, UGLL_MAY_INSERT);
- }
- struct breakpoint *
- create_and_insert_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
- {
- struct breakpoint *b;
-
- b = create_solib_event_breakpoint_1 (gdbarch, address, UGLL_INSERT);
- if (!b->loc->inserted)
- {
- delete_breakpoint (b);
- return NULL;
- }
- return b;
- }
- void
- disable_breakpoints_in_shlibs (void)
- {
- struct bp_location *loc, **locp_tmp;
- ALL_BP_LOCATIONS (loc, locp_tmp)
- {
-
- struct breakpoint *b = loc->owner;
-
- if (((b->type == bp_breakpoint)
- || (b->type == bp_jit_event)
- || (b->type == bp_hardware_breakpoint)
- || (is_tracepoint (b)))
- && loc->pspace == current_program_space
- && !loc->shlib_disabled
- && solib_name_from_address (loc->pspace, loc->address)
- )
- {
- loc->shlib_disabled = 1;
- }
- }
- }
- static void
- disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
- {
- struct bp_location *loc, **locp_tmp;
- int disabled_shlib_breaks = 0;
-
- if (exec_bfd != NULL
- && bfd_get_flavour (exec_bfd) == bfd_target_aout_flavour)
- return;
- ALL_BP_LOCATIONS (loc, locp_tmp)
- {
-
- struct breakpoint *b = loc->owner;
- if (solib->pspace == loc->pspace
- && !loc->shlib_disabled
- && (((b->type == bp_breakpoint
- || b->type == bp_jit_event
- || b->type == bp_hardware_breakpoint)
- && (loc->loc_type == bp_loc_hardware_breakpoint
- || loc->loc_type == bp_loc_software_breakpoint))
- || is_tracepoint (b))
- && solib_contains_address_p (solib, loc->address))
- {
- loc->shlib_disabled = 1;
-
- loc->inserted = 0;
-
- observer_notify_breakpoint_modified (b);
- if (!disabled_shlib_breaks)
- {
- target_terminal_ours_for_output ();
- warning (_("Temporarily disabling breakpoints "
- "for unloaded shared library \"%s\""),
- solib->so_name);
- }
- disabled_shlib_breaks = 1;
- }
- }
- }
- static void
- disable_breakpoints_in_freed_objfile (struct objfile *objfile)
- {
- struct breakpoint *b;
- if (objfile == NULL)
- return;
-
- if ((objfile->flags & OBJF_SHARED) == 0
- || (objfile->flags & OBJF_USERLOADED) == 0)
- return;
- ALL_BREAKPOINTS (b)
- {
- struct bp_location *loc;
- int bp_modified = 0;
- if (!is_breakpoint (b) && !is_tracepoint (b))
- continue;
- for (loc = b->loc; loc != NULL; loc = loc->next)
- {
- CORE_ADDR loc_addr = loc->address;
- if (loc->loc_type != bp_loc_hardware_breakpoint
- && loc->loc_type != bp_loc_software_breakpoint)
- continue;
- if (loc->shlib_disabled != 0)
- continue;
- if (objfile->pspace != loc->pspace)
- continue;
- if (loc->loc_type != bp_loc_hardware_breakpoint
- && loc->loc_type != bp_loc_software_breakpoint)
- continue;
- if (is_addr_in_objfile (loc_addr, objfile))
- {
- loc->shlib_disabled = 1;
-
- mark_breakpoint_location_modified (loc);
- bp_modified = 1;
- }
- }
- if (bp_modified)
- observer_notify_breakpoint_modified (b);
- }
- }
- struct fork_catchpoint
- {
-
- struct breakpoint base;
-
- ptid_t forked_inferior_pid;
- };
- static int
- insert_catch_fork (struct bp_location *bl)
- {
- return target_insert_fork_catchpoint (ptid_get_pid (inferior_ptid));
- }
- static int
- remove_catch_fork (struct bp_location *bl)
- {
- return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
- }
- static int
- breakpoint_hit_catch_fork (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
- if (ws->kind != TARGET_WAITKIND_FORKED)
- return 0;
- c->forked_inferior_pid = ws->value.related_pid;
- return 1;
- }
- static enum print_stop_action
- print_it_catch_fork (bpstat bs)
- {
- struct ui_out *uiout = current_uiout;
- struct breakpoint *b = bs->breakpoint_at;
- struct fork_catchpoint *c = (struct fork_catchpoint *) bs->breakpoint_at;
- annotate_catchpoint (b->number);
- if (b->disposition == disp_del)
- ui_out_text (uiout, "\nTemporary catchpoint ");
- else
- ui_out_text (uiout, "\nCatchpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_FORK));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, " (forked process ");
- ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
- ui_out_text (uiout, "), ");
- return PRINT_SRC_AND_LOC;
- }
- static void
- print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc)
- {
- struct fork_catchpoint *c = (struct fork_catchpoint *) b;
- struct value_print_options opts;
- struct ui_out *uiout = current_uiout;
- get_user_print_options (&opts);
-
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- ui_out_text (uiout, "fork");
- if (!ptid_equal (c->forked_inferior_pid, null_ptid))
- {
- ui_out_text (uiout, ", process ");
- ui_out_field_int (uiout, "what",
- ptid_get_pid (c->forked_inferior_pid));
- ui_out_spaces (uiout, 1);
- }
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "catch-type", "fork");
- }
- static void
- print_mention_catch_fork (struct breakpoint *b)
- {
- printf_filtered (_("Catchpoint %d (fork)"), b->number);
- }
- static void
- print_recreate_catch_fork (struct breakpoint *b, struct ui_file *fp)
- {
- fprintf_unfiltered (fp, "catch fork");
- print_recreate_thread (b, fp);
- }
- static struct breakpoint_ops catch_fork_breakpoint_ops;
- static int
- insert_catch_vfork (struct bp_location *bl)
- {
- return target_insert_vfork_catchpoint (ptid_get_pid (inferior_ptid));
- }
- static int
- remove_catch_vfork (struct bp_location *bl)
- {
- return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
- }
- static int
- breakpoint_hit_catch_vfork (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner;
- if (ws->kind != TARGET_WAITKIND_VFORKED)
- return 0;
- c->forked_inferior_pid = ws->value.related_pid;
- return 1;
- }
- static enum print_stop_action
- print_it_catch_vfork (bpstat bs)
- {
- struct ui_out *uiout = current_uiout;
- struct breakpoint *b = bs->breakpoint_at;
- struct fork_catchpoint *c = (struct fork_catchpoint *) b;
- annotate_catchpoint (b->number);
- if (b->disposition == disp_del)
- ui_out_text (uiout, "\nTemporary catchpoint ");
- else
- ui_out_text (uiout, "\nCatchpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_VFORK));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, " (vforked process ");
- ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
- ui_out_text (uiout, "), ");
- return PRINT_SRC_AND_LOC;
- }
- static void
- print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc)
- {
- struct fork_catchpoint *c = (struct fork_catchpoint *) b;
- struct value_print_options opts;
- struct ui_out *uiout = current_uiout;
- get_user_print_options (&opts);
-
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- ui_out_text (uiout, "vfork");
- if (!ptid_equal (c->forked_inferior_pid, null_ptid))
- {
- ui_out_text (uiout, ", process ");
- ui_out_field_int (uiout, "what",
- ptid_get_pid (c->forked_inferior_pid));
- ui_out_spaces (uiout, 1);
- }
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "catch-type", "vfork");
- }
- static void
- print_mention_catch_vfork (struct breakpoint *b)
- {
- printf_filtered (_("Catchpoint %d (vfork)"), b->number);
- }
- static void
- print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
- {
- fprintf_unfiltered (fp, "catch vfork");
- print_recreate_thread (b, fp);
- }
- static struct breakpoint_ops catch_vfork_breakpoint_ops;
- struct solib_catchpoint
- {
-
- struct breakpoint base;
-
- unsigned char is_load;
-
- char *regex;
- regex_t compiled;
- };
- static void
- dtor_catch_solib (struct breakpoint *b)
- {
- struct solib_catchpoint *self = (struct solib_catchpoint *) b;
- if (self->regex)
- regfree (&self->compiled);
- xfree (self->regex);
- base_breakpoint_ops.dtor (b);
- }
- static int
- insert_catch_solib (struct bp_location *ignore)
- {
- return 0;
- }
- static int
- remove_catch_solib (struct bp_location *ignore)
- {
- return 0;
- }
- static int
- breakpoint_hit_catch_solib (const struct bp_location *bl,
- struct address_space *aspace,
- CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- struct solib_catchpoint *self = (struct solib_catchpoint *) bl->owner;
- struct breakpoint *other;
- if (ws->kind == TARGET_WAITKIND_LOADED)
- return 1;
- ALL_BREAKPOINTS (other)
- {
- struct bp_location *other_bl;
- if (other == bl->owner)
- continue;
- if (other->type != bp_shlib_event)
- continue;
- if (self->base.pspace != NULL && other->pspace != self->base.pspace)
- continue;
- for (other_bl = other->loc; other_bl != NULL; other_bl = other_bl->next)
- {
- if (other->ops->breakpoint_hit (other_bl, aspace, bp_addr, ws))
- return 1;
- }
- }
- return 0;
- }
- static void
- check_status_catch_solib (struct bpstats *bs)
- {
- struct solib_catchpoint *self
- = (struct solib_catchpoint *) bs->breakpoint_at;
- int ix;
- if (self->is_load)
- {
- struct so_list *iter;
- for (ix = 0;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
- {
- if (!self->regex
- || regexec (&self->compiled, iter->so_name, 0, NULL, 0) == 0)
- return;
- }
- }
- else
- {
- char *iter;
- for (ix = 0;
- VEC_iterate (char_ptr, current_program_space->deleted_solibs,
- ix, iter);
- ++ix)
- {
- if (!self->regex
- || regexec (&self->compiled, iter, 0, NULL, 0) == 0)
- return;
- }
- }
- bs->stop = 0;
- bs->print_it = print_it_noop;
- }
- static enum print_stop_action
- print_it_catch_solib (bpstat bs)
- {
- struct breakpoint *b = bs->breakpoint_at;
- struct ui_out *uiout = current_uiout;
- annotate_catchpoint (b->number);
- if (b->disposition == disp_del)
- ui_out_text (uiout, "\nTemporary catchpoint ");
- else
- ui_out_text (uiout, "\nCatchpoint ");
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, "\n");
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- print_solib_event (1);
- return PRINT_SRC_AND_LOC;
- }
- static void
- print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
- {
- struct solib_catchpoint *self = (struct solib_catchpoint *) b;
- struct value_print_options opts;
- struct ui_out *uiout = current_uiout;
- char *msg;
- get_user_print_options (&opts);
-
- if (opts.addressprint)
- {
- annotate_field (4);
- ui_out_field_skip (uiout, "addr");
- }
- annotate_field (5);
- if (self->is_load)
- {
- if (self->regex)
- msg = xstrprintf (_("load of library matching %s"), self->regex);
- else
- msg = xstrdup (_("load of library"));
- }
- else
- {
- if (self->regex)
- msg = xstrprintf (_("unload of library matching %s"), self->regex);
- else
- msg = xstrdup (_("unload of library"));
- }
- ui_out_field_string (uiout, "what", msg);
- xfree (msg);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "catch-type",
- self->is_load ? "load" : "unload");
- }
- static void
- print_mention_catch_solib (struct breakpoint *b)
- {
- struct solib_catchpoint *self = (struct solib_catchpoint *) b;
- printf_filtered (_("Catchpoint %d (%s)"), b->number,
- self->is_load ? "load" : "unload");
- }
- static void
- print_recreate_catch_solib (struct breakpoint *b, struct ui_file *fp)
- {
- struct solib_catchpoint *self = (struct solib_catchpoint *) b;
- fprintf_unfiltered (fp, "%s %s",
- b->disposition == disp_del ? "tcatch" : "catch",
- self->is_load ? "load" : "unload");
- if (self->regex)
- fprintf_unfiltered (fp, " %s", self->regex);
- fprintf_unfiltered (fp, "\n");
- }
- static struct breakpoint_ops catch_solib_breakpoint_ops;
- void
- add_solib_catchpoint (char *arg, int is_load, int is_temp, int enabled)
- {
- struct solib_catchpoint *c;
- struct gdbarch *gdbarch = get_current_arch ();
- struct cleanup *cleanup;
- if (!arg)
- arg = "";
- arg = skip_spaces (arg);
- c = XCNEW (struct solib_catchpoint);
- cleanup = make_cleanup (xfree, c);
- if (*arg != '\0')
- {
- int errcode;
- errcode = regcomp (&c->compiled, arg, REG_NOSUB);
- if (errcode != 0)
- {
- char *err = get_regcomp_error (errcode, &c->compiled);
- make_cleanup (xfree, err);
- error (_("Invalid regexp (%s): %s"), err, arg);
- }
- c->regex = xstrdup (arg);
- }
- c->is_load = is_load;
- init_catchpoint (&c->base, gdbarch, is_temp, NULL,
- &catch_solib_breakpoint_ops);
- c->base.enable_state = enabled ? bp_enabled : bp_disabled;
- discard_cleanups (cleanup);
- install_breakpoint (0, &c->base, 1);
- }
- static void
- catch_load_or_unload (char *arg, int from_tty, int is_load,
- struct cmd_list_element *command)
- {
- int tempflag;
- const int enabled = 1;
- tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
- add_solib_catchpoint (arg, is_load, tempflag, enabled);
- }
- static void
- catch_load_command_1 (char *arg, int from_tty,
- struct cmd_list_element *command)
- {
- catch_load_or_unload (arg, from_tty, 1, command);
- }
- static void
- catch_unload_command_1 (char *arg, int from_tty,
- struct cmd_list_element *command)
- {
- catch_load_or_unload (arg, from_tty, 0, command);
- }
- struct syscall_catchpoint
- {
-
- struct breakpoint base;
-
- VEC(int) *syscalls_to_be_caught;
- };
- static void
- dtor_catch_syscall (struct breakpoint *b)
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
- VEC_free (int, c->syscalls_to_be_caught);
- base_breakpoint_ops.dtor (b);
- }
- static const struct inferior_data *catch_syscall_inferior_data = NULL;
- struct catch_syscall_inferior_data
- {
-
-
- int any_syscall_count;
-
- VEC(int) *syscalls_counts;
-
- int total_syscalls_count;
- };
- static struct catch_syscall_inferior_data*
- get_catch_syscall_inferior_data (struct inferior *inf)
- {
- struct catch_syscall_inferior_data *inf_data;
- inf_data = inferior_data (inf, catch_syscall_inferior_data);
- if (inf_data == NULL)
- {
- inf_data = XCNEW (struct catch_syscall_inferior_data);
- set_inferior_data (inf, catch_syscall_inferior_data, inf_data);
- }
- return inf_data;
- }
- static void
- catch_syscall_inferior_data_cleanup (struct inferior *inf, void *arg)
- {
- xfree (arg);
- }
- static int
- insert_catch_syscall (struct bp_location *bl)
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
- struct inferior *inf = current_inferior ();
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (inf);
- ++inf_data->total_syscalls_count;
- if (!c->syscalls_to_be_caught)
- ++inf_data->any_syscall_count;
- else
- {
- int i, iter;
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- int elem;
- if (iter >= VEC_length (int, inf_data->syscalls_counts))
- {
- int old_size = VEC_length (int, inf_data->syscalls_counts);
- uintptr_t vec_addr_offset
- = old_size * ((uintptr_t) sizeof (int));
- uintptr_t vec_addr;
- VEC_safe_grow (int, inf_data->syscalls_counts, iter + 1);
- vec_addr = ((uintptr_t) VEC_address (int,
- inf_data->syscalls_counts)
- + vec_addr_offset);
- memset ((void *) vec_addr, 0,
- (iter + 1 - old_size) * sizeof (int));
- }
- elem = VEC_index (int, inf_data->syscalls_counts, iter);
- VEC_replace (int, inf_data->syscalls_counts, iter, ++elem);
- }
- }
- return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
- inf_data->total_syscalls_count != 0,
- inf_data->any_syscall_count,
- VEC_length (int,
- inf_data->syscalls_counts),
- VEC_address (int,
- inf_data->syscalls_counts));
- }
- static int
- remove_catch_syscall (struct bp_location *bl)
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
- struct inferior *inf = current_inferior ();
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (inf);
- --inf_data->total_syscalls_count;
- if (!c->syscalls_to_be_caught)
- --inf_data->any_syscall_count;
- else
- {
- int i, iter;
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- int elem;
- if (iter >= VEC_length (int, inf_data->syscalls_counts))
-
- continue;
- elem = VEC_index (int, inf_data->syscalls_counts, iter);
- VEC_replace (int, inf_data->syscalls_counts, iter, --elem);
- }
- }
- return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
- inf_data->total_syscalls_count != 0,
- inf_data->any_syscall_count,
- VEC_length (int,
- inf_data->syscalls_counts),
- VEC_address (int,
- inf_data->syscalls_counts));
- }
- static int
- breakpoint_hit_catch_syscall (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
-
- int syscall_number = 0;
- const struct syscall_catchpoint *c
- = (const struct syscall_catchpoint *) bl->owner;
- if (ws->kind != TARGET_WAITKIND_SYSCALL_ENTRY
- && ws->kind != TARGET_WAITKIND_SYSCALL_RETURN)
- return 0;
- syscall_number = ws->value.syscall_number;
-
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- if (syscall_number == iter)
- return 1;
- return 0;
- }
- return 1;
- }
- static enum print_stop_action
- print_it_catch_syscall (bpstat bs)
- {
- struct ui_out *uiout = current_uiout;
- struct breakpoint *b = bs->breakpoint_at;
-
- ptid_t ptid;
- struct target_waitstatus last;
- struct syscall s;
- struct gdbarch *gdbarch = bs->bp_location_at->gdbarch;
- get_last_target_status (&ptid, &last);
- get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
- annotate_catchpoint (b->number);
- if (b->disposition == disp_del)
- ui_out_text (uiout, "\nTemporary catchpoint ");
- else
- ui_out_text (uiout, "\nCatchpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
- ? EXEC_ASYNC_SYSCALL_ENTRY
- : EXEC_ASYNC_SYSCALL_RETURN));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
- ui_out_text (uiout, " (call to syscall ");
- else
- ui_out_text (uiout, " (returned from syscall ");
- if (s.name == NULL || ui_out_is_mi_like_p (uiout))
- ui_out_field_int (uiout, "syscall-number", last.value.syscall_number);
- if (s.name != NULL)
- ui_out_field_string (uiout, "syscall-name", s.name);
- ui_out_text (uiout, "), ");
- return PRINT_SRC_AND_LOC;
- }
- static void
- print_one_catch_syscall (struct breakpoint *b,
- struct bp_location **last_loc)
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
- struct value_print_options opts;
- struct ui_out *uiout = current_uiout;
- struct gdbarch *gdbarch = b->loc->gdbarch;
- get_user_print_options (&opts);
-
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- if (c->syscalls_to_be_caught
- && VEC_length (int, c->syscalls_to_be_caught) > 1)
- ui_out_text (uiout, "syscalls \"");
- else
- ui_out_text (uiout, "syscall \"");
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
- char *text = xstrprintf ("%s", "");
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- char *x = text;
- struct syscall s;
- get_syscall_by_number (gdbarch, iter, &s);
- if (s.name != NULL)
- text = xstrprintf ("%s%s, ", text, s.name);
- else
- text = xstrprintf ("%s%d, ", text, iter);
-
- xfree (x);
- }
-
- text[strlen (text) - 2] = '\0';
- ui_out_field_string (uiout, "what", text);
- }
- else
- ui_out_field_string (uiout, "what", "<any syscall>");
- ui_out_text (uiout, "\" ");
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "catch-type", "syscall");
- }
- static void
- print_mention_catch_syscall (struct breakpoint *b)
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
- struct gdbarch *gdbarch = b->loc->gdbarch;
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
- if (VEC_length (int, c->syscalls_to_be_caught) > 1)
- printf_filtered (_("Catchpoint %d (syscalls"), b->number);
- else
- printf_filtered (_("Catchpoint %d (syscall"), b->number);
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- struct syscall s;
- get_syscall_by_number (gdbarch, iter, &s);
- if (s.name)
- printf_filtered (" '%s' [%d]", s.name, s.number);
- else
- printf_filtered (" %d", s.number);
- }
- printf_filtered (")");
- }
- else
- printf_filtered (_("Catchpoint %d (any syscall)"),
- b->number);
- }
- static void
- print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
- struct gdbarch *gdbarch = b->loc->gdbarch;
- fprintf_unfiltered (fp, "catch syscall");
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- {
- struct syscall s;
- get_syscall_by_number (gdbarch, iter, &s);
- if (s.name)
- fprintf_unfiltered (fp, " %s", s.name);
- else
- fprintf_unfiltered (fp, " %d", s.number);
- }
- }
- print_recreate_thread (b, fp);
- }
- static struct breakpoint_ops catch_syscall_breakpoint_ops;
- static int
- syscall_catchpoint_p (struct breakpoint *b)
- {
- return (b->ops == &catch_syscall_breakpoint_ops);
- }
- void
- init_catchpoint (struct breakpoint *b,
- struct gdbarch *gdbarch, int tempflag,
- char *cond_string,
- const struct breakpoint_ops *ops)
- {
- struct symtab_and_line sal;
- init_sal (&sal);
- sal.pspace = current_program_space;
- init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops);
- b->cond_string = (cond_string == NULL) ? NULL : xstrdup (cond_string);
- b->disposition = tempflag ? disp_del : disp_donttouch;
- }
- void
- install_breakpoint (int internal, struct breakpoint *b, int update_gll)
- {
- add_to_breakpoint_chain (b);
- set_breakpoint_number (internal, b);
- if (is_tracepoint (b))
- set_tracepoint_count (breakpoint_count);
- if (!internal)
- mention (b);
- observer_notify_breakpoint_created (b);
- if (update_gll)
- update_global_location_list (UGLL_MAY_INSERT);
- }
- static void
- create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
- int tempflag, char *cond_string,
- const struct breakpoint_ops *ops)
- {
- struct fork_catchpoint *c = XNEW (struct fork_catchpoint);
- init_catchpoint (&c->base, gdbarch, tempflag, cond_string, ops);
- c->forked_inferior_pid = null_ptid;
- install_breakpoint (0, &c->base, 1);
- }
- struct exec_catchpoint
- {
-
- struct breakpoint base;
-
- char *exec_pathname;
- };
- static void
- dtor_catch_exec (struct breakpoint *b)
- {
- struct exec_catchpoint *c = (struct exec_catchpoint *) b;
- xfree (c->exec_pathname);
- base_breakpoint_ops.dtor (b);
- }
- static int
- insert_catch_exec (struct bp_location *bl)
- {
- return target_insert_exec_catchpoint (ptid_get_pid (inferior_ptid));
- }
- static int
- remove_catch_exec (struct bp_location *bl)
- {
- return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
- }
- static int
- breakpoint_hit_catch_exec (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner;
- if (ws->kind != TARGET_WAITKIND_EXECD)
- return 0;
- c->exec_pathname = xstrdup (ws->value.execd_pathname);
- return 1;
- }
- static enum print_stop_action
- print_it_catch_exec (bpstat bs)
- {
- struct ui_out *uiout = current_uiout;
- struct breakpoint *b = bs->breakpoint_at;
- struct exec_catchpoint *c = (struct exec_catchpoint *) b;
- annotate_catchpoint (b->number);
- if (b->disposition == disp_del)
- ui_out_text (uiout, "\nTemporary catchpoint ");
- else
- ui_out_text (uiout, "\nCatchpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_EXEC));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, " (exec'd ");
- ui_out_field_string (uiout, "new-exec", c->exec_pathname);
- ui_out_text (uiout, "), ");
- return PRINT_SRC_AND_LOC;
- }
- static void
- print_one_catch_exec (struct breakpoint *b, struct bp_location **last_loc)
- {
- struct exec_catchpoint *c = (struct exec_catchpoint *) b;
- struct value_print_options opts;
- struct ui_out *uiout = current_uiout;
- get_user_print_options (&opts);
-
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- ui_out_text (uiout, "exec");
- if (c->exec_pathname != NULL)
- {
- ui_out_text (uiout, ", program \"");
- ui_out_field_string (uiout, "what", c->exec_pathname);
- ui_out_text (uiout, "\" ");
- }
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string (uiout, "catch-type", "exec");
- }
- static void
- print_mention_catch_exec (struct breakpoint *b)
- {
- printf_filtered (_("Catchpoint %d (exec)"), b->number);
- }
- static void
- print_recreate_catch_exec (struct breakpoint *b, struct ui_file *fp)
- {
- fprintf_unfiltered (fp, "catch exec");
- print_recreate_thread (b, fp);
- }
- static struct breakpoint_ops catch_exec_breakpoint_ops;
- static void
- create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
- const struct breakpoint_ops *ops)
- {
- struct syscall_catchpoint *c;
- struct gdbarch *gdbarch = get_current_arch ();
- c = XNEW (struct syscall_catchpoint);
- init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
- c->syscalls_to_be_caught = filter;
- install_breakpoint (0, &c->base, 1);
- }
- static int
- hw_breakpoint_used_count (void)
- {
- int i = 0;
- struct breakpoint *b;
- struct bp_location *bl;
- ALL_BREAKPOINTS (b)
- {
- if (b->type == bp_hardware_breakpoint && breakpoint_enabled (b))
- for (bl = b->loc; bl; bl = bl->next)
- {
-
- i += b->ops->resources_needed (bl);
- }
- }
- return i;
- }
- static int
- hw_watchpoint_use_count (struct breakpoint *b)
- {
- int i = 0;
- struct bp_location *bl;
- if (!breakpoint_enabled (b))
- return 0;
- for (bl = b->loc; bl; bl = bl->next)
- {
-
- i += b->ops->resources_needed (bl);
- }
- return i;
- }
- static int
- hw_watchpoint_used_count_others (struct breakpoint *except,
- enum bptype type, int *other_type_used)
- {
- int i = 0;
- struct breakpoint *b;
- *other_type_used = 0;
- ALL_BREAKPOINTS (b)
- {
- if (b == except)
- continue;
- if (!breakpoint_enabled (b))
- continue;
- if (b->type == type)
- i += hw_watchpoint_use_count (b);
- else if (is_hardware_watchpoint (b))
- *other_type_used = 1;
- }
- return i;
- }
- void
- disable_watchpoints_before_interactive_call_start (void)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- {
- if (is_watchpoint (b) && breakpoint_enabled (b))
- {
- b->enable_state = bp_call_disabled;
- update_global_location_list (UGLL_DONT_INSERT);
- }
- }
- }
- void
- enable_watchpoints_after_interactive_call_stop (void)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- {
- if (is_watchpoint (b) && b->enable_state == bp_call_disabled)
- {
- b->enable_state = bp_enabled;
- update_global_location_list (UGLL_MAY_INSERT);
- }
- }
- }
- void
- disable_breakpoints_before_startup (void)
- {
- current_program_space->executing_startup = 1;
- update_global_location_list (UGLL_DONT_INSERT);
- }
- void
- enable_breakpoints_after_startup (void)
- {
- current_program_space->executing_startup = 0;
- breakpoint_re_set ();
- }
- static struct breakpoint *
- new_single_step_breakpoint (int thread, struct gdbarch *gdbarch)
- {
- struct breakpoint *b = XNEW (struct breakpoint);
- init_raw_breakpoint_without_location (b, gdbarch, bp_single_step,
- &momentary_breakpoint_ops);
- b->disposition = disp_donttouch;
- b->frame_id = null_frame_id;
- b->thread = thread;
- gdb_assert (b->thread != 0);
- add_to_breakpoint_chain (b);
- return b;
- }
- struct breakpoint *
- set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
- struct frame_id frame_id, enum bptype type)
- {
- struct breakpoint *b;
-
- gdb_assert (!frame_id_artificial_p (frame_id));
- b = set_raw_breakpoint (gdbarch, sal, type, &momentary_breakpoint_ops);
- b->enable_state = bp_enabled;
- b->disposition = disp_donttouch;
- b->frame_id = frame_id;
-
- if (in_thread_list (inferior_ptid))
- b->thread = pid_to_thread_id (inferior_ptid);
- update_global_location_list_nothrow (UGLL_MAY_INSERT);
- return b;
- }
- static struct breakpoint *
- momentary_breakpoint_from_master (struct breakpoint *orig,
- enum bptype type,
- const struct breakpoint_ops *ops,
- int loc_enabled)
- {
- struct breakpoint *copy;
- copy = set_raw_breakpoint_without_location (orig->gdbarch, type, ops);
- copy->loc = allocate_bp_location (copy);
- set_breakpoint_location_function (copy->loc, 1);
- copy->loc->gdbarch = orig->loc->gdbarch;
- copy->loc->requested_address = orig->loc->requested_address;
- copy->loc->address = orig->loc->address;
- copy->loc->section = orig->loc->section;
- copy->loc->pspace = orig->loc->pspace;
- copy->loc->probe = orig->loc->probe;
- copy->loc->line_number = orig->loc->line_number;
- copy->loc->symtab = orig->loc->symtab;
- copy->loc->enabled = loc_enabled;
- copy->frame_id = orig->frame_id;
- copy->thread = orig->thread;
- copy->pspace = orig->pspace;
- copy->enable_state = bp_enabled;
- copy->disposition = disp_donttouch;
- copy->number = internal_breakpoint_number--;
- update_global_location_list_nothrow (UGLL_DONT_INSERT);
- return copy;
- }
- struct breakpoint *
- clone_momentary_breakpoint (struct breakpoint *orig)
- {
-
- if (orig == NULL)
- return NULL;
- return momentary_breakpoint_from_master (orig, orig->type, orig->ops, 0);
- }
- struct breakpoint *
- set_momentary_breakpoint_at_pc (struct gdbarch *gdbarch, CORE_ADDR pc,
- enum bptype type)
- {
- struct symtab_and_line sal;
- sal = find_pc_line (pc, 0);
- sal.pc = pc;
- sal.section = find_pc_overlay (pc);
- sal.explicit_pc = 1;
- return set_momentary_breakpoint (gdbarch, sal, null_frame_id, type);
- }
- static void
- mention (struct breakpoint *b)
- {
- b->ops->print_mention (b);
- if (ui_out_is_mi_like_p (current_uiout))
- return;
- printf_filtered ("\n");
- }
- static int bp_loc_is_permanent (struct bp_location *loc);
- static struct bp_location *
- add_location_to_breakpoint (struct breakpoint *b,
- const struct symtab_and_line *sal)
- {
- struct bp_location *loc, **tmp;
- CORE_ADDR adjusted_address;
- struct gdbarch *loc_gdbarch = get_sal_arch (*sal);
- if (loc_gdbarch == NULL)
- loc_gdbarch = b->gdbarch;
-
- adjusted_address = adjust_breakpoint_address (loc_gdbarch,
- sal->pc, b->type);
-
- loc = allocate_bp_location (b);
- for (tmp = &(b->loc); *tmp != NULL && (*tmp)->address <= adjusted_address;
- tmp = &((*tmp)->next))
- ;
- loc->next = *tmp;
- *tmp = loc;
- loc->requested_address = sal->pc;
- loc->address = adjusted_address;
- loc->pspace = sal->pspace;
- loc->probe.probe = sal->probe;
- loc->probe.objfile = sal->objfile;
- gdb_assert (loc->pspace != NULL);
- loc->section = sal->section;
- loc->gdbarch = loc_gdbarch;
- loc->line_number = sal->line;
- loc->symtab = sal->symtab;
- set_breakpoint_location_function (loc,
- sal->explicit_pc || sal->explicit_line);
- if (bp_loc_is_permanent (loc))
- {
- loc->inserted = 1;
- loc->permanent = 1;
- }
- return loc;
- }
- static int
- bp_loc_is_permanent (struct bp_location *loc)
- {
- int len;
- CORE_ADDR addr;
- const gdb_byte *bpoint;
- gdb_byte *target_mem;
- struct cleanup *cleanup;
- int retval = 0;
- gdb_assert (loc != NULL);
-
- if (loc->owner->type == bp_call_dummy)
- return 0;
- addr = loc->address;
- bpoint = gdbarch_breakpoint_from_pc (loc->gdbarch, &addr, &len);
-
- if (bpoint == NULL)
- return 0;
- target_mem = alloca (len);
-
- cleanup = save_current_space_and_thread ();
- switch_to_program_space_and_thread (loc->pspace);
- make_show_memory_breakpoints_cleanup (0);
- if (target_read_memory (loc->address, target_mem, len) == 0
- && memcmp (target_mem, bpoint, len) == 0)
- retval = 1;
- do_cleanups (cleanup);
- return retval;
- }
- static void
- update_dprintf_command_list (struct breakpoint *b)
- {
- char *dprintf_args = b->extra_string;
- char *printf_line = NULL;
- if (!dprintf_args)
- return;
- dprintf_args = skip_spaces (dprintf_args);
-
- if (*dprintf_args == ',')
- ++dprintf_args;
- dprintf_args = skip_spaces (dprintf_args);
- if (*dprintf_args != '"')
- error (_("Bad format string, missing '\"'."));
- if (strcmp (dprintf_style, dprintf_style_gdb) == 0)
- printf_line = xstrprintf ("printf %s", dprintf_args);
- else if (strcmp (dprintf_style, dprintf_style_call) == 0)
- {
- if (!dprintf_function)
- error (_("No function supplied for dprintf call"));
- if (dprintf_channel && strlen (dprintf_channel) > 0)
- printf_line = xstrprintf ("call (void) %s (%s,%s)",
- dprintf_function,
- dprintf_channel,
- dprintf_args);
- else
- printf_line = xstrprintf ("call (void) %s (%s)",
- dprintf_function,
- dprintf_args);
- }
- else if (strcmp (dprintf_style, dprintf_style_agent) == 0)
- {
- if (target_can_run_breakpoint_commands ())
- printf_line = xstrprintf ("agent-printf %s", dprintf_args);
- else
- {
- warning (_("Target cannot run dprintf commands, falling back to GDB printf"));
- printf_line = xstrprintf ("printf %s", dprintf_args);
- }
- }
- else
- internal_error (__FILE__, __LINE__,
- _("Invalid dprintf style."));
- gdb_assert (printf_line != NULL);
-
- {
- struct command_line *printf_cmd_line
- = xmalloc (sizeof (struct command_line));
- printf_cmd_line = xmalloc (sizeof (struct command_line));
- printf_cmd_line->control_type = simple_control;
- printf_cmd_line->body_count = 0;
- printf_cmd_line->body_list = NULL;
- printf_cmd_line->next = NULL;
- printf_cmd_line->line = printf_line;
- breakpoint_set_commands (b, printf_cmd_line);
- }
- }
- static void
- update_dprintf_commands (char *args, int from_tty,
- struct cmd_list_element *c)
- {
- struct breakpoint *b;
- ALL_BREAKPOINTS (b)
- {
- if (b->type == bp_dprintf)
- update_dprintf_command_list (b);
- }
- }
- static void
- init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch,
- struct symtabs_and_lines sals, char *addr_string,
- char *filter, char *cond_string,
- char *extra_string,
- enum bptype type, enum bpdisp disposition,
- int thread, int task, int ignore_count,
- const struct breakpoint_ops *ops, int from_tty,
- int enabled, int internal, unsigned flags,
- int display_canonical)
- {
- int i;
- if (type == bp_hardware_breakpoint)
- {
- int target_resources_ok;
- i = hw_breakpoint_used_count ();
- target_resources_ok =
- target_can_use_hardware_watchpoint (bp_hardware_breakpoint,
- i + 1, 0);
- if (target_resources_ok == 0)
- error (_("No hardware breakpoint support in the target."));
- else if (target_resources_ok < 0)
- error (_("Hardware breakpoints used exceeds limit."));
- }
- gdb_assert (sals.nelts > 0);
- for (i = 0; i < sals.nelts; ++i)
- {
- struct symtab_and_line sal = sals.sals[i];
- struct bp_location *loc;
- if (from_tty)
- {
- struct gdbarch *loc_gdbarch = get_sal_arch (sal);
- if (!loc_gdbarch)
- loc_gdbarch = gdbarch;
- describe_other_breakpoints (loc_gdbarch,
- sal.pspace, sal.pc, sal.section, thread);
- }
- if (i == 0)
- {
- init_raw_breakpoint (b, gdbarch, sal, type, ops);
- b->thread = thread;
- b->task = task;
- b->cond_string = cond_string;
- b->extra_string = extra_string;
- b->ignore_count = ignore_count;
- b->enable_state = enabled ? bp_enabled : bp_disabled;
- b->disposition = disposition;
- if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
- b->loc->inserted = 1;
- if (type == bp_static_tracepoint)
- {
- struct tracepoint *t = (struct tracepoint *) b;
- struct static_tracepoint_marker marker;
- if (strace_marker_p (b))
- {
-
- char *p = &addr_string[3];
- char *endp;
- char *marker_str;
- p = skip_spaces (p);
- endp = skip_to_space (p);
- marker_str = savestring (p, endp - p);
- t->static_trace_marker_id = marker_str;
- printf_filtered (_("Probed static tracepoint "
- "marker \"%s\"\n"),
- t->static_trace_marker_id);
- }
- else if (target_static_tracepoint_marker_at (sal.pc, &marker))
- {
- t->static_trace_marker_id = xstrdup (marker.str_id);
- release_static_tracepoint_marker (&marker);
- printf_filtered (_("Probed static tracepoint "
- "marker \"%s\"\n"),
- t->static_trace_marker_id);
- }
- else
- warning (_("Couldn't determine the static "
- "tracepoint marker to probe"));
- }
- loc = b->loc;
- }
- else
- {
- loc = add_location_to_breakpoint (b, &sal);
- if ((flags & CREATE_BREAKPOINT_FLAGS_INSERTED) != 0)
- loc->inserted = 1;
- }
- if (b->cond_string)
- {
- const char *arg = b->cond_string;
- loc->cond = parse_exp_1 (&arg, loc->address,
- block_for_pc (loc->address), 0);
- if (*arg)
- error (_("Garbage '%s' follows condition"), arg);
- }
-
- if (type == bp_dprintf)
- {
- if (b->extra_string)
- update_dprintf_command_list (b);
- else
- error (_("Format string required"));
- }
- else if (b->extra_string)
- error (_("Garbage '%s' at end of command"), b->extra_string);
- }
- b->display_canonical = display_canonical;
- if (addr_string)
- b->addr_string = addr_string;
- else
-
- b->addr_string
- = xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));
- b->filter = filter;
- }
- static void
- create_breakpoint_sal (struct gdbarch *gdbarch,
- struct symtabs_and_lines sals, char *addr_string,
- char *filter, char *cond_string,
- char *extra_string,
- enum bptype type, enum bpdisp disposition,
- int thread, int task, int ignore_count,
- const struct breakpoint_ops *ops, int from_tty,
- int enabled, int internal, unsigned flags,
- int display_canonical)
- {
- struct breakpoint *b;
- struct cleanup *old_chain;
- if (is_tracepoint_type (type))
- {
- struct tracepoint *t;
- t = XCNEW (struct tracepoint);
- b = &t->base;
- }
- else
- b = XNEW (struct breakpoint);
- old_chain = make_cleanup (xfree, b);
- init_breakpoint_sal (b, gdbarch,
- sals, addr_string,
- filter, cond_string, extra_string,
- type, disposition,
- thread, task, ignore_count,
- ops, from_tty,
- enabled, internal, flags,
- display_canonical);
- discard_cleanups (old_chain);
- install_breakpoint (internal, b, 0);
- }
- static void
- create_breakpoints_sal (struct gdbarch *gdbarch,
- struct linespec_result *canonical,
- char *cond_string, char *extra_string,
- enum bptype type, enum bpdisp disposition,
- int thread, int task, int ignore_count,
- const struct breakpoint_ops *ops, int from_tty,
- int enabled, int internal, unsigned flags)
- {
- int i;
- struct linespec_sals *lsal;
- if (canonical->pre_expanded)
- gdb_assert (VEC_length (linespec_sals, canonical->sals) == 1);
- for (i = 0; VEC_iterate (linespec_sals, canonical->sals, i, lsal); ++i)
- {
-
- char *addr_string = (canonical->addr_string
- ? xstrdup (canonical->addr_string)
- : NULL);
- char *filter_string = lsal->canonical ? xstrdup (lsal->canonical) : NULL;
- struct cleanup *inner = make_cleanup (xfree, addr_string);
- make_cleanup (xfree, filter_string);
- create_breakpoint_sal (gdbarch, lsal->sals,
- addr_string,
- filter_string,
- cond_string, extra_string,
- type, disposition,
- thread, task, ignore_count, ops,
- from_tty, enabled, internal, flags,
- canonical->special_display);
- discard_cleanups (inner);
- }
- }
- static void
- parse_breakpoint_sals (char **address,
- struct linespec_result *canonical)
- {
-
- if ((*address) == NULL
- || (strncmp ((*address), "if", 2) == 0 && isspace ((*address)[2])))
- {
-
- if (last_displayed_sal_is_valid ())
- {
- struct linespec_sals lsal;
- struct symtab_and_line sal;
- CORE_ADDR pc;
- init_sal (&sal);
- lsal.sals.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
-
- get_last_displayed_sal (&sal);
- pc = sal.pc;
- sal = find_pc_line (pc, 0);
-
- sal.pc = pc;
- sal.explicit_pc = 1;
- lsal.sals.sals[0] = sal;
- lsal.sals.nelts = 1;
- lsal.canonical = NULL;
- VEC_safe_push (linespec_sals, canonical->sals, &lsal);
- }
- else
- error (_("No default breakpoint address now."));
- }
- else
- {
- struct symtab_and_line cursal = get_current_source_symtab_and_line ();
-
- if (last_displayed_sal_is_valid ()
- && (!cursal.symtab
- || ((strchr ("+-", (*address)[0]) != NULL)
- && ((*address)[1] != '['))))
- decode_line_full (address, DECODE_LINE_FUNFIRSTLINE,
- get_last_displayed_symtab (),
- get_last_displayed_line (),
- canonical, NULL, NULL);
- else
- decode_line_full (address, DECODE_LINE_FUNFIRSTLINE,
- cursal.symtab, cursal.line, canonical, NULL, NULL);
- }
- }
- static void
- breakpoint_sals_to_pc (struct symtabs_and_lines *sals)
- {
- int i;
- for (i = 0; i < sals->nelts; i++)
- resolve_sal_pc (&sals->sals[i]);
- }
- static void
- check_fast_tracepoint_sals (struct gdbarch *gdbarch,
- struct symtabs_and_lines *sals)
- {
- int i, rslt;
- struct symtab_and_line *sal;
- char *msg;
- struct cleanup *old_chain;
- for (i = 0; i < sals->nelts; i++)
- {
- struct gdbarch *sarch;
- sal = &sals->sals[i];
- sarch = get_sal_arch (*sal);
-
- if (sarch == NULL)
- sarch = gdbarch;
- rslt = gdbarch_fast_tracepoint_valid_at (sarch, sal->pc,
- NULL, &msg);
- old_chain = make_cleanup (xfree, msg);
- if (!rslt)
- error (_("May not have a fast tracepoint at 0x%s%s"),
- paddress (sarch, sal->pc), (msg ? msg : ""));
- do_cleanups (old_chain);
- }
- }
- static void ATTRIBUTE_NORETURN
- invalid_thread_id_error (int id)
- {
- error (_("Unknown thread %d."), id);
- }
- static void
- find_condition_and_thread (const char *tok, CORE_ADDR pc,
- char **cond_string, int *thread, int *task,
- char **rest)
- {
- *cond_string = NULL;
- *thread = -1;
- *task = 0;
- *rest = NULL;
- while (tok && *tok)
- {
- const char *end_tok;
- int toklen;
- const char *cond_start = NULL;
- const char *cond_end = NULL;
- tok = skip_spaces_const (tok);
- if ((*tok == '"' || *tok == ',') && rest)
- {
- *rest = savestring (tok, strlen (tok));
- return;
- }
- end_tok = skip_to_space_const (tok);
- toklen = end_tok - tok;
- if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
- {
- struct expression *expr;
- tok = cond_start = end_tok + 1;
- expr = parse_exp_1 (&tok, pc, block_for_pc (pc), 0);
- xfree (expr);
- cond_end = tok;
- *cond_string = savestring (cond_start, cond_end - cond_start);
- }
- else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0)
- {
- char *tmptok;
- tok = end_tok + 1;
- *thread = strtol (tok, &tmptok, 0);
- if (tok == tmptok)
- error (_("Junk after thread keyword."));
- if (!valid_thread_id (*thread))
- invalid_thread_id_error (*thread);
- tok = tmptok;
- }
- else if (toklen >= 1 && strncmp (tok, "task", toklen) == 0)
- {
- char *tmptok;
- tok = end_tok + 1;
- *task = strtol (tok, &tmptok, 0);
- if (tok == tmptok)
- error (_("Junk after task keyword."));
- if (!valid_task_id (*task))
- error (_("Unknown task %d."), *task);
- tok = tmptok;
- }
- else if (rest)
- {
- *rest = savestring (tok, strlen (tok));
- return;
- }
- else
- error (_("Junk at end of arguments."));
- }
- }
- static struct symtabs_and_lines
- decode_static_tracepoint_spec (char **arg_p)
- {
- VEC(static_tracepoint_marker_p) *markers = NULL;
- struct symtabs_and_lines sals;
- struct cleanup *old_chain;
- char *p = &(*arg_p)[3];
- char *endp;
- char *marker_str;
- int i;
- p = skip_spaces (p);
- endp = skip_to_space (p);
- marker_str = savestring (p, endp - p);
- old_chain = make_cleanup (xfree, marker_str);
- markers = target_static_tracepoint_markers_by_strid (marker_str);
- if (VEC_empty(static_tracepoint_marker_p, markers))
- error (_("No known static tracepoint marker named %s"), marker_str);
- sals.nelts = VEC_length(static_tracepoint_marker_p, markers);
- sals.sals = xmalloc (sizeof *sals.sals * sals.nelts);
- for (i = 0; i < sals.nelts; i++)
- {
- struct static_tracepoint_marker *marker;
- marker = VEC_index (static_tracepoint_marker_p, markers, i);
- init_sal (&sals.sals[i]);
- sals.sals[i] = find_pc_line (marker->address, 0);
- sals.sals[i].pc = marker->address;
- release_static_tracepoint_marker (marker);
- }
- do_cleanups (old_chain);
- *arg_p = endp;
- return sals;
- }
- int
- create_breakpoint (struct gdbarch *gdbarch,
- char *arg, char *cond_string,
- int thread, char *extra_string,
- int parse_arg,
- int tempflag, enum bptype type_wanted,
- int ignore_count,
- enum auto_boolean pending_break_support,
- const struct breakpoint_ops *ops,
- int from_tty, int enabled, int internal,
- unsigned flags)
- {
- volatile struct gdb_exception e;
- char *copy_arg = NULL;
- char *addr_start = arg;
- struct linespec_result canonical;
- struct cleanup *old_chain;
- struct cleanup *bkpt_chain = NULL;
- int pending = 0;
- int task = 0;
- int prev_bkpt_count = breakpoint_count;
- gdb_assert (ops != NULL);
- init_linespec_result (&canonical);
- TRY_CATCH (e, RETURN_MASK_ALL)
- {
- ops->create_sals_from_address (&arg, &canonical, type_wanted,
- addr_start, ©_arg);
- }
-
- switch (e.reason)
- {
- case GDB_NO_ERROR:
- if (VEC_empty (linespec_sals, canonical.sals))
- return 0;
- break;
- case RETURN_ERROR:
- switch (e.error)
- {
- case NOT_FOUND_ERROR:
-
- if (pending_break_support == AUTO_BOOLEAN_FALSE)
- throw_exception (e);
- exception_print (gdb_stderr, e);
-
- if (pending_break_support == AUTO_BOOLEAN_AUTO
- && !nquery (_("Make %s pending on future shared library load? "),
- bptype_string (type_wanted)))
- return 0;
-
- {
- struct linespec_sals lsal;
- copy_arg = xstrdup (addr_start);
- lsal.canonical = xstrdup (copy_arg);
- lsal.sals.nelts = 1;
- lsal.sals.sals = XNEW (struct symtab_and_line);
- init_sal (&lsal.sals.sals[0]);
- pending = 1;
- VEC_safe_push (linespec_sals, canonical.sals, &lsal);
- }
- break;
- default:
- throw_exception (e);
- }
- break;
- default:
- throw_exception (e);
- }
-
- old_chain = make_cleanup_destroy_linespec_result (&canonical);
-
- bkpt_chain = make_cleanup (null_cleanup, 0);
-
- if (!pending)
- {
- int ix;
- struct linespec_sals *iter;
- for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
- breakpoint_sals_to_pc (&iter->sals);
- }
-
- if (!pending && type_wanted == bp_fast_tracepoint)
- {
- int ix;
- struct linespec_sals *iter;
- for (ix = 0; VEC_iterate (linespec_sals, canonical.sals, ix, iter); ++ix)
- check_fast_tracepoint_sals (gdbarch, &iter->sals);
- }
-
- if (!pending)
- {
- if (parse_arg)
- {
- char *rest;
- struct linespec_sals *lsal;
- lsal = VEC_index (linespec_sals, canonical.sals, 0);
-
- find_condition_and_thread (arg, lsal->sals.sals[0].pc, &cond_string,
- &thread, &task, &rest);
- if (cond_string)
- make_cleanup (xfree, cond_string);
- if (rest)
- make_cleanup (xfree, rest);
- if (rest)
- extra_string = rest;
- }
- else
- {
- if (*arg != '\0')
- error (_("Garbage '%s' at end of location"), arg);
-
- if (cond_string)
- {
- cond_string = xstrdup (cond_string);
- make_cleanup (xfree, cond_string);
- }
-
- if (extra_string)
- {
- extra_string = xstrdup (extra_string);
- make_cleanup (xfree, extra_string);
- }
- }
- ops->create_breakpoints_sal (gdbarch, &canonical,
- cond_string, extra_string, type_wanted,
- tempflag ? disp_del : disp_donttouch,
- thread, task, ignore_count, ops,
- from_tty, enabled, internal, flags);
- }
- else
- {
- struct breakpoint *b;
- make_cleanup (xfree, copy_arg);
- if (is_tracepoint_type (type_wanted))
- {
- struct tracepoint *t;
- t = XCNEW (struct tracepoint);
- b = &t->base;
- }
- else
- b = XNEW (struct breakpoint);
- init_raw_breakpoint_without_location (b, gdbarch, type_wanted, ops);
- b->addr_string = copy_arg;
- if (parse_arg)
- b->cond_string = NULL;
- else
- {
-
- if (cond_string)
- {
- cond_string = xstrdup (cond_string);
- make_cleanup (xfree, cond_string);
- }
- b->cond_string = cond_string;
- }
- b->extra_string = NULL;
- b->ignore_count = ignore_count;
- b->disposition = tempflag ? disp_del : disp_donttouch;
- b->condition_not_parsed = 1;
- b->enable_state = enabled ? bp_enabled : bp_disabled;
- if ((type_wanted != bp_breakpoint
- && type_wanted != bp_hardware_breakpoint) || thread != -1)
- b->pspace = current_program_space;
- install_breakpoint (internal, b, 0);
- }
- if (VEC_length (linespec_sals, canonical.sals) > 1)
- {
- warning (_("Multiple breakpoints were set.\nUse the "
- "\"delete\" command to delete unwanted breakpoints."));
- prev_breakpoint_count = prev_bkpt_count;
- }
-
- discard_cleanups (bkpt_chain);
-
- do_cleanups (old_chain);
-
- update_global_location_list (UGLL_MAY_INSERT);
- return 1;
- }
- static void
- break_command_1 (char *arg, int flag, int from_tty)
- {
- int tempflag = flag & BP_TEMPFLAG;
- enum bptype type_wanted = (flag & BP_HARDWAREFLAG
- ? bp_hardware_breakpoint
- : bp_breakpoint);
- struct breakpoint_ops *ops;
- const char *arg_cp = arg;
-
- if (arg && probe_linespec_to_ops (&arg_cp) != NULL)
- ops = &bkpt_probe_breakpoint_ops;
- else
- ops = &bkpt_breakpoint_ops;
- create_breakpoint (get_current_arch (),
- arg,
- NULL, 0, NULL, 1 ,
- tempflag, type_wanted,
- 0 ,
- pending_break_support,
- ops,
- from_tty,
- 1 ,
- 0 ,
- 0);
- }
- void
- resolve_sal_pc (struct symtab_and_line *sal)
- {
- CORE_ADDR pc;
- if (sal->pc == 0 && sal->symtab != NULL)
- {
- if (!find_line_pc (sal->symtab, sal->line, &pc))
- error (_("No line %d in file \"%s\"."),
- sal->line, symtab_to_filename_for_display (sal->symtab));
- sal->pc = pc;
-
- if (sal->explicit_line)
- skip_prologue_sal (sal);
- }
- if (sal->section == 0 && sal->symtab != NULL)
- {
- const struct blockvector *bv;
- const struct block *b;
- struct symbol *sym;
- bv = blockvector_for_pc_sect (sal->pc, 0, &b,
- SYMTAB_COMPUNIT (sal->symtab));
- if (bv != NULL)
- {
- sym = block_linkage_function (b);
- if (sym != NULL)
- {
- fixup_symbol_section (sym, SYMTAB_OBJFILE (sal->symtab));
- sal->section = SYMBOL_OBJ_SECTION (SYMTAB_OBJFILE (sal->symtab),
- sym);
- }
- else
- {
-
- struct bound_minimal_symbol msym;
- struct cleanup *old_chain = save_current_space_and_thread ();
- switch_to_program_space_and_thread (sal->pspace);
- msym = lookup_minimal_symbol_by_pc (sal->pc);
- if (msym.minsym)
- sal->section = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym);
- do_cleanups (old_chain);
- }
- }
- }
- }
- void
- break_command (char *arg, int from_tty)
- {
- break_command_1 (arg, 0, from_tty);
- }
- void
- tbreak_command (char *arg, int from_tty)
- {
- break_command_1 (arg, BP_TEMPFLAG, from_tty);
- }
- static void
- hbreak_command (char *arg, int from_tty)
- {
- break_command_1 (arg, BP_HARDWAREFLAG, from_tty);
- }
- static void
- thbreak_command (char *arg, int from_tty)
- {
- break_command_1 (arg, (BP_TEMPFLAG | BP_HARDWAREFLAG), from_tty);
- }
- static void
- stop_command (char *arg, int from_tty)
- {
- printf_filtered (_("Specify the type of breakpoint to set.\n\
- Usage: stop in <function | address>\n\
- stop at <line>\n"));
- }
- static void
- stopin_command (char *arg, int from_tty)
- {
- int badInput = 0;
- if (arg == (char *) NULL)
- badInput = 1;
- else if (*arg != '*')
- {
- char *argptr = arg;
- int hasColon = 0;
-
- while (*argptr && !hasColon)
- {
- hasColon = (*argptr == ':');
- argptr++;
- }
- if (hasColon)
- badInput = (*argptr != ':');
- else
- badInput = isdigit (*arg);
- }
- if (badInput)
- printf_filtered (_("Usage: stop in <function | address>\n"));
- else
- break_command_1 (arg, 0, from_tty);
- }
- static void
- stopat_command (char *arg, int from_tty)
- {
- int badInput = 0;
- if (arg == (char *) NULL || *arg == '*')
- badInput = 1;
- else
- {
- char *argptr = arg;
- int hasColon = 0;
-
- while (*argptr && !hasColon)
- {
- hasColon = (*argptr == ':');
- argptr++;
- }
- if (hasColon)
- badInput = (*argptr == ':');
- else
- badInput = !isdigit (*arg);
- }
- if (badInput)
- printf_filtered (_("Usage: stop at <line>\n"));
- else
- break_command_1 (arg, 0, from_tty);
- }
- static void
- dprintf_command (char *arg, int from_tty)
- {
- create_breakpoint (get_current_arch (),
- arg,
- NULL, 0, NULL, 1 ,
- 0, bp_dprintf,
- 0 ,
- pending_break_support,
- &dprintf_breakpoint_ops,
- from_tty,
- 1 ,
- 0 ,
- 0);
- }
- static void
- agent_printf_command (char *arg, int from_tty)
- {
- error (_("May only run agent-printf on the target"));
- }
- static int
- breakpoint_hit_ranged_breakpoint (const struct bp_location *bl,
- struct address_space *aspace,
- CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- if (ws->kind != TARGET_WAITKIND_STOPPED
- || ws->value.sig != GDB_SIGNAL_TRAP)
- return 0;
- return breakpoint_address_match_range (bl->pspace->aspace, bl->address,
- bl->length, aspace, bp_addr);
- }
- static int
- resources_needed_ranged_breakpoint (const struct bp_location *bl)
- {
- return target_ranged_break_num_registers ();
- }
- static enum print_stop_action
- print_it_ranged_breakpoint (bpstat bs)
- {
- struct breakpoint *b = bs->breakpoint_at;
- struct bp_location *bl = b->loc;
- struct ui_out *uiout = current_uiout;
- gdb_assert (b->type == bp_hardware_breakpoint);
-
- gdb_assert (bl && bl->next == NULL);
- annotate_breakpoint (b->number);
- if (b->disposition == disp_del)
- ui_out_text (uiout, "\nTemporary ranged breakpoint ");
- else
- ui_out_text (uiout, "\nRanged breakpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, ", ");
- return PRINT_SRC_AND_LOC;
- }
- static void
- print_one_ranged_breakpoint (struct breakpoint *b,
- struct bp_location **last_loc)
- {
- struct bp_location *bl = b->loc;
- struct value_print_options opts;
- struct ui_out *uiout = current_uiout;
-
- gdb_assert (bl && bl->next == NULL);
- get_user_print_options (&opts);
- if (opts.addressprint)
-
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- print_breakpoint_location (b, bl);
- *last_loc = bl;
- }
- static void
- print_one_detail_ranged_breakpoint (const struct breakpoint *b,
- struct ui_out *uiout)
- {
- CORE_ADDR address_start, address_end;
- struct bp_location *bl = b->loc;
- struct ui_file *stb = mem_fileopen ();
- struct cleanup *cleanup = make_cleanup_ui_file_delete (stb);
- gdb_assert (bl);
- address_start = bl->address;
- address_end = address_start + bl->length - 1;
- ui_out_text (uiout, "\taddress range: ");
- fprintf_unfiltered (stb, "[%s, %s]",
- print_core_address (bl->gdbarch, address_start),
- print_core_address (bl->gdbarch, address_end));
- ui_out_field_stream (uiout, "addr", stb);
- ui_out_text (uiout, "\n");
- do_cleanups (cleanup);
- }
- static void
- print_mention_ranged_breakpoint (struct breakpoint *b)
- {
- struct bp_location *bl = b->loc;
- struct ui_out *uiout = current_uiout;
- gdb_assert (bl);
- gdb_assert (b->type == bp_hardware_breakpoint);
- if (ui_out_is_mi_like_p (uiout))
- return;
- printf_filtered (_("Hardware assisted ranged breakpoint %d from %s to %s."),
- b->number, paddress (bl->gdbarch, bl->address),
- paddress (bl->gdbarch, bl->address + bl->length - 1));
- }
- static void
- print_recreate_ranged_breakpoint (struct breakpoint *b, struct ui_file *fp)
- {
- fprintf_unfiltered (fp, "break-range %s, %s", b->addr_string,
- b->addr_string_range_end);
- print_recreate_thread (b, fp);
- }
- static struct breakpoint_ops ranged_breakpoint_ops;
- static CORE_ADDR
- find_breakpoint_range_end (struct symtab_and_line sal)
- {
- CORE_ADDR end;
-
- if (sal.explicit_pc)
- end = sal.pc;
- else
- {
- int ret;
- CORE_ADDR start;
- ret = find_line_pc_range (sal, &start, &end);
- if (!ret)
- error (_("Could not find location of the end of the range."));
-
- end--;
- }
- return end;
- }
- static void
- break_range_command (char *arg, int from_tty)
- {
- char *arg_start, *addr_string_start, *addr_string_end;
- struct linespec_result canonical_start, canonical_end;
- int bp_count, can_use_bp, length;
- CORE_ADDR end;
- struct breakpoint *b;
- struct symtab_and_line sal_start, sal_end;
- struct cleanup *cleanup_bkpt;
- struct linespec_sals *lsal_start, *lsal_end;
-
- if (target_ranged_break_num_registers () < 0)
- error (_("This target does not support hardware ranged breakpoints."));
- bp_count = hw_breakpoint_used_count ();
- bp_count += target_ranged_break_num_registers ();
- can_use_bp = target_can_use_hardware_watchpoint (bp_hardware_breakpoint,
- bp_count, 0);
- if (can_use_bp < 0)
- error (_("Hardware breakpoints used exceeds limit."));
- arg = skip_spaces (arg);
- if (arg == NULL || arg[0] == '\0')
- error(_("No address range specified."));
- init_linespec_result (&canonical_start);
- arg_start = arg;
- parse_breakpoint_sals (&arg, &canonical_start);
- cleanup_bkpt = make_cleanup_destroy_linespec_result (&canonical_start);
- if (arg[0] != ',')
- error (_("Too few arguments."));
- else if (VEC_empty (linespec_sals, canonical_start.sals))
- error (_("Could not find location of the beginning of the range."));
- lsal_start = VEC_index (linespec_sals, canonical_start.sals, 0);
- if (VEC_length (linespec_sals, canonical_start.sals) > 1
- || lsal_start->sals.nelts != 1)
- error (_("Cannot create a ranged breakpoint with multiple locations."));
- sal_start = lsal_start->sals.sals[0];
- addr_string_start = savestring (arg_start, arg - arg_start);
- make_cleanup (xfree, addr_string_start);
- arg++;
- arg = skip_spaces (arg);
-
- init_linespec_result (&canonical_end);
- arg_start = arg;
-
- decode_line_full (&arg, DECODE_LINE_FUNFIRSTLINE,
- sal_start.symtab, sal_start.line,
- &canonical_end, NULL, NULL);
- make_cleanup_destroy_linespec_result (&canonical_end);
- if (VEC_empty (linespec_sals, canonical_end.sals))
- error (_("Could not find location of the end of the range."));
- lsal_end = VEC_index (linespec_sals, canonical_end.sals, 0);
- if (VEC_length (linespec_sals, canonical_end.sals) > 1
- || lsal_end->sals.nelts != 1)
- error (_("Cannot create a ranged breakpoint with multiple locations."));
- sal_end = lsal_end->sals.sals[0];
- addr_string_end = savestring (arg_start, arg - arg_start);
- make_cleanup (xfree, addr_string_end);
- end = find_breakpoint_range_end (sal_end);
- if (sal_start.pc > end)
- error (_("Invalid address range, end precedes start."));
- length = end - sal_start.pc + 1;
- if (length < 0)
-
- error (_("Address range too large."));
- else if (length == 1)
- {
-
- hbreak_command (addr_string_start, 1);
- do_cleanups (cleanup_bkpt);
- return;
- }
-
- b = set_raw_breakpoint (get_current_arch (), sal_start,
- bp_hardware_breakpoint, &ranged_breakpoint_ops);
- set_breakpoint_count (breakpoint_count + 1);
- b->number = breakpoint_count;
- b->disposition = disp_donttouch;
- b->addr_string = xstrdup (addr_string_start);
- b->addr_string_range_end = xstrdup (addr_string_end);
- b->loc->length = length;
- do_cleanups (cleanup_bkpt);
- mention (b);
- observer_notify_breakpoint_created (b);
- update_global_location_list (UGLL_MAY_INSERT);
- }
- static int
- watchpoint_exp_is_const (const struct expression *exp)
- {
- int i = exp->nelts;
- while (i > 0)
- {
- int oplenp, argsp;
-
- operator_length (exp, i, &oplenp, &argsp);
- i -= oplenp;
- switch (exp->elts[i].opcode)
- {
- case BINOP_ADD:
- case BINOP_SUB:
- case BINOP_MUL:
- case BINOP_DIV:
- case BINOP_REM:
- case BINOP_MOD:
- case BINOP_LSH:
- case BINOP_RSH:
- case BINOP_LOGICAL_AND:
- case BINOP_LOGICAL_OR:
- case BINOP_BITWISE_AND:
- case BINOP_BITWISE_IOR:
- case BINOP_BITWISE_XOR:
- case BINOP_EQUAL:
- case BINOP_NOTEQUAL:
- case BINOP_LESS:
- case BINOP_GTR:
- case BINOP_LEQ:
- case BINOP_GEQ:
- case BINOP_REPEAT:
- case BINOP_COMMA:
- case BINOP_EXP:
- case BINOP_MIN:
- case BINOP_MAX:
- case BINOP_INTDIV:
- case BINOP_CONCAT:
- case TERNOP_COND:
- case TERNOP_SLICE:
- case OP_LONG:
- case OP_DOUBLE:
- case OP_DECFLOAT:
- case OP_LAST:
- case OP_COMPLEX:
- case OP_STRING:
- case OP_ARRAY:
- case OP_TYPE:
- case OP_TYPEOF:
- case OP_DECLTYPE:
- case OP_TYPEID:
- case OP_NAME:
- case OP_OBJC_NSSTRING:
- case UNOP_NEG:
- case UNOP_LOGICAL_NOT:
- case UNOP_COMPLEMENT:
- case UNOP_ADDR:
- case UNOP_HIGH:
- case UNOP_CAST:
- case UNOP_CAST_TYPE:
- case UNOP_REINTERPRET_CAST:
- case UNOP_DYNAMIC_CAST:
-
- break;
- case OP_VAR_VALUE:
-
- {
- struct symbol *s = exp->elts[i + 2].symbol;
- if (SYMBOL_CLASS (s) != LOC_BLOCK
- && SYMBOL_CLASS (s) != LOC_CONST
- && SYMBOL_CLASS (s) != LOC_CONST_BYTES)
- return 0;
- break;
- }
-
- default:
- return 0;
- }
- }
- return 1;
- }
- static void
- dtor_watchpoint (struct breakpoint *self)
- {
- struct watchpoint *w = (struct watchpoint *) self;
- xfree (w->cond_exp);
- xfree (w->exp);
- xfree (w->exp_string);
- xfree (w->exp_string_reparse);
- value_free (w->val);
- base_breakpoint_ops.dtor (self);
- }
- static void
- re_set_watchpoint (struct breakpoint *b)
- {
- struct watchpoint *w = (struct watchpoint *) b;
-
- update_watchpoint (w, 1 );
- }
- static int
- insert_watchpoint (struct bp_location *bl)
- {
- struct watchpoint *w = (struct watchpoint *) bl->owner;
- int length = w->exact ? 1 : bl->length;
- return target_insert_watchpoint (bl->address, length, bl->watchpoint_type,
- w->cond_exp);
- }
- static int
- remove_watchpoint (struct bp_location *bl)
- {
- struct watchpoint *w = (struct watchpoint *) bl->owner;
- int length = w->exact ? 1 : bl->length;
- return target_remove_watchpoint (bl->address, length, bl->watchpoint_type,
- w->cond_exp);
- }
- static int
- breakpoint_hit_watchpoint (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- struct breakpoint *b = bl->owner;
- struct watchpoint *w = (struct watchpoint *) b;
-
- if (is_hardware_watchpoint (b)
- && w->watchpoint_triggered == watch_triggered_no)
- return 0;
- return 1;
- }
- static void
- check_status_watchpoint (bpstat bs)
- {
- gdb_assert (is_watchpoint (bs->breakpoint_at));
- bpstat_check_watchpoint (bs);
- }
- static int
- resources_needed_watchpoint (const struct bp_location *bl)
- {
- struct watchpoint *w = (struct watchpoint *) bl->owner;
- int length = w->exact? 1 : bl->length;
- return target_region_ok_for_hw_watchpoint (bl->address, length);
- }
- static int
- works_in_software_mode_watchpoint (const struct breakpoint *b)
- {
-
- return b->type == bp_watchpoint || b->type == bp_hardware_watchpoint;
- }
- static enum print_stop_action
- print_it_watchpoint (bpstat bs)
- {
- struct cleanup *old_chain;
- struct breakpoint *b;
- struct ui_file *stb;
- enum print_stop_action result;
- struct watchpoint *w;
- struct ui_out *uiout = current_uiout;
- gdb_assert (bs->bp_location_at != NULL);
- b = bs->breakpoint_at;
- w = (struct watchpoint *) b;
- stb = mem_fileopen ();
- old_chain = make_cleanup_ui_file_delete (stb);
- switch (b->type)
- {
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- annotate_watchpoint (b->number);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
- mention (b);
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nOld value = ");
- watchpoint_value_print (bs->old_val, stb);
- ui_out_field_stream (uiout, "old", stb);
- ui_out_text (uiout, "\nNew value = ");
- watchpoint_value_print (w->val, stb);
- ui_out_field_stream (uiout, "new", stb);
- ui_out_text (uiout, "\n");
-
- result = PRINT_UNKNOWN;
- break;
- case bp_read_watchpoint:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
- mention (b);
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nValue = ");
- watchpoint_value_print (w->val, stb);
- ui_out_field_stream (uiout, "value", stb);
- ui_out_text (uiout, "\n");
- result = PRINT_UNKNOWN;
- break;
- case bp_access_watchpoint:
- if (bs->old_val != NULL)
- {
- annotate_watchpoint (b->number);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
- mention (b);
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nOld value = ");
- watchpoint_value_print (bs->old_val, stb);
- ui_out_field_stream (uiout, "old", stb);
- ui_out_text (uiout, "\nNew value = ");
- }
- else
- {
- mention (b);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nValue = ");
- }
- watchpoint_value_print (w->val, stb);
- ui_out_field_stream (uiout, "new", stb);
- ui_out_text (uiout, "\n");
- result = PRINT_UNKNOWN;
- break;
- default:
- result = PRINT_UNKNOWN;
- }
- do_cleanups (old_chain);
- return result;
- }
- static void
- print_mention_watchpoint (struct breakpoint *b)
- {
- struct cleanup *ui_out_chain;
- struct watchpoint *w = (struct watchpoint *) b;
- struct ui_out *uiout = current_uiout;
- switch (b->type)
- {
- case bp_watchpoint:
- ui_out_text (uiout, "Watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
- break;
- case bp_hardware_watchpoint:
- ui_out_text (uiout, "Hardware watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
- break;
- case bp_read_watchpoint:
- ui_out_text (uiout, "Hardware read watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
- break;
- case bp_access_watchpoint:
- ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("Invalid hardware watchpoint type."));
- }
- ui_out_field_int (uiout, "number", b->number);
- ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", w->exp_string);
- do_cleanups (ui_out_chain);
- }
- static void
- print_recreate_watchpoint (struct breakpoint *b, struct ui_file *fp)
- {
- struct watchpoint *w = (struct watchpoint *) b;
- switch (b->type)
- {
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- fprintf_unfiltered (fp, "watch");
- break;
- case bp_read_watchpoint:
- fprintf_unfiltered (fp, "rwatch");
- break;
- case bp_access_watchpoint:
- fprintf_unfiltered (fp, "awatch");
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("Invalid watchpoint type."));
- }
- fprintf_unfiltered (fp, " %s", w->exp_string);
- print_recreate_thread (b, fp);
- }
- static int
- explains_signal_watchpoint (struct breakpoint *b, enum gdb_signal sig)
- {
-
- if (b->type == bp_watchpoint && sig != GDB_SIGNAL_TRAP)
- return 0;
- return 1;
- }
- static struct breakpoint_ops watchpoint_breakpoint_ops;
- static int
- insert_masked_watchpoint (struct bp_location *bl)
- {
- struct watchpoint *w = (struct watchpoint *) bl->owner;
- return target_insert_mask_watchpoint (bl->address, w->hw_wp_mask,
- bl->watchpoint_type);
- }
- static int
- remove_masked_watchpoint (struct bp_location *bl)
- {
- struct watchpoint *w = (struct watchpoint *) bl->owner;
- return target_remove_mask_watchpoint (bl->address, w->hw_wp_mask,
- bl->watchpoint_type);
- }
- static int
- resources_needed_masked_watchpoint (const struct bp_location *bl)
- {
- struct watchpoint *w = (struct watchpoint *) bl->owner;
- return target_masked_watch_num_registers (bl->address, w->hw_wp_mask);
- }
- static int
- works_in_software_mode_masked_watchpoint (const struct breakpoint *b)
- {
- return 0;
- }
- static enum print_stop_action
- print_it_masked_watchpoint (bpstat bs)
- {
- struct breakpoint *b = bs->breakpoint_at;
- struct ui_out *uiout = current_uiout;
-
- gdb_assert (b->loc && b->loc->next == NULL);
- switch (b->type)
- {
- case bp_hardware_watchpoint:
- annotate_watchpoint (b->number);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
- break;
- case bp_read_watchpoint:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
- break;
- case bp_access_watchpoint:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("Invalid hardware watchpoint type."));
- }
- mention (b);
- ui_out_text (uiout, _("\n\
- Check the underlying instruction at PC for the memory\n\
- address and value which triggered this watchpoint.\n"));
- ui_out_text (uiout, "\n");
-
- return PRINT_UNKNOWN;
- }
- static void
- print_one_detail_masked_watchpoint (const struct breakpoint *b,
- struct ui_out *uiout)
- {
- struct watchpoint *w = (struct watchpoint *) b;
-
- gdb_assert (b->loc && b->loc->next == NULL);
- ui_out_text (uiout, "\tmask ");
- ui_out_field_core_addr (uiout, "mask", b->loc->gdbarch, w->hw_wp_mask);
- ui_out_text (uiout, "\n");
- }
- static void
- print_mention_masked_watchpoint (struct breakpoint *b)
- {
- struct watchpoint *w = (struct watchpoint *) b;
- struct ui_out *uiout = current_uiout;
- struct cleanup *ui_out_chain;
- switch (b->type)
- {
- case bp_hardware_watchpoint:
- ui_out_text (uiout, "Masked hardware watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
- break;
- case bp_read_watchpoint:
- ui_out_text (uiout, "Masked hardware read watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
- break;
- case bp_access_watchpoint:
- ui_out_text (uiout, "Masked hardware access (read/write) watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("Invalid hardware watchpoint type."));
- }
- ui_out_field_int (uiout, "number", b->number);
- ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", w->exp_string);
- do_cleanups (ui_out_chain);
- }
- static void
- print_recreate_masked_watchpoint (struct breakpoint *b, struct ui_file *fp)
- {
- struct watchpoint *w = (struct watchpoint *) b;
- char tmp[40];
- switch (b->type)
- {
- case bp_hardware_watchpoint:
- fprintf_unfiltered (fp, "watch");
- break;
- case bp_read_watchpoint:
- fprintf_unfiltered (fp, "rwatch");
- break;
- case bp_access_watchpoint:
- fprintf_unfiltered (fp, "awatch");
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("Invalid hardware watchpoint type."));
- }
- sprintf_vma (tmp, w->hw_wp_mask);
- fprintf_unfiltered (fp, " %s mask 0x%s", w->exp_string, tmp);
- print_recreate_thread (b, fp);
- }
- static struct breakpoint_ops masked_watchpoint_breakpoint_ops;
- static int
- is_masked_watchpoint (const struct breakpoint *b)
- {
- return b->ops == &masked_watchpoint_breakpoint_ops;
- }
- static void
- watch_command_1 (const char *arg, int accessflag, int from_tty,
- int just_location, int internal)
- {
- volatile struct gdb_exception e;
- struct breakpoint *b, *scope_breakpoint = NULL;
- struct expression *exp;
- const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
- struct value *val, *mark, *result;
- int saved_bitpos = 0, saved_bitsize = 0;
- struct frame_info *frame;
- const char *exp_start = NULL;
- const char *exp_end = NULL;
- const char *tok, *end_tok;
- int toklen = -1;
- const char *cond_start = NULL;
- const char *cond_end = NULL;
- enum bptype bp_type;
- int thread = -1;
- int pc = 0;
-
- int use_mask = 0;
- CORE_ADDR mask = 0;
- struct watchpoint *w;
- char *expression;
- struct cleanup *back_to;
-
- if (arg != NULL && arg[0] != '\0')
- {
- const char *value_start;
- exp_end = arg + strlen (arg);
-
- for (tok = exp_end - 1; tok > arg; tok--)
- {
-
- while (tok > arg && (*tok == ' ' || *tok == '\t'))
- tok--;
-
- while (tok > arg && (*tok != ' ' && *tok != '\t'))
- tok--;
- value_start = tok + 1;
-
- while (tok > arg && (*tok == ' ' || *tok == '\t'))
- tok--;
- end_tok = tok;
-
- while (tok > arg && (*tok != ' ' && *tok != '\t'))
- tok--;
- tok++;
- toklen = end_tok - tok + 1;
- if (toklen == 6 && !strncmp (tok, "thread", 6))
- {
-
- char *endp;
- if (thread != -1)
- error(_("You can specify only one thread."));
-
- thread = strtol (value_start, &endp, 0);
-
- if (*endp != ' ' && *endp != '\t' && *endp != '\0')
- error (_("Invalid thread ID specification %s."), value_start);
-
- if (!valid_thread_id (thread))
- invalid_thread_id_error (thread);
- }
- else if (toklen == 4 && !strncmp (tok, "mask", 4))
- {
-
- struct value *mask_value, *mark;
- if (use_mask)
- error(_("You can specify only one mask."));
- use_mask = just_location = 1;
- mark = value_mark ();
- mask_value = parse_to_comma_and_eval (&value_start);
- mask = value_as_address (mask_value);
- value_free_to_mark (mark);
- }
- else
-
- break;
-
- exp_end = tok;
- }
- }
- else
- exp_end = arg;
-
- innermost_block = NULL;
- expression = savestring (arg, exp_end - arg);
- back_to = make_cleanup (xfree, expression);
- exp_start = arg = expression;
- exp = parse_exp_1 (&arg, 0, 0, 0);
- exp_end = arg;
-
- while (exp_end > exp_start && (exp_end[-1] == ' ' || exp_end[-1] == '\t'))
- --exp_end;
-
- if (watchpoint_exp_is_const (exp))
- {
- int len;
- len = exp_end - exp_start;
- while (len > 0 && isspace (exp_start[len - 1]))
- len--;
- error (_("Cannot watch constant value `%.*s'."), len, exp_start);
- }
- exp_valid_block = innermost_block;
- mark = value_mark ();
- fetch_subexp_value (exp, &pc, &val, &result, NULL, just_location);
- if (val != NULL && just_location)
- {
- saved_bitpos = value_bitpos (val);
- saved_bitsize = value_bitsize (val);
- }
- if (just_location)
- {
- int ret;
- exp_valid_block = NULL;
- val = value_addr (result);
- release_value (val);
- value_free_to_mark (mark);
- if (use_mask)
- {
- ret = target_masked_watch_num_registers (value_as_address (val),
- mask);
- if (ret == -1)
- error (_("This target does not support masked watchpoints."));
- else if (ret == -2)
- error (_("Invalid mask or memory region."));
- }
- }
- else if (val != NULL)
- release_value (val);
- tok = skip_spaces_const (arg);
- end_tok = skip_to_space_const (tok);
- toklen = end_tok - tok;
- if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
- {
- struct expression *cond;
- innermost_block = NULL;
- tok = cond_start = end_tok + 1;
- cond = parse_exp_1 (&tok, 0, 0, 0);
-
- cond_exp_valid_block = innermost_block;
- xfree (cond);
- cond_end = tok;
- }
- if (*tok)
- error (_("Junk at end of command."));
- frame = block_innermost_frame (exp_valid_block);
-
- if (exp_valid_block && frame)
- {
- if (frame_id_p (frame_unwind_caller_id (frame)))
- {
- scope_breakpoint
- = create_internal_breakpoint (frame_unwind_caller_arch (frame),
- frame_unwind_caller_pc (frame),
- bp_watchpoint_scope,
- &momentary_breakpoint_ops);
- scope_breakpoint->enable_state = bp_enabled;
-
- scope_breakpoint->disposition = disp_del;
-
- scope_breakpoint->frame_id = frame_unwind_caller_id (frame);
-
- scope_breakpoint->loc->gdbarch
- = frame_unwind_caller_arch (frame);
- scope_breakpoint->loc->requested_address
- = frame_unwind_caller_pc (frame);
- scope_breakpoint->loc->address
- = adjust_breakpoint_address (scope_breakpoint->loc->gdbarch,
- scope_breakpoint->loc->requested_address,
- scope_breakpoint->type);
- }
- }
-
- if (accessflag == hw_read)
- bp_type = bp_read_watchpoint;
- else if (accessflag == hw_access)
- bp_type = bp_access_watchpoint;
- else
- bp_type = bp_hardware_watchpoint;
- w = XCNEW (struct watchpoint);
- b = &w->base;
- if (use_mask)
- init_raw_breakpoint_without_location (b, NULL, bp_type,
- &masked_watchpoint_breakpoint_ops);
- else
- init_raw_breakpoint_without_location (b, NULL, bp_type,
- &watchpoint_breakpoint_ops);
- b->thread = thread;
- b->disposition = disp_donttouch;
- b->pspace = current_program_space;
- w->exp = exp;
- w->exp_valid_block = exp_valid_block;
- w->cond_exp_valid_block = cond_exp_valid_block;
- if (just_location)
- {
- struct type *t = value_type (val);
- CORE_ADDR addr = value_as_address (val);
- char *name;
- t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
- name = type_to_string (t);
- w->exp_string_reparse = xstrprintf ("* (%s *) %s", name,
- core_addr_to_string (addr));
- xfree (name);
- w->exp_string = xstrprintf ("-location %.*s",
- (int) (exp_end - exp_start), exp_start);
-
- b->language = language_c;
- }
- else
- w->exp_string = savestring (exp_start, exp_end - exp_start);
- if (use_mask)
- {
- w->hw_wp_mask = mask;
- }
- else
- {
- w->val = val;
- w->val_bitpos = saved_bitpos;
- w->val_bitsize = saved_bitsize;
- w->val_valid = 1;
- }
- if (cond_start)
- b->cond_string = savestring (cond_start, cond_end - cond_start);
- else
- b->cond_string = 0;
- if (frame)
- {
- w->watchpoint_frame = get_frame_id (frame);
- w->watchpoint_thread = inferior_ptid;
- }
- else
- {
- w->watchpoint_frame = null_frame_id;
- w->watchpoint_thread = null_ptid;
- }
- if (scope_breakpoint != NULL)
- {
-
- b->related_breakpoint = scope_breakpoint;
- scope_breakpoint->related_breakpoint = b;
- }
- if (!just_location)
- value_free_to_mark (mark);
- TRY_CATCH (e, RETURN_MASK_ALL)
- {
-
- update_watchpoint (w, 1);
- }
- if (e.reason < 0)
- {
- delete_breakpoint (b);
- throw_exception (e);
- }
- install_breakpoint (internal, b, 1);
- do_cleanups (back_to);
- }
- static int
- can_use_hardware_watchpoint (struct value *v)
- {
- int found_memory_cnt = 0;
- struct value *head = v;
-
- if (!can_use_hw_watchpoints)
- return 0;
-
- FIXME
- for (; v; v = value_next (v))
- {
- if (VALUE_LVAL (v) == lval_memory)
- {
- if (v != head && value_lazy (v))
-
- ;
- else
- {
-
- struct type *vtype = check_typedef (value_type (v));
-
- if (v == head
- || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT
- && TYPE_CODE (vtype) != TYPE_CODE_ARRAY))
- {
- CORE_ADDR vaddr = value_address (v);
- int len;
- int num_regs;
- len = (target_exact_watchpoints
- && is_scalar_type_recursive (vtype))?
- 1 : TYPE_LENGTH (value_type (v));
- num_regs = target_region_ok_for_hw_watchpoint (vaddr, len);
- if (!num_regs)
- return 0;
- else
- found_memory_cnt += num_regs;
- }
- }
- }
- else if (VALUE_LVAL (v) != not_lval
- && deprecated_value_modifiable (v) == 0)
- return 0;
- else if (VALUE_LVAL (v) == lval_register)
- return 0;
- }
-
- return found_memory_cnt;
- }
- void
- watch_command_wrapper (char *arg, int from_tty, int internal)
- {
- watch_command_1 (arg, hw_write, from_tty, 0, internal);
- }
- static void
- watch_maybe_just_location (char *arg, int accessflag, int from_tty)
- {
- int just_location = 0;
- if (arg
- && (check_for_argument (&arg, "-location", sizeof ("-location") - 1)
- || check_for_argument (&arg, "-l", sizeof ("-l") - 1)))
- {
- arg = skip_spaces (arg);
- just_location = 1;
- }
- watch_command_1 (arg, accessflag, from_tty, just_location, 0);
- }
- static void
- watch_command (char *arg, int from_tty)
- {
- watch_maybe_just_location (arg, hw_write, from_tty);
- }
- void
- rwatch_command_wrapper (char *arg, int from_tty, int internal)
- {
- watch_command_1 (arg, hw_read, from_tty, 0, internal);
- }
- static void
- rwatch_command (char *arg, int from_tty)
- {
- watch_maybe_just_location (arg, hw_read, from_tty);
- }
- void
- awatch_command_wrapper (char *arg, int from_tty, int internal)
- {
- watch_command_1 (arg, hw_access, from_tty, 0, internal);
- }
- static void
- awatch_command (char *arg, int from_tty)
- {
- watch_maybe_just_location (arg, hw_access, from_tty);
- }
- struct until_break_command_continuation_args
- {
- struct breakpoint *breakpoint;
- struct breakpoint *breakpoint2;
- int thread_num;
- };
- static void
- until_break_command_continuation (void *arg, int err)
- {
- struct until_break_command_continuation_args *a = arg;
- delete_breakpoint (a->breakpoint);
- if (a->breakpoint2)
- delete_breakpoint (a->breakpoint2);
- delete_longjmp_breakpoint (a->thread_num);
- }
- void
- until_break_command (char *arg, int from_tty, int anywhere)
- {
- struct symtabs_and_lines sals;
- struct symtab_and_line sal;
- struct frame_info *frame;
- struct gdbarch *frame_gdbarch;
- struct frame_id stack_frame_id;
- struct frame_id caller_frame_id;
- struct breakpoint *breakpoint;
- struct breakpoint *breakpoint2 = NULL;
- struct cleanup *old_chain;
- int thread;
- struct thread_info *tp;
- clear_proceed_status (0);
-
- if (last_displayed_sal_is_valid ())
- sals = decode_line_1 (&arg, DECODE_LINE_FUNFIRSTLINE,
- get_last_displayed_symtab (),
- get_last_displayed_line ());
- else
- sals = decode_line_1 (&arg, DECODE_LINE_FUNFIRSTLINE,
- (struct symtab *) NULL, 0);
- if (sals.nelts != 1)
- error (_("Couldn't get information on specified line."));
- sal = sals.sals[0];
- xfree (sals.sals);
- if (*arg)
- error (_("Junk at end of arguments."));
- resolve_sal_pc (&sal);
- tp = inferior_thread ();
- thread = tp->num;
- old_chain = make_cleanup (null_cleanup, NULL);
-
- frame = get_selected_frame (NULL);
- frame_gdbarch = get_frame_arch (frame);
- stack_frame_id = get_stack_frame_id (frame);
- caller_frame_id = frame_unwind_caller_id (frame);
-
- if (frame_id_p (caller_frame_id))
- {
- struct symtab_and_line sal2;
- sal2 = find_pc_line (frame_unwind_caller_pc (frame), 0);
- sal2.pc = frame_unwind_caller_pc (frame);
- breakpoint2 = set_momentary_breakpoint (frame_unwind_caller_arch (frame),
- sal2,
- caller_frame_id,
- bp_until);
- make_cleanup_delete_breakpoint (breakpoint2);
- set_longjmp_breakpoint (tp, caller_frame_id);
- make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
- }
-
- frame = NULL;
- if (anywhere)
-
- breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
- null_frame_id, bp_until);
- else
-
- breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
- stack_frame_id, bp_until);
- make_cleanup_delete_breakpoint (breakpoint);
- proceed (-1, GDB_SIGNAL_DEFAULT, 0);
-
- if (target_can_async_p () && is_running (inferior_ptid))
- {
- struct until_break_command_continuation_args *args;
- args = xmalloc (sizeof (*args));
- args->breakpoint = breakpoint;
- args->breakpoint2 = breakpoint2;
- args->thread_num = thread;
- discard_cleanups (old_chain);
- add_continuation (inferior_thread (),
- until_break_command_continuation, args,
- xfree);
- }
- else
- do_cleanups (old_chain);
- }
- char *
- ep_parse_optional_if_clause (char **arg)
- {
- char *cond_string;
- if (((*arg)[0] != 'i') || ((*arg)[1] != 'f') || !isspace ((*arg)[2]))
- return NULL;
-
- (*arg) += 2;
-
- *arg = skip_spaces (*arg);
- cond_string = *arg;
-
- (*arg) += strlen (cond_string);
- return cond_string;
- }
- typedef enum
- {
- catch_fork_temporary, catch_vfork_temporary,
- catch_fork_permanent, catch_vfork_permanent
- }
- catch_fork_kind;
- static void
- catch_fork_command_1 (char *arg, int from_tty,
- struct cmd_list_element *command)
- {
- struct gdbarch *gdbarch = get_current_arch ();
- char *cond_string = NULL;
- catch_fork_kind fork_kind;
- int tempflag;
- fork_kind = (catch_fork_kind) (uintptr_t) get_cmd_context (command);
- tempflag = (fork_kind == catch_fork_temporary
- || fork_kind == catch_vfork_temporary);
- if (!arg)
- arg = "";
- arg = skip_spaces (arg);
-
- cond_string = ep_parse_optional_if_clause (&arg);
- if ((*arg != '\0') && !isspace (*arg))
- error (_("Junk at end of arguments."));
-
- switch (fork_kind)
- {
- case catch_fork_temporary:
- case catch_fork_permanent:
- create_fork_vfork_event_catchpoint (gdbarch, tempflag, cond_string,
- &catch_fork_breakpoint_ops);
- break;
- case catch_vfork_temporary:
- case catch_vfork_permanent:
- create_fork_vfork_event_catchpoint (gdbarch, tempflag, cond_string,
- &catch_vfork_breakpoint_ops);
- break;
- default:
- error (_("unsupported or unknown fork kind; cannot catch it"));
- break;
- }
- }
- static void
- catch_exec_command_1 (char *arg, int from_tty,
- struct cmd_list_element *command)
- {
- struct exec_catchpoint *c;
- struct gdbarch *gdbarch = get_current_arch ();
- int tempflag;
- char *cond_string = NULL;
- tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
- if (!arg)
- arg = "";
- arg = skip_spaces (arg);
-
- cond_string = ep_parse_optional_if_clause (&arg);
- if ((*arg != '\0') && !isspace (*arg))
- error (_("Junk at end of arguments."));
- c = XNEW (struct exec_catchpoint);
- init_catchpoint (&c->base, gdbarch, tempflag, cond_string,
- &catch_exec_breakpoint_ops);
- c->exec_pathname = NULL;
- install_breakpoint (0, &c->base, 1);
- }
- void
- init_ada_exception_breakpoint (struct breakpoint *b,
- struct gdbarch *gdbarch,
- struct symtab_and_line sal,
- char *addr_string,
- const struct breakpoint_ops *ops,
- int tempflag,
- int enabled,
- int from_tty)
- {
- if (from_tty)
- {
- struct gdbarch *loc_gdbarch = get_sal_arch (sal);
- if (!loc_gdbarch)
- loc_gdbarch = gdbarch;
- describe_other_breakpoints (loc_gdbarch,
- sal.pspace, sal.pc, sal.section, -1);
- FIXME
- }
- init_raw_breakpoint (b, gdbarch, sal, bp_breakpoint, ops);
- b->enable_state = enabled ? bp_enabled : bp_disabled;
- b->disposition = tempflag ? disp_del : disp_donttouch;
- b->addr_string = addr_string;
- b->language = language_ada;
- }
- static VEC(int) *
- catch_syscall_split_args (char *arg)
- {
- VEC(int) *result = NULL;
- struct cleanup *cleanup = make_cleanup (VEC_cleanup (int), &result);
- struct gdbarch *gdbarch = target_gdbarch ();
- while (*arg != '\0')
- {
- int i, syscall_number;
- char *endptr;
- char cur_name[128];
- struct syscall s;
-
- arg = skip_spaces (arg);
- for (i = 0; i < 127 && arg[i] && !isspace (arg[i]); ++i)
- cur_name[i] = arg[i];
- cur_name[i] = '\0';
- arg += i;
-
- syscall_number = (int) strtol (cur_name, &endptr, 0);
- if (*endptr == '\0')
- get_syscall_by_number (gdbarch, syscall_number, &s);
- else
- {
-
- get_syscall_by_name (gdbarch, cur_name, &s);
- if (s.number == UNKNOWN_SYSCALL)
-
- error (_("Unknown syscall name '%s'."), cur_name);
- }
-
- VEC_safe_push (int, result, s.number);
- }
- discard_cleanups (cleanup);
- return result;
- }
- static void
- catch_syscall_command_1 (char *arg, int from_tty,
- struct cmd_list_element *command)
- {
- int tempflag;
- VEC(int) *filter;
- struct syscall s;
- struct gdbarch *gdbarch = get_current_arch ();
-
- if (gdbarch_get_syscall_number_p (gdbarch) == 0)
- error (_("The feature 'catch syscall' is not supported on \
- this architecture yet."));
- tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
- arg = skip_spaces (arg);
-
- get_syscall_by_number (gdbarch, 0, &s);
-
- if (arg != NULL)
- filter = catch_syscall_split_args (arg);
- else
- filter = NULL;
- create_syscall_event_catchpoint (tempflag, filter,
- &catch_syscall_breakpoint_ops);
- }
- static void
- catch_command (char *arg, int from_tty)
- {
- error (_("Catch requires an event name."));
- }
- static void
- tcatch_command (char *arg, int from_tty)
- {
- error (_("Catch requires an event name."));
- }
- static int
- compare_breakpoints (const void *a, const void *b)
- {
- const breakpoint_p *ba = a;
- uintptr_t ua = (uintptr_t) *ba;
- const breakpoint_p *bb = b;
- uintptr_t ub = (uintptr_t) *bb;
- if ((*ba)->number < (*bb)->number)
- return -1;
- else if ((*ba)->number > (*bb)->number)
- return 1;
-
- if (ua < ub)
- return -1;
- return ua > ub ? 1 : 0;
- }
- static void
- clear_command (char *arg, int from_tty)
- {
- struct breakpoint *b, *prev;
- VEC(breakpoint_p) *found = 0;
- int ix;
- int default_match;
- struct symtabs_and_lines sals;
- struct symtab_and_line sal;
- int i;
- struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
- if (arg)
- {
- sals = decode_line_with_current_source (arg,
- (DECODE_LINE_FUNFIRSTLINE
- | DECODE_LINE_LIST_MODE));
- make_cleanup (xfree, sals.sals);
- default_match = 0;
- }
- else
- {
- sals.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- make_cleanup (xfree, sals.sals);
- init_sal (&sal);
-
- get_last_displayed_sal (&sal);
- if (sal.symtab == 0)
- error (_("No source file specified."));
- sals.sals[0] = sal;
- sals.nelts = 1;
- default_match = 1;
- }
-
-
- found = NULL;
- make_cleanup (VEC_cleanup (breakpoint_p), &found);
- for (i = 0; i < sals.nelts; i++)
- {
- const char *sal_fullname;
-
- sal = sals.sals[i];
- sal_fullname = (sal.symtab == NULL
- ? NULL : symtab_to_fullname (sal.symtab));
-
- ALL_BREAKPOINTS (b)
- {
- int match = 0;
-
- if (b->type != bp_none && !is_watchpoint (b))
- {
- struct bp_location *loc = b->loc;
- for (; loc; loc = loc->next)
- {
-
- int pc_match = (!sal.explicit_line
- && sal.pc
- && (loc->pspace == sal.pspace)
- && (loc->address == sal.pc)
- && (!section_is_overlay (loc->section)
- || loc->section == sal.section));
- int line_match = 0;
- if ((default_match || sal.explicit_line)
- && loc->symtab != NULL
- && sal_fullname != NULL
- && sal.pspace == loc->pspace
- && loc->line_number == sal.line
- && filename_cmp (symtab_to_fullname (loc->symtab),
- sal_fullname) == 0)
- line_match = 1;
- if (pc_match || line_match)
- {
- match = 1;
- break;
- }
- }
- }
- if (match)
- VEC_safe_push(breakpoint_p, found, b);
- }
- }
-
- if (VEC_empty(breakpoint_p, found))
- {
- if (arg)
- error (_("No breakpoint at %s."), arg);
- else
- error (_("No breakpoint at this line."));
- }
-
- qsort (VEC_address (breakpoint_p, found),
- VEC_length (breakpoint_p, found),
- sizeof (breakpoint_p),
- compare_breakpoints);
- prev = VEC_index (breakpoint_p, found, 0);
- for (ix = 1; VEC_iterate (breakpoint_p, found, ix, b); ++ix)
- {
- if (b == prev)
- {
- VEC_ordered_remove (breakpoint_p, found, ix);
- --ix;
- }
- }
- if (VEC_length(breakpoint_p, found) > 1)
- from_tty = 1;
- if (from_tty)
- {
- if (VEC_length(breakpoint_p, found) == 1)
- printf_unfiltered (_("Deleted breakpoint "));
- else
- printf_unfiltered (_("Deleted breakpoints "));
- }
- for (ix = 0; VEC_iterate(breakpoint_p, found, ix, b); ix++)
- {
- if (from_tty)
- printf_unfiltered ("%d ", b->number);
- delete_breakpoint (b);
- }
- if (from_tty)
- putchar_unfiltered ('\n');
- do_cleanups (cleanups);
- }
- void
- breakpoint_auto_delete (bpstat bs)
- {
- struct breakpoint *b, *b_tmp;
- for (; bs; bs = bs->next)
- if (bs->breakpoint_at
- && bs->breakpoint_at->disposition == disp_del
- && bs->stop)
- delete_breakpoint (bs->breakpoint_at);
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- {
- if (b->disposition == disp_del_at_next_stop)
- delete_breakpoint (b);
- }
- }
- static int
- bp_location_compare (const void *ap, const void *bp)
- {
- struct bp_location *a = *(void **) ap;
- struct bp_location *b = *(void **) bp;
- if (a->address != b->address)
- return (a->address > b->address) - (a->address < b->address);
-
- if (a->pspace->num != b->pspace->num)
- return ((a->pspace->num > b->pspace->num)
- - (a->pspace->num < b->pspace->num));
-
- if (a->permanent != b->permanent)
- return (a->permanent < b->permanent) - (a->permanent > b->permanent);
-
- if (a->owner->number != b->owner->number)
- return ((a->owner->number > b->owner->number)
- - (a->owner->number < b->owner->number));
- return (a > b) - (a < b);
- }
- static void
- bp_location_target_extensions_update (void)
- {
- struct bp_location *bl, **blp_tmp;
- bp_location_placed_address_before_address_max = 0;
- bp_location_shadow_len_after_address_max = 0;
- ALL_BP_LOCATIONS (bl, blp_tmp)
- {
- CORE_ADDR start, end, addr;
- if (!bp_location_has_shadow (bl))
- continue;
- start = bl->target_info.placed_address;
- end = start + bl->target_info.shadow_len;
- gdb_assert (bl->address >= start);
- addr = bl->address - start;
- if (addr > bp_location_placed_address_before_address_max)
- bp_location_placed_address_before_address_max = addr;
-
- gdb_assert (bl->address < end);
- addr = end - bl->address;
- if (addr > bp_location_shadow_len_after_address_max)
- bp_location_shadow_len_after_address_max = addr;
- }
- }
- static void
- download_tracepoint_locations (void)
- {
- struct breakpoint *b;
- struct cleanup *old_chain;
- if (!target_can_download_tracepoint ())
- return;
- old_chain = save_current_space_and_thread ();
- ALL_TRACEPOINTS (b)
- {
- struct bp_location *bl;
- struct tracepoint *t;
- int bp_location_downloaded = 0;
- if ((b->type == bp_fast_tracepoint
- ? !may_insert_fast_tracepoints
- : !may_insert_tracepoints))
- continue;
- for (bl = b->loc; bl; bl = bl->next)
- {
-
- if (!should_be_inserted (bl) || bl->inserted)
- continue;
- switch_to_program_space_and_thread (bl->pspace);
- target_download_tracepoint (bl);
- bl->inserted = 1;
- bp_location_downloaded = 1;
- }
- t = (struct tracepoint *) b;
- t->number_on_target = b->number;
- if (bp_location_downloaded)
- observer_notify_breakpoint_modified (b);
- }
- do_cleanups (old_chain);
- }
- static void
- swap_insertion (struct bp_location *left, struct bp_location *right)
- {
- const int left_inserted = left->inserted;
- const int left_duplicate = left->duplicate;
- const int left_needs_update = left->needs_update;
- const struct bp_target_info left_target_info = left->target_info;
-
- if (is_tracepoint (left->owner))
- gdb_assert (!left->duplicate);
- if (is_tracepoint (right->owner))
- gdb_assert (!right->duplicate);
- left->inserted = right->inserted;
- left->duplicate = right->duplicate;
- left->needs_update = right->needs_update;
- left->target_info = right->target_info;
- right->inserted = left_inserted;
- right->duplicate = left_duplicate;
- right->needs_update = left_needs_update;
- right->target_info = left_target_info;
- }
- static void
- force_breakpoint_reinsertion (struct bp_location *bl)
- {
- struct bp_location **locp = NULL, **loc2p;
- struct bp_location *loc;
- CORE_ADDR address = 0;
- int pspace_num;
- address = bl->address;
- pspace_num = bl->pspace->num;
-
- if (gdb_evaluates_breakpoint_condition_p ()
- || !target_supports_evaluation_of_breakpoint_conditions ())
- return;
-
- ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, address)
- {
- loc = *loc2p;
- if (!is_breakpoint (loc->owner)
- || pspace_num != loc->pspace->num)
- continue;
-
- loc->condition_changed = condition_updated;
-
- if (loc->cond_bytecode)
- {
- free_agent_expr (loc->cond_bytecode);
- loc->cond_bytecode = NULL;
- }
- }
- }
- static void
- update_global_location_list (enum ugll_insert_mode insert_mode)
- {
- struct breakpoint *b;
- struct bp_location **locp, *loc;
- struct cleanup *cleanups;
-
- CORE_ADDR last_addr = 0;
-
- int last_pspace_num = -1;
-
- struct bp_location *bp_loc_first;
- struct bp_location *wp_loc_first;
- struct bp_location *awp_loc_first;
- struct bp_location *rwp_loc_first;
-
- struct bp_location **old_location, **old_locp;
- unsigned old_location_count;
- old_location = bp_location;
- old_location_count = bp_location_count;
- bp_location = NULL;
- bp_location_count = 0;
- cleanups = make_cleanup (xfree, old_location);
- ALL_BREAKPOINTS (b)
- for (loc = b->loc; loc; loc = loc->next)
- bp_location_count++;
- bp_location = xmalloc (sizeof (*bp_location) * bp_location_count);
- locp = bp_location;
- ALL_BREAKPOINTS (b)
- for (loc = b->loc; loc; loc = loc->next)
- *locp++ = loc;
- qsort (bp_location, bp_location_count, sizeof (*bp_location),
- bp_location_compare);
- bp_location_target_extensions_update ();
-
- locp = bp_location;
- for (old_locp = old_location; old_locp < old_location + old_location_count;
- old_locp++)
- {
- struct bp_location *old_loc = *old_locp;
- struct bp_location **loc2p;
-
- int found_object = 0;
-
- int keep_in_target = 0;
- int removed = 0;
-
- while (locp < bp_location + bp_location_count
- && (*locp)->address < old_loc->address)
- locp++;
- for (loc2p = locp;
- (loc2p < bp_location + bp_location_count
- && (*loc2p)->address == old_loc->address);
- loc2p++)
- {
-
- if ((*loc2p)->condition_changed == condition_modified
- && (last_addr != old_loc->address
- || last_pspace_num != old_loc->pspace->num))
- {
- force_breakpoint_reinsertion (*loc2p);
- last_pspace_num = old_loc->pspace->num;
- }
- if (*loc2p == old_loc)
- found_object = 1;
- }
-
- last_addr = old_loc->address;
-
- if (!found_object)
- force_breakpoint_reinsertion (old_loc);
-
- if (old_loc->inserted)
- {
-
- if (found_object && should_be_inserted (old_loc))
- {
-
- keep_in_target = 1;
- }
- else
- {
-
-
-
- if (breakpoint_address_is_meaningful (old_loc->owner))
- {
- for (loc2p = locp;
- (loc2p < bp_location + bp_location_count
- && (*loc2p)->address == old_loc->address);
- loc2p++)
- {
- struct bp_location *loc2 = *loc2p;
- if (breakpoint_locations_match (loc2, old_loc))
- {
-
- if (is_hardware_watchpoint (old_loc->owner))
- {
- gdb_assert (is_hardware_watchpoint (loc2->owner));
- loc2->watchpoint_type = old_loc->watchpoint_type;
- }
-
- if (loc2 != old_loc
- && unduplicated_should_be_inserted (loc2))
- {
- swap_insertion (old_loc, loc2);
- keep_in_target = 1;
- break;
- }
- }
- }
- }
- }
- if (!keep_in_target)
- {
- if (remove_breakpoint (old_loc, mark_uninserted))
- {
-
- printf_filtered (_("warning: Error removing "
- "breakpoint %d\n"),
- old_loc->owner->number);
- }
- removed = 1;
- }
- }
- if (!found_object)
- {
- if (removed && non_stop
- && breakpoint_address_is_meaningful (old_loc->owner)
- && !is_hardware_watchpoint (old_loc->owner))
- {
-
- old_loc->events_till_retirement = 3 * (thread_count () + 1);
- old_loc->owner = NULL;
- VEC_safe_push (bp_location_p, moribund_locations, old_loc);
- }
- else
- {
- old_loc->owner = NULL;
- decref_bp_location (&old_loc);
- }
- }
- }
-
- bp_loc_first = NULL;
- wp_loc_first = NULL;
- awp_loc_first = NULL;
- rwp_loc_first = NULL;
- ALL_BP_LOCATIONS (loc, locp)
- {
-
- struct bp_location **loc_first_p;
- b = loc->owner;
- if (!unduplicated_should_be_inserted (loc)
- || !breakpoint_address_is_meaningful (b)
-
- || is_tracepoint (b))
- {
-
- loc->condition_changed = condition_unchanged;
- continue;
- }
-
- if (loc->permanent && ! loc->inserted)
- internal_error (__FILE__, __LINE__,
- _("allegedly permanent breakpoint is not "
- "actually inserted"));
- if (b->type == bp_hardware_watchpoint)
- loc_first_p = &wp_loc_first;
- else if (b->type == bp_read_watchpoint)
- loc_first_p = &rwp_loc_first;
- else if (b->type == bp_access_watchpoint)
- loc_first_p = &awp_loc_first;
- else
- loc_first_p = &bp_loc_first;
- if (*loc_first_p == NULL
- || (overlay_debugging && loc->section != (*loc_first_p)->section)
- || !breakpoint_locations_match (loc, *loc_first_p))
- {
- *loc_first_p = loc;
- loc->duplicate = 0;
- if (is_breakpoint (loc->owner) && loc->condition_changed)
- {
- loc->needs_update = 1;
-
- loc->condition_changed = condition_unchanged;
- }
- continue;
- }
-
- if (loc->inserted)
- swap_insertion (loc, *loc_first_p);
- loc->duplicate = 1;
-
- loc->condition_changed = condition_unchanged;
- if (loc->inserted && !loc->permanent
- && (*loc_first_p)->permanent)
- internal_error (__FILE__, __LINE__,
- _("another breakpoint was inserted on top of "
- "a permanent breakpoint"));
- }
- if (insert_mode == UGLL_INSERT || breakpoints_should_be_inserted_now ())
- {
- if (insert_mode != UGLL_DONT_INSERT)
- insert_breakpoint_locations ();
- else
- {
-
- update_inserted_breakpoint_locations ();
- }
- }
- if (insert_mode != UGLL_DONT_INSERT)
- download_tracepoint_locations ();
- do_cleanups (cleanups);
- }
- void
- breakpoint_retire_moribund (void)
- {
- struct bp_location *loc;
- int ix;
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
- if (--(loc->events_till_retirement) == 0)
- {
- decref_bp_location (&loc);
- VEC_unordered_remove (bp_location_p, moribund_locations, ix);
- --ix;
- }
- }
- static void
- update_global_location_list_nothrow (enum ugll_insert_mode insert_mode)
- {
- volatile struct gdb_exception e;
- TRY_CATCH (e, RETURN_MASK_ERROR)
- update_global_location_list (insert_mode);
- }
- static void
- bpstat_remove_bp_location (bpstat bps, struct breakpoint *bpt)
- {
- bpstat bs;
- for (bs = bps; bs; bs = bs->next)
- if (bs->breakpoint_at == bpt)
- {
- bs->breakpoint_at = NULL;
- bs->old_val = NULL;
-
- }
- }
- static int
- bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
- {
- struct breakpoint *bpt = data;
- bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
- return 0;
- }
- static void
- say_where (struct breakpoint *b)
- {
- struct value_print_options opts;
- get_user_print_options (&opts);
-
- if (b->loc == NULL)
- {
- printf_filtered (_(" (%s) pending."), b->addr_string);
- }
- else
- {
- if (opts.addressprint || b->loc->symtab == NULL)
- {
- printf_filtered (" at ");
- fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
- gdb_stdout);
- }
- if (b->loc->symtab != NULL)
- {
-
- if (b->loc->next == NULL)
- printf_filtered (": file %s, line %d.",
- symtab_to_filename_for_display (b->loc->symtab),
- b->loc->line_number);
- else
-
- printf_filtered (": %s.", b->addr_string);
- }
- if (b->loc->next)
- {
- struct bp_location *loc = b->loc;
- int n = 0;
- for (; loc; loc = loc->next)
- ++n;
- printf_filtered (" (%d locations)", n);
- }
- }
- }
- static void
- bp_location_dtor (struct bp_location *self)
- {
- xfree (self->cond);
- if (self->cond_bytecode)
- free_agent_expr (self->cond_bytecode);
- xfree (self->function_name);
- VEC_free (agent_expr_p, self->target_info.conditions);
- VEC_free (agent_expr_p, self->target_info.tcommands);
- }
- static const struct bp_location_ops bp_location_ops =
- {
- bp_location_dtor
- };
- static void
- base_breakpoint_dtor (struct breakpoint *self)
- {
- decref_counted_command_line (&self->commands);
- xfree (self->cond_string);
- xfree (self->extra_string);
- xfree (self->addr_string);
- xfree (self->filter);
- xfree (self->addr_string_range_end);
- }
- static struct bp_location *
- base_breakpoint_allocate_location (struct breakpoint *self)
- {
- struct bp_location *loc;
- loc = XNEW (struct bp_location);
- init_bp_location (loc, &bp_location_ops, self);
- return loc;
- }
- static void
- base_breakpoint_re_set (struct breakpoint *b)
- {
-
- }
- #define internal_error_pure_virtual_called() \
- gdb_assert_not_reached ("pure virtual function called")
- static int
- base_breakpoint_insert_location (struct bp_location *bl)
- {
- internal_error_pure_virtual_called ();
- }
- static int
- base_breakpoint_remove_location (struct bp_location *bl)
- {
- internal_error_pure_virtual_called ();
- }
- static int
- base_breakpoint_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace,
- CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- internal_error_pure_virtual_called ();
- }
- static void
- base_breakpoint_check_status (bpstat bs)
- {
-
- }
- static int
- base_breakpoint_works_in_software_mode (const struct breakpoint *b)
- {
- internal_error_pure_virtual_called ();
- }
- static int
- base_breakpoint_resources_needed (const struct bp_location *bl)
- {
- internal_error_pure_virtual_called ();
- }
- static enum print_stop_action
- base_breakpoint_print_it (bpstat bs)
- {
- internal_error_pure_virtual_called ();
- }
- static void
- base_breakpoint_print_one_detail (const struct breakpoint *self,
- struct ui_out *uiout)
- {
-
- }
- static void
- base_breakpoint_print_mention (struct breakpoint *b)
- {
- internal_error_pure_virtual_called ();
- }
- static void
- base_breakpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
- {
- internal_error_pure_virtual_called ();
- }
- static void
- base_breakpoint_create_sals_from_address (char **arg,
- struct linespec_result *canonical,
- enum bptype type_wanted,
- char *addr_start,
- char **copy_arg)
- {
- internal_error_pure_virtual_called ();
- }
- static void
- base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch,
- struct linespec_result *c,
- char *cond_string,
- char *extra_string,
- enum bptype type_wanted,
- enum bpdisp disposition,
- int thread,
- int task, int ignore_count,
- const struct breakpoint_ops *o,
- int from_tty, int enabled,
- int internal, unsigned flags)
- {
- internal_error_pure_virtual_called ();
- }
- static void
- base_breakpoint_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
- {
- internal_error_pure_virtual_called ();
- }
- static int
- base_breakpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig)
- {
- return 1;
- }
- static void
- base_breakpoint_after_condition_true (struct bpstats *bs)
- {
-
- }
- struct breakpoint_ops base_breakpoint_ops =
- {
- base_breakpoint_dtor,
- base_breakpoint_allocate_location,
- base_breakpoint_re_set,
- base_breakpoint_insert_location,
- base_breakpoint_remove_location,
- base_breakpoint_breakpoint_hit,
- base_breakpoint_check_status,
- base_breakpoint_resources_needed,
- base_breakpoint_works_in_software_mode,
- base_breakpoint_print_it,
- NULL,
- base_breakpoint_print_one_detail,
- base_breakpoint_print_mention,
- base_breakpoint_print_recreate,
- base_breakpoint_create_sals_from_address,
- base_breakpoint_create_breakpoints_sal,
- base_breakpoint_decode_linespec,
- base_breakpoint_explains_signal,
- base_breakpoint_after_condition_true,
- };
- static void
- bkpt_re_set (struct breakpoint *b)
- {
- FIXME
- if (b->addr_string == NULL)
- {
-
- delete_breakpoint (b);
- return;
- }
- breakpoint_re_set_default (b);
- }
- static int
- bkpt_insert_location (struct bp_location *bl)
- {
- if (bl->loc_type == bp_loc_hardware_breakpoint)
- return target_insert_hw_breakpoint (bl->gdbarch, &bl->target_info);
- else
- return target_insert_breakpoint (bl->gdbarch, &bl->target_info);
- }
- static int
- bkpt_remove_location (struct bp_location *bl)
- {
- if (bl->loc_type == bp_loc_hardware_breakpoint)
- return target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info);
- else
- return target_remove_breakpoint (bl->gdbarch, &bl->target_info);
- }
- static int
- bkpt_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- if (ws->kind != TARGET_WAITKIND_STOPPED
- || ws->value.sig != GDB_SIGNAL_TRAP)
- return 0;
- if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
- aspace, bp_addr))
- return 0;
- if (overlay_debugging
- && section_is_overlay (bl->section)
- && !section_is_mapped (bl->section))
- return 0;
- return 1;
- }
- static int
- dprintf_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
- if (dprintf_style == dprintf_style_agent
- && target_can_run_breakpoint_commands ())
- {
-
- return 0;
- }
- return bkpt_breakpoint_hit (bl, aspace, bp_addr, ws);
- }
- static int
- bkpt_resources_needed (const struct bp_location *bl)
- {
- gdb_assert (bl->owner->type == bp_hardware_breakpoint);
- return 1;
- }
- static enum print_stop_action
- bkpt_print_it (bpstat bs)
- {
- struct breakpoint *b;
- const struct bp_location *bl;
- int bp_temp;
- struct ui_out *uiout = current_uiout;
- gdb_assert (bs->bp_location_at != NULL);
- bl = bs->bp_location_at;
- b = bs->breakpoint_at;
- bp_temp = b->disposition == disp_del;
- if (bl->address != bl->requested_address)
- breakpoint_adjustment_warning (bl->requested_address,
- bl->address,
- b->number, 1);
- annotate_breakpoint (b->number);
- if (bp_temp)
- ui_out_text (uiout, "\nTemporary breakpoint ");
- else
- ui_out_text (uiout, "\nBreakpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, ", ");
- return PRINT_SRC_AND_LOC;
- }
- static void
- bkpt_print_mention (struct breakpoint *b)
- {
- if (ui_out_is_mi_like_p (current_uiout))
- return;
- switch (b->type)
- {
- case bp_breakpoint:
- case bp_gnu_ifunc_resolver:
- if (b->disposition == disp_del)
- printf_filtered (_("Temporary breakpoint"));
- else
- printf_filtered (_("Breakpoint"));
- printf_filtered (_(" %d"), b->number);
- if (b->type == bp_gnu_ifunc_resolver)
- printf_filtered (_(" at gnu-indirect-function resolver"));
- break;
- case bp_hardware_breakpoint:
- printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
- break;
- case bp_dprintf:
- printf_filtered (_("Dprintf %d"), b->number);
- break;
- }
- say_where (b);
- }
- static void
- bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
- {
- if (tp->type == bp_breakpoint && tp->disposition == disp_del)
- fprintf_unfiltered (fp, "tbreak");
- else if (tp->type == bp_breakpoint)
- fprintf_unfiltered (fp, "break");
- else if (tp->type == bp_hardware_breakpoint
- && tp->disposition == disp_del)
- fprintf_unfiltered (fp, "thbreak");
- else if (tp->type == bp_hardware_breakpoint)
- fprintf_unfiltered (fp, "hbreak");
- else
- internal_error (__FILE__, __LINE__,
- _("unhandled breakpoint type %d"), (int) tp->type);
- fprintf_unfiltered (fp, " %s", tp->addr_string);
- print_recreate_thread (tp, fp);
- }
- static void
- bkpt_create_sals_from_address (char **arg,
- struct linespec_result *canonical,
- enum bptype type_wanted,
- char *addr_start, char **copy_arg)
- {
- create_sals_from_address_default (arg, canonical, type_wanted,
- addr_start, copy_arg);
- }
- static void
- bkpt_create_breakpoints_sal (struct gdbarch *gdbarch,
- struct linespec_result *canonical,
- char *cond_string,
- char *extra_string,
- enum bptype type_wanted,
- enum bpdisp disposition,
- int thread,
- int task, int ignore_count,
- const struct breakpoint_ops *ops,
- int from_tty, int enabled,
- int internal, unsigned flags)
- {
- create_breakpoints_sal_default (gdbarch, canonical,
- cond_string, extra_string,
- type_wanted,
- disposition, thread, task,
- ignore_count, ops, from_tty,
- enabled, internal, flags);
- }
- static void
- bkpt_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
- {
- decode_linespec_default (b, s, sals);
- }
- static void
- internal_bkpt_re_set (struct breakpoint *b)
- {
- switch (b->type)
- {
-
- case bp_overlay_event:
- case bp_longjmp_master:
- case bp_std_terminate_master:
- case bp_exception_master:
- delete_breakpoint (b);
- break;
-
- case bp_shlib_event:
-
- case bp_thread_event:
- break;
- }
- }
- static void
- internal_bkpt_check_status (bpstat bs)
- {
- if (bs->breakpoint_at->type == bp_shlib_event)
- {
-
- bs->stop = stop_on_solib_events;
- bs->print = stop_on_solib_events;
- }
- else
- bs->stop = 0;
- }
- static enum print_stop_action
- internal_bkpt_print_it (bpstat bs)
- {
- struct breakpoint *b;
- b = bs->breakpoint_at;
- switch (b->type)
- {
- case bp_shlib_event:
-
- print_solib_event (0);
- break;
- case bp_thread_event:
-
- printf_filtered (_("Thread Event Breakpoint: gdb should not stop!\n"));
- break;
- case bp_overlay_event:
-
- printf_filtered (_("Overlay Event Breakpoint: gdb should not stop!\n"));
- break;
- case bp_longjmp_master:
-
- printf_filtered (_("Longjmp Master Breakpoint: gdb should not stop!\n"));
- break;
- case bp_std_terminate_master:
-
- printf_filtered (_("std::terminate Master Breakpoint: "
- "gdb should not stop!\n"));
- break;
- case bp_exception_master:
-
- printf_filtered (_("Exception Master Breakpoint: "
- "gdb should not stop!\n"));
- break;
- }
- return PRINT_NOTHING;
- }
- static void
- internal_bkpt_print_mention (struct breakpoint *b)
- {
-
- }
- static void
- momentary_bkpt_re_set (struct breakpoint *b)
- {
-
- }
- static void
- momentary_bkpt_check_status (bpstat bs)
- {
-
- }
- static enum print_stop_action
- momentary_bkpt_print_it (bpstat bs)
- {
- struct ui_out *uiout = current_uiout;
- if (ui_out_is_mi_like_p (uiout))
- {
- struct breakpoint *b = bs->breakpoint_at;
- switch (b->type)
- {
- case bp_finish:
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED));
- break;
- case bp_until:
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
- break;
- }
- }
- return PRINT_UNKNOWN;
- }
- static void
- momentary_bkpt_print_mention (struct breakpoint *b)
- {
-
- }
- static void
- longjmp_bkpt_dtor (struct breakpoint *self)
- {
- struct thread_info *tp = find_thread_id (self->thread);
- if (tp)
- tp->initiating_frame = null_frame_id;
- momentary_breakpoint_ops.dtor (self);
- }
- static int
- bkpt_probe_insert_location (struct bp_location *bl)
- {
- int v = bkpt_insert_location (bl);
- if (v == 0)
- {
-
- if (bl->probe.probe->pops->set_semaphore != NULL)
- bl->probe.probe->pops->set_semaphore (bl->probe.probe,
- bl->probe.objfile,
- bl->gdbarch);
- }
- return v;
- }
- static int
- bkpt_probe_remove_location (struct bp_location *bl)
- {
-
- if (bl->probe.probe->pops->clear_semaphore != NULL)
- bl->probe.probe->pops->clear_semaphore (bl->probe.probe,
- bl->probe.objfile,
- bl->gdbarch);
- return bkpt_remove_location (bl);
- }
- static void
- bkpt_probe_create_sals_from_address (char **arg,
- struct linespec_result *canonical,
- enum bptype type_wanted,
- char *addr_start, char **copy_arg)
- {
- struct linespec_sals lsal;
- lsal.sals = parse_probes (arg, canonical);
- *copy_arg = xstrdup (canonical->addr_string);
- lsal.canonical = xstrdup (*copy_arg);
- VEC_safe_push (linespec_sals, canonical->sals, &lsal);
- }
- static void
- bkpt_probe_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
- {
- *sals = parse_probes (s, NULL);
- if (!sals->sals)
- error (_("probe not found"));
- }
- static void
- tracepoint_re_set (struct breakpoint *b)
- {
- breakpoint_re_set_default (b);
- }
- static int
- tracepoint_breakpoint_hit (const struct bp_location *bl,
- struct address_space *aspace, CORE_ADDR bp_addr,
- const struct target_waitstatus *ws)
- {
-
- return 0;
- }
- static void
- tracepoint_print_one_detail (const struct breakpoint *self,
- struct ui_out *uiout)
- {
- struct tracepoint *tp = (struct tracepoint *) self;
- if (tp->static_trace_marker_id)
- {
- gdb_assert (self->type == bp_static_tracepoint);
- ui_out_text (uiout, "\tmarker id is ");
- ui_out_field_string (uiout, "static-tracepoint-marker-string-id",
- tp->static_trace_marker_id);
- ui_out_text (uiout, "\n");
- }
- }
- static void
- tracepoint_print_mention (struct breakpoint *b)
- {
- if (ui_out_is_mi_like_p (current_uiout))
- return;
- switch (b->type)
- {
- case bp_tracepoint:
- printf_filtered (_("Tracepoint"));
- printf_filtered (_(" %d"), b->number);
- break;
- case bp_fast_tracepoint:
- printf_filtered (_("Fast tracepoint"));
- printf_filtered (_(" %d"), b->number);
- break;
- case bp_static_tracepoint:
- printf_filtered (_("Static tracepoint"));
- printf_filtered (_(" %d"), b->number);
- break;
- default:
- internal_error (__FILE__, __LINE__,
- _("unhandled tracepoint type %d"), (int) b->type);
- }
- say_where (b);
- }
- static void
- tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp)
- {
- struct tracepoint *tp = (struct tracepoint *) self;
- if (self->type == bp_fast_tracepoint)
- fprintf_unfiltered (fp, "ftrace");
- if (self->type == bp_static_tracepoint)
- fprintf_unfiltered (fp, "strace");
- else if (self->type == bp_tracepoint)
- fprintf_unfiltered (fp, "trace");
- else
- internal_error (__FILE__, __LINE__,
- _("unhandled tracepoint type %d"), (int) self->type);
- fprintf_unfiltered (fp, " %s", self->addr_string);
- print_recreate_thread (self, fp);
- if (tp->pass_count)
- fprintf_unfiltered (fp, " passcount %d\n", tp->pass_count);
- }
- static void
- tracepoint_create_sals_from_address (char **arg,
- struct linespec_result *canonical,
- enum bptype type_wanted,
- char *addr_start, char **copy_arg)
- {
- create_sals_from_address_default (arg, canonical, type_wanted,
- addr_start, copy_arg);
- }
- static void
- tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch,
- struct linespec_result *canonical,
- char *cond_string,
- char *extra_string,
- enum bptype type_wanted,
- enum bpdisp disposition,
- int thread,
- int task, int ignore_count,
- const struct breakpoint_ops *ops,
- int from_tty, int enabled,
- int internal, unsigned flags)
- {
- create_breakpoints_sal_default (gdbarch, canonical,
- cond_string, extra_string,
- type_wanted,
- disposition, thread, task,
- ignore_count, ops, from_tty,
- enabled, internal, flags);
- }
- static void
- tracepoint_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
- {
- decode_linespec_default (b, s, sals);
- }
- struct breakpoint_ops tracepoint_breakpoint_ops;
- static void
- tracepoint_probe_create_sals_from_address (char **arg,
- struct linespec_result *canonical,
- enum bptype type_wanted,
- char *addr_start, char **copy_arg)
- {
-
- bkpt_probe_create_sals_from_address (arg, canonical, type_wanted,
- addr_start, copy_arg);
- }
- static void
- tracepoint_probe_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
- {
-
- bkpt_probe_decode_linespec (b, s, sals);
- }
- static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
- static void
- dprintf_re_set (struct breakpoint *b)
- {
- breakpoint_re_set_default (b);
-
- if (b->loc != NULL && b->extra_string == NULL)
- error (_("Format string required"));
-
- if (b->extra_string != NULL)
- update_dprintf_command_list (b);
- }
- static void
- dprintf_print_recreate (struct breakpoint *tp, struct ui_file *fp)
- {
- fprintf_unfiltered (fp, "dprintf %s%s", tp->addr_string,
- tp->extra_string);
- print_recreate_thread (tp, fp);
- }
- static void
- dprintf_after_condition_true (struct bpstats *bs)
- {
- struct cleanup *old_chain;
- struct bpstats tmp_bs = { NULL };
- struct bpstats *tmp_bs_p = &tmp_bs;
-
- bs->stop = 0;
-
- tmp_bs.commands = bs->commands;
- bs->commands = NULL;
- old_chain = make_cleanup_decref_counted_command_line (&tmp_bs.commands);
- bpstat_do_actions_1 (&tmp_bs_p);
-
- do_cleanups (old_chain);
- }
- static void
- strace_marker_create_sals_from_address (char **arg,
- struct linespec_result *canonical,
- enum bptype type_wanted,
- char *addr_start, char **copy_arg)
- {
- struct linespec_sals lsal;
- lsal.sals = decode_static_tracepoint_spec (arg);
- *copy_arg = savestring (addr_start, *arg - addr_start);
- canonical->addr_string = xstrdup (*copy_arg);
- lsal.canonical = xstrdup (*copy_arg);
- VEC_safe_push (linespec_sals, canonical->sals, &lsal);
- }
- static void
- strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
- struct linespec_result *canonical,
- char *cond_string,
- char *extra_string,
- enum bptype type_wanted,
- enum bpdisp disposition,
- int thread,
- int task, int ignore_count,
- const struct breakpoint_ops *ops,
- int from_tty, int enabled,
- int internal, unsigned flags)
- {
- int i;
- struct linespec_sals *lsal = VEC_index (linespec_sals,
- canonical->sals, 0);
-
- for (i = 0; i < lsal->sals.nelts; ++i)
- {
- struct symtabs_and_lines expanded;
- struct tracepoint *tp;
- struct cleanup *old_chain;
- char *addr_string;
- expanded.nelts = 1;
- expanded.sals = &lsal->sals.sals[i];
- addr_string = xstrdup (canonical->addr_string);
- old_chain = make_cleanup (xfree, addr_string);
- tp = XCNEW (struct tracepoint);
- init_breakpoint_sal (&tp->base, gdbarch, expanded,
- addr_string, NULL,
- cond_string, extra_string,
- type_wanted, disposition,
- thread, task, ignore_count, ops,
- from_tty, enabled, internal, flags,
- canonical->special_display);
-
- tp->static_trace_marker_id_idx = i;
- install_breakpoint (internal, &tp->base, 0);
- discard_cleanups (old_chain);
- }
- }
- static void
- strace_marker_decode_linespec (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
- {
- struct tracepoint *tp = (struct tracepoint *) b;
- *sals = decode_static_tracepoint_spec (s);
- if (sals->nelts > tp->static_trace_marker_id_idx)
- {
- sals->sals[0] = sals->sals[tp->static_trace_marker_id_idx];
- sals->nelts = 1;
- }
- else
- error (_("marker %s not found"), tp->static_trace_marker_id);
- }
- static struct breakpoint_ops strace_marker_breakpoint_ops;
- static int
- strace_marker_p (struct breakpoint *b)
- {
- return b->ops == &strace_marker_breakpoint_ops;
- }
- void
- delete_breakpoint (struct breakpoint *bpt)
- {
- struct breakpoint *b;
- gdb_assert (bpt != NULL);
-
- if (bpt->type == bp_none)
- return;
-
- if (bpt->related_breakpoint != bpt)
- {
- struct breakpoint *related;
- struct watchpoint *w;
- if (bpt->type == bp_watchpoint_scope)
- w = (struct watchpoint *) bpt->related_breakpoint;
- else if (bpt->related_breakpoint->type == bp_watchpoint_scope)
- w = (struct watchpoint *) bpt;
- else
- w = NULL;
- if (w != NULL)
- watchpoint_del_at_next_stop (w);
-
- for (related = bpt; related->related_breakpoint != bpt;
- related = related->related_breakpoint);
- related->related_breakpoint = bpt->related_breakpoint;
- bpt->related_breakpoint = bpt;
- }
-
- if (bpt->number)
- observer_notify_breakpoint_deleted (bpt);
- if (breakpoint_chain == bpt)
- breakpoint_chain = bpt->next;
- ALL_BREAKPOINTS (b)
- if (b->next == bpt)
- {
- b->next = bpt->next;
- break;
- }
-
- FIXME
- iterate_over_threads (bpstat_remove_breakpoint_callback, bpt);
-
- update_global_location_list (UGLL_DONT_INSERT);
- bpt->ops->dtor (bpt);
-
- bpt->type = bp_none;
- xfree (bpt);
- }
- static void
- do_delete_breakpoint_cleanup (void *b)
- {
- delete_breakpoint (b);
- }
- struct cleanup *
- make_cleanup_delete_breakpoint (struct breakpoint *b)
- {
- return make_cleanup (do_delete_breakpoint_cleanup, b);
- }
- static void
- iterate_over_related_breakpoints (struct breakpoint *b,
- void (*function) (struct breakpoint *,
- void *),
- void *data)
- {
- struct breakpoint *related;
- related = b;
- do
- {
- struct breakpoint *next;
-
- next = related->related_breakpoint;
- if (next == related)
- {
-
- function (related, data);
-
- break;
- }
- else
- function (related, data);
- related = next;
- }
- while (related != b);
- }
- static void
- do_delete_breakpoint (struct breakpoint *b, void *ignore)
- {
- delete_breakpoint (b);
- }
- static void
- do_map_delete_breakpoint (struct breakpoint *b, void *ignore)
- {
- iterate_over_related_breakpoints (b, do_delete_breakpoint, NULL);
- }
- void
- delete_command (char *arg, int from_tty)
- {
- struct breakpoint *b, *b_tmp;
- dont_repeat ();
- if (arg == 0)
- {
- int breaks_to_delete = 0;
-
- ALL_BREAKPOINTS (b)
- if (user_breakpoint_p (b))
- {
- breaks_to_delete = 1;
- break;
- }
-
- if (!from_tty
- || (breaks_to_delete && query (_("Delete all breakpoints? "))))
- {
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (user_breakpoint_p (b))
- delete_breakpoint (b);
- }
- }
- else
- map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
- }
- static int
- all_locations_are_pending (struct bp_location *loc)
- {
- for (; loc; loc = loc->next)
- if (!loc->shlib_disabled
- && !loc->pspace->executing_startup)
- return 0;
- return 1;
- }
- static int
- ambiguous_names_p (struct bp_location *loc)
- {
- struct bp_location *l;
- htab_t htab = htab_create_alloc (13, htab_hash_string,
- (int (*) (const void *,
- const void *)) streq,
- NULL, xcalloc, xfree);
- for (l = loc; l != NULL; l = l->next)
- {
- const char **slot;
- const char *name = l->function_name;
-
- if (name == NULL)
- continue;
- slot = (const char **) htab_find_slot (htab, (const void *) name,
- INSERT);
-
- if (*slot != NULL)
- {
- htab_delete (htab);
- return 1;
- }
- *slot = name;
- }
- htab_delete (htab);
- return 0;
- }
- static struct symtab_and_line
- update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
- {
- struct tracepoint *tp = (struct tracepoint *) b;
- struct static_tracepoint_marker marker;
- CORE_ADDR pc;
- pc = sal.pc;
- if (sal.line)
- find_line_pc (sal.symtab, sal.line, &pc);
- if (target_static_tracepoint_marker_at (pc, &marker))
- {
- if (strcmp (tp->static_trace_marker_id, marker.str_id) != 0)
- warning (_("static tracepoint %d changed probed marker from %s to %s"),
- b->number,
- tp->static_trace_marker_id, marker.str_id);
- xfree (tp->static_trace_marker_id);
- tp->static_trace_marker_id = xstrdup (marker.str_id);
- release_static_tracepoint_marker (&marker);
- return sal;
- }
-
- if (!sal.explicit_pc
- && sal.line != 0
- && sal.symtab != NULL
- && tp->static_trace_marker_id != NULL)
- {
- VEC(static_tracepoint_marker_p) *markers;
- markers
- = target_static_tracepoint_markers_by_strid (tp->static_trace_marker_id);
- if (!VEC_empty(static_tracepoint_marker_p, markers))
- {
- struct symtab_and_line sal2;
- struct symbol *sym;
- struct static_tracepoint_marker *tpmarker;
- struct ui_out *uiout = current_uiout;
- tpmarker = VEC_index (static_tracepoint_marker_p, markers, 0);
- xfree (tp->static_trace_marker_id);
- tp->static_trace_marker_id = xstrdup (tpmarker->str_id);
- warning (_("marker for static tracepoint %d (%s) not "
- "found at previous line number"),
- b->number, tp->static_trace_marker_id);
- init_sal (&sal2);
- sal2.pc = tpmarker->address;
- sal2 = find_pc_line (tpmarker->address, 0);
- sym = find_pc_sect_function (tpmarker->address, NULL);
- ui_out_text (uiout, "Now in ");
- if (sym)
- {
- ui_out_field_string (uiout, "func",
- SYMBOL_PRINT_NAME (sym));
- ui_out_text (uiout, " at ");
- }
- ui_out_field_string (uiout, "file",
- symtab_to_filename_for_display (sal2.symtab));
- ui_out_text (uiout, ":");
- if (ui_out_is_mi_like_p (uiout))
- {
- const char *fullname = symtab_to_fullname (sal2.symtab);
- ui_out_field_string (uiout, "fullname", fullname);
- }
- ui_out_field_int (uiout, "line", sal2.line);
- ui_out_text (uiout, "\n");
- b->loc->line_number = sal2.line;
- b->loc->symtab = sym != NULL ? sal2.symtab : NULL;
- xfree (b->addr_string);
- b->addr_string = xstrprintf ("%s:%d",
- symtab_to_filename_for_display (sal2.symtab),
- b->loc->line_number);
-
- release_static_tracepoint_marker (tpmarker);
- }
- }
- return sal;
- }
- static int
- locations_are_equal (struct bp_location *a, struct bp_location *b)
- {
- while (a && b)
- {
- if (a->address != b->address)
- return 0;
- if (a->shlib_disabled != b->shlib_disabled)
- return 0;
- if (a->enabled != b->enabled)
- return 0;
- a = a->next;
- b = b->next;
- }
- if ((a == NULL) != (b == NULL))
- return 0;
- return 1;
- }
- void
- update_breakpoint_locations (struct breakpoint *b,
- struct symtabs_and_lines sals,
- struct symtabs_and_lines sals_end)
- {
- int i;
- struct bp_location *existing_locations = b->loc;
- if (sals_end.nelts != 0 && (sals.nelts != 1 || sals_end.nelts != 1))
- {
-
- b->enable_state = bp_disabled;
- update_global_location_list (UGLL_MAY_INSERT);
- printf_unfiltered (_("Could not reset ranged breakpoint %d: "
- "multiple locations found\n"),
- b->number);
- return;
- }
-
- if (all_locations_are_pending (existing_locations) && sals.nelts == 0)
- return;
- b->loc = NULL;
- for (i = 0; i < sals.nelts; ++i)
- {
- struct bp_location *new_loc;
- switch_to_program_space_and_thread (sals.sals[i].pspace);
- new_loc = add_location_to_breakpoint (b, &(sals.sals[i]));
-
- if (b->cond_string != NULL)
- {
- const char *s;
- volatile struct gdb_exception e;
- s = b->cond_string;
- TRY_CATCH (e, RETURN_MASK_ERROR)
- {
- new_loc->cond = parse_exp_1 (&s, sals.sals[i].pc,
- block_for_pc (sals.sals[i].pc),
- 0);
- }
- if (e.reason < 0)
- {
- warning (_("failed to reevaluate condition "
- "for breakpoint %d: %s"),
- b->number, e.message);
- new_loc->enabled = 0;
- }
- }
- if (sals_end.nelts)
- {
- CORE_ADDR end = find_breakpoint_range_end (sals_end.sals[0]);
- new_loc->length = end - sals.sals[0].pc + 1;
- }
- }
-
- {
- struct bp_location *e = existing_locations;
-
- int have_ambiguous_names = ambiguous_names_p (b->loc);
- for (; e; e = e->next)
- {
- if (!e->enabled && e->function_name)
- {
- struct bp_location *l = b->loc;
- if (have_ambiguous_names)
- {
- for (; l; l = l->next)
- if (breakpoint_locations_match (e, l))
- {
- l->enabled = 0;
- break;
- }
- }
- else
- {
- for (; l; l = l->next)
- if (l->function_name
- && strcmp (e->function_name, l->function_name) == 0)
- {
- l->enabled = 0;
- break;
- }
- }
- }
- }
- }
- if (!locations_are_equal (existing_locations, b->loc))
- observer_notify_breakpoint_modified (b);
- update_global_location_list (UGLL_MAY_INSERT);
- }
- static struct symtabs_and_lines
- addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
- {
- char *s;
- struct symtabs_and_lines sals = {0};
- volatile struct gdb_exception e;
- gdb_assert (b->ops != NULL);
- s = addr_string;
- TRY_CATCH (e, RETURN_MASK_ERROR)
- {
- b->ops->decode_linespec (b, &s, &sals);
- }
- if (e.reason < 0)
- {
- int not_found_and_ok = 0;
-
- if (e.error == NOT_FOUND_ERROR
- && (b->condition_not_parsed
- || (b->loc && b->loc->shlib_disabled)
- || (b->loc && b->loc->pspace->executing_startup)
- || b->enable_state == bp_disabled))
- not_found_and_ok = 1;
- if (!not_found_and_ok)
- {
-
- b->enable_state = bp_disabled;
- throw_exception (e);
- }
- }
- if (e.reason == 0 || e.error != NOT_FOUND_ERROR)
- {
- int i;
- for (i = 0; i < sals.nelts; ++i)
- resolve_sal_pc (&sals.sals[i]);
- if (b->condition_not_parsed && s && s[0])
- {
- char *cond_string, *extra_string;
- int thread, task;
- find_condition_and_thread (s, sals.sals[0].pc,
- &cond_string, &thread, &task,
- &extra_string);
- if (cond_string)
- b->cond_string = cond_string;
- b->thread = thread;
- b->task = task;
- if (extra_string)
- b->extra_string = extra_string;
- b->condition_not_parsed = 0;
- }
- if (b->type == bp_static_tracepoint && !strace_marker_p (b))
- sals.sals[0] = update_static_tracepoint (b, sals.sals[0]);
- *found = 1;
- }
- else
- *found = 0;
- return sals;
- }
- static void
- breakpoint_re_set_default (struct breakpoint *b)
- {
- int found;
- struct symtabs_and_lines sals, sals_end;
- struct symtabs_and_lines expanded = {0};
- struct symtabs_and_lines expanded_end = {0};
- sals = addr_string_to_sals (b, b->addr_string, &found);
- if (found)
- {
- make_cleanup (xfree, sals.sals);
- expanded = sals;
- }
- if (b->addr_string_range_end)
- {
- sals_end = addr_string_to_sals (b, b->addr_string_range_end, &found);
- if (found)
- {
- make_cleanup (xfree, sals_end.sals);
- expanded_end = sals_end;
- }
- }
- update_breakpoint_locations (b, expanded, expanded_end);
- }
- static void
- create_sals_from_address_default (char **arg,
- struct linespec_result *canonical,
- enum bptype type_wanted,
- char *addr_start, char **copy_arg)
- {
- parse_breakpoint_sals (arg, canonical);
- }
- static void
- create_breakpoints_sal_default (struct gdbarch *gdbarch,
- struct linespec_result *canonical,
- char *cond_string,
- char *extra_string,
- enum bptype type_wanted,
- enum bpdisp disposition,
- int thread,
- int task, int ignore_count,
- const struct breakpoint_ops *ops,
- int from_tty, int enabled,
- int internal, unsigned flags)
- {
- create_breakpoints_sal (gdbarch, canonical, cond_string,
- extra_string,
- type_wanted, disposition,
- thread, task, ignore_count, ops, from_tty,
- enabled, internal, flags);
- }
- static void
- decode_linespec_default (struct breakpoint *b, char **s,
- struct symtabs_and_lines *sals)
- {
- struct linespec_result canonical;
- init_linespec_result (&canonical);
- decode_line_full (s, DECODE_LINE_FUNFIRSTLINE,
- (struct symtab *) NULL, 0,
- &canonical, multiple_symbols_all,
- b->filter);
-
- gdb_assert (VEC_length (linespec_sals, canonical.sals) < 2);
- if (VEC_length (linespec_sals, canonical.sals) > 0)
- {
- struct linespec_sals *lsal;
- lsal = VEC_index (linespec_sals, canonical.sals, 0);
- *sals = lsal->sals;
-
- lsal->sals.sals = NULL;
- }
- destroy_linespec_result (&canonical);
- }
- static struct cleanup *
- prepare_re_set_context (struct breakpoint *b)
- {
- struct cleanup *cleanups;
- input_radix = b->input_radix;
- cleanups = save_current_space_and_thread ();
- if (b->pspace != NULL)
- switch_to_program_space_and_thread (b->pspace);
- set_language (b->language);
- return cleanups;
- }
- static int
- breakpoint_re_set_one (void *bint)
- {
-
- struct breakpoint *b = (struct breakpoint *) bint;
- struct cleanup *cleanups;
- cleanups = prepare_re_set_context (b);
- b->ops->re_set (b);
- do_cleanups (cleanups);
- return 0;
- }
- void
- breakpoint_re_set (void)
- {
- struct breakpoint *b, *b_tmp;
- enum language save_language;
- int save_input_radix;
- struct cleanup *old_chain;
- save_language = current_language->la_language;
- save_input_radix = input_radix;
- old_chain = save_current_program_space ();
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- {
-
- char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
- b->number);
- struct cleanup *cleanups = make_cleanup (xfree, message);
- catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
- do_cleanups (cleanups);
- }
- set_language (save_language);
- input_radix = save_input_radix;
- jit_breakpoint_re_set ();
- do_cleanups (old_chain);
- create_overlay_event_breakpoint ();
- create_longjmp_master_breakpoint ();
- create_std_terminate_master_breakpoint ();
- create_exception_master_breakpoint ();
- }
- void
- breakpoint_re_set_thread (struct breakpoint *b)
- {
- if (b->thread != -1)
- {
- if (in_thread_list (inferior_ptid))
- b->thread = pid_to_thread_id (inferior_ptid);
-
- b->loc->pspace = current_program_space;
- }
- }
- void
- set_ignore_count (int bptnum, int count, int from_tty)
- {
- struct breakpoint *b;
- if (count < 0)
- count = 0;
- ALL_BREAKPOINTS (b)
- if (b->number == bptnum)
- {
- if (is_tracepoint (b))
- {
- if (from_tty && count != 0)
- printf_filtered (_("Ignore count ignored for tracepoint %d."),
- bptnum);
- return;
- }
- b->ignore_count = count;
- if (from_tty)
- {
- if (count == 0)
- printf_filtered (_("Will stop next time "
- "breakpoint %d is reached."),
- bptnum);
- else if (count == 1)
- printf_filtered (_("Will ignore next crossing of breakpoint %d."),
- bptnum);
- else
- printf_filtered (_("Will ignore next %d "
- "crossings of breakpoint %d."),
- count, bptnum);
- }
- observer_notify_breakpoint_modified (b);
- return;
- }
- error (_("No breakpoint number %d."), bptnum);
- }
- static void
- ignore_command (char *args, int from_tty)
- {
- char *p = args;
- int num;
- if (p == 0)
- error_no_arg (_("a breakpoint number"));
- num = get_number (&p);
- if (num == 0)
- error (_("bad breakpoint number: '%s'"), args);
- if (*p == 0)
- error (_("Second argument (specified ignore-count) is missing."));
- set_ignore_count (num,
- longest_to_int (value_as_long (parse_and_eval (p))),
- from_tty);
- if (from_tty)
- printf_filtered ("\n");
- }
- static void
- map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *,
- void *),
- void *data)
- {
- int num;
- struct breakpoint *b, *tmp;
- int match;
- struct get_number_or_range_state state;
- if (args == 0)
- error_no_arg (_("one or more breakpoint numbers"));
- init_number_or_range (&state, args);
- while (!state.finished)
- {
- const char *p = state.string;
- match = 0;
- num = get_number_or_range (&state);
- if (num == 0)
- {
- warning (_("bad breakpoint number at or near '%s'"), p);
- }
- else
- {
- ALL_BREAKPOINTS_SAFE (b, tmp)
- if (b->number == num)
- {
- match = 1;
- function (b, data);
- break;
- }
- if (match == 0)
- printf_unfiltered (_("No breakpoint number %d.\n"), num);
- }
- }
- }
- static struct bp_location *
- find_location_by_number (char *number)
- {
- char *dot = strchr (number, '.');
- char *p1;
- int bp_num;
- int loc_num;
- struct breakpoint *b;
- struct bp_location *loc;
- *dot = '\0';
- p1 = number;
- bp_num = get_number (&p1);
- if (bp_num == 0)
- error (_("Bad breakpoint number '%s'"), number);
- ALL_BREAKPOINTS (b)
- if (b->number == bp_num)
- {
- break;
- }
- if (!b || b->number != bp_num)
- error (_("Bad breakpoint number '%s'"), number);
- p1 = dot+1;
- loc_num = get_number (&p1);
- if (loc_num == 0)
- error (_("Bad breakpoint location number '%s'"), number);
- --loc_num;
- loc = b->loc;
- for (;loc_num && loc; --loc_num, loc = loc->next)
- ;
- if (!loc)
- error (_("Bad breakpoint location number '%s'"), dot+1);
- return loc;
- }
- void
- disable_breakpoint (struct breakpoint *bpt)
- {
-
- if (bpt->type == bp_watchpoint_scope)
- return;
- bpt->enable_state = bp_disabled;
-
- mark_breakpoint_modified (bpt);
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && is_tracepoint (bpt))
- {
- struct bp_location *location;
- for (location = bpt->loc; location; location = location->next)
- target_disable_tracepoint (location);
- }
- update_global_location_list (UGLL_DONT_INSERT);
- observer_notify_breakpoint_modified (bpt);
- }
- static void
- do_disable_breakpoint (struct breakpoint *b, void *ignore)
- {
- disable_breakpoint (b);
- }
- static void
- do_map_disable_breakpoint (struct breakpoint *b, void *ignore)
- {
- iterate_over_related_breakpoints (b, do_disable_breakpoint, NULL);
- }
- static void
- disable_command (char *args, int from_tty)
- {
- if (args == 0)
- {
- struct breakpoint *bpt;
- ALL_BREAKPOINTS (bpt)
- if (user_breakpoint_p (bpt))
- disable_breakpoint (bpt);
- }
- else
- {
- char *num = extract_arg (&args);
- while (num)
- {
- if (strchr (num, '.'))
- {
- struct bp_location *loc = find_location_by_number (num);
- if (loc)
- {
- if (loc->enabled)
- {
- loc->enabled = 0;
- mark_breakpoint_location_modified (loc);
- }
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && loc->owner
- && is_tracepoint (loc->owner))
- target_disable_tracepoint (loc);
- }
- update_global_location_list (UGLL_DONT_INSERT);
- }
- else
- map_breakpoint_numbers (num, do_map_disable_breakpoint, NULL);
- num = extract_arg (&args);
- }
- }
- }
- static void
- enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
- int count)
- {
- int target_resources_ok;
- if (bpt->type == bp_hardware_breakpoint)
- {
- int i;
- i = hw_breakpoint_used_count ();
- target_resources_ok =
- target_can_use_hardware_watchpoint (bp_hardware_breakpoint,
- i + 1, 0);
- if (target_resources_ok == 0)
- error (_("No hardware breakpoint support in the target."));
- else if (target_resources_ok < 0)
- error (_("Hardware breakpoints used exceeds limit."));
- }
- if (is_watchpoint (bpt))
- {
-
- enum enable_state orig_enable_state = 0;
- volatile struct gdb_exception e;
- TRY_CATCH (e, RETURN_MASK_ALL)
- {
- struct watchpoint *w = (struct watchpoint *) bpt;
- orig_enable_state = bpt->enable_state;
- bpt->enable_state = bp_enabled;
- update_watchpoint (w, 1 );
- }
- if (e.reason < 0)
- {
- bpt->enable_state = orig_enable_state;
- exception_fprintf (gdb_stderr, e, _("Cannot enable watchpoint %d: "),
- bpt->number);
- return;
- }
- }
- bpt->enable_state = bp_enabled;
-
- mark_breakpoint_modified (bpt);
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && is_tracepoint (bpt))
- {
- struct bp_location *location;
- for (location = bpt->loc; location; location = location->next)
- target_enable_tracepoint (location);
- }
- bpt->disposition = disposition;
- bpt->enable_count = count;
- update_global_location_list (UGLL_MAY_INSERT);
- observer_notify_breakpoint_modified (bpt);
- }
- void
- enable_breakpoint (struct breakpoint *bpt)
- {
- enable_breakpoint_disp (bpt, bpt->disposition, 0);
- }
- static void
- do_enable_breakpoint (struct breakpoint *bpt, void *arg)
- {
- enable_breakpoint (bpt);
- }
- static void
- do_map_enable_breakpoint (struct breakpoint *b, void *ignore)
- {
- iterate_over_related_breakpoints (b, do_enable_breakpoint, NULL);
- }
- static void
- enable_command (char *args, int from_tty)
- {
- if (args == 0)
- {
- struct breakpoint *bpt;
- ALL_BREAKPOINTS (bpt)
- if (user_breakpoint_p (bpt))
- enable_breakpoint (bpt);
- }
- else
- {
- char *num = extract_arg (&args);
- while (num)
- {
- if (strchr (num, '.'))
- {
- struct bp_location *loc = find_location_by_number (num);
- if (loc)
- {
- if (!loc->enabled)
- {
- loc->enabled = 1;
- mark_breakpoint_location_modified (loc);
- }
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && loc->owner
- && is_tracepoint (loc->owner))
- target_enable_tracepoint (loc);
- }
- update_global_location_list (UGLL_MAY_INSERT);
- }
- else
- map_breakpoint_numbers (num, do_map_enable_breakpoint, NULL);
- num = extract_arg (&args);
- }
- }
- }
- struct disp_data
- {
- enum bpdisp disp;
- int count;
- };
- static void
- do_enable_breakpoint_disp (struct breakpoint *bpt, void *arg)
- {
- struct disp_data disp_data = *(struct disp_data *) arg;
- enable_breakpoint_disp (bpt, disp_data.disp, disp_data.count);
- }
- static void
- do_map_enable_once_breakpoint (struct breakpoint *bpt, void *ignore)
- {
- struct disp_data disp = { disp_disable, 1 };
- iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
- }
- static void
- enable_once_command (char *args, int from_tty)
- {
- map_breakpoint_numbers (args, do_map_enable_once_breakpoint, NULL);
- }
- static void
- do_map_enable_count_breakpoint (struct breakpoint *bpt, void *countptr)
- {
- struct disp_data disp = { disp_disable, *(int *) countptr };
- iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
- }
- static void
- enable_count_command (char *args, int from_tty)
- {
- int count = get_number (&args);
- map_breakpoint_numbers (args, do_map_enable_count_breakpoint, &count);
- }
- static void
- do_map_enable_delete_breakpoint (struct breakpoint *bpt, void *ignore)
- {
- struct disp_data disp = { disp_del, 1 };
- iterate_over_related_breakpoints (bpt, do_enable_breakpoint_disp, &disp);
- }
- static void
- enable_delete_command (char *args, int from_tty)
- {
- map_breakpoint_numbers (args, do_map_enable_delete_breakpoint, NULL);
- }
- static void
- set_breakpoint_cmd (char *args, int from_tty)
- {
- }
- static void
- show_breakpoint_cmd (char *args, int from_tty)
- {
- }
- static void
- invalidate_bp_value_on_memory_change (struct inferior *inferior,
- CORE_ADDR addr, ssize_t len,
- const bfd_byte *data)
- {
- struct breakpoint *bp;
- ALL_BREAKPOINTS (bp)
- if (bp->enable_state == bp_enabled
- && bp->type == bp_hardware_watchpoint)
- {
- struct watchpoint *wp = (struct watchpoint *) bp;
- if (wp->val_valid && wp->val)
- {
- struct bp_location *loc;
- for (loc = bp->loc; loc != NULL; loc = loc->next)
- if (loc->loc_type == bp_loc_hardware_watchpoint
- && loc->address + loc->length > addr
- && addr + len > loc->address)
- {
- value_free (wp->val);
- wp->val = NULL;
- wp->val_valid = 0;
- }
- }
- }
- }
- void
- insert_single_step_breakpoint (struct gdbarch *gdbarch,
- struct address_space *aspace,
- CORE_ADDR next_pc)
- {
- struct thread_info *tp = inferior_thread ();
- struct symtab_and_line sal;
- CORE_ADDR pc = next_pc;
- if (tp->control.single_step_breakpoints == NULL)
- {
- tp->control.single_step_breakpoints
- = new_single_step_breakpoint (tp->num, gdbarch);
- }
- sal = find_pc_line (pc, 0);
- sal.pc = pc;
- sal.section = find_pc_overlay (pc);
- sal.explicit_pc = 1;
- add_location_to_breakpoint (tp->control.single_step_breakpoints, &sal);
- update_global_location_list (UGLL_INSERT);
- }
- int
- breakpoint_has_location_inserted_here (struct breakpoint *bp,
- struct address_space *aspace,
- CORE_ADDR pc)
- {
- struct bp_location *loc;
- for (loc = bp->loc; loc != NULL; loc = loc->next)
- if (loc->inserted
- && breakpoint_location_address_match (loc, aspace, pc))
- return 1;
- return 0;
- }
- int
- single_step_breakpoint_inserted_here_p (struct address_space *aspace,
- CORE_ADDR pc)
- {
- struct breakpoint *bpt;
- ALL_BREAKPOINTS (bpt)
- {
- if (bpt->type == bp_single_step
- && breakpoint_has_location_inserted_here (bpt, aspace, pc))
- return 1;
- }
- return 0;
- }
- static int
- is_syscall_catchpoint_enabled (struct breakpoint *bp)
- {
- if (syscall_catchpoint_p (bp)
- && bp->enable_state != bp_disabled
- && bp->enable_state != bp_call_disabled)
- return 1;
- else
- return 0;
- }
- int
- catch_syscall_enabled (void)
- {
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (current_inferior ());
- return inf_data->total_syscalls_count != 0;
- }
- int
- catching_syscall_number (int syscall_number)
- {
- struct breakpoint *bp;
- ALL_BREAKPOINTS (bp)
- if (is_syscall_catchpoint_enabled (bp))
- {
- struct syscall_catchpoint *c = (struct syscall_catchpoint *) bp;
- if (c->syscalls_to_be_caught)
- {
- int i, iter;
- for (i = 0;
- VEC_iterate (int, c->syscalls_to_be_caught, i, iter);
- i++)
- if (syscall_number == iter)
- return 1;
- }
- else
- return 1;
- }
- return 0;
- }
- static VEC (char_ptr) *
- catch_syscall_completer (struct cmd_list_element *cmd,
- const char *text, const char *word)
- {
- const char **list = get_syscall_names (get_current_arch ());
- VEC (char_ptr) *retlist
- = (list == NULL) ? NULL : complete_on_enum (list, word, word);
- xfree (list);
- return retlist;
- }
- static void
- set_tracepoint_count (int num)
- {
- tracepoint_count = num;
- set_internalvar_integer (lookup_internalvar ("tpnum"), num);
- }
- static void
- trace_command (char *arg, int from_tty)
- {
- struct breakpoint_ops *ops;
- const char *arg_cp = arg;
- if (arg && probe_linespec_to_ops (&arg_cp))
- ops = &tracepoint_probe_breakpoint_ops;
- else
- ops = &tracepoint_breakpoint_ops;
- create_breakpoint (get_current_arch (),
- arg,
- NULL, 0, NULL, 1 ,
- 0 ,
- bp_tracepoint ,
- 0 ,
- pending_break_support,
- ops,
- from_tty,
- 1 ,
- 0 , 0);
- }
- static void
- ftrace_command (char *arg, int from_tty)
- {
- create_breakpoint (get_current_arch (),
- arg,
- NULL, 0, NULL, 1 ,
- 0 ,
- bp_fast_tracepoint ,
- 0 ,
- pending_break_support,
- &tracepoint_breakpoint_ops,
- from_tty,
- 1 ,
- 0 , 0);
- }
- static void
- strace_command (char *arg, int from_tty)
- {
- struct breakpoint_ops *ops;
-
- if (arg && strncmp (arg, "-m", 2) == 0 && isspace (arg[2]))
- ops = &strace_marker_breakpoint_ops;
- else
- ops = &tracepoint_breakpoint_ops;
- create_breakpoint (get_current_arch (),
- arg,
- NULL, 0, NULL, 1 ,
- 0 ,
- bp_static_tracepoint ,
- 0 ,
- pending_break_support,
- ops,
- from_tty,
- 1 ,
- 0 , 0);
- }
- static struct uploaded_tp *this_utp;
- static int next_cmd;
- static char *
- read_uploaded_action (void)
- {
- char *rslt;
- VEC_iterate (char_ptr, this_utp->cmd_strings, next_cmd, rslt);
- next_cmd++;
- return rslt;
- }
- struct tracepoint *
- create_tracepoint_from_upload (struct uploaded_tp *utp)
- {
- char *addr_str, small_buf[100];
- struct tracepoint *tp;
- if (utp->at_string)
- addr_str = utp->at_string;
- else
- {
-
- warning (_("Uploaded tracepoint %d has no "
- "source location, using raw address"),
- utp->number);
- xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (utp->addr));
- addr_str = small_buf;
- }
-
- if (utp->cond && !utp->cond_string)
- warning (_("Uploaded tracepoint %d condition "
- "has no source form, ignoring it"),
- utp->number);
- if (!create_breakpoint (get_current_arch (),
- addr_str,
- utp->cond_string, -1, NULL,
- 0 ,
- 0 ,
- utp->type ,
- 0 ,
- pending_break_support,
- &tracepoint_breakpoint_ops,
- 0 ,
- utp->enabled ,
- 0 ,
- CREATE_BREAKPOINT_FLAGS_INSERTED))
- return NULL;
-
- tp = get_tracepoint (tracepoint_count);
- gdb_assert (tp != NULL);
- if (utp->pass > 0)
- {
- xsnprintf (small_buf, sizeof (small_buf), "%d %d", utp->pass,
- tp->base.number);
- trace_pass_command (small_buf, 0);
- }
-
- if (!VEC_empty (char_ptr, utp->cmd_strings))
- {
- struct command_line *cmd_list;
- this_utp = utp;
- next_cmd = 0;
- cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
- breakpoint_set_commands (&tp->base, cmd_list);
- }
- else if (!VEC_empty (char_ptr, utp->actions)
- || !VEC_empty (char_ptr, utp->step_actions))
- warning (_("Uploaded tracepoint %d actions "
- "have no source form, ignoring them"),
- utp->number);
-
- tp->base.hit_count = utp->hit_count;
- tp->traceframe_usage = utp->traceframe_usage;
- return tp;
- }
- static void
- tracepoints_info (char *args, int from_tty)
- {
- struct ui_out *uiout = current_uiout;
- int num_printed;
- num_printed = breakpoint_1 (args, 0, is_tracepoint);
- if (num_printed == 0)
- {
- if (args == NULL || *args == '\0')
- ui_out_message (uiout, 0, "No tracepoints.\n");
- else
- ui_out_message (uiout, 0, "No tracepoint matching '%s'.\n", args);
- }
- default_collect_info ();
- }
- static void
- enable_trace_command (char *args, int from_tty)
- {
- enable_command (args, from_tty);
- }
- static void
- disable_trace_command (char *args, int from_tty)
- {
- disable_command (args, from_tty);
- }
- static void
- delete_trace_command (char *arg, int from_tty)
- {
- struct breakpoint *b, *b_tmp;
- dont_repeat ();
- if (arg == 0)
- {
- int breaks_to_delete = 0;
-
- ALL_TRACEPOINTS (b)
- if (is_tracepoint (b) && user_breakpoint_p (b))
- {
- breaks_to_delete = 1;
- break;
- }
-
- if (!from_tty
- || (breaks_to_delete && query (_("Delete all tracepoints? "))))
- {
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- if (is_tracepoint (b) && user_breakpoint_p (b))
- delete_breakpoint (b);
- }
- }
- else
- map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
- }
- static void
- trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
- {
- tp->pass_count = count;
- observer_notify_breakpoint_modified (&tp->base);
- if (from_tty)
- printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
- tp->base.number, count);
- }
- static void
- trace_pass_command (char *args, int from_tty)
- {
- struct tracepoint *t1;
- unsigned int count;
- if (args == 0 || *args == 0)
- error (_("passcount command requires an "
- "argument (count + optional TP num)"));
- count = strtoul (args, &args, 10);
- args = skip_spaces (args);
- if (*args && strncasecmp (args, "all", 3) == 0)
- {
- struct breakpoint *b;
- args += 3;
- if (*args)
- error (_("Junk at end of arguments."));
- ALL_TRACEPOINTS (b)
- {
- t1 = (struct tracepoint *) b;
- trace_pass_set_count (t1, count, from_tty);
- }
- }
- else if (*args == '\0')
- {
- t1 = get_tracepoint_by_number (&args, NULL);
- if (t1)
- trace_pass_set_count (t1, count, from_tty);
- }
- else
- {
- struct get_number_or_range_state state;
- init_number_or_range (&state, args);
- while (!state.finished)
- {
- t1 = get_tracepoint_by_number (&args, &state);
- if (t1)
- trace_pass_set_count (t1, count, from_tty);
- }
- }
- }
- struct tracepoint *
- get_tracepoint (int num)
- {
- struct breakpoint *t;
- ALL_TRACEPOINTS (t)
- if (t->number == num)
- return (struct tracepoint *) t;
- return NULL;
- }
- struct tracepoint *
- get_tracepoint_by_number_on_target (int num)
- {
- struct breakpoint *b;
- ALL_TRACEPOINTS (b)
- {
- struct tracepoint *t = (struct tracepoint *) b;
- if (t->number_on_target == num)
- return t;
- }
- return NULL;
- }
- struct tracepoint *
- get_tracepoint_by_number (char **arg,
- struct get_number_or_range_state *state)
- {
- struct breakpoint *t;
- int tpnum;
- char *instring = arg == NULL ? NULL : *arg;
- if (state)
- {
- gdb_assert (!state->finished);
- tpnum = get_number_or_range (state);
- }
- else if (arg == NULL || *arg == NULL || ! **arg)
- tpnum = tracepoint_count;
- else
- tpnum = get_number (arg);
- if (tpnum <= 0)
- {
- if (instring && *instring)
- printf_filtered (_("bad tracepoint number at or near '%s'\n"),
- instring);
- else
- printf_filtered (_("No previous tracepoint\n"));
- return NULL;
- }
- ALL_TRACEPOINTS (t)
- if (t->number == tpnum)
- {
- return (struct tracepoint *) t;
- }
- printf_unfiltered ("No tracepoint number %d.\n", tpnum);
- return NULL;
- }
- void
- print_recreate_thread (struct breakpoint *b, struct ui_file *fp)
- {
- if (b->thread != -1)
- fprintf_unfiltered (fp, " thread %d", b->thread);
- if (b->task != 0)
- fprintf_unfiltered (fp, " task %d", b->task);
- fprintf_unfiltered (fp, "\n");
- }
- static void
- save_breakpoints (char *filename, int from_tty,
- int (*filter) (const struct breakpoint *))
- {
- struct breakpoint *tp;
- int any = 0;
- struct cleanup *cleanup;
- struct ui_file *fp;
- int extra_trace_bits = 0;
- if (filename == 0 || *filename == 0)
- error (_("Argument required (file name in which to save)"));
-
- ALL_BREAKPOINTS (tp)
- {
-
- if (!user_breakpoint_p (tp))
- continue;
-
- if (filter && !filter (tp))
- continue;
- any = 1;
- if (is_tracepoint (tp))
- {
- extra_trace_bits = 1;
-
- break;
- }
- }
- if (!any)
- {
- warning (_("Nothing to save."));
- return;
- }
- filename = tilde_expand (filename);
- cleanup = make_cleanup (xfree, filename);
- fp = gdb_fopen (filename, "w");
- if (!fp)
- error (_("Unable to open file '%s' for saving (%s)"),
- filename, safe_strerror (errno));
- make_cleanup_ui_file_delete (fp);
- if (extra_trace_bits)
- save_trace_state_variables (fp);
- ALL_BREAKPOINTS (tp)
- {
-
- if (!user_breakpoint_p (tp))
- continue;
-
- if (filter && !filter (tp))
- continue;
- tp->ops->print_recreate (tp, fp);
-
- if (tp->cond_string)
- fprintf_unfiltered (fp, " condition $bpnum %s\n", tp->cond_string);
- if (tp->ignore_count)
- fprintf_unfiltered (fp, " ignore $bpnum %d\n", tp->ignore_count);
- if (tp->type != bp_dprintf && tp->commands)
- {
- volatile struct gdb_exception ex;
- fprintf_unfiltered (fp, " commands\n");
- ui_out_redirect (current_uiout, fp);
- TRY_CATCH (ex, RETURN_MASK_ALL)
- {
- print_command_lines (current_uiout, tp->commands->commands, 2);
- }
- ui_out_redirect (current_uiout, NULL);
- if (ex.reason < 0)
- throw_exception (ex);
- fprintf_unfiltered (fp, " end\n");
- }
- if (tp->enable_state == bp_disabled)
- fprintf_unfiltered (fp, "disable $bpnum\n");
-
- if (!is_watchpoint (tp) && tp->loc && tp->loc->next)
- {
- struct bp_location *loc;
- int n = 1;
- for (loc = tp->loc; loc != NULL; loc = loc->next, n++)
- if (!loc->enabled)
- fprintf_unfiltered (fp, "disable $bpnum.%d\n", n);
- }
- }
- if (extra_trace_bits && *default_collect)
- fprintf_unfiltered (fp, "set default-collect %s\n", default_collect);
- if (from_tty)
- printf_filtered (_("Saved to file '%s'.\n"), filename);
- do_cleanups (cleanup);
- }
- static void
- save_breakpoints_command (char *args, int from_tty)
- {
- save_breakpoints (args, from_tty, NULL);
- }
- static void
- save_tracepoints_command (char *args, int from_tty)
- {
- save_breakpoints (args, from_tty, is_tracepoint);
- }
- VEC(breakpoint_p) *
- all_tracepoints (void)
- {
- VEC(breakpoint_p) *tp_vec = 0;
- struct breakpoint *tp;
- ALL_TRACEPOINTS (tp)
- {
- VEC_safe_push (breakpoint_p, tp_vec, tp);
- }
- return tp_vec;
- }
- #define BREAK_ARGS_HELP(command) \
- command" [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]\n\
- PROBE_MODIFIER shall be present if the command is to be placed in a\n\
- probe point. Accepted values are `-probe' (for a generic, automatically\n\
- guessed probe type) or `-probe-stap' (for a SystemTap probe).\n\
- LOCATION may be a line number, function name, or \"*\" and an address.\n\
- If a line number is specified, break at start of code for that line.\n\
- If a function is specified, break at start of code for that function.\n\
- If an address is specified, break at that exact address.\n\
- With no LOCATION, uses current execution address of the selected\n\
- stack frame. This is useful for breaking on return to a stack frame.\n\
- \n\
- THREADNUM is the number from \"info threads\".\n\
- CONDITION is a boolean expression.\n\
- \n\
- Multiple breakpoints at one place are permitted, and useful if their\n\
- conditions are different.\n\
- \n\
- Do \"help breakpoints\" for info on other commands dealing with breakpoints."
- static struct cmd_list_element *catch_cmdlist;
- static struct cmd_list_element *tcatch_cmdlist;
- void
- add_catch_command (char *name, char *docstring,
- cmd_sfunc_ftype *sfunc,
- completer_ftype *completer,
- void *user_data_catch,
- void *user_data_tcatch)
- {
- struct cmd_list_element *command;
- command = add_cmd (name, class_breakpoint, NULL, docstring,
- &catch_cmdlist);
- set_cmd_sfunc (command, sfunc);
- set_cmd_context (command, user_data_catch);
- set_cmd_completer (command, completer);
- command = add_cmd (name, class_breakpoint, NULL, docstring,
- &tcatch_cmdlist);
- set_cmd_sfunc (command, sfunc);
- set_cmd_context (command, user_data_tcatch);
- set_cmd_completer (command, completer);
- }
- static void
- clear_syscall_counts (struct inferior *inf)
- {
- struct catch_syscall_inferior_data *inf_data
- = get_catch_syscall_inferior_data (inf);
- inf_data->total_syscalls_count = 0;
- inf_data->any_syscall_count = 0;
- VEC_free (int, inf_data->syscalls_counts);
- }
- static void
- save_command (char *arg, int from_tty)
- {
- printf_unfiltered (_("\"save\" must be followed by "
- "the name of a save subcommand.\n"));
- help_list (save_cmdlist, "save ", all_commands, gdb_stdout);
- }
- struct breakpoint *
- iterate_over_breakpoints (int (*callback) (struct breakpoint *, void *),
- void *data)
- {
- struct breakpoint *b, *b_tmp;
- ALL_BREAKPOINTS_SAFE (b, b_tmp)
- {
- if ((*callback) (b, data))
- return b;
- }
- return NULL;
- }
- static int
- is_non_inline_function (struct breakpoint *b)
- {
-
- if (b->type == bp_shlib_event)
- return 1;
- return 0;
- }
- int
- pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc,
- const struct target_waitstatus *ws)
- {
- struct breakpoint *b;
- struct bp_location *bl;
- ALL_BREAKPOINTS (b)
- {
- if (!is_non_inline_function (b))
- continue;
- for (bl = b->loc; bl != NULL; bl = bl->next)
- {
- if (!bl->shlib_disabled
- && bpstat_check_location (bl, aspace, pc, ws))
- return 1;
- }
- }
- return 0;
- }
- void
- breakpoint_free_objfile (struct objfile *objfile)
- {
- struct bp_location **locp, *loc;
- ALL_BP_LOCATIONS (loc, locp)
- if (loc->symtab != NULL && SYMTAB_OBJFILE (loc->symtab) == objfile)
- loc->symtab = NULL;
- }
- void
- initialize_breakpoint_ops (void)
- {
- static int initialized = 0;
- struct breakpoint_ops *ops;
- if (initialized)
- return;
- initialized = 1;
-
- ops = &bkpt_base_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->re_set = bkpt_re_set;
- ops->insert_location = bkpt_insert_location;
- ops->remove_location = bkpt_remove_location;
- ops->breakpoint_hit = bkpt_breakpoint_hit;
- ops->create_sals_from_address = bkpt_create_sals_from_address;
- ops->create_breakpoints_sal = bkpt_create_breakpoints_sal;
- ops->decode_linespec = bkpt_decode_linespec;
-
- ops = &bkpt_breakpoint_ops;
- *ops = bkpt_base_breakpoint_ops;
- ops->re_set = bkpt_re_set;
- ops->resources_needed = bkpt_resources_needed;
- ops->print_it = bkpt_print_it;
- ops->print_mention = bkpt_print_mention;
- ops->print_recreate = bkpt_print_recreate;
-
- ops = &ranged_breakpoint_ops;
- *ops = bkpt_breakpoint_ops;
- ops->breakpoint_hit = breakpoint_hit_ranged_breakpoint;
- ops->resources_needed = resources_needed_ranged_breakpoint;
- ops->print_it = print_it_ranged_breakpoint;
- ops->print_one = print_one_ranged_breakpoint;
- ops->print_one_detail = print_one_detail_ranged_breakpoint;
- ops->print_mention = print_mention_ranged_breakpoint;
- ops->print_recreate = print_recreate_ranged_breakpoint;
-
- ops = &internal_breakpoint_ops;
- *ops = bkpt_base_breakpoint_ops;
- ops->re_set = internal_bkpt_re_set;
- ops->check_status = internal_bkpt_check_status;
- ops->print_it = internal_bkpt_print_it;
- ops->print_mention = internal_bkpt_print_mention;
-
- ops = &momentary_breakpoint_ops;
- *ops = bkpt_base_breakpoint_ops;
- ops->re_set = momentary_bkpt_re_set;
- ops->check_status = momentary_bkpt_check_status;
- ops->print_it = momentary_bkpt_print_it;
- ops->print_mention = momentary_bkpt_print_mention;
-
- ops = &longjmp_breakpoint_ops;
- *ops = momentary_breakpoint_ops;
- ops->dtor = longjmp_bkpt_dtor;
-
- ops = &bkpt_probe_breakpoint_ops;
- *ops = bkpt_breakpoint_ops;
- ops->insert_location = bkpt_probe_insert_location;
- ops->remove_location = bkpt_probe_remove_location;
- ops->create_sals_from_address = bkpt_probe_create_sals_from_address;
- ops->decode_linespec = bkpt_probe_decode_linespec;
-
- ops = &watchpoint_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->dtor = dtor_watchpoint;
- ops->re_set = re_set_watchpoint;
- ops->insert_location = insert_watchpoint;
- ops->remove_location = remove_watchpoint;
- ops->breakpoint_hit = breakpoint_hit_watchpoint;
- ops->check_status = check_status_watchpoint;
- ops->resources_needed = resources_needed_watchpoint;
- ops->works_in_software_mode = works_in_software_mode_watchpoint;
- ops->print_it = print_it_watchpoint;
- ops->print_mention = print_mention_watchpoint;
- ops->print_recreate = print_recreate_watchpoint;
- ops->explains_signal = explains_signal_watchpoint;
-
- ops = &masked_watchpoint_breakpoint_ops;
- *ops = watchpoint_breakpoint_ops;
- ops->insert_location = insert_masked_watchpoint;
- ops->remove_location = remove_masked_watchpoint;
- ops->resources_needed = resources_needed_masked_watchpoint;
- ops->works_in_software_mode = works_in_software_mode_masked_watchpoint;
- ops->print_it = print_it_masked_watchpoint;
- ops->print_one_detail = print_one_detail_masked_watchpoint;
- ops->print_mention = print_mention_masked_watchpoint;
- ops->print_recreate = print_recreate_masked_watchpoint;
-
- ops = &tracepoint_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->re_set = tracepoint_re_set;
- ops->breakpoint_hit = tracepoint_breakpoint_hit;
- ops->print_one_detail = tracepoint_print_one_detail;
- ops->print_mention = tracepoint_print_mention;
- ops->print_recreate = tracepoint_print_recreate;
- ops->create_sals_from_address = tracepoint_create_sals_from_address;
- ops->create_breakpoints_sal = tracepoint_create_breakpoints_sal;
- ops->decode_linespec = tracepoint_decode_linespec;
-
- ops = &tracepoint_probe_breakpoint_ops;
- *ops = tracepoint_breakpoint_ops;
- ops->create_sals_from_address = tracepoint_probe_create_sals_from_address;
- ops->decode_linespec = tracepoint_probe_decode_linespec;
-
- ops = &strace_marker_breakpoint_ops;
- *ops = tracepoint_breakpoint_ops;
- ops->create_sals_from_address = strace_marker_create_sals_from_address;
- ops->create_breakpoints_sal = strace_marker_create_breakpoints_sal;
- ops->decode_linespec = strace_marker_decode_linespec;
-
- ops = &catch_fork_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->insert_location = insert_catch_fork;
- ops->remove_location = remove_catch_fork;
- ops->breakpoint_hit = breakpoint_hit_catch_fork;
- ops->print_it = print_it_catch_fork;
- ops->print_one = print_one_catch_fork;
- ops->print_mention = print_mention_catch_fork;
- ops->print_recreate = print_recreate_catch_fork;
-
- ops = &catch_vfork_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->insert_location = insert_catch_vfork;
- ops->remove_location = remove_catch_vfork;
- ops->breakpoint_hit = breakpoint_hit_catch_vfork;
- ops->print_it = print_it_catch_vfork;
- ops->print_one = print_one_catch_vfork;
- ops->print_mention = print_mention_catch_vfork;
- ops->print_recreate = print_recreate_catch_vfork;
-
- ops = &catch_exec_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->dtor = dtor_catch_exec;
- ops->insert_location = insert_catch_exec;
- ops->remove_location = remove_catch_exec;
- ops->breakpoint_hit = breakpoint_hit_catch_exec;
- ops->print_it = print_it_catch_exec;
- ops->print_one = print_one_catch_exec;
- ops->print_mention = print_mention_catch_exec;
- ops->print_recreate = print_recreate_catch_exec;
-
- ops = &catch_syscall_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->dtor = dtor_catch_syscall;
- ops->insert_location = insert_catch_syscall;
- ops->remove_location = remove_catch_syscall;
- ops->breakpoint_hit = breakpoint_hit_catch_syscall;
- ops->print_it = print_it_catch_syscall;
- ops->print_one = print_one_catch_syscall;
- ops->print_mention = print_mention_catch_syscall;
- ops->print_recreate = print_recreate_catch_syscall;
-
- ops = &catch_solib_breakpoint_ops;
- *ops = base_breakpoint_ops;
- ops->dtor = dtor_catch_solib;
- ops->insert_location = insert_catch_solib;
- ops->remove_location = remove_catch_solib;
- ops->breakpoint_hit = breakpoint_hit_catch_solib;
- ops->check_status = check_status_catch_solib;
- ops->print_it = print_it_catch_solib;
- ops->print_one = print_one_catch_solib;
- ops->print_mention = print_mention_catch_solib;
- ops->print_recreate = print_recreate_catch_solib;
- ops = &dprintf_breakpoint_ops;
- *ops = bkpt_base_breakpoint_ops;
- ops->re_set = dprintf_re_set;
- ops->resources_needed = bkpt_resources_needed;
- ops->print_it = bkpt_print_it;
- ops->print_mention = bkpt_print_mention;
- ops->print_recreate = dprintf_print_recreate;
- ops->after_condition_true = dprintf_after_condition_true;
- ops->breakpoint_hit = dprintf_breakpoint_hit;
- }
- static struct cmd_list_element *enablebreaklist = NULL;
- void
- _initialize_breakpoint (void)
- {
- struct cmd_list_element *c;
- initialize_breakpoint_ops ();
- observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
- observer_attach_free_objfile (disable_breakpoints_in_freed_objfile);
- observer_attach_inferior_exit (clear_syscall_counts);
- observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
- breakpoint_objfile_key
- = register_objfile_data_with_cleanup (NULL, free_breakpoint_probes);
- catch_syscall_inferior_data
- = register_inferior_data_with_cleanup (NULL,
- catch_syscall_inferior_data_cleanup);
- breakpoint_chain = 0;
-
- breakpoint_count = 0;
- tracepoint_count = 0;
- add_com ("ignore", class_breakpoint, ignore_command, _("\
- Set ignore-count of breakpoint number N to COUNT.\n\
- Usage is `ignore N COUNT'."));
- if (xdb_commands)
- add_com_alias ("bc", "ignore", class_breakpoint, 1);
- add_com ("commands", class_breakpoint, commands_command, _("\
- Set commands to be executed when a breakpoint is hit.\n\
- Give breakpoint number as argument after \"commands\".\n\
- With no argument, the targeted breakpoint is the last one set.\n\
- The commands themselves follow starting on the next line.\n\
- Type a line containing \"end\" to indicate the end of them.\n\
- Give \"silent\" as the first line to make the breakpoint silent;\n\
- then no output is printed when it is hit, except what the commands print."));
- c = add_com ("condition", class_breakpoint, condition_command, _("\
- Specify breakpoint number N to break only if COND is true.\n\
- Usage is `condition N COND', where N is an integer and COND is an\n\
- expression to be evaluated whenever breakpoint N is reached."));
- set_cmd_completer (c, condition_completer);
- c = add_com ("tbreak", class_breakpoint, tbreak_command, _("\
- Set a temporary breakpoint.\n\
- Like \"break\" except the breakpoint is only temporary,\n\
- so it will be deleted when hit. Equivalent to \"break\" followed\n\
- by using \"enable delete\" on the breakpoint number.\n\
- \n"
- BREAK_ARGS_HELP ("tbreak")));
- set_cmd_completer (c, location_completer);
- c = add_com ("hbreak", class_breakpoint, hbreak_command, _("\
- Set a hardware assisted breakpoint.\n\
- Like \"break\" except the breakpoint requires hardware support,\n\
- some target hardware may not have this support.\n\
- \n"
- BREAK_ARGS_HELP ("hbreak")));
- set_cmd_completer (c, location_completer);
- c = add_com ("thbreak", class_breakpoint, thbreak_command, _("\
- Set a temporary hardware assisted breakpoint.\n\
- Like \"hbreak\" except the breakpoint is only temporary,\n\
- so it will be deleted when hit.\n\
- \n"
- BREAK_ARGS_HELP ("thbreak")));
- set_cmd_completer (c, location_completer);
- add_prefix_cmd ("enable", class_breakpoint, enable_command, _("\
- Enable some breakpoints.\n\
- Give breakpoint numbers (separated by spaces) as arguments.\n\
- With no subcommand, breakpoints are enabled until you command otherwise.\n\
- This is used to cancel the effect of the \"disable\" command.\n\
- With a subcommand you can enable temporarily."),
- &enablelist, "enable ", 1, &cmdlist);
- if (xdb_commands)
- add_com ("ab", class_breakpoint, enable_command, _("\
- Enable some breakpoints.\n\
- Give breakpoint numbers (separated by spaces) as arguments.\n\
- With no subcommand, breakpoints are enabled until you command otherwise.\n\
- This is used to cancel the effect of the \"disable\" command.\n\
- With a subcommand you can enable temporarily."));
- add_com_alias ("en", "enable", class_breakpoint, 1);
- add_prefix_cmd ("breakpoints", class_breakpoint, enable_command, _("\
- Enable some breakpoints.\n\
- Give breakpoint numbers (separated by spaces) as arguments.\n\
- This is used to cancel the effect of the \"disable\" command.\n\
- May be abbreviated to simply \"enable\".\n"),
- &enablebreaklist, "enable breakpoints ", 1, &enablelist);
- add_cmd ("once", no_class, enable_once_command, _("\
- Enable breakpoints for one hit. Give breakpoint numbers.\n\
- If a breakpoint is hit while enabled in this fashion, it becomes disabled."),
- &enablebreaklist);
- add_cmd ("delete", no_class, enable_delete_command, _("\
- Enable breakpoints and delete when hit. Give breakpoint numbers.\n\
- If a breakpoint is hit while enabled in this fashion, it is deleted."),
- &enablebreaklist);
- add_cmd ("count", no_class, enable_count_command, _("\
- Enable breakpoints for COUNT hits. Give count and then breakpoint numbers.\n\
- If a breakpoint is hit while enabled in this fashion,\n\
- the count is decremented; when it reaches zero, the breakpoint is disabled."),
- &enablebreaklist);
- add_cmd ("delete", no_class, enable_delete_command, _("\
- Enable breakpoints and delete when hit. Give breakpoint numbers.\n\
- If a breakpoint is hit while enabled in this fashion, it is deleted."),
- &enablelist);
- add_cmd ("once", no_class, enable_once_command, _("\
- Enable breakpoints for one hit. Give breakpoint numbers.\n\
- If a breakpoint is hit while enabled in this fashion, it becomes disabled."),
- &enablelist);
- add_cmd ("count", no_class, enable_count_command, _("\
- Enable breakpoints for COUNT hits. Give count and then breakpoint numbers.\n\
- If a breakpoint is hit while enabled in this fashion,\n\
- the count is decremented; when it reaches zero, the breakpoint is disabled."),
- &enablelist);
- add_prefix_cmd ("disable", class_breakpoint, disable_command, _("\
- Disable some breakpoints.\n\
- Arguments are breakpoint numbers with spaces in between.\n\
- To disable all breakpoints, give no argument.\n\
- A disabled breakpoint is not forgotten, but has no effect until re-enabled."),
- &disablelist, "disable ", 1, &cmdlist);
- add_com_alias ("dis", "disable", class_breakpoint, 1);
- add_com_alias ("disa", "disable", class_breakpoint, 1);
- if (xdb_commands)
- add_com ("sb", class_breakpoint, disable_command, _("\
- Disable some breakpoints.\n\
- Arguments are breakpoint numbers with spaces in between.\n\
- To disable all breakpoints, give no argument.\n\
- A disabled breakpoint is not forgotten, but has no effect until re-enabled."));
- add_cmd ("breakpoints", class_alias, disable_command, _("\
- Disable some breakpoints.\n\
- Arguments are breakpoint numbers with spaces in between.\n\
- To disable all breakpoints, give no argument.\n\
- A disabled breakpoint is not forgotten, but has no effect until re-enabled.\n\
- This command may be abbreviated \"disable\"."),
- &disablelist);
- add_prefix_cmd ("delete", class_breakpoint, delete_command, _("\
- Delete some breakpoints or auto-display expressions.\n\
- Arguments are breakpoint numbers with spaces in between.\n\
- To delete all breakpoints, give no argument.\n\
- \n\
- Also a prefix command for deletion of other GDB objects.\n\
- The \"unset\" command is also an alias for \"delete\"."),
- &deletelist, "delete ", 1, &cmdlist);
- add_com_alias ("d", "delete", class_breakpoint, 1);
- add_com_alias ("del", "delete", class_breakpoint, 1);
- if (xdb_commands)
- add_com ("db", class_breakpoint, delete_command, _("\
- Delete some breakpoints.\n\
- Arguments are breakpoint numbers with spaces in between.\n\
- To delete all breakpoints, give no argument.\n"));
- add_cmd ("breakpoints", class_alias, delete_command, _("\
- Delete some breakpoints or auto-display expressions.\n\
- Arguments are breakpoint numbers with spaces in between.\n\
- To delete all breakpoints, give no argument.\n\
- This command may be abbreviated \"delete\"."),
- &deletelist);
- add_com ("clear", class_breakpoint, clear_command, _("\
- Clear breakpoint at specified line or function.\n\
- Argument may be line number, function name, or \"*\" and an address.\n\
- If line number is specified, all breakpoints in that line are cleared.\n\
- If function is specified, breakpoints at beginning of function are cleared.\n\
- If an address is specified, breakpoints at that address are cleared.\n\
- \n\
- With no argument, clears all breakpoints in the line that the selected frame\n\
- is executing in.\n\
- \n\
- See also the \"delete\" command which clears breakpoints by number."));
- add_com_alias ("cl", "clear", class_breakpoint, 1);
- c = add_com ("break", class_breakpoint, break_command, _("\
- Set breakpoint at specified line or function.\n"
- BREAK_ARGS_HELP ("break")));
- set_cmd_completer (c, location_completer);
- add_com_alias ("b", "break", class_run, 1);
- add_com_alias ("br", "break", class_run, 1);
- add_com_alias ("bre", "break", class_run, 1);
- add_com_alias ("brea", "break", class_run, 1);
- if (xdb_commands)
- add_com_alias ("ba", "break", class_breakpoint, 1);
- if (dbx_commands)
- {
- add_abbrev_prefix_cmd ("stop", class_breakpoint, stop_command, _("\
- Break in function/address or break at a line in the current file."),
- &stoplist, "stop ", 1, &cmdlist);
- add_cmd ("in", class_breakpoint, stopin_command,
- _("Break in function or address."), &stoplist);
- add_cmd ("at", class_breakpoint, stopat_command,
- _("Break at a line in the current file."), &stoplist);
- add_com ("status", class_info, breakpoints_info, _("\
- Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
- The \"Type\" column indicates one of:\n\
- \tbreakpoint - normal breakpoint\n\
- \twatchpoint - watchpoint\n\
- The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
- the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
- breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
- address and file/line number respectively.\n\
- \n\
- Convenience variable \"$_\" and default examine address for \"x\"\n\
- are set to the address of the last breakpoint listed unless the command\n\
- is prefixed with \"server \".\n\n\
- Convenience variable \"$bpnum\" contains the number of the last\n\
- breakpoint set."));
- }
- add_info ("breakpoints", breakpoints_info, _("\
- Status of specified breakpoints (all user-settable breakpoints if no argument).\n\
- The \"Type\" column indicates one of:\n\
- \tbreakpoint - normal breakpoint\n\
- \twatchpoint - watchpoint\n\
- The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
- the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
- breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
- address and file/line number respectively.\n\
- \n\
- Convenience variable \"$_\" and default examine address for \"x\"\n\
- are set to the address of the last breakpoint listed unless the command\n\
- is prefixed with \"server \".\n\n\
- Convenience variable \"$bpnum\" contains the number of the last\n\
- breakpoint set."));
- add_info_alias ("b", "breakpoints", 1);
- if (xdb_commands)
- add_com ("lb", class_breakpoint, breakpoints_info, _("\
- Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
- The \"Type\" column indicates one of:\n\
- \tbreakpoint - normal breakpoint\n\
- \twatchpoint - watchpoint\n\
- The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
- the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
- breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
- address and file/line number respectively.\n\
- \n\
- Convenience variable \"$_\" and default examine address for \"x\"\n\
- are set to the address of the last breakpoint listed unless the command\n\
- is prefixed with \"server \".\n\n\
- Convenience variable \"$bpnum\" contains the number of the last\n\
- breakpoint set."));
- add_cmd ("breakpoints", class_maintenance, maintenance_info_breakpoints, _("\
- Status of all breakpoints, or breakpoint number NUMBER.\n\
- The \"Type\" column indicates one of:\n\
- \tbreakpoint - normal breakpoint\n\
- \twatchpoint - watchpoint\n\
- \tlongjmp - internal breakpoint used to step through longjmp()\n\
- \tlongjmp resume - internal breakpoint at the target of longjmp()\n\
- \tuntil - internal breakpoint used by the \"until\" command\n\
- \tfinish - internal breakpoint used by the \"finish\" command\n\
- The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
- the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
- breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
- address and file/line number respectively.\n\
- \n\
- Convenience variable \"$_\" and default examine address for \"x\"\n\
- are set to the address of the last breakpoint listed unless the command\n\
- is prefixed with \"server \".\n\n\
- Convenience variable \"$bpnum\" contains the number of the last\n\
- breakpoint set."),
- &maintenanceinfolist);
- add_prefix_cmd ("catch", class_breakpoint, catch_command, _("\
- Set catchpoints to catch events."),
- &catch_cmdlist, "catch ",
- 0, &cmdlist);
- add_prefix_cmd ("tcatch", class_breakpoint, tcatch_command, _("\
- Set temporary catchpoints to catch events."),
- &tcatch_cmdlist, "tcatch ",
- 0, &cmdlist);
- add_catch_command ("fork", _("Catch calls to fork."),
- catch_fork_command_1,
- NULL,
- (void *) (uintptr_t) catch_fork_permanent,
- (void *) (uintptr_t) catch_fork_temporary);
- add_catch_command ("vfork", _("Catch calls to vfork."),
- catch_fork_command_1,
- NULL,
- (void *) (uintptr_t) catch_vfork_permanent,
- (void *) (uintptr_t) catch_vfork_temporary);
- add_catch_command ("exec", _("Catch calls to exec."),
- catch_exec_command_1,
- NULL,
- CATCH_PERMANENT,
- CATCH_TEMPORARY);
- add_catch_command ("load", _("Catch loads of shared libraries.\n\
- Usage: catch load [REGEX]\n\
- If REGEX is given, only stop for libraries matching the regular expression."),
- catch_load_command_1,
- NULL,
- CATCH_PERMANENT,
- CATCH_TEMPORARY);
- add_catch_command ("unload", _("Catch unloads of shared libraries.\n\
- Usage: catch unload [REGEX]\n\
- If REGEX is given, only stop for libraries matching the regular expression."),
- catch_unload_command_1,
- NULL,
- CATCH_PERMANENT,
- CATCH_TEMPORARY);
- add_catch_command ("syscall", _("\
- Catch system calls by their names and/or numbers.\n\
- Arguments say which system calls to catch. If no arguments\n\
- are given, every system call will be caught.\n\
- Arguments, if given, should be one or more system call names\n\
- (if your system supports that), or system call numbers."),
- catch_syscall_command_1,
- catch_syscall_completer,
- CATCH_PERMANENT,
- CATCH_TEMPORARY);
- c = add_com ("watch", class_breakpoint, watch_command, _("\
- Set a watchpoint for an expression.\n\
- Usage: watch [-l|-location] EXPRESSION\n\
- A watchpoint stops execution of your program whenever the value of\n\
- an expression changes.\n\
- If -l or -location is given, this evaluates EXPRESSION and watches\n\
- the memory to which it refers."));
- set_cmd_completer (c, expression_completer);
- c = add_com ("rwatch", class_breakpoint, rwatch_command, _("\
- Set a read watchpoint for an expression.\n\
- Usage: rwatch [-l|-location] EXPRESSION\n\
- A watchpoint stops execution of your program whenever the value of\n\
- an expression is read.\n\
- If -l or -location is given, this evaluates EXPRESSION and watches\n\
- the memory to which it refers."));
- set_cmd_completer (c, expression_completer);
- c = add_com ("awatch", class_breakpoint, awatch_command, _("\
- Set a watchpoint for an expression.\n\
- Usage: awatch [-l|-location] EXPRESSION\n\
- A watchpoint stops execution of your program whenever the value of\n\
- an expression is either read or written.\n\
- If -l or -location is given, this evaluates EXPRESSION and watches\n\
- the memory to which it refers."));
- set_cmd_completer (c, expression_completer);
- add_info ("watchpoints", watchpoints_info, _("\
- Status of specified watchpoints (all watchpoints if no argument)."));
- XXX
- add_setshow_zinteger_cmd ("can-use-hw-watchpoints", class_support,
- &can_use_hw_watchpoints, _("\
- Set debugger's willingness to use watchpoint hardware."), _("\
- Show debugger's willingness to use watchpoint hardware."), _("\
- If zero, gdb will not use hardware for new watchpoints, even if\n\
- such is available. (However, any hardware watchpoints that were\n\
- created before setting this to nonzero, will continue to use watchpoint\n\
- hardware.)"),
- NULL,
- show_can_use_hw_watchpoints,
- &setlist, &showlist);
- can_use_hw_watchpoints = 1;
-
- c = add_com ("trace", class_breakpoint, trace_command, _("\
- Set a tracepoint at specified line or function.\n\
- \n"
- BREAK_ARGS_HELP ("trace") "\n\
- Do \"help tracepoints\" for info on other tracepoint commands."));
- set_cmd_completer (c, location_completer);
- add_com_alias ("tp", "trace", class_alias, 0);
- add_com_alias ("tr", "trace", class_alias, 1);
- add_com_alias ("tra", "trace", class_alias, 1);
- add_com_alias ("trac", "trace", class_alias, 1);
- c = add_com ("ftrace", class_breakpoint, ftrace_command, _("\
- Set a fast tracepoint at specified line or function.\n\
- \n"
- BREAK_ARGS_HELP ("ftrace") "\n\
- Do \"help tracepoints\" for info on other tracepoint commands."));
- set_cmd_completer (c, location_completer);
- c = add_com ("strace", class_breakpoint, strace_command, _("\
- Set a static tracepoint at specified line, function or marker.\n\
- \n\
- strace [LOCATION] [if CONDITION]\n\
- LOCATION may be a line number, function name, \"*\" and an address,\n\
- or -m MARKER_ID.\n\
- If a line number is specified, probe the marker at start of code\n\
- for that line. If a function is specified, probe the marker at start\n\
- of code for that function. If an address is specified, probe the marker\n\
- at that exact address. If a marker id is specified, probe the marker\n\
- with that name. With no LOCATION, uses current execution address of\n\
- the selected stack frame.\n\
- Static tracepoints accept an extra collect action -- ``collect $_sdata''.\n\
- This collects arbitrary user data passed in the probe point call to the\n\
- tracing library. You can inspect it when analyzing the trace buffer,\n\
- by printing the $_sdata variable like any other convenience variable.\n\
- \n\
- CONDITION is a boolean expression.\n\
- \n\
- Multiple tracepoints at one place are permitted, and useful if their\n\
- conditions are different.\n\
- \n\
- Do \"help breakpoints\" for info on other commands dealing with breakpoints.\n\
- Do \"help tracepoints\" for info on other tracepoint commands."));
- set_cmd_completer (c, location_completer);
- add_info ("tracepoints", tracepoints_info, _("\
- Status of specified tracepoints (all tracepoints if no argument).\n\
- Convenience variable \"$tpnum\" contains the number of the\n\
- last tracepoint set."));
- add_info_alias ("tp", "tracepoints", 1);
- add_cmd ("tracepoints", class_trace, delete_trace_command, _("\
- Delete specified tracepoints.\n\
- Arguments are tracepoint numbers, separated by spaces.\n\
- No argument means delete all tracepoints."),
- &deletelist);
- add_alias_cmd ("tr", "tracepoints", class_trace, 1, &deletelist);
- c = add_cmd ("tracepoints", class_trace, disable_trace_command, _("\
- Disable specified tracepoints.\n\
- Arguments are tracepoint numbers, separated by spaces.\n\
- No argument means disable all tracepoints."),
- &disablelist);
- deprecate_cmd (c, "disable");
- c = add_cmd ("tracepoints", class_trace, enable_trace_command, _("\
- Enable specified tracepoints.\n\
- Arguments are tracepoint numbers, separated by spaces.\n\
- No argument means enable all tracepoints."),
- &enablelist);
- deprecate_cmd (c, "enable");
- add_com ("passcount", class_trace, trace_pass_command, _("\
- Set the passcount for a tracepoint.\n\
- The trace will end when the tracepoint has been passed 'count' times.\n\
- Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
- if TPNUM is omitted, passcount refers to the last tracepoint defined."));
- add_prefix_cmd ("save", class_breakpoint, save_command,
- _("Save breakpoint definitions as a script."),
- &save_cmdlist, "save ",
- 0, &cmdlist);
- c = add_cmd ("breakpoints", class_breakpoint, save_breakpoints_command, _("\
- Save current breakpoint definitions as a script.\n\
- This includes all types of breakpoints (breakpoints, watchpoints,\n\
- catchpoints, tracepoints). Use the 'source' command in another debug\n\
- session to restore them."),
- &save_cmdlist);
- set_cmd_completer (c, filename_completer);
- c = add_cmd ("tracepoints", class_trace, save_tracepoints_command, _("\
- Save current tracepoint definitions as a script.\n\
- Use the 'source' command in another debug session to restore them."),
- &save_cmdlist);
- set_cmd_completer (c, filename_completer);
- c = add_com_alias ("save-tracepoints", "save tracepoints", class_trace, 0);
- deprecate_cmd (c, "save tracepoints");
- add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, _("\
- Breakpoint specific settings\n\
- Configure various breakpoint-specific variables such as\n\
- pending breakpoint behavior"),
- &breakpoint_set_cmdlist, "set breakpoint ",
- 0, &setlist);
- add_prefix_cmd ("breakpoint", class_maintenance, show_breakpoint_cmd, _("\
- Breakpoint specific settings\n\
- Configure various breakpoint-specific variables such as\n\
- pending breakpoint behavior"),
- &breakpoint_show_cmdlist, "show breakpoint ",
- 0, &showlist);
- add_setshow_auto_boolean_cmd ("pending", no_class,
- &pending_break_support, _("\
- Set debugger's behavior regarding pending breakpoints."), _("\
- Show debugger's behavior regarding pending breakpoints."), _("\
- If on, an unrecognized breakpoint location will cause gdb to create a\n\
- pending breakpoint. If off, an unrecognized breakpoint location results in\n\
- an error. If auto, an unrecognized breakpoint location results in a\n\
- user-query to see if a pending breakpoint should be created."),
- NULL,
- show_pending_break_support,
- &breakpoint_set_cmdlist,
- &breakpoint_show_cmdlist);
- pending_break_support = AUTO_BOOLEAN_AUTO;
- add_setshow_boolean_cmd ("auto-hw", no_class,
- &automatic_hardware_breakpoints, _("\
- Set automatic usage of hardware breakpoints."), _("\
- Show automatic usage of hardware breakpoints."), _("\
- If set, the debugger will automatically use hardware breakpoints for\n\
- breakpoints set with \"break\" but falling in read-only memory. If not set,\n\
- a warning will be emitted for such breakpoints."),
- NULL,
- show_automatic_hardware_breakpoints,
- &breakpoint_set_cmdlist,
- &breakpoint_show_cmdlist);
- add_setshow_boolean_cmd ("always-inserted", class_support,
- &always_inserted_mode, _("\
- Set mode for inserting breakpoints."), _("\
- Show mode for inserting breakpoints."), _("\
- When this mode is on, breakpoints are inserted immediately as soon as\n\
- they're created, kept inserted even when execution stops, and removed\n\
- only when the user deletes them. When this mode is off (the default),\n\
- breakpoints are inserted only when execution continues, and removed\n\
- when execution stops."),
- NULL,
- &show_always_inserted_mode,
- &breakpoint_set_cmdlist,
- &breakpoint_show_cmdlist);
- add_setshow_enum_cmd ("condition-evaluation", class_breakpoint,
- condition_evaluation_enums,
- &condition_evaluation_mode_1, _("\
- Set mode of breakpoint condition evaluation."), _("\
- Show mode of breakpoint condition evaluation."), _("\
- When this is set to \"host\", breakpoint conditions will be\n\
- evaluated on the host's side by GDB. When it is set to \"target\",\n\
- breakpoint conditions will be downloaded to the target (if the target\n\
- supports such feature) and conditions will be evaluated on the target's side.\n\
- If this is set to \"auto\" (default), this will be automatically set to\n\
- \"target\" if it supports condition evaluation, otherwise it will\n\
- be set to \"gdb\""),
- &set_condition_evaluation_mode,
- &show_condition_evaluation_mode,
- &breakpoint_set_cmdlist,
- &breakpoint_show_cmdlist);
- add_com ("break-range", class_breakpoint, break_range_command, _("\
- Set a breakpoint for an address range.\n\
- break-range START-LOCATION, END-LOCATION\n\
- where START-LOCATION and END-LOCATION can be one of the following:\n\
- LINENUM, for that line in the current file,\n\
- FILE:LINENUM, for that line in that file,\n\
- +OFFSET, for that number of lines after the current line\n\
- or the start of the range\n\
- FUNCTION, for the first line in that function,\n\
- FILE:FUNCTION, to distinguish among like-named static functions.\n\
- *ADDRESS, for the instruction at that address.\n\
- \n\
- The breakpoint will stop execution of the inferior whenever it executes\n\
- an instruction at any address within the [START-LOCATION, END-LOCATION]\n\
- range (including START-LOCATION and END-LOCATION)."));
- c = add_com ("dprintf", class_breakpoint, dprintf_command, _("\
- Set a dynamic printf at specified line or function.\n\
- dprintf location,format string,arg1,arg2,...\n\
- location may be a line number, function name, or \"*\" and an address.\n\
- If a line number is specified, break at start of code for that line.\n\
- If a function is specified, break at start of code for that function."));
- set_cmd_completer (c, location_completer);
- add_setshow_enum_cmd ("dprintf-style", class_support,
- dprintf_style_enums, &dprintf_style, _("\
- Set the style of usage for dynamic printf."), _("\
- Show the style of usage for dynamic printf."), _("\
- This setting chooses how GDB will do a dynamic printf.\n\
- If the value is \"gdb\", then the printing is done by GDB to its own\n\
- console, as with the \"printf\" command.\n\
- If the value is \"call\", the print is done by calling a function in your\n\
- program; by default printf(), but you can choose a different function or\n\
- output stream by setting dprintf-function and dprintf-channel."),
- update_dprintf_commands, NULL,
- &setlist, &showlist);
- dprintf_function = xstrdup ("printf");
- add_setshow_string_cmd ("dprintf-function", class_support,
- &dprintf_function, _("\
- Set the function to use for dynamic printf"), _("\
- Show the function to use for dynamic printf"), NULL,
- update_dprintf_commands, NULL,
- &setlist, &showlist);
- dprintf_channel = xstrdup ("");
- add_setshow_string_cmd ("dprintf-channel", class_support,
- &dprintf_channel, _("\
- Set the channel to use for dynamic printf"), _("\
- Show the channel to use for dynamic printf"), NULL,
- update_dprintf_commands, NULL,
- &setlist, &showlist);
- add_setshow_boolean_cmd ("disconnected-dprintf", no_class,
- &disconnected_dprintf, _("\
- Set whether dprintf continues after GDB disconnects."), _("\
- Show whether dprintf continues after GDB disconnects."), _("\
- Use this to let dprintf commands continue to hit and produce output\n\
- even if GDB disconnects or detaches from the target."),
- NULL,
- NULL,
- &setlist, &showlist);
- add_com ("agent-printf", class_vars, agent_printf_command, _("\
- agent-printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
- (target agent only) This is useful for formatted output in user-defined commands."));
- automatic_hardware_breakpoints = 1;
- observer_attach_about_to_proceed (breakpoint_about_to_proceed);
- observer_attach_thread_exit (remove_threaded_breakpoints);
- }