X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fbreakpoint.c;h=8d9926c11d78af6a444b80812ade2fc4a8d9f68b;hb=197f0a605dde6bdc173692d9a8272940263ac108;hp=809eb53bbf4480f29c04c5a60236037dd937e071;hpb=4a64f543e68bd1a6f2fbf7409c7fb4e9fdf73d78;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 809eb53bbf..8d9926c11d 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2,7 +2,7 @@ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010 Free Software Foundation, Inc. + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GDB. @@ -62,6 +62,7 @@ #include "jit.h" #include "xml-syscall.h" #include "parser-defs.h" +#include "cli/cli-utils.h" /* readline include files */ #include "readline/readline.h" @@ -98,7 +99,7 @@ static void clear_command (char *, int); static void catch_command (char *, int); -static int can_use_hardware_watchpoint (struct value *); +static int can_use_hardware_watchpoint (struct value *, int); static void break_command_1 (char *, int, int); @@ -132,7 +133,8 @@ static void breakpoints_info (char *, int); static void watchpoints_info (char *, int); -static int breakpoint_1 (int, int, int (*) (const struct breakpoint *)); +static int breakpoint_1 (char *, int, + int (*) (const struct breakpoint *)); static int breakpoint_cond_eval (void *); @@ -142,8 +144,6 @@ static void commands_command (char *, int); static void condition_command (char *, int); -static int get_number_trailer (char **, int); - typedef enum { mark_inserted, @@ -185,8 +185,6 @@ static void catch_exception_command_1 (enum exception_event_kind ex_event, static void tcatch_command (char *arg, int from_tty); -static void ep_skip_leading_whitespace (char **s); - static void detach_single_step_breakpoints (void); static int single_step_breakpoint_inserted_here_p (struct address_space *, @@ -268,8 +266,9 @@ 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"), + fprintf_filtered (file, + _("Debugger's willingness to use " + "watchpoint hardware is %s.\n"), value); } @@ -283,8 +282,9 @@ 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"), + fprintf_filtered (file, + _("Debugger's behavior regarding " + "pending breakpoints is %s.\n"), value); } @@ -298,8 +298,8 @@ 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"), + fprintf_filtered (file, + _("Automatic usage of hardware breakpoints is %s.\n"), value); } @@ -324,12 +324,14 @@ show_always_inserted_mode (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { if (always_inserted_mode == always_inserted_auto) - fprintf_filtered (file, _("\ -Always inserted breakpoint mode is %s (currently %s).\n"), + fprintf_filtered (file, + _("Always inserted breakpoint " + "mode is %s (currently %s).\n"), value, breakpoints_always_inserted_mode () ? "on" : "off"); else - fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"), value); + fprintf_filtered (file, _("Always inserted breakpoint mode is %s.\n"), + value); } int @@ -347,6 +349,9 @@ static int executing_breakpoint_commands; /* Are overlay event breakpoints enabled? */ static int overlay_events_enabled; +/* See description in breakpoint.h. */ +int target_exact_watchpoints = 0; + /* Walk the following statement or block through all breakpoints. ALL_BREAKPOINTS_SAFE does so even if the statment deletes the current breakpoint. */ @@ -546,163 +551,6 @@ int default_breakpoint_line; struct program_space *default_breakpoint_pspace; -/* *PP is a string denoting a breakpoint. Get the number of the - breakpoint. Advance *PP after the string and any trailing - whitespace. - - Currently the string can either be a number or "$" followed by the - name of a convenience variable. Making it an expression wouldn't - work well for map_breakpoint_numbers (e.g. "4 + 5 + 6"). - - If the string is a NULL pointer, that denotes the last breakpoint. - - TRAILER is a character which can be found after the number; most - commonly this is `-'. If you don't want a trailer, use \0. */ - -static int -get_number_trailer (char **pp, int trailer) -{ - int retval = 0; /* default */ - char *p = *pp; - - if (p == NULL) - /* Empty line means refer to the last breakpoint. */ - return breakpoint_count; - else if (*p == '$') - { - /* Make a copy of the name, so we can null-terminate it - to pass to lookup_internalvar(). */ - char *varname; - char *start = ++p; - LONGEST val; - - while (isalnum (*p) || *p == '_') - p++; - varname = (char *) alloca (p - start + 1); - strncpy (varname, start, p - start); - varname[p - start] = '\0'; - if (get_internalvar_integer (lookup_internalvar (varname), &val)) - retval = (int) val; - else - { - printf_filtered (_("Convenience variable must have integer value.\n")); - retval = 0; - } - } - else - { - if (*p == '-') - ++p; - while (*p >= '0' && *p <= '9') - ++p; - if (p == *pp) - /* There is no number here. (e.g. "cond a == b"). */ - { - /* Skip non-numeric token. */ - while (*p && !isspace((int) *p)) - ++p; - /* Return zero, which caller must interpret as error. */ - retval = 0; - } - else - retval = atoi (*pp); - } - if (!(isspace (*p) || *p == '\0' || *p == trailer)) - { - /* Trailing junk: return 0 and let caller print error msg. */ - while (!(isspace (*p) || *p == '\0' || *p == trailer)) - ++p; - retval = 0; - } - while (isspace (*p)) - p++; - *pp = p; - return retval; -} - - -/* Like get_number_trailer, but don't allow a trailer. */ -int -get_number (char **pp) -{ - return get_number_trailer (pp, '\0'); -} - -/* Parse a number or a range. - A number will be of the form handled by get_number. - A range will be of the form - , and - will represent all the integers between number1 and number2, - inclusive. - - While processing a range, this fuction is called iteratively; - At each call it will return the next value in the range. - - At the beginning of parsing a range, the char pointer PP will - be advanced past and left pointing at the '-' token. - Subsequent calls will not advance the pointer until the range - is completed. The call that completes the range will advance - pointer PP past . */ - -int -get_number_or_range (char **pp) -{ - static int last_retval, end_value; - static char *end_ptr; - static int in_range = 0; - - if (**pp != '-') - { - /* Default case: pp is pointing either to a solo number, - or to the first number of a range. */ - last_retval = get_number_trailer (pp, '-'); - if (**pp == '-') - { - char **temp; - - /* This is the start of a range ( - ). - Skip the '-', parse and remember the second number, - and also remember the end of the final token. */ - - temp = &end_ptr; - end_ptr = *pp + 1; - while (isspace ((int) *end_ptr)) - end_ptr++; /* skip white space */ - end_value = get_number (temp); - if (end_value < last_retval) - { - error (_("inverted range")); - } - else if (end_value == last_retval) - { - /* Degenerate range (number1 == number2). Advance the - token pointer so that the range will be treated as a - single number. */ - *pp = end_ptr; - } - else - in_range = 1; - } - } - else if (! in_range) - error (_("negative value")); - else - { - /* pp points to the '-' that betokens a range. All - number-parsing has already been done. Return the next - integer value (one greater than the saved previous value). - Do not advance the token pointer 'pp' until the end of range - is reached. */ - - if (++last_retval == end_value) - { - /* End of range reached; advance token pointer. */ - *pp = end_ptr; - in_range = 0; - } - } - return last_retval; -} - /* Return the breakpoint with the specified number, or NULL if the number does not refer to an existing breakpoint. */ @@ -816,7 +664,8 @@ check_no_tracepoint_commands (struct command_line *commands) int i; if (c->control_type == while_stepping_control) - error (_("The 'while-stepping' command can only be used for tracepoints")); + 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]); @@ -863,14 +712,15 @@ validate_commands_for_breakpoint (struct breakpoint *b, if (c->control_type == while_stepping_control) { if (b->type == bp_fast_tracepoint) - error (_("\ -The 'while-stepping' command cannot be used for 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")); + error (_("The 'while-stepping' command " + "cannot be used for static tracepoint")); if (while_stepping) - error (_("The 'while-stepping' command can be used only once")); + error (_("The 'while-stepping' command " + "can be used only once")); else while_stepping = c; } @@ -930,6 +780,46 @@ breakpoint_set_commands (struct breakpoint *b, observer_notify_breakpoint_modified (b->number); } +/* Set the internal `silent' flag on the breakpoint. Note that this + is not the same as the "silent" that may appear in the breakpoint's + commands. */ + +void +breakpoint_set_silent (struct breakpoint *b, int silent) +{ + int old_silent = b->silent; + + b->silent = silent; + if (old_silent != silent) + observer_notify_breakpoint_modified (b->number); +} + +/* Set the thread for this breakpoint. If THREAD is -1, make the + breakpoint work for any thread. */ + +void +breakpoint_set_thread (struct breakpoint *b, int thread) +{ + int old_thread = b->thread; + + b->thread = thread; + if (old_thread != thread) + observer_notify_breakpoint_modified (b->number); +} + +/* Set the task for this breakpoint. If TASK is 0, make the + breakpoint work for any task. */ + +void +breakpoint_set_task (struct breakpoint *b, int task) +{ + int old_task = b->task; + + b->task = task; + if (old_task != task) + observer_notify_breakpoint_modified (b->number); +} + void check_tracepoint_command (char *line, void *closure) { @@ -977,7 +867,8 @@ do_map_commands_command (struct breakpoint *b, void *data) struct cleanup *old_chain; char *str; - str = xstrprintf (_("Type commands for breakpoint(s) %s, one per line."), + str = xstrprintf (_("Type commands for breakpoint(s) " + "%s, one per line."), info->arg); old_chain = make_cleanup (xfree, str); @@ -1220,18 +1111,6 @@ breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len) } -/* A wrapper function for inserting catchpoints. */ -static void -insert_catchpoint (struct ui_out *uo, void *args) -{ - struct breakpoint *b = (struct breakpoint *) args; - - gdb_assert (b->type == bp_catchpoint); - gdb_assert (b->ops != NULL && b->ops->insert != NULL); - - b->ops->insert (b); -} - /* Return true if BPT is of any hardware watchpoint kind. */ static int @@ -1335,11 +1214,6 @@ update_watchpoint (struct breakpoint *b, int reparse) if (!watchpoint_in_thread_scope (b)) return; - /* We don't free locations. They are stored in bp_location array - and update_global_locations will eventually delete them and - remove breakpoints if needed. */ - b->loc = NULL; - if (b->disposition == disp_del_at_next_stop) return; @@ -1350,7 +1224,15 @@ update_watchpoint (struct breakpoint *b, int reparse) within_current_scope = 1; else { - struct frame_info *fi; + struct frame_info *fi = get_current_frame (); + struct gdbarch *frame_arch = get_frame_arch (fi); + CORE_ADDR frame_pc = get_frame_pc (fi); + + /* If we're in a function epilogue, unwinding may not work + properly, so do not attempt to recreate locations at this + point. See similar comments in watchpoint_check. */ + if (gdbarch_in_function_epilogue_p (frame_arch, frame_pc)) + return; /* Save the current frame's ID so we can restore it after evaluating the watchpoint expression on its own frame. */ @@ -1366,6 +1248,11 @@ update_watchpoint (struct breakpoint *b, int reparse) select_frame (fi); } + /* We don't free locations. They are stored in the bp_location array + and update_global_location_list will eventually delete them and + remove breakpoints if needed. */ + b->loc = NULL; + if (within_current_scope && reparse) { char *s; @@ -1430,43 +1317,10 @@ update_watchpoint (struct breakpoint *b, int reparse) b->val_valid = 1; } - /* Change the type of breakpoint between hardware assisted or - an ordinary watchpoint depending on the hardware support - and free hardware slots. REPARSE is set when the inferior - is started. */ - if ((b->type == bp_watchpoint || b->type == bp_hardware_watchpoint) - && reparse) - { - int i, mem_cnt, other_type_used; - - /* We need to determine how many resources are already - used for all other hardware watchpoints to see if we - still have enough resources to also fit this watchpoint - in as well. To avoid the hw_watchpoint_used_count call - below from counting this watchpoint, make sure that it - is marked as a software watchpoint. */ - b->type = bp_watchpoint; - i = hw_watchpoint_used_count (bp_hardware_watchpoint, - &other_type_used); - mem_cnt = can_use_hardware_watchpoint (val_chain); - - if (!mem_cnt) - b->type = bp_watchpoint; - else - { - int target_resources_ok = target_can_use_hardware_watchpoint - (bp_hardware_watchpoint, i + mem_cnt, other_type_used); - if (target_resources_ok <= 0) - b->type = bp_watchpoint; - else - b->type = bp_hardware_watchpoint; - } - } - frame_pspace = get_frame_program_space (get_selected_frame (NULL)); /* Look at each value on the value chain. */ - for (v = val_chain; v; v = next) + for (v = val_chain; v; v = value_next (v)) { /* If it's a memory location, and GDB actually needed its contents to evaluate the expression, then we @@ -1509,7 +1363,62 @@ update_watchpoint (struct breakpoint *b, int reparse) loc->watchpoint_type = type; } } + } + + /* Change the type of breakpoint between hardware assisted or + an ordinary watchpoint depending on the hardware support + and free hardware slots. REPARSE is set when the inferior + is started. */ + if ((b->type == bp_watchpoint || b->type == bp_hardware_watchpoint) + && reparse) + { + int reg_cnt; + enum bp_loc_type loc_type; + struct bp_location *bl; + + reg_cnt = can_use_hardware_watchpoint (val_chain, b->exact); + + if (reg_cnt) + { + int i, target_resources_ok, other_type_used; + enum enable_state orig_enable_state; + + /* We need to determine how many resources are already + used for all other hardware watchpoints plus this one + to see if we still have enough resources to also fit + this watchpoint in as well. To guarantee the + hw_watchpoint_used_count call below counts this + watchpoint, make sure that it is marked as a hardware + watchpoint. */ + b->type = bp_hardware_watchpoint; + + /* hw_watchpoint_used_count ignores disabled watchpoints, + and b might be disabled if we're being called from + do_enable_breakpoint. */ + orig_enable_state = b->enable_state; + b->enable_state = bp_enabled; + + i = hw_watchpoint_used_count (bp_hardware_watchpoint, + &other_type_used); + + b->enable_state = orig_enable_state; + + target_resources_ok = target_can_use_hardware_watchpoint + (bp_hardware_watchpoint, i, other_type_used); + if (target_resources_ok <= 0) + b->type = bp_watchpoint; + } + else + b->type = bp_watchpoint; + + loc_type = (b->type == bp_watchpoint? bp_loc_other + : bp_loc_hardware_watchpoint); + for (bl = b->loc; bl; bl = bl->next) + bl->loc_type = loc_type; + } + for (v = val_chain; v; v = next) + { next = value_next (v); if (v != b->val) value_free (v); @@ -1648,15 +1557,18 @@ insert_bp_location (struct bp_location *bl, bl->loc_type = new_type; if (!said) { - fprintf_filtered (gdb_stdout, _("\ -Note: automatically using hardware breakpoints for read-only addresses.\n")); + fprintf_filtered (gdb_stdout, + _("Note: automatically using " + "hardware breakpoints for " + "read-only addresses.\n")); said = 1; } } } else if (bl->loc_type == bp_loc_software_breakpoint && mr->attrib.mode != MEM_RW) - warning (_("cannot set software breakpoint at readonly address %s"), + warning (_("cannot set software breakpoint " + "at readonly address %s"), paddress (bl->gdbarch, bl->address)); } } @@ -1698,7 +1610,8 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); &bl->overlay_target_info); if (val != 0) fprintf_unfiltered (tmp_error_stream, - "Overlay breakpoint %d failed: in ROM?\n", + "Overlay breakpoint %d " + "failed: in ROM?\n", bl->owner->number); } } @@ -1735,7 +1648,8 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); "Cannot insert breakpoint %d.\n", bl->owner->number); fprintf_unfiltered (tmp_error_stream, - "Temporarily disabling shared library breakpoints:\n"); + "Temporarily disabling shared " + "library breakpoints:\n"); } *disabled_breaks = 1; fprintf_unfiltered (tmp_error_stream, @@ -1746,8 +1660,9 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); if (bl->loc_type == bp_loc_hardware_breakpoint) { *hw_breakpoint_error = 1; - fprintf_unfiltered (tmp_error_stream, - "Cannot insert hardware breakpoint %d.\n", + fprintf_unfiltered (tmp_error_stream, + "Cannot insert hardware " + "breakpoint %d.\n", bl->owner->number); } else @@ -1776,10 +1691,10 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); watchpoints. It's not clear that it's necessary... */ && bl->owner->disposition != disp_del_at_next_stop) { - val = target_insert_watchpoint (bl->address, - bl->length, - bl->watchpoint_type, - bl->owner->cond_exp); + gdb_assert (bl->owner->ops != NULL + && bl->owner->ops->insert_location != NULL); + + val = bl->owner->ops->insert_location (bl); /* If trying to set a read-watchpoint, and it turns out it's not supported, try emulating one with an access watchpoint. */ @@ -1805,12 +1720,12 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); if (val == 1) { - val = target_insert_watchpoint (bl->address, - bl->length, - hw_access, - bl->owner->cond_exp); - if (val == 0) - bl->watchpoint_type = hw_access; + bl->watchpoint_type = hw_access; + val = bl->owner->ops->insert_location (bl); + + if (val) + /* Back to the original value. */ + bl->watchpoint_type = hw_read; } } @@ -1819,14 +1734,23 @@ Note: automatically using hardware breakpoints for read-only addresses.\n")); else if (bl->owner->type == bp_catchpoint) { - struct gdb_exception e = catch_exception (uiout, insert_catchpoint, - bl->owner, RETURN_MASK_ERROR); - exception_fprintf (gdb_stderr, e, "warning: inserting catchpoint %d: ", - bl->owner->number); - if (e.reason < 0) - bl->owner->enable_state = bp_disabled; - else - bl->inserted = 1; + gdb_assert (bl->owner->ops != NULL + && bl->owner->ops->insert_location != NULL); + + val = bl->owner->ops->insert_location (bl); + if (val) + { + bl->owner->enable_state = bp_disabled; + + if (val == 1) + warning (_("\ +Error inserting catchpoint %d: Your system does not support this type\n\ +of catchpoint."), bl->owner->number); + else + warning (_("Error inserting catchpoint %d."), bl->owner->number); + } + + bl->inserted = (val == 0); /* We've already printed an error message if there was a problem inserting this catchpoint, and we've disabled the catchpoint, @@ -2065,7 +1989,7 @@ reattach_breakpoints (int pid) struct cleanup *old_chain; struct bp_location *bl, **blp_tmp; int val; - struct ui_file *tmp_error_stream = mem_fileopen (); + struct ui_file *tmp_error_stream; int dummy1 = 0, dummy2 = 0; struct inferior *inf; struct thread_info *tp; @@ -2079,6 +2003,7 @@ reattach_breakpoints (int pid) inferior_ptid = tp->ptid; + tmp_error_stream = mem_fileopen (); make_cleanup_ui_file_delete (tmp_error_stream); ALL_BP_LOCATIONS (bl, blp_tmp) @@ -2141,22 +2066,94 @@ create_internal_breakpoint (struct gdbarch *gdbarch, return b; } +static const char *const longjmp_names[] = + { + "longjmp", "_longjmp", "siglongjmp", "_siglongjmp" + }; +#define NUM_LONGJMP_NAMES ARRAY_SIZE(longjmp_names) + +/* Per-objfile data private to breakpoint.c. */ +struct breakpoint_objfile_data +{ + /* Minimal symbol for "_ovly_debug_event" (if any). */ + struct minimal_symbol *overlay_msym; + + /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */ + struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES]; + + /* Minimal symbol for "std::terminate()" (if any). */ + struct minimal_symbol *terminate_msym; + + /* Minimal symbol for "_Unwind_DebugHook" (if any). */ + struct minimal_symbol *exception_msym; +}; + +static const struct objfile_data *breakpoint_objfile_key; + +/* Minimal symbol not found sentinel. */ +static struct minimal_symbol msym_not_found; + +/* Returns TRUE if MSYM point to the "not found" sentinel. */ + +static int +msym_not_found_p (const struct minimal_symbol *msym) +{ + return msym == &msym_not_found; +} + +/* Return per-objfile data needed by breakpoint.c. + Allocate the data if necessary. */ + +static struct breakpoint_objfile_data * +get_breakpoint_objfile_data (struct objfile *objfile) +{ + struct breakpoint_objfile_data *bp_objfile_data; + + bp_objfile_data = objfile_data (objfile, breakpoint_objfile_key); + if (bp_objfile_data == NULL) + { + bp_objfile_data = obstack_alloc (&objfile->objfile_obstack, + sizeof (*bp_objfile_data)); + + memset (bp_objfile_data, 0, sizeof (*bp_objfile_data)); + set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data); + } + return bp_objfile_data; +} + static void -create_overlay_event_breakpoint (char *func_name) +create_overlay_event_breakpoint (void) { struct objfile *objfile; + const char *const func_name = "_ovly_debug_event"; ALL_OBJFILES (objfile) { struct breakpoint *b; - struct minimal_symbol *m; + struct breakpoint_objfile_data *bp_objfile_data; + CORE_ADDR addr; - m = lookup_minimal_symbol_text (func_name, objfile); - if (m == NULL) - continue; + bp_objfile_data = get_breakpoint_objfile_data (objfile); + + if (msym_not_found_p (bp_objfile_data->overlay_msym)) + continue; + + if (bp_objfile_data->overlay_msym == NULL) + { + struct minimal_symbol *m; + + m = lookup_minimal_symbol_text (func_name, objfile); + if (m == NULL) + { + /* Avoid future lookups in this objfile. */ + bp_objfile_data->overlay_msym = &msym_not_found; + continue; + } + bp_objfile_data->overlay_msym = m; + } - b = create_internal_breakpoint (get_objfile_arch (objfile), - SYMBOL_VALUE_ADDRESS (m), + addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym); + b = create_internal_breakpoint (get_objfile_arch (objfile), addr, bp_overlay_event); b->addr_string = xstrdup (func_name); @@ -2175,70 +2172,117 @@ create_overlay_event_breakpoint (char *func_name) } static void -create_longjmp_master_breakpoint (char *func_name) +create_longjmp_master_breakpoint (void) { struct program_space *pspace; - struct objfile *objfile; struct cleanup *old_chain; old_chain = save_current_program_space (); ALL_PSPACES (pspace) - ALL_OBJFILES (objfile) + { + struct objfile *objfile; + + set_current_program_space (pspace); + + ALL_OBJFILES (objfile) { - struct breakpoint *b; - struct minimal_symbol *m; + int i; + struct gdbarch *gdbarch; + struct breakpoint_objfile_data *bp_objfile_data; - if (!gdbarch_get_longjmp_target_p (get_objfile_arch (objfile))) + gdbarch = get_objfile_arch (objfile); + if (!gdbarch_get_longjmp_target_p (gdbarch)) continue; - set_current_program_space (pspace); + bp_objfile_data = get_breakpoint_objfile_data (objfile); - m = lookup_minimal_symbol_text (func_name, objfile); - if (m == NULL) - continue; + for (i = 0; i < NUM_LONGJMP_NAMES; i++) + { + struct breakpoint *b; + const char *func_name; + CORE_ADDR addr; - b = create_internal_breakpoint (get_objfile_arch (objfile), - SYMBOL_VALUE_ADDRESS (m), - bp_longjmp_master); - b->addr_string = xstrdup (func_name); - b->enable_state = bp_disabled; + if (msym_not_found_p (bp_objfile_data->longjmp_msym[i])) + continue; + + func_name = longjmp_names[i]; + if (bp_objfile_data->longjmp_msym[i] == NULL) + { + struct minimal_symbol *m; + + m = lookup_minimal_symbol_text (func_name, objfile); + if (m == NULL) + { + /* Prevent future lookups in this objfile. */ + bp_objfile_data->longjmp_msym[i] = &msym_not_found; + continue; + } + bp_objfile_data->longjmp_msym[i] = m; + } + + addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]); + b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master); + b->addr_string = xstrdup (func_name); + b->enable_state = bp_disabled; + } } + } update_global_location_list (1); do_cleanups (old_chain); } -/* Create a master std::terminate breakpoint. The actual function - looked for is named FUNC_NAME. */ +/* Create a master std::terminate breakpoint. */ static void -create_std_terminate_master_breakpoint (const char *func_name) +create_std_terminate_master_breakpoint (void) { struct program_space *pspace; - struct objfile *objfile; 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 minimal_symbol *m; + struct breakpoint_objfile_data *bp_objfile_data; - set_current_program_space (pspace); + bp_objfile_data = get_breakpoint_objfile_data (objfile); - m = lookup_minimal_symbol (func_name, NULL, objfile); - if (m == NULL || (MSYMBOL_TYPE (m) != mst_text - && MSYMBOL_TYPE (m) != mst_file_text)) - continue; + if (msym_not_found_p (bp_objfile_data->terminate_msym)) + continue; - b = create_internal_breakpoint (get_objfile_arch (objfile), - SYMBOL_VALUE_ADDRESS (m), + if (bp_objfile_data->terminate_msym == NULL) + { + struct minimal_symbol *m; + + m = lookup_minimal_symbol (func_name, NULL, objfile); + if (m == NULL || (MSYMBOL_TYPE (m) != mst_text + && MSYMBOL_TYPE (m) != mst_file_text)) + { + /* Prevent future lookups in this objfile. */ + bp_objfile_data->terminate_msym = &msym_not_found; + continue; + } + bp_objfile_data->terminate_msym = m; + } + + addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym); + b = create_internal_breakpoint (get_objfile_arch (objfile), addr, bp_std_terminate_master); b->addr_string = xstrdup (func_name); b->enable_state = bp_disabled; } + } + update_global_location_list (1); do_cleanups (old_chain); @@ -2250,24 +2294,42 @@ void create_exception_master_breakpoint (void) { struct objfile *objfile; + const char *const func_name = "_Unwind_DebugHook"; ALL_OBJFILES (objfile) { - struct minimal_symbol *debug_hook; + struct breakpoint *b; + struct gdbarch *gdbarch; + struct breakpoint_objfile_data *bp_objfile_data; + CORE_ADDR addr; - debug_hook = lookup_minimal_symbol ("_Unwind_DebugHook", NULL, objfile); - if (debug_hook != NULL) + bp_objfile_data = get_breakpoint_objfile_data (objfile); + + if (msym_not_found_p (bp_objfile_data->exception_msym)) + continue; + + gdbarch = get_objfile_arch (objfile); + + if (bp_objfile_data->exception_msym == NULL) { - struct breakpoint *b; - CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (debug_hook); - struct gdbarch *gdbarch = get_objfile_arch (objfile); + struct minimal_symbol *debug_hook; - addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, - ¤t_target); - b = create_internal_breakpoint (gdbarch, addr, bp_exception_master); - b->addr_string = xstrdup ("_Unwind_DebugHook"); - b->enable_state = bp_disabled; + debug_hook = lookup_minimal_symbol (func_name, NULL, objfile); + if (debug_hook == NULL) + { + bp_objfile_data->exception_msym = &msym_not_found; + continue; + } + + bp_objfile_data->exception_msym = debug_hook; } + + addr = SYMBOL_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); + b->addr_string = xstrdup (func_name); + b->enable_state = bp_disabled; } update_global_location_list (1); @@ -2386,12 +2448,9 @@ update_breakpoints_after_exec (void) } } /* FIXME what about longjmp breakpoints? Re-create them here? */ - create_overlay_event_breakpoint ("_ovly_debug_event"); - create_longjmp_master_breakpoint ("longjmp"); - create_longjmp_master_breakpoint ("_longjmp"); - create_longjmp_master_breakpoint ("siglongjmp"); - create_longjmp_master_breakpoint ("_siglongjmp"); - create_std_terminate_master_breakpoint ("std::terminate()"); + create_overlay_event_breakpoint (); + create_longjmp_master_breakpoint (); + create_std_terminate_master_breakpoint (); create_exception_master_breakpoint (); } @@ -2523,10 +2582,11 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) } 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); - val = target_remove_watchpoint (bl->address, bl->length, - bl->watchpoint_type, - bl->owner->cond_exp); + bl->owner->ops->remove_location (bl); /* Failure to remove any of the hardware watchpoints comes here. */ if ((is == mark_uninserted) && (bl->inserted)) @@ -2537,11 +2597,13 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) && breakpoint_enabled (bl->owner) && !bl->duplicate) { - gdb_assert (bl->owner->ops != NULL && bl->owner->ops->remove != NULL); + gdb_assert (bl->owner->ops != NULL + && bl->owner->ops->remove_location != NULL); - val = bl->owner->ops->remove (bl->owner); + val = bl->owner->ops->remove_location (bl); if (val) return val; + bl->inserted = (is == mark_inserted); } @@ -2799,7 +2861,8 @@ breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc) inserted at PC. */ int -software_breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc) +software_breakpoint_inserted_here_p (struct address_space *aspace, + CORE_ADDR pc) { struct bp_location *bl, **blp_tmp; @@ -3246,11 +3309,6 @@ print_it_typical (bpstat bs) int bp_temp = 0; enum print_stop_action result; - /* bs->breakpoint_at can be NULL if it was a momentary breakpoint - which has since been deleted. */ - if (bs->breakpoint_at == NULL) - return PRINT_UNKNOWN; - gdb_assert (bs->bp_location_at != NULL); bl = bs->bp_location_at; @@ -3313,13 +3371,15 @@ print_it_typical (bpstat bs) case bp_std_terminate_master: /* These should never be enabled. */ - printf_filtered (_("std::terminate Master Breakpoint: gdb should not stop!\n")); + printf_filtered (_("std::terminate Master Breakpoint: " + "gdb should not stop!\n")); result = PRINT_NOTHING; break; case bp_exception_master: /* These should never be enabled. */ - printf_filtered (_("Exception Master Breakpoint: gdb should not stop!\n")); + printf_filtered (_("Exception Master Breakpoint: " + "gdb should not stop!\n")); result = PRINT_NOTHING; break; @@ -3454,10 +3514,14 @@ print_bp_stop_message (bpstat bs) { struct breakpoint *b = bs->breakpoint_at; + /* bs->breakpoint_at can be NULL if it was a momentary breakpoint + which has since been deleted. */ + if (b == NULL) + return PRINT_UNKNOWN; + /* Normal case. Call the breakpoint's print_it method, or print_it_typical. */ - /* FIXME: how breakpoint can ever be NULL here? */ - if (b != NULL && b->ops != NULL && b->ops->print_it != NULL) + if (b->ops != NULL && b->ops->print_it != NULL) return b->ops->print_it (b); else return print_it_typical (bs); @@ -3745,7 +3809,8 @@ watchpoint_check (void *p) (uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE)); ui_out_text (uiout, "\nWatchpoint "); ui_out_field_int (uiout, "wpnum", b->number); - ui_out_text (uiout, " deleted because the program has left the block in\n\ + ui_out_text (uiout, + " deleted because the program has left the block in\n\ which its expression is valid.\n"); if (b->related_breakpoint) @@ -3859,8 +3924,9 @@ bpstat_check_watchpoint (bpstat bs) if (must_check_value) { - char *message = xstrprintf ("Error evaluating expression for watchpoint %d\n", - b->number); + char *message + = xstrprintf ("Error evaluating expression for watchpoint %d\n", + b->number); struct cleanup *cleanups = make_cleanup (xfree, message); int e = catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL); @@ -4498,12 +4564,40 @@ bpstat_causes_stop (bpstat bs) +/* Compute a string of spaces suitable to indent the next line + so it starts at the position corresponding to the table column + named COL_NAME in the currently active table of UIOUT. */ + +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; +} + /* Print the LOC location out of the list of B->LOC locations. */ -static void print_breakpoint_location (struct breakpoint *b, - struct bp_location *loc, - char *wrap_indent, - struct ui_stream *stb) +static void +print_breakpoint_location (struct breakpoint *b, + struct bp_location *loc) { struct cleanup *old_chain = save_current_program_space (); @@ -4522,8 +4616,9 @@ static void print_breakpoint_location (struct breakpoint *b, ui_out_text (uiout, "in "); ui_out_field_string (uiout, "func", SYMBOL_PRINT_NAME (sym)); - ui_out_wrap_hint (uiout, wrap_indent); - ui_out_text (uiout, " at "); + 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", b->source_file); ui_out_text (uiout, ":"); @@ -4541,9 +4636,14 @@ static void print_breakpoint_location (struct breakpoint *b, } else if (loc) { + struct ui_stream *stb = ui_out_stream_new (uiout); + struct cleanup *stb_chain = make_cleanup_ui_out_stream_delete (stb); + print_address_symbolic (loc->gdbarch, loc->address, stb->stream, demangle, ""); ui_out_field_stream (uiout, "at", stb); + + do_cleanups (stb_chain); } else ui_out_field_string (uiout, "pending", b->addr_string); @@ -4607,14 +4707,10 @@ print_one_breakpoint_location (struct breakpoint *b, struct bp_location *loc, int loc_number, struct bp_location **last_loc, - int print_address_bits, int allflag) { struct command_line *l; static char bpenables[] = "nynny"; - char wrap_indent[80]; - struct ui_stream *stb = ui_out_stream_new (uiout); - struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb); struct cleanup *bkpt_chain; int header_of_multiple = 0; @@ -4676,15 +4772,6 @@ print_one_breakpoint_location (struct breakpoint *b, /* 5 and 6 */ - strcpy (wrap_indent, " "); - if (opts.addressprint) - { - if (print_address_bits <= 32) - strcat (wrap_indent, " "); - else - strcat (wrap_indent, " "); - } - if (b->ops != NULL && b->ops->print_one != NULL) { /* Although the print_one can possibly print all locations, @@ -4749,7 +4836,7 @@ print_one_breakpoint_location (struct breakpoint *b, } annotate_field (5); if (!header_of_multiple) - print_breakpoint_location (b, loc, wrap_indent, stb); + print_breakpoint_location (b, loc); if (b->loc) *last_loc = b->loc; break; @@ -4905,17 +4992,14 @@ print_one_breakpoint_location (struct breakpoint *b, } do_cleanups (bkpt_chain); - do_cleanups (old_chain); } static void print_one_breakpoint (struct breakpoint *b, struct bp_location **last_loc, - int print_address_bits, int allflag) { - print_one_breakpoint_location (b, NULL, 0, last_loc, - print_address_bits, allflag); + print_one_breakpoint_location (b, NULL, 0, last_loc, allflag); /* If this breakpoint has custom print function, it's already printed. Otherwise, print individual @@ -4928,7 +5012,7 @@ print_one_breakpoint (struct breakpoint *b, situation. Note that while hardware watchpoints have several locations - internally, that's no a property exposed to user. */ + internally, that's not a property exposed to user. */ if (b->loc && !is_hardware_watchpoint (b) && (b->loc->next || !b->loc->enabled) @@ -4937,8 +5021,7 @@ print_one_breakpoint (struct breakpoint *b, struct bp_location *loc; int n = 1; for (loc = b->loc; loc; loc = loc->next, ++n) - print_one_breakpoint_location (b, loc, n, last_loc, - print_address_bits, allflag); + print_one_breakpoint_location (b, loc, n, last_loc, allflag); } } } @@ -4982,9 +5065,7 @@ do_captured_breakpoint_query (struct ui_out *uiout, void *data) { if (args->bnum == b->number) { - int print_address_bits = breakpoint_address_bits (b); - - print_one_breakpoint (b, &dummy_loc, print_address_bits, 0); + print_one_breakpoint (b, &dummy_loc, 0); return GDB_RC_OK; } } @@ -5020,6 +5101,15 @@ user_settable_breakpoint (const struct breakpoint *b) || is_watchpoint (b)); } +/* Return true if this breakpoint was set by the user, false if it is + internal or momentary. */ + +int +user_breakpoint_p (struct breakpoint *b) +{ + return user_settable_breakpoint (b) && b->number > 0; +} + /* Print information on user settable breakpoint (watchpoint, etc) number BNUM. If BNUM is -1 print all user-settable breakpoints. If ALLFLAG is non-zero, include non-user-settable breakpoints. If @@ -5028,7 +5118,7 @@ user_settable_breakpoint (const struct breakpoint *b) breakpoints listed. */ static int -breakpoint_1 (int bnum, int allflag, +breakpoint_1 (char *args, int allflag, int (*filter) (const struct breakpoint *)) { struct breakpoint *b; @@ -5045,37 +5135,46 @@ breakpoint_1 (int bnum, int allflag, required for address fields. */ nr_printable_breakpoints = 0; ALL_BREAKPOINTS (b) - if (bnum == -1 - || bnum == b->number) - { - /* If we have a filter, only list the breakpoints it accepts. */ - if (filter && !filter (b)) - continue; - - if (allflag || (user_settable_breakpoint (b) - && b->number > 0)) - { - int addr_bit, type_len; + { + /* If we have a filter, only list the breakpoints it accepts. */ + if (filter && !filter (b)) + continue; - addr_bit = breakpoint_address_bits (b); - if (addr_bit > print_address_bits) - print_address_bits = addr_bit; + /* If we have an "args" string, it is a list of breakpoints to + accept. Skip the others. */ + 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; + } - type_len = strlen (bptype_string (b->type)); - if (type_len > print_type_col_width) - print_type_col_width = type_len; + if (allflag || user_breakpoint_p (b)) + { + int addr_bit, type_len; - nr_printable_breakpoints++; - } - } + 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, + = 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, + = make_cleanup_ui_out_table_begin_end (uiout, 5, + nr_printable_breakpoints, "BreakpointTable"); if (nr_printable_breakpoints > 0) @@ -5094,16 +5193,16 @@ breakpoint_1 (int bnum, int allflag, annotate_field (3); ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb"); /* 4 */ 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"); /* 5 */ - else - ui_out_table_header (uiout, 18, ui_left, - "addr", "Address"); /* 5 */ - } + { + if (nr_printable_breakpoints > 0) + annotate_field (4); + if (print_address_bits <= 32) + ui_out_table_header (uiout, 10, ui_left, + "addr", "Address"); /* 5 */ + else + ui_out_table_header (uiout, 18, ui_left, + "addr", "Address"); /* 5 */ + } if (nr_printable_breakpoints > 0) annotate_field (5); ui_out_table_header (uiout, 40, ui_noalign, "what", "What"); /* 6 */ @@ -5112,23 +5211,34 @@ breakpoint_1 (int bnum, int allflag, annotate_breakpoints_table (); ALL_BREAKPOINTS (b) - { - QUIT; - if (bnum == -1 - || bnum == b->number) - { - /* If we have a filter, only list the breakpoints it accepts. */ - if (filter && !filter (b)) - continue; - - /* We only print out user settable breakpoints unless the - allflag is set. */ - if (allflag || (user_settable_breakpoint (b) - && b->number > 0)) - print_one_breakpoint (b, &last_loc, print_address_bits, allflag); - } - } - + { + QUIT; + /* If we have a filter, only list the breakpoints it accepts. */ + if (filter && !filter (b)) + continue; + + /* If we have an "args" string, it is a list of breakpoints to + accept. Skip the others. */ + + if (args != NULL && *args != '\0') + { + if (allflag) /* maintenance info breakpoint */ + { + if (parse_and_eval_long (args) != b->number) + continue; + } + else /* all others */ + { + if (!number_is_in_list (args, b->number)) + continue; + } + } + /* We only print out user settable breakpoints unless the + allflag is set. */ + if (allflag || user_breakpoint_p (b)) + print_one_breakpoint (b, &last_loc, allflag); + } + do_cleanups (bkpttbl_chain); if (nr_printable_breakpoints == 0) @@ -5137,12 +5247,12 @@ breakpoint_1 (int bnum, int allflag, empty list. */ if (!filter) { - if (bnum == -1) + 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 number %d.\n", - bnum); + "No breakpoint or watchpoint matching '%s'.\n", + args); } } else @@ -5178,46 +5288,31 @@ default_collect_info (void) } static void -breakpoints_info (char *bnum_exp, int from_tty) +breakpoints_info (char *args, int from_tty) { - int bnum = -1; - - if (bnum_exp) - bnum = parse_and_eval_long (bnum_exp); - - breakpoint_1 (bnum, 0, NULL); + breakpoint_1 (args, 0, NULL); default_collect_info (); } static void -watchpoints_info (char *wpnum_exp, int from_tty) +watchpoints_info (char *args, int from_tty) { - int wpnum = -1, num_printed; - - if (wpnum_exp) - wpnum = parse_and_eval_long (wpnum_exp); - - num_printed = breakpoint_1 (wpnum, 0, is_watchpoint); + int num_printed = breakpoint_1 (args, 0, is_watchpoint); if (num_printed == 0) { - if (wpnum == -1) + if (args == NULL || *args == '\0') ui_out_message (uiout, 0, "No watchpoints.\n"); else - ui_out_message (uiout, 0, "No watchpoint number %d.\n", wpnum); + ui_out_message (uiout, 0, "No watchpoint matching '%s'.\n", args); } } static void -maintenance_info_breakpoints (char *bnum_exp, int from_tty) +maintenance_info_breakpoints (char *args, int from_tty) { - int bnum = -1; - - if (bnum_exp) - bnum = parse_and_eval_long (bnum_exp); - - breakpoint_1 (bnum, 1, NULL); + breakpoint_1 (args, 1, NULL); default_collect_info (); } @@ -5408,8 +5503,10 @@ static void breakpoint_adjustment_warning (CORE_ADDR from_addr, CORE_ADDR to_addr, int bnum, int have_bnum) { - char astr1[40]; - char astr2[40]; + /* The longest string possibly returned by hex_string_custom + is 50 chars. These must be at least that big for safety. */ + 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)); @@ -5865,6 +5962,19 @@ create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address) return b; } +/* Remove JIT code registration and unregistration breakpoint(s). */ + +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) { @@ -5962,7 +6072,8 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib) if (!disabled_shlib_breaks) { target_terminal_ours_for_output (); - warning (_("Temporarily disabling breakpoints for unloaded shared library \"%s\""), + warning (_("Temporarily disabling breakpoints " + "for unloaded shared library \"%s\""), solib->so_name); } disabled_shlib_breaks = 1; @@ -5975,17 +6086,17 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib) /* Implement the "insert" breakpoint_ops method for fork catchpoints. */ -static void -insert_catch_fork (struct breakpoint *b) +static int +insert_catch_fork (struct bp_location *bl) { - target_insert_fork_catchpoint (PIDGET (inferior_ptid)); + return target_insert_fork_catchpoint (PIDGET (inferior_ptid)); } /* Implement the "remove" breakpoint_ops method for fork catchpoints. */ static int -remove_catch_fork (struct breakpoint *b) +remove_catch_fork (struct bp_location *bl) { return target_remove_fork_catchpoint (PIDGET (inferior_ptid)); } @@ -6062,6 +6173,7 @@ static struct breakpoint_ops catch_fork_breakpoint_ops = insert_catch_fork, remove_catch_fork, breakpoint_hit_catch_fork, + NULL, /* resources_needed */ print_it_catch_fork, print_one_catch_fork, print_mention_catch_fork, @@ -6071,17 +6183,17 @@ static struct breakpoint_ops catch_fork_breakpoint_ops = /* Implement the "insert" breakpoint_ops method for vfork catchpoints. */ -static void -insert_catch_vfork (struct breakpoint *b) +static int +insert_catch_vfork (struct bp_location *bl) { - target_insert_vfork_catchpoint (PIDGET (inferior_ptid)); + return target_insert_vfork_catchpoint (PIDGET (inferior_ptid)); } /* Implement the "remove" breakpoint_ops method for vfork catchpoints. */ static int -remove_catch_vfork (struct breakpoint *b) +remove_catch_vfork (struct bp_location *bl) { return target_remove_vfork_catchpoint (PIDGET (inferior_ptid)); } @@ -6157,6 +6269,7 @@ static struct breakpoint_ops catch_vfork_breakpoint_ops = insert_catch_vfork, remove_catch_vfork, breakpoint_hit_catch_vfork, + NULL, /* resources_needed */ print_it_catch_vfork, print_one_catch_vfork, print_mention_catch_vfork, @@ -6166,20 +6279,20 @@ static struct breakpoint_ops catch_vfork_breakpoint_ops = /* Implement the "insert" breakpoint_ops method for syscall catchpoints. */ -static void -insert_catch_syscall (struct breakpoint *b) +static int +insert_catch_syscall (struct bp_location *bl) { struct inferior *inf = current_inferior (); ++inf->total_syscalls_count; - if (!b->syscalls_to_be_caught) + if (!bl->owner->syscalls_to_be_caught) ++inf->any_syscall_count; else { int i, iter; for (i = 0; - VEC_iterate (int, b->syscalls_to_be_caught, i, iter); + VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter); i++) { int elem; @@ -6187,7 +6300,8 @@ insert_catch_syscall (struct breakpoint *b) if (iter >= VEC_length (int, inf->syscalls_counts)) { int old_size = VEC_length (int, inf->syscalls_counts); - uintptr_t vec_addr_offset = old_size * ((uintptr_t) sizeof (int)); + uintptr_t vec_addr_offset + = old_size * ((uintptr_t) sizeof (int)); uintptr_t vec_addr; VEC_safe_grow (int, inf->syscalls_counts, iter + 1); vec_addr = (uintptr_t) VEC_address (int, inf->syscalls_counts) + @@ -6200,30 +6314,30 @@ insert_catch_syscall (struct breakpoint *b) } } - target_set_syscall_catchpoint (PIDGET (inferior_ptid), - inf->total_syscalls_count != 0, - inf->any_syscall_count, - VEC_length (int, inf->syscalls_counts), - VEC_address (int, inf->syscalls_counts)); + return target_set_syscall_catchpoint (PIDGET (inferior_ptid), + inf->total_syscalls_count != 0, + inf->any_syscall_count, + VEC_length (int, inf->syscalls_counts), + VEC_address (int, inf->syscalls_counts)); } /* Implement the "remove" breakpoint_ops method for syscall catchpoints. */ static int -remove_catch_syscall (struct breakpoint *b) +remove_catch_syscall (struct bp_location *bl) { struct inferior *inf = current_inferior (); --inf->total_syscalls_count; - if (!b->syscalls_to_be_caught) + if (!bl->owner->syscalls_to_be_caught) --inf->any_syscall_count; else { int i, iter; for (i = 0; - VEC_iterate (int, b->syscalls_to_be_caught, i, iter); + VEC_iterate (int, bl->owner->syscalls_to_be_caught, i, iter); i++) { int elem; @@ -6239,7 +6353,8 @@ remove_catch_syscall (struct breakpoint *b) inf->total_syscalls_count != 0, inf->any_syscall_count, VEC_length (int, inf->syscalls_counts), - VEC_address (int, inf->syscalls_counts)); + VEC_address (int, + inf->syscalls_counts)); } /* Implement the "breakpoint_hit" breakpoint_ops method for syscall @@ -6438,6 +6553,7 @@ static struct breakpoint_ops catch_syscall_breakpoint_ops = insert_catch_syscall, remove_catch_syscall, breakpoint_hit_catch_syscall, + NULL, /* resources_needed */ print_it_catch_syscall, print_one_catch_syscall, print_mention_catch_syscall, @@ -6522,14 +6638,14 @@ create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch, /* Exec catchpoints. */ -static void -insert_catch_exec (struct breakpoint *b) +static int +insert_catch_exec (struct bp_location *bl) { - target_insert_exec_catchpoint (PIDGET (inferior_ptid)); + return target_insert_exec_catchpoint (PIDGET (inferior_ptid)); } static int -remove_catch_exec (struct breakpoint *b) +remove_catch_exec (struct bp_location *bl) { return target_remove_exec_catchpoint (PIDGET (inferior_ptid)); } @@ -6591,6 +6707,7 @@ static struct breakpoint_ops catch_exec_breakpoint_ops = insert_catch_exec, remove_catch_exec, breakpoint_hit_catch_exec, + NULL, /* resources_needed */ print_it_catch_exec, print_one_catch_exec, print_mention_catch_exec, @@ -6631,20 +6748,30 @@ hw_breakpoint_used_count (void) static int hw_watchpoint_used_count (enum bptype type, int *other_type_used) { - struct breakpoint *b; int i = 0; + struct breakpoint *b; + struct bp_location *bl; *other_type_used = 0; ALL_BREAKPOINTS (b) - { - if (breakpoint_enabled (b)) - { + { + if (!breakpoint_enabled (b)) + continue; + if (b->type == type) - i++; + for (bl = b->loc; bl; bl = bl->next) + { + /* Special types of hardware watchpoints may use more than + one register. */ + if (b->ops && b->ops->resources_needed) + i += b->ops->resources_needed (bl); + else + i++; + } else if (is_hardware_watchpoint (b)) *other_type_used = 1; - } - } + } + return i; } @@ -6839,7 +6966,8 @@ mention (struct breakpoint *b) switch (b->type) { case bp_none: - printf_filtered (_("(apparently deleted?) Eventpoint %d: "), b->number); + printf_filtered (_("(apparently deleted?) Eventpoint %d: "), + b->number); break; case bp_watchpoint: ui_out_text (uiout, "Watchpoint "); @@ -7122,17 +7250,15 @@ create_breakpoint_sal (struct gdbarch *gdbarch, char *marker_str; int i; - while (*p == ' ' || *p == '\t') - p++; + p = skip_spaces (p); - endp = p; - while (*endp != ' ' && *endp != '\t' && *endp != '\0') - endp++; + endp = skip_to_space (p); marker_str = savestring (p, endp - p); b->static_trace_marker_id = marker_str; - printf_filtered (_("Probed static tracepoint marker \"%s\"\n"), + printf_filtered (_("Probed static tracepoint " + "marker \"%s\"\n"), b->static_trace_marker_id); } else if (target_static_tracepoint_marker_at (sal.pc, &marker)) @@ -7140,12 +7266,13 @@ create_breakpoint_sal (struct gdbarch *gdbarch, b->static_trace_marker_id = xstrdup (marker.str_id); release_static_tracepoint_marker (&marker); - printf_filtered (_("Probed static tracepoint marker \"%s\"\n"), + printf_filtered (_("Probed static tracepoint " + "marker \"%s\"\n"), b->static_trace_marker_id); } else - warning (_("\ -Couldn't determine the static tracepoint marker to probe")); + warning (_("Couldn't determine the static " + "tracepoint marker to probe")); } if (enabled && b->pspace->executing_startup @@ -7359,10 +7486,13 @@ create_breakpoints_sal (struct gdbarch *gdbarch, } } -/* Parse ARG which is assumed to be a SAL specification possibly +/* Parse ADDRESS which is assumed to be a SAL specification possibly followed by conditionals. On return, SALS contains an array of SAL addresses found. ADDR_STRING contains a vector of (canonical) - address strings. ARG points to the end of the SAL. */ + address strings. ADDRESS points to the end of the SAL. + + The array and the line spec strings are allocated on the heap, it is + the caller's responsibility to free them. */ static void parse_breakpoint_sals (char **address, @@ -7517,13 +7647,9 @@ find_condition_and_thread (char *tok, CORE_ADDR pc, char *cond_start = NULL; char *cond_end = NULL; - while (*tok == ' ' || *tok == '\t') - tok++; + tok = skip_spaces (tok); - end_tok = tok; - - while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') - end_tok++; + end_tok = skip_to_space (tok); toklen = end_tok - tok; @@ -7582,12 +7708,9 @@ decode_static_tracepoint_spec (char **arg_p) char *marker_str; int i; - while (*p == ' ' || *p == '\t') - p++; + p = skip_spaces (p); - endp = p; - while (*endp != ' ' && *endp != '\t' && *endp != '\0') - endp++; + endp = skip_to_space (p); marker_str = savestring (p, endp - p); old_chain = make_cleanup (xfree, marker_str); @@ -7701,7 +7824,8 @@ create_breakpoint (struct gdbarch *gdbarch, /* If pending breakpoint support is auto query and the user selects no, then simply return the error code. */ if (pending_break_support == AUTO_BOOLEAN_AUTO - && !nquery (_("Make breakpoint pending on future shared library load? "))) + && !nquery (_("Make breakpoint pending on " + "future shared library load? "))) return 0; /* At this point, either the user was queried about setting @@ -7718,6 +7842,7 @@ create_breakpoint (struct gdbarch *gdbarch, default: throw_exception (e); } + break; default: if (!sals.nelts) return 0; @@ -7836,7 +7961,8 @@ create_breakpoint (struct gdbarch *gdbarch, } else create_breakpoints_sal (gdbarch, sals, addr_string, cond_string, - type_wanted, tempflag ? disp_del : disp_donttouch, + type_wanted, + tempflag ? disp_del : disp_donttouch, thread, task, ignore_count, ops, from_tty, enabled, internal); } @@ -7874,8 +8000,8 @@ create_breakpoint (struct gdbarch *gdbarch, if (sals.nelts > 1) { - warning (_("Multiple breakpoints were set.\n" - "Use the \"delete\" command to delete unwanted breakpoints.")); + warning (_("Multiple breakpoints were set.\nUse the " + "\"delete\" command to delete unwanted breakpoints.")); prev_breakpoint_count = prev_bkpt_count; } @@ -8182,6 +8308,53 @@ watchpoint_exp_is_const (const struct expression *exp) return 1; } +/* Implement the "insert" breakpoint_ops method for hardware watchpoints. */ + +static int +insert_watchpoint (struct bp_location *bl) +{ + int length = bl->owner->exact? 1 : bl->length; + + return target_insert_watchpoint (bl->address, length, bl->watchpoint_type, + bl->owner->cond_exp); +} + +/* Implement the "remove" breakpoint_ops method for hardware watchpoints. */ + +static int +remove_watchpoint (struct bp_location *bl) +{ + int length = bl->owner->exact? 1 : bl->length; + + return target_remove_watchpoint (bl->address, length, bl->watchpoint_type, + bl->owner->cond_exp); +} + +/* Implement the "resources_needed" breakpoint_ops method for + hardware watchpoints. */ + +static int +resources_needed_watchpoint (const struct bp_location *bl) +{ + int length = bl->owner->exact? 1 : bl->length; + + return target_region_ok_for_hw_watchpoint (bl->address, length); +} + +/* The breakpoint_ops structure to be used in hardware watchpoints. */ + +static struct breakpoint_ops watchpoint_breakpoint_ops = +{ + insert_watchpoint, + remove_watchpoint, + NULL, /* breakpoint_hit */ + resources_needed_watchpoint, + NULL, /* print_it */ + NULL, /* print_one */ + NULL, /* print_mention */ + NULL /* print_recreate */ +}; + /* accessflag: hw_write: watch write, hw_read: watch read, hw_access: watch access (read or write) */ @@ -8202,7 +8375,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty, char *cond_end = NULL; int i, other_type_used, target_resources_ok = 0; enum bptype bp_type; - int mem_cnt = 0; + int reg_cnt = 0; int thread = -1; int pc = 0; @@ -8303,13 +8476,8 @@ watch_command_1 (char *arg, int accessflag, int from_tty, else if (val != NULL) release_value (val); - tok = arg; - while (*tok == ' ' || *tok == '\t') - tok++; - end_tok = tok; - - while (*end_tok != ' ' && *end_tok != '\t' && *end_tok != '\000') - end_tok++; + tok = skip_spaces (arg); + end_tok = skip_to_space (tok); toklen = end_tok - tok; if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) @@ -8337,25 +8505,26 @@ watch_command_1 (char *arg, int accessflag, int from_tty, else bp_type = bp_hardware_watchpoint; - mem_cnt = can_use_hardware_watchpoint (val); - if (mem_cnt == 0 && bp_type != bp_hardware_watchpoint) + reg_cnt = can_use_hardware_watchpoint (val, target_exact_watchpoints); + if (reg_cnt == 0 && bp_type != bp_hardware_watchpoint) error (_("Expression cannot be implemented with read/access watchpoint.")); - if (mem_cnt != 0) + if (reg_cnt != 0) { i = hw_watchpoint_used_count (bp_type, &other_type_used); target_resources_ok = - target_can_use_hardware_watchpoint (bp_type, i + mem_cnt, + target_can_use_hardware_watchpoint (bp_type, i + reg_cnt, other_type_used); if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint) error (_("Target does not support this type of hardware watchpoint.")); if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint) - error (_("Target can only support one kind of HW watchpoint at a time.")); + error (_("Target can only support one kind " + "of HW watchpoint at a time.")); } /* Change the type of breakpoint to an ordinary watchpoint if a hardware watchpoint could not be set. */ - if (!mem_cnt || target_resources_ok <= 0) + if (!reg_cnt || target_resources_ok <= 0) bp_type = bp_watchpoint; frame = block_innermost_frame (exp_valid_block); @@ -8424,6 +8593,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty, b->exp_string = savestring (exp_start, exp_end - exp_start); b->val = val; b->val_valid = 1; + b->ops = &watchpoint_breakpoint_ops; + + /* Use an exact watchpoint when there's only one memory region to be + watched, and only one debug register is needed to watch it. */ + b->exact = target_exact_watchpoints && reg_cnt == 1; + if (cond_start) b->cond_string = savestring (cond_start, cond_end - cond_start); else @@ -8463,12 +8638,15 @@ watch_command_1 (char *arg, int accessflag, int from_tty, update_global_location_list (1); } -/* Return count of locations need to be watched and can be handled in - hardware. If the watchpoint can not be handled in hardware return - zero. */ +/* Return count of debug registers needed to watch the given expression. + If EXACT_WATCHPOINTS is 1, then consider that only the address of + the start of the watched region will be monitored (i.e., all accesses + will be aligned). This uses less debug registers on some targets. + + If the watchpoint cannot be handled in hardware return zero. */ static int -can_use_hardware_watchpoint (struct value *v) +can_use_hardware_watchpoint (struct value *v, int exact_watchpoints) { int found_memory_cnt = 0; struct value *head = v; @@ -8521,12 +8699,18 @@ can_use_hardware_watchpoint (struct value *v) && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) { CORE_ADDR vaddr = value_address (v); - int len = TYPE_LENGTH (value_type (v)); + int len; + int num_regs; + + len = (exact_watchpoints + && is_scalar_type_recursive (vtype))? + 1 : TYPE_LENGTH (value_type (v)); - if (!target_region_ok_for_hw_watchpoint (vaddr, len)) + num_regs = target_region_ok_for_hw_watchpoint (vaddr, len); + if (!num_regs) return 0; else - found_memory_cnt++; + found_memory_cnt += num_regs; } } } @@ -8577,7 +8761,7 @@ watch_maybe_just_location (char *arg, int accessflag, int from_tty) && (check_for_argument (&arg, "-location", sizeof ("-location") - 1) || check_for_argument (&arg, "-l", sizeof ("-l") - 1))) { - ep_skip_leading_whitespace (&arg); + arg = skip_spaces (arg); just_location = 1; } @@ -8734,15 +8918,6 @@ until_break_command (char *arg, int from_tty, int anywhere) do_cleanups (old_chain); } -static void -ep_skip_leading_whitespace (char **s) -{ - if ((s == NULL) || (*s == NULL)) - return; - while (isspace (**s)) - *s += 1; -} - /* This function attempts to parse an optional "if " clause from the arg string. If one is not found, it returns NULL. @@ -8764,7 +8939,7 @@ ep_parse_optional_if_clause (char **arg) /* Skip any extra leading whitespace, and record the start of the condition string. */ - ep_skip_leading_whitespace (arg); + *arg = skip_spaces (*arg); cond_string = *arg; /* Assume that the condition occupies the remainder of the arg @@ -8799,7 +8974,7 @@ catch_fork_command_1 (char *arg, int from_tty, if (!arg) arg = ""; - ep_skip_leading_whitespace (&arg); + arg = skip_spaces (arg); /* The allowed syntax is: catch [v]fork @@ -8843,7 +9018,7 @@ catch_exec_command_1 (char *arg, int from_tty, if (!arg) arg = ""; - ep_skip_leading_whitespace (&arg); + arg = skip_spaces (arg); /* The allowed syntax is: catch exec @@ -8952,6 +9127,7 @@ static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = { NULL, /* insert */ NULL, /* remove */ NULL, /* breakpoint_hit */ + NULL, /* resources_needed */ print_exception_catchpoint, print_one_exception_catchpoint, print_mention_exception_catchpoint, @@ -8992,7 +9168,7 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg, if (!arg) arg = ""; - ep_skip_leading_whitespace (&arg); + arg = skip_spaces (arg); cond_string = ep_parse_optional_if_clause (&arg); @@ -9178,11 +9354,11 @@ catch_syscall_command_1 (char *arg, int from_tty, /* Checking if the feature if supported. */ if (gdbarch_get_syscall_number_p (gdbarch) == 0) error (_("The feature 'catch syscall' is not supported on \ -this architeture yet.")); +this architecture yet.")); tempflag = get_cmd_context (command) == CATCH_TEMPORARY; - ep_skip_leading_whitespace (&arg); + arg = skip_spaces (arg); /* We need to do this first "dummy" translation in order to get the syscall XML file loaded or, most important, @@ -9208,7 +9384,8 @@ this architeture yet.")); /* Implement the "catch assert" command. */ static void -catch_assert_command (char *arg, int from_tty, struct cmd_list_element *command) +catch_assert_command (char *arg, int from_tty, + struct cmd_list_element *command) { struct gdbarch *gdbarch = get_current_arch (); int tempflag; @@ -9333,7 +9510,8 @@ clear_command (char *arg, int from_tty) && b->source_file != NULL && sal.symtab != NULL && sal.pspace == loc->pspace - && strcmp (b->source_file, sal.symtab->filename) == 0 + && strcmp (b->source_file, + sal.symtab->filename) == 0 && b->line_number == sal.line); if (pc_match || line_match) { @@ -9642,7 +9820,8 @@ update_global_location_list (int should_insert) Note that at this point, old_loc->owner is still valid, as delete_breakpoint frees the breakpoint only after calling us. */ - printf_filtered (_("warning: Error removing breakpoint %d\n"), + printf_filtered (_("warning: Error removing " + "breakpoint %d\n"), old_loc->owner->number); } removed = 1; @@ -10221,7 +10400,8 @@ update_breakpoint_locations (struct breakpoint *b, } if (e.reason < 0) { - warning (_("failed to reevaluate condition for breakpoint %d: %s"), + warning (_("failed to reevaluate condition " + "for breakpoint %d: %s"), b->number, e.message); new_loc->enabled = 0; } @@ -10348,8 +10528,8 @@ breakpoint_re_set_one (void *bint) error (_("marker %s not found"), b->static_trace_marker_id); } else - sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL, - not_found_ptr); + sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, + (char ***) NULL, not_found_ptr); } if (e.reason < 0) { @@ -10520,12 +10700,9 @@ breakpoint_re_set (void) do_cleanups (old_chain); - create_overlay_event_breakpoint ("_ovly_debug_event"); - create_longjmp_master_breakpoint ("longjmp"); - create_longjmp_master_breakpoint ("_longjmp"); - create_longjmp_master_breakpoint ("siglongjmp"); - create_longjmp_master_breakpoint ("_siglongjmp"); - create_std_terminate_master_breakpoint ("std::terminate()"); + create_overlay_event_breakpoint (); + create_longjmp_master_breakpoint (); + create_std_terminate_master_breakpoint (); create_exception_master_breakpoint (); } @@ -10576,13 +10753,15 @@ set_ignore_count (int bptnum, int count, int from_tty) if (from_tty) { if (count == 0) - printf_filtered (_("Will stop next time breakpoint %d is reached."), + 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."), + printf_filtered (_("Will ignore next %d " + "crossings of breakpoint %d."), count, bptnum); } breakpoints_changed (); @@ -10593,13 +10772,6 @@ set_ignore_count (int bptnum, int count, int from_tty) error (_("No breakpoint number %d."), bptnum); } -void -make_breakpoint_silent (struct breakpoint *b) -{ - /* Silence the breakpoint. */ - b->silent = 1; -} - /* Command to set ignore-count of breakpoint N to COUNT. */ static void @@ -10632,21 +10804,23 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *, void *), void *data) { - char *p = args; - char *p1; int num; struct breakpoint *b, *tmp; int match; + struct get_number_or_range_state state; - if (p == 0) + if (args == 0) error_no_arg (_("one or more breakpoint numbers")); - while (*p) + init_number_or_range (&state, args); + + while (!state.finished) { + char *p = state.string; + match = 0; - p1 = p; - num = get_number_or_range (&p1); + num = get_number_or_range (&state); if (num == 0) { warning (_("bad breakpoint number at or near '%s'"), p); @@ -10666,7 +10840,6 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *, if (match == 0) printf_unfiltered (_("No breakpoint number %d.\n"), num); } - p = p1; } } @@ -10683,7 +10856,7 @@ find_location_by_number (char *number) *dot = '\0'; p1 = number; - bp_num = get_number_or_range (&p1); + bp_num = get_number (&p1); if (bp_num == 0) error (_("Bad breakpoint number '%s'"), number); @@ -10697,7 +10870,7 @@ find_location_by_number (char *number) error (_("Bad breakpoint number '%s'"), number); p1 = dot+1; - loc_num = get_number_or_range (&p1); + loc_num = get_number (&p1); if (loc_num == 0) error (_("Bad breakpoint location number '%s'"), number); @@ -10757,7 +10930,7 @@ disable_command (char *args, int from_tty) case bp_none: warning (_("attempted to disable apparently deleted breakpoint #%d?"), bpt->number); - continue; + break; case bp_breakpoint: case bp_tracepoint: case bp_fast_tracepoint: @@ -10769,8 +10942,9 @@ disable_command (char *args, int from_tty) case bp_read_watchpoint: case bp_access_watchpoint: disable_breakpoint (bpt); + break; default: - continue; + break; } else if (strchr (args, '.')) { @@ -10858,7 +11032,7 @@ enable_command (char *args, int from_tty) case bp_none: warning (_("attempted to enable apparently deleted breakpoint #%d?"), bpt->number); - continue; + break; case bp_breakpoint: case bp_tracepoint: case bp_fast_tracepoint: @@ -10870,8 +11044,9 @@ enable_command (char *args, int from_tty) case bp_read_watchpoint: case bp_access_watchpoint: enable_breakpoint (bpt); + break; default: - continue; + break; } else if (strchr (args, '.')) { @@ -11190,8 +11365,11 @@ catch_syscall_completer (struct cmd_list_element *cmd, char *text, char *word) { const char **list = get_syscall_names (); + char **retlist + = (list == NULL) ? NULL : complete_on_enum (list, text, word); - return (list == NULL) ? NULL : complete_on_enum (list, text, word); + xfree (list); + return retlist; } /* Tracepoint-specific operations. */ @@ -11295,7 +11473,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) address. Since there is no way to confirm that the address means the same thing as when the trace was started, warn the user. */ - warning (_("Uploaded tracepoint %d has no source location, using raw address"), + warning (_("Uploaded tracepoint %d has no " + "source location, using raw address"), utp->number); sprintf (small_buf, "*%s", hex_string (utp->addr)); addr_str = small_buf; @@ -11303,7 +11482,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) /* There's not much we can do with a sequence of bytecodes. */ if (utp->cond && !utp->cond_string) - warning (_("Uploaded tracepoint %d condition has no source form, ignoring it"), + warning (_("Uploaded tracepoint %d condition " + "has no source form, ignoring it"), utp->number); if (!create_breakpoint (get_current_arch (), @@ -11349,7 +11529,8 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) } 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"), + warning (_("Uploaded tracepoint %d actions " + "have no source form, ignoring them"), utp->number); return tp; @@ -11359,21 +11540,18 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) omitted. */ static void -tracepoints_info (char *tpnum_exp, int from_tty) +tracepoints_info (char *args, int from_tty) { - int tpnum = -1, num_printed; + int num_printed; - if (tpnum_exp) - tpnum = parse_and_eval_long (tpnum_exp); - - num_printed = breakpoint_1 (tpnum, 0, is_tracepoint); + num_printed = breakpoint_1 (args, 0, is_tracepoint); if (num_printed == 0) { - if (tpnum == -1) + if (args == NULL || *args == '\0') ui_out_message (uiout, 0, "No tracepoints.\n"); else - ui_out_message (uiout, 0, "No tracepoint number %d.\n", tpnum); + ui_out_message (uiout, 0, "No tracepoint matching '%s'.\n", args); } default_collect_info (); @@ -11436,6 +11614,18 @@ delete_trace_command (char *arg, int from_tty) map_breakpoint_numbers (arg, do_delete_breakpoint, NULL); } +/* Helper function for trace_pass_command. */ + +static void +trace_pass_set_count (struct breakpoint *bp, int count, int from_tty) +{ + bp->pass_count = count; + observer_notify_tracepoint_modified (bp->number); + if (from_tty) + printf_filtered (_("Setting tracepoint %d's passcount to %d\n"), + bp->number, count); +} + /* Set passcount for tracepoint. First command argument is passcount, second is tracepoint number. @@ -11445,12 +11635,12 @@ delete_trace_command (char *arg, int from_tty) static void trace_pass_command (char *args, int from_tty) { - struct breakpoint *t1 = (struct breakpoint *) -1, *t2; + struct breakpoint *t1; unsigned int count; - int all = 0; if (args == 0 || *args == 0) - error (_("passcount command requires an argument (count + optional TP num)")); + error (_("passcount command requires an " + "argument (count + optional TP num)")); count = strtoul (args, &args, 10); /* Count comes first, then TP num. */ @@ -11460,31 +11650,32 @@ trace_pass_command (char *args, int from_tty) if (*args && strncasecmp (args, "all", 3) == 0) { args += 3; /* Skip special argument "all". */ - all = 1; if (*args) error (_("Junk at end of arguments.")); - } - else - t1 = get_tracepoint_by_number (&args, 1, 1); - do + ALL_TRACEPOINTS (t1) + { + trace_pass_set_count (t1, count, from_tty); + } + } + else if (*args == '\0') { + t1 = get_tracepoint_by_number (&args, NULL, 1); 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) { - ALL_TRACEPOINTS (t2) - if (t1 == (struct breakpoint *) -1 || t1 == t2) - { - t2->pass_count = count; - observer_notify_tracepoint_modified (t2->number); - if (from_tty) - printf_filtered (_("Setting tracepoint %d's passcount to %d\n"), - t2->number, count); - } - if (! all && *args) - t1 = get_tracepoint_by_number (&args, 1, 0); + t1 = get_tracepoint_by_number (&args, &state, 1); + if (t1) + trace_pass_set_count (t1, count, from_tty); } } - while (*args); } struct breakpoint * @@ -11516,18 +11707,25 @@ get_tracepoint_by_number_on_target (int num) } /* Utility: parse a tracepoint number and look it up in the list. - If MULTI_P is true, there might be a range of tracepoints in ARG. - if OPTIONAL_P is true, then if the argument is missing, the most + If STATE is not NULL, use, get_number_or_range_state and ignore ARG. + If OPTIONAL_P is true, then if the argument is missing, the most recent tracepoint (tracepoint_count) is returned. */ struct breakpoint * -get_tracepoint_by_number (char **arg, int multi_p, int optional_p) +get_tracepoint_by_number (char **arg, + struct get_number_or_range_state *state, + int optional_p) { extern int tracepoint_count; struct breakpoint *t; int tpnum; char *instring = arg == NULL ? NULL : *arg; - if (arg == NULL || *arg == NULL || ! **arg) + if (state) + { + gdb_assert (!state->finished); + tpnum = get_number_or_range (state); + } + else if (arg == NULL || *arg == NULL || ! **arg) { if (optional_p) tpnum = tracepoint_count; @@ -11535,7 +11733,7 @@ get_tracepoint_by_number (char **arg, int multi_p, int optional_p) error_no_arg (_("tracepoint number")); } else - tpnum = multi_p ? get_number_or_range (arg) : get_number (arg); + tpnum = get_number (arg); if (tpnum <= 0) { @@ -11543,7 +11741,8 @@ get_tracepoint_by_number (char **arg, int multi_p, int optional_p) printf_filtered (_("bad tracepoint number at or near '%s'\n"), instring); else - printf_filtered (_("Tracepoint argument missing and no previous tracepoint\n")); + printf_filtered (_("Tracepoint argument missing " + "and no previous tracepoint\n")); return NULL; } @@ -11553,9 +11752,6 @@ get_tracepoint_by_number (char **arg, int multi_p, int optional_p) return t; } - /* FIXME: if we are in the middle of a range we don't want to give - a message. The current interface to get_number_or_range doesn't - allow us to discover this. */ printf_unfiltered ("No tracepoint number %d.\n", tpnum); return NULL; } @@ -11583,7 +11779,7 @@ save_breakpoints (char *filename, int from_tty, ALL_BREAKPOINTS (tp) { /* Skip internal and momentary breakpoints. */ - if (!user_settable_breakpoint (tp) || tp->number < 0) + if (!user_breakpoint_p (tp)) continue; /* If we have a filter, only save the breakpoints it accepts. */ @@ -11621,7 +11817,7 @@ save_breakpoints (char *filename, int from_tty, ALL_BREAKPOINTS (tp) { /* Skip internal and momentary breakpoints. */ - if (!user_settable_breakpoint (tp) || tp->number < 0) + if (!user_breakpoint_p (tp)) continue; /* If we have a filter, only save the breakpoints it accepts. */ @@ -11834,8 +12030,8 @@ clear_syscall_counts (struct inferior *inf) static void save_command (char *arg, int from_tty) { - printf_unfiltered (_("\ -\"save\" must be followed by the name of a save subcommand.\n")); + printf_unfiltered (_("\"save\" must be followed by " + "the name of a save subcommand.\n")); help_list (save_cmdlist, "save ", -1, gdb_stdout); } @@ -11863,6 +12059,8 @@ _initialize_breakpoint (void) observer_attach_inferior_exit (clear_syscall_counts); observer_attach_memory_changed (invalidate_bp_value_on_memory_change); + breakpoint_objfile_key = register_objfile_data (); + breakpoint_chain = 0; /* Don't bother to call set_breakpoint_count. $bpnum isn't useful before a breakpoint is set. */ @@ -11900,7 +12098,7 @@ BREAK_ARGS_HELP ("tbreak"))); set_cmd_completer (c, location_completer); c = add_com ("hbreak", class_breakpoint, hbreak_command, _("\ -Set a hardware assisted breakpoint.\n\ +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" @@ -12058,7 +12256,7 @@ breakpoint set.")); } add_info ("breakpoints", breakpoints_info, _("\ -Status of user-settable breakpoints, or breakpoint number NUMBER.\n\ +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\ @@ -12206,9 +12404,7 @@ the memory to which it refers.")); set_cmd_completer (c, expression_completer); add_info ("watchpoints", watchpoints_info, _("\ -Status of watchpoints, or watchpoint number NUMBER.")); - - +Status of specified watchpoints (all watchpoints if no argument).")); /* XXX: cagney/2005-02-23: This should be a boolean, and should respond to changes - contrary to the description. */ @@ -12274,7 +12470,7 @@ Do \"help tracepoints\" for info on other tracepoint commands.")); set_cmd_completer (c, location_completer); add_info ("tracepoints", tracepoints_info, _("\ -Status of tracepoints, or tracepoint number NUMBER.\n\ +Status of specified tracepoints (all tracepoints if no argument).\n\ Convenience variable \"$tpnum\" contains the number of the\n\ last tracepoint set."));