X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fbreakpoint.c;h=aead882acd885b13694af3f90e5a6fe525b6c46c;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=6b6e1f6c257cfee7f507db2ddd5c71b1768eedb3;hpb=d7154a8d08b142d1258dc2e4189ff0d00cd26493;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 6b6e1f6c25..aead882acd 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1,6 +1,6 @@ /* Everything about breakpoints, for GDB. - Copyright (C) 1986-2018 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -59,19 +59,17 @@ #include "gdb_regex.h" #include "probe.h" #include "cli/cli-utils.h" -#include "continuations.h" #include "stack.h" -#include "skip.h" #include "ax-gdb.h" #include "dummy-frame.h" #include "interps.h" -#include "format.h" +#include "gdbsupport/format.h" #include "thread-fsm.h" #include "tid-parse.h" +#include "cli/cli-style.h" /* readline include files */ -#include "readline/readline.h" -#include "readline/history.h" +#include "readline/tilde.h" /* readline defines this. */ #undef savestring @@ -80,16 +78,8 @@ #include "extension.h" #include #include "progspace-and-thread.h" -#include "common/array-view.h" -#include "common/gdb_optional.h" - -/* Enums for exception-handling support. */ -enum exception_event_kind -{ - EX_EVENT_THROW, - EX_EVENT_RETHROW, - EX_EVENT_CATCH -}; +#include "gdbsupport/array-view.h" +#include "gdbsupport/gdb_optional.h" /* Prototypes for local functions. */ @@ -154,6 +144,10 @@ static void describe_other_breakpoints (struct gdbarch *, static int watchpoint_locations_match (struct bp_location *loc1, struct bp_location *loc2); +static int breakpoint_locations_match (struct bp_location *loc1, + struct bp_location *loc2, + bool sw_hw_bps_match = false); + static int breakpoint_location_address_match (struct bp_location *bl, const struct address_space *aspace, CORE_ADDR addr); @@ -223,15 +217,13 @@ 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 void trace_pass_command (const char *, int); static void set_tracepoint_count (int num); -static int is_masked_watchpoint (const struct breakpoint *b); +static bool is_masked_watchpoint (const struct breakpoint *b); static struct bp_location **get_first_locp_gte_addr (CORE_ADDR address); @@ -258,6 +250,9 @@ struct breakpoint_ops bkpt_breakpoint_ops; /* Breakpoints set on probes. */ static struct breakpoint_ops bkpt_probe_breakpoint_ops; +/* Tracepoints set on probes. */ +static struct breakpoint_ops tracepoint_probe_breakpoint_ops; + /* Dynamic printf class type. */ struct breakpoint_ops dprintf_breakpoint_ops; @@ -298,7 +293,7 @@ static char *dprintf_channel; /* True if dprintf commands should continue to operate even if GDB has disconnected. */ -static int disconnected_dprintf = 1; +static bool disconnected_dprintf = true; struct command_line * breakpoint_commands (struct breakpoint *b) @@ -309,7 +304,7 @@ breakpoint_commands (struct breakpoint *b) /* Flag indicating that a command has proceeded the inferior past the current breakpoint. */ -static int breakpoint_proceeded; +static bool breakpoint_proceeded; const char * bpdisp_text (enum bpdisp disp) @@ -354,11 +349,11 @@ show_pending_break_support (struct ui_file *file, int from_tty, value); } -/* If 1, gdb will automatically use hardware breakpoints for breakpoints +/* If true, gdb will automatically use hardware breakpoints for breakpoints set with "break" but falling in read-only memory. - If 0, gdb will warn about such breakpoints, but won't automatically + If false, gdb will warn about such breakpoints, but won't automatically use hardware breakpoints. */ -static int automatic_hardware_breakpoints; +static bool automatic_hardware_breakpoints; static void show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty, struct cmd_list_element *c, @@ -376,7 +371,7 @@ show_automatic_hardware_breakpoints (struct ui_file *file, int from_tty, breakpoints until the next resume, and removes them again when the target fully stops. This is a bit safer in case GDB crashes while processing user input. */ -static int always_inserted_mode = 0; +static bool always_inserted_mode = false; static void show_always_inserted_mode (struct ui_file *file, int from_tty, @@ -398,10 +393,8 @@ breakpoints_should_be_inserted_now (void) no threads under GDB's control yet. */ return 1; } - else if (target_has_execution) + else { - struct thread_info *tp; - if (always_inserted_mode) { /* The user wants breakpoints inserted even if all threads @@ -409,12 +402,14 @@ breakpoints_should_be_inserted_now (void) return 1; } - if (threads_are_executing ()) - return 1; + for (inferior *inf : all_inferiors ()) + if (inf->has_execution () + && threads_are_executing (inf->process_target ())) + return 1; /* Don't remove breakpoints yet if, even though all threads are stopped, we still have events to process. */ - ALL_NON_EXITED_THREADS (tp) + for (thread_info *tp : all_non_exited_threads ()) if (tp->resumed && tp->suspend.waitstatus_pending_p) return 1; @@ -487,7 +482,7 @@ static int executing_breakpoint_commands; static int overlay_events_enabled; /* See description in breakpoint.h. */ -int target_exact_watchpoints = 0; +bool target_exact_watchpoints = false; /* Walk the following statement or block through all breakpoints. ALL_BREAKPOINTS_SAFE does so even if the statement deletes the @@ -531,9 +526,9 @@ int target_exact_watchpoints = 0; /* Chains of all breakpoints defined. */ -struct breakpoint *breakpoint_chain; +static struct breakpoint *breakpoint_chain; -/* Array is sorted by bp_locations_compare - primarily by the ADDRESS. */ +/* Array is sorted by bp_location_is_less_than - primarily by the ADDRESS. */ static struct bp_location **bp_locations; @@ -787,7 +782,7 @@ show_condition_evaluation_mode (struct ui_file *file, int from_tty, /* A comparison function for bp_location AP and BP that is used by bsearch. This comparison function only cares about addresses, unlike - the more general bp_locations_compare function. */ + the more general bp_location_is_less_than function. */ static int bp_locations_compare_addrs (const void *ap, const void *bp) @@ -880,12 +875,12 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp, { struct watchpoint *w = (struct watchpoint *) b; - innermost_block.reset (); + innermost_block_tracker tracker; arg = exp; - w->cond_exp = parse_exp_1 (&arg, 0, 0, 0); + w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker); if (*arg) error (_("Junk at end of expression")); - w->cond_exp_valid_block = innermost_block.block (); + w->cond_exp_valid_block = tracker.block (); } else { @@ -941,10 +936,7 @@ condition_completer (struct cmd_list_element *cmd, xsnprintf (number, sizeof (number), "%d", b->number); if (strncmp (number, text, len) == 0) - { - gdb::unique_xmalloc_ptr copy (xstrdup (number)); - tracker.add_completion (std::move (copy)); - } + tracker.add_completion (make_unique_xstrdup (number)); } return; @@ -1048,7 +1040,9 @@ is_longjmp_type (bptype type) return type == bp_longjmp || type == bp_exception; } -int +/* See breakpoint.h. */ + +bool is_tracepoint (const struct breakpoint *b) { return is_tracepoint_type (b->type); @@ -1219,6 +1213,10 @@ commands_command_1 (const char *arg, int from_tty, struct command_line *control) { counted_command_line cmd; + /* cmd_read will be true once we have read cmd. Note that cmd might still be + NULL after the call to read_command_lines if the user provides an empty + list of command by just typing "end". */ + bool cmd_read = false; std::string new_arg; @@ -1235,8 +1233,9 @@ commands_command_1 (const char *arg, int from_tty, map_breakpoint_numbers (arg, [&] (breakpoint *b) { - if (cmd == NULL) + if (!cmd_read) { + gdb_assert (cmd == NULL); if (control != NULL) cmd = control->body_list_0; else @@ -1256,6 +1255,7 @@ commands_command_1 (const char *arg, int from_tty, cmd = read_command_lines (str.c_str (), from_tty, 1, validator); } + cmd_read = true; } /* If a breakpoint was on the list more than once, we don't need to @@ -1498,12 +1498,9 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf, } } - - -/* Return true if BPT is either a software breakpoint or a hardware - breakpoint. */ +/* See breakpoint.h. */ -int +bool is_breakpoint (const struct breakpoint *bpt) { return (bpt->type == bp_breakpoint @@ -1513,7 +1510,7 @@ is_breakpoint (const struct breakpoint *bpt) /* Return true if BPT is of any hardware watchpoint kind. */ -static int +static bool is_hardware_watchpoint (const struct breakpoint *bpt) { return (bpt->type == bp_hardware_watchpoint @@ -1521,10 +1518,9 @@ is_hardware_watchpoint (const struct breakpoint *bpt) || bpt->type == bp_access_watchpoint); } -/* Return true if BPT is of any watchpoint kind, hardware or - software. */ +/* See breakpoint.h. */ -int +bool is_watchpoint (const struct breakpoint *bpt) { return (is_hardware_watchpoint (bpt) @@ -1609,7 +1605,7 @@ software_watchpoint_add_no_memory_location (struct breakpoint *b, /* Returns true if B is a software watchpoint that is not watching any memory (e.g., "watch $pc"). */ -static int +static bool is_no_memory_software_watchpoint (struct breakpoint *b) { return (b->type == bp_watchpoint @@ -1736,7 +1732,7 @@ update_watchpoint (struct watchpoint *b, int reparse) to the user when the old value and the new value may actually be completely different objects. */ b->val = NULL; - b->val_valid = 0; + b->val_valid = false; /* Note that unlike with breakpoints, the watchpoint's condition expression is stored in the breakpoint object, not in the @@ -1789,7 +1785,7 @@ update_watchpoint (struct watchpoint *b, int reparse) if (b->val_bitsize != 0) v = extract_bitfield_from_watchpoint_value (b, v); b->val = release_value (v); - b->val_valid = 1; + b->val_valid = true; } frame_pspace = get_frame_program_space (get_selected_frame (NULL)); @@ -1814,8 +1810,8 @@ update_watchpoint (struct watchpoint *b, int reparse) for it explicitly, never if they just happen to appear in the middle of some value chain. */ if (v == result - || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT - && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) + || (vtype->code () != TYPE_CODE_STRUCT + && vtype->code () != TYPE_CODE_ARRAY)) { CORE_ADDR addr; enum target_hw_bp_type type; @@ -2091,18 +2087,17 @@ parse_cond_to_aexpr (CORE_ADDR scope, struct expression *cond) /* We don't want to stop processing, so catch any errors that may show up. */ - TRY + try { aexpr = gen_eval_for_expr (scope, cond); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { /* If we got here, it means the condition could not be parsed to a valid bytecode expression and thus can't be evaluated on the target's side. It's no use iterating through the conditions. */ } - END_CATCH /* We have a valid agent expression. */ return aexpr; @@ -2134,10 +2129,14 @@ build_target_condition_list (struct bp_location *bl) return; /* Do a first pass to check for locations with no assigned - conditions or conditions that fail to parse to a valid agent expression - bytecode. If any of these happen, then it's no use to send conditions - to the target since this location will always trigger and generate a - response back to GDB. */ + conditions or conditions that fail to parse to a valid agent + expression bytecode. If any of these happen, then it's no use to + send conditions to the target since this location will always + trigger and generate a response back to GDB. Note we consider + all locations at the same address irrespective of type, i.e., + even if the locations aren't considered duplicates (e.g., + software breakpoint and hardware breakpoint at the same + address). */ ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address) { loc = (*loc2p); @@ -2186,8 +2185,12 @@ build_target_condition_list (struct bp_location *bl) } } - /* No NULL conditions or failed bytecode generation. Build a condition list - for this location's address. */ + /* No NULL conditions or failed bytecode generation. Build a + condition list for this location's address. If we have software + and hardware locations at the same address, they aren't + considered duplicates, but we still marge all the conditions + anyway, as it's simpler, and doesn't really make a practical + difference. */ ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address) { loc = (*loc2p); @@ -2266,19 +2269,18 @@ parse_cmd_to_aexpr (CORE_ADDR scope, char *cmd) /* We don't want to stop processing, so catch any errors that may show up. */ - TRY + try { aexpr = gen_printf (scope, gdbarch, 0, 0, format_start, format_end - format_start, argvec.size (), argvec.data ()); } - CATCH (ex, RETURN_MASK_ERROR) + catch (const gdb_exception_error &ex) { /* If we got here, it means the command could not be parsed to a valid bytecode expression and thus can't be evaluated on the target's side. It's no use iterating through the other commands. */ } - END_CATCH /* We have a valid agent expression, return it. */ return aexpr; @@ -2306,9 +2308,9 @@ build_target_command_list (struct bp_location *bl) if (dprintf_style != dprintf_style_agent) return; - /* For now, if we have any duplicate location that isn't a dprintf, - don't install the target-side commands, as that would make the - breakpoint not be reported to the core, and we'd lose + /* For now, if we have any location at the same address that isn't a + dprintf, don't install the target-side commands, as that would + make the breakpoint not be reported to the core, and we'd lose control. */ ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address) { @@ -2370,12 +2372,19 @@ build_target_command_list (struct bp_location *bl) } } - /* No NULL commands or failed bytecode generation. Build a command list - for this location's address. */ + /* No NULL commands or failed bytecode generation. Build a command + list for all duplicate locations at this location's address. + Note that here we must care for whether the breakpoint location + types are considered duplicates, otherwise, say, if we have a + software and hardware location at the same address, the target + could end up running the commands twice. For the moment, we only + support targets-side commands with dprintf, but it doesn't hurt + to be pedantically correct in case that changes. */ ALL_BP_LOCATIONS_AT_ADDR (loc2p, locp, bl->address) { loc = (*loc2p); - if (loc->owner->extra_string + if (breakpoint_locations_match (bl, loc) + && loc->owner->extra_string && is_breakpoint (loc->owner) && loc->pspace->num == bl->pspace->num && loc->owner->enable_state == bp_enabled @@ -2430,7 +2439,7 @@ insert_bp_location (struct bp_location *bl, int *hw_breakpoint_error, int *hw_bp_error_explained_already) { - gdb_exception bp_excpt = exception_none; + gdb_exception bp_excpt; if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update)) return 0; @@ -2461,79 +2470,38 @@ insert_bp_location (struct bp_location *bl, bl->needs_update = 0; } + /* If "set breakpoint auto-hw" is "on" and a software breakpoint was + set at a read-only address, then a breakpoint location will have + been changed to hardware breakpoint before we get here. If it is + "off" however, error out before actually trying to insert the + breakpoint, with a nicer error message. */ if (bl->loc_type == bp_loc_software_breakpoint - || bl->loc_type == bp_loc_hardware_breakpoint) + && !automatic_hardware_breakpoints) { - if (bl->owner->type != bp_hardware_breakpoint) - { - /* If the explicitly specified breakpoint type - is not hardware breakpoint, check the memory map to see - if the breakpoint address is in read only memory or not. - - Two important cases are: - - location type is not hardware breakpoint, memory - is readonly. We change the type of the location to - hardware breakpoint. - - location type is hardware breakpoint, memory is - read-write. This means we've previously made the - location hardware one, but then the memory map changed, - so we undo. - - When breakpoints are removed, remove_breakpoints will use - location types we've just set here, the only possible - problem is that memory map has changed during running - program, but it's not going to work anyway with current - gdb. */ - struct mem_region *mr - = lookup_mem_region (bl->target_info.reqstd_address); - - if (mr) - { - if (automatic_hardware_breakpoints) - { - enum bp_loc_type new_type; - - if (mr->attrib.mode != MEM_RW) - new_type = bp_loc_hardware_breakpoint; - else - new_type = bp_loc_software_breakpoint; - - if (new_type != bl->loc_type) - { - static int said = 0; + mem_region *mr = lookup_mem_region (bl->address); - 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 (mr != nullptr && 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 (bl->loc_type == bp_loc_software_breakpoint + || bl->loc_type == bp_loc_hardware_breakpoint) + { /* First check to see if we have to handle an overlay. */ if (overlay_debugging == ovly_off || bl->section == NULL || !(section_is_overlay (bl->section))) { /* No overlay handling: just set the breakpoint. */ - TRY + try { int val; @@ -2541,11 +2509,10 @@ insert_bp_location (struct bp_location *bl, if (val) bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR}; } - CATCH (e, RETURN_MASK_ALL) + catch (gdb_exception &e) { - bp_excpt = e; + bp_excpt = std::move (e); } - END_CATCH } else { @@ -2568,7 +2535,7 @@ insert_bp_location (struct bp_location *bl, bl->overlay_target_info.reqstd_address = addr; /* No overlay handling: just set the breakpoint. */ - TRY + try { int val; @@ -2581,11 +2548,10 @@ insert_bp_location (struct bp_location *bl, bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR}; } - CATCH (e, RETURN_MASK_ALL) + catch (gdb_exception &e) { - bp_excpt = e; + bp_excpt = std::move (e); } - END_CATCH if (bp_excpt.reason != 0) fprintf_unfiltered (tmp_error_stream, @@ -2598,7 +2564,7 @@ insert_bp_location (struct bp_location *bl, if (section_is_mapped (bl->section)) { /* Yes. This overlay section is mapped into memory. */ - TRY + try { int val; @@ -2606,11 +2572,10 @@ insert_bp_location (struct bp_location *bl, if (val) bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR}; } - CATCH (e, RETURN_MASK_ALL) + catch (gdb_exception &e) { - bp_excpt = e; + bp_excpt = std::move (e); } - END_CATCH } else { @@ -2669,7 +2634,7 @@ insert_bp_location (struct bp_location *bl, bp_excpt.message ? ":" : ".\n"); if (bp_excpt.message != NULL) fprintf_unfiltered (tmp_error_stream, "%s.\n", - bp_excpt.message); + bp_excpt.what ()); } else { @@ -2689,7 +2654,7 @@ insert_bp_location (struct bp_location *bl, fprintf_unfiltered (tmp_error_stream, "Cannot insert breakpoint %d: %s\n", bl->owner->number, - bp_excpt.message); + bp_excpt.what ()); } } return 1; @@ -2843,7 +2808,11 @@ insert_breakpoints (void) /* Updating watchpoints creates new locations, so update the global location list. Explicitly tell ugll to insert locations and - ignore breakpoints_always_inserted_mode. */ + ignore breakpoints_always_inserted_mode. Also, + update_global_location_list tries to "upgrade" software + breakpoints to hardware breakpoints to handle "set breakpoint + auto-hw", so we need to call it even if we don't have new + locations. */ update_global_location_list (UGLL_INSERT); } @@ -2892,7 +2861,7 @@ update_inserted_breakpoint_locations (void) /* We only want to update locations that are already inserted and need updating. This is to avoid unwanted insertion during deletion of breakpoints. */ - if (!bl->inserted || (bl->inserted && !bl->needs_update)) + if (!bl->inserted || !bl->needs_update) continue; switch_to_program_space_and_thread (bl->pspace); @@ -2902,7 +2871,7 @@ update_inserted_breakpoint_locations (void) if we aren't attached to any process yet, we should still insert breakpoints. */ if (!gdbarch_has_global_breakpoints (target_gdbarch ()) - && inferior_ptid == null_ptid) + && (inferior_ptid == null_ptid || !target_has_execution)) continue; val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks, @@ -2958,7 +2927,7 @@ insert_breakpoint_locations (void) if we aren't attached to any process yet, we should still insert breakpoints. */ if (!gdbarch_has_global_breakpoints (target_gdbarch ()) - && inferior_ptid == null_ptid) + && (inferior_ptid == null_ptid || !target_has_execution)) continue; val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks, @@ -3059,9 +3028,9 @@ Thread-specific breakpoint %d deleted - thread %s no longer in the thread list.\ } } -/* Remove breakpoints of inferior INF. */ +/* See breakpoint.h. */ -int +void remove_breakpoints_inf (inferior *inf) { struct bp_location *bl, **blp_tmp; @@ -3076,10 +3045,9 @@ remove_breakpoints_inf (inferior *inf) { val = remove_breakpoint (bl); if (val != 0) - return val; + return; } } - return 0; } static int internal_breakpoint_number = -1; @@ -3155,7 +3123,8 @@ struct breakpoint_objfile_data std::vector exception_probes; }; -static const struct objfile_data *breakpoint_objfile_key; +static const struct objfile_key + breakpoint_objfile_key; /* Minimal symbol not found sentinel. */ static struct minimal_symbol msym_not_found; @@ -3176,32 +3145,18 @@ get_breakpoint_objfile_data (struct objfile *objfile) { struct breakpoint_objfile_data *bp_objfile_data; - bp_objfile_data = ((struct breakpoint_objfile_data *) - objfile_data (objfile, breakpoint_objfile_key)); + bp_objfile_data = breakpoint_objfile_key.get (objfile); if (bp_objfile_data == NULL) - { - bp_objfile_data = new breakpoint_objfile_data (); - set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data); - } + bp_objfile_data = breakpoint_objfile_key.emplace (objfile); return bp_objfile_data; } -static void -free_breakpoint_objfile_data (struct objfile *obj, void *data) -{ - struct breakpoint_objfile_data *bp_objfile_data - = (struct breakpoint_objfile_data *) data; - - delete bp_objfile_data; -} - static void create_overlay_event_breakpoint (void) { - struct objfile *objfile; const char *const func_name = "_ovly_debug_event"; - ALL_OBJFILES (objfile) + for (objfile *objfile : current_program_space->objfiles ()) { struct breakpoint *b; struct breakpoint_objfile_data *bp_objfile_data; @@ -3228,7 +3183,7 @@ create_overlay_event_breakpoint (void) } addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym); - b = create_internal_breakpoint (get_objfile_arch (objfile), addr, + b = create_internal_breakpoint (objfile->arch (), addr, bp_overlay_event, &internal_breakpoint_ops); initialize_explicit_location (&explicit_loc); @@ -3251,158 +3206,151 @@ create_overlay_event_breakpoint (void) static void create_longjmp_master_breakpoint (void) { - struct program_space *pspace; - scoped_restore_current_program_space restore_pspace; - ALL_PSPACES (pspace) - { - struct objfile *objfile; - - set_current_program_space (pspace); - - ALL_OBJFILES (objfile) + for (struct program_space *pspace : program_spaces) { - int i; - struct gdbarch *gdbarch; - struct breakpoint_objfile_data *bp_objfile_data; + set_current_program_space (pspace); - gdbarch = get_objfile_arch (objfile); + for (objfile *objfile : current_program_space->objfiles ()) + { + int i; + struct gdbarch *gdbarch; + struct breakpoint_objfile_data *bp_objfile_data; - bp_objfile_data = get_breakpoint_objfile_data (objfile); + gdbarch = objfile->arch (); - if (!bp_objfile_data->longjmp_searched) - { - std::vector ret - = find_probes_in_objfile (objfile, "libc", "longjmp"); + bp_objfile_data = get_breakpoint_objfile_data (objfile); - if (!ret.empty ()) + if (!bp_objfile_data->longjmp_searched) { - /* We are only interested in checking one element. */ - probe *p = ret[0]; + std::vector ret + = find_probes_in_objfile (objfile, "libc", "longjmp"); - if (!p->can_evaluate_arguments ()) + if (!ret.empty ()) { - /* We cannot use the probe interface here, because it does - not know how to evaluate arguments. */ - ret.clear (); + /* We are only interested in checking one element. */ + probe *p = ret[0]; + + if (!p->can_evaluate_arguments ()) + { + /* We cannot use the probe interface here, + because it does not know how to evaluate + arguments. */ + ret.clear (); + } } + bp_objfile_data->longjmp_probes = ret; + bp_objfile_data->longjmp_searched = 1; } - bp_objfile_data->longjmp_probes = ret; - bp_objfile_data->longjmp_searched = 1; - } - if (!bp_objfile_data->longjmp_probes.empty ()) - { - struct gdbarch *gdbarch = get_objfile_arch (objfile); - - for (probe *p : bp_objfile_data->longjmp_probes) + if (!bp_objfile_data->longjmp_probes.empty ()) { - struct breakpoint *b; + for (probe *p : bp_objfile_data->longjmp_probes) + { + struct breakpoint *b; + + b = create_internal_breakpoint (gdbarch, + p->get_relocated_address (objfile), + bp_longjmp_master, + &internal_breakpoint_ops); + b->location = new_probe_location ("-probe-stap libc:longjmp"); + b->enable_state = bp_disabled; + } - b = create_internal_breakpoint (gdbarch, - p->get_relocated_address (objfile), - bp_longjmp_master, - &internal_breakpoint_ops); - b->location = new_probe_location ("-probe-stap libc:longjmp"); - b->enable_state = bp_disabled; + continue; } - continue; - } - - if (!gdbarch_get_longjmp_target_p (gdbarch)) - continue; - - for (i = 0; i < NUM_LONGJMP_NAMES; i++) - { - struct breakpoint *b; - const char *func_name; - CORE_ADDR addr; - struct explicit_location explicit_loc; - - if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym)) + if (!gdbarch_get_longjmp_target_p (gdbarch)) continue; - func_name = longjmp_names[i]; - if (bp_objfile_data->longjmp_msym[i].minsym == NULL) + for (i = 0; i < NUM_LONGJMP_NAMES; i++) { - struct bound_minimal_symbol m; + struct breakpoint *b; + const char *func_name; + CORE_ADDR addr; + struct explicit_location explicit_loc; + + if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym)) + continue; - m = lookup_minimal_symbol_text (func_name, objfile); - if (m.minsym == NULL) + func_name = longjmp_names[i]; + if (bp_objfile_data->longjmp_msym[i].minsym == NULL) { - /* Prevent future lookups in this objfile. */ - bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found; - continue; + struct bound_minimal_symbol m; + + m = lookup_minimal_symbol_text (func_name, objfile); + if (m.minsym == NULL) + { + /* Prevent future lookups in this objfile. */ + bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found; + continue; + } + bp_objfile_data->longjmp_msym[i] = m; } - bp_objfile_data->longjmp_msym[i] = m; - } - addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]); - b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master, - &internal_breakpoint_ops); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name = ASTRDUP (func_name); - b->location = new_explicit_location (&explicit_loc); - b->enable_state = bp_disabled; + addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]); + b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master, + &internal_breakpoint_ops); + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (func_name); + b->location = new_explicit_location (&explicit_loc); + b->enable_state = bp_disabled; + } } } - } } /* Create a master std::terminate breakpoint. */ static void create_std_terminate_master_breakpoint (void) { - struct program_space *pspace; const char *const func_name = "std::terminate()"; scoped_restore_current_program_space restore_pspace; - ALL_PSPACES (pspace) - { - struct objfile *objfile; - CORE_ADDR addr; - - set_current_program_space (pspace); - - ALL_OBJFILES (objfile) + for (struct program_space *pspace : program_spaces) { - struct breakpoint *b; - struct breakpoint_objfile_data *bp_objfile_data; - struct explicit_location explicit_loc; - - bp_objfile_data = get_breakpoint_objfile_data (objfile); + CORE_ADDR addr; - if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym)) - continue; + set_current_program_space (pspace); - if (bp_objfile_data->terminate_msym.minsym == NULL) + for (objfile *objfile : current_program_space->objfiles ()) { - struct bound_minimal_symbol m; + struct breakpoint *b; + struct breakpoint_objfile_data *bp_objfile_data; + struct explicit_location explicit_loc; + + bp_objfile_data = get_breakpoint_objfile_data (objfile); + + if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym)) + continue; - 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)) + if (bp_objfile_data->terminate_msym.minsym == NULL) { - /* Prevent future lookups in this objfile. */ - bp_objfile_data->terminate_msym.minsym = &msym_not_found; - continue; + struct bound_minimal_symbol m; + + m = lookup_minimal_symbol (func_name, NULL, objfile); + if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text + && MSYMBOL_TYPE (m.minsym) != mst_file_text)) + { + /* Prevent future lookups in this objfile. */ + bp_objfile_data->terminate_msym.minsym = &msym_not_found; + continue; + } + bp_objfile_data->terminate_msym = m; } - bp_objfile_data->terminate_msym = m; - } - addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym); - b = create_internal_breakpoint (get_objfile_arch (objfile), addr, - bp_std_terminate_master, - &internal_breakpoint_ops); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name = ASTRDUP (func_name); - b->location = new_explicit_location (&explicit_loc); - b->enable_state = bp_disabled; + addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym); + b = create_internal_breakpoint (objfile->arch (), addr, + bp_std_terminate_master, + &internal_breakpoint_ops); + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (func_name); + b->location = new_explicit_location (&explicit_loc); + b->enable_state = bp_disabled; + } } - } } /* Install a master breakpoint on the unwinder's debug hook. */ @@ -3410,10 +3358,9 @@ create_std_terminate_master_breakpoint (void) static void create_exception_master_breakpoint (void) { - struct objfile *objfile; const char *const func_name = "_Unwind_DebugHook"; - ALL_OBJFILES (objfile) + for (objfile *objfile : current_program_space->objfiles ()) { struct breakpoint *b; struct gdbarch *gdbarch; @@ -3447,12 +3394,10 @@ create_exception_master_breakpoint (void) if (!bp_objfile_data->exception_probes.empty ()) { - struct gdbarch *gdbarch = get_objfile_arch (objfile); + gdbarch = objfile->arch (); for (probe *p : bp_objfile_data->exception_probes) { - struct breakpoint *b; - b = create_internal_breakpoint (gdbarch, p->get_relocated_address (objfile), bp_exception_master, @@ -3469,7 +3414,7 @@ create_exception_master_breakpoint (void) if (msym_not_found_p (bp_objfile_data->exception_msym.minsym)) continue; - gdbarch = get_objfile_arch (objfile); + gdbarch = objfile->arch (); if (bp_objfile_data->exception_msym.minsym == NULL) { @@ -3936,7 +3881,7 @@ breakpoint_init_inferior (enum inf_context context) /* Reset val field to force reread of starting value in insert_breakpoints. */ w->val.reset (nullptr); - w->val_valid = 0; + w->val_valid = false; } } } @@ -4162,15 +4107,13 @@ hardware_watchpoint_inserted_in_range (const address_space *aspace, } return 0; } - -/* bpstat stuff. External routines' interfaces are documented - in breakpoint.h. */ +/* See breakpoint.h. */ -int -is_catchpoint (struct breakpoint *ep) +bool +is_catchpoint (struct breakpoint *b) { - return (ep->type == bp_catchpoint); + return (b->type == bp_catchpoint); } /* Frees any storage that is part of a bpstat. Does not walk the @@ -4263,7 +4206,7 @@ bpstat_find_breakpoint (bpstat bsp, struct breakpoint *breakpoint) /* See breakpoint.h. */ -int +bool bpstat_explains_signal (bpstat bsp, enum gdb_signal sig) { for (; bsp != NULL; bsp = bsp->next) @@ -4273,17 +4216,17 @@ bpstat_explains_signal (bpstat bsp, enum gdb_signal sig) /* A moribund location can never explain a signal other than GDB_SIGNAL_TRAP. */ if (sig == GDB_SIGNAL_TRAP) - return 1; + return true; } else { if (bsp->breakpoint_at->ops->explains_signal (bsp->breakpoint_at, sig)) - return 1; + return true; } } - return 0; + return false; } /* Put in *NUM the breakpoint number of the first breakpoint we are @@ -4472,7 +4415,7 @@ get_bpstat_thread () void bpstat_do_actions (void) { - struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup (); + auto cleanup_if_error = make_scope_exit (bpstat_clear_actions); thread_info *tp; /* Do any commands attached to breakpoint we are stopped at. */ @@ -4486,7 +4429,7 @@ bpstat_do_actions (void) break; } - discard_cleanups (cleanup_if_error); + cleanup_if_error.release (); } /* Print out the (old or new) value associated with a watchpoint. */ @@ -4495,7 +4438,7 @@ static void watchpoint_value_print (struct value *val, struct ui_file *stream) { if (val == NULL) - fprintf_unfiltered (stream, _("")); + fprintf_styled (stream, metadata_style.style (), _("")); else { struct value_print_options opts; @@ -4521,13 +4464,13 @@ maybe_print_thread_hit_breakpoint (struct ui_out *uiout) struct thread_info *thr = inferior_thread (); uiout->text ("Thread "); - uiout->field_fmt ("thread-id", "%s", print_thread_id (thr)); + uiout->field_string ("thread-id", print_thread_id (thr)); name = thr->name != NULL ? thr->name : target_thread_name (thr); if (name != NULL) { uiout->text (" \""); - uiout->field_fmt ("name", "%s", name); + uiout->field_string ("name", name); uiout->text ("\""); } @@ -4915,7 +4858,7 @@ watchpoint_check (bpstat bs) { bs->old_val = b->val; b->val = release_value (new_val); - b->val_valid = 1; + b->val_valid = true; if (new_val != NULL) value_free_to_mark (mark); return WP_VALUE_CHANGED; @@ -4950,10 +4893,10 @@ watchpoint_check (bpstat bs) if (uiout->is_mi_like_p ()) uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE)); - uiout->text ("\nWatchpoint "); - uiout->field_int ("wpnum", b->number); - uiout->text (" deleted because the program has left the block in\n" - "which its expression is valid.\n"); + uiout->message ("\nWatchpoint %pF deleted because the program has " + "left the block in\n" + "which its expression is valid.\n", + signed_field ("wpnum", b->number)); } /* Make sure the watchpoint's commands aren't executed. */ @@ -5020,11 +4963,11 @@ bpstat_check_watchpoint (bpstat bs) { wp_check_result e; - TRY + try { e = watchpoint_check (bs); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { exception_fprintf (gdb_stderr, ex, "Error evaluating expression " @@ -5039,7 +4982,6 @@ bpstat_check_watchpoint (bpstat bs) watchpoint_del_at_next_stop (b); e = WP_DELETED; } - END_CATCH switch (e) { @@ -5258,16 +5200,15 @@ bpstat_check_breakpoint_conditions (bpstat bs, thread_info *thread) } if (within_current_scope) { - TRY + try { condition_result = breakpoint_cond_eval (cond); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { exception_fprintf (gdb_stderr, ex, "Error in testing breakpoint condition:\n"); } - END_CATCH } else { @@ -5525,7 +5466,7 @@ bpstat_what (bpstat bs_head) retval.main_action = BPSTAT_WHAT_KEEP_CHECKING; retval.call_dummy = STOP_NONE; - retval.is_longjmp = 0; + retval.is_longjmp = false; for (bs = bs_head; bs != NULL; bs = bs->next) { @@ -5637,8 +5578,10 @@ bpstat_what (bpstat bs_head) } else { - /* There was a catchpoint, but we're not stopping. - This requires no further action. */ + /* Some catchpoints are implemented with breakpoints. + For those, we need to step over the breakpoint. */ + if (bs->bp_location_at->loc_type != bp_loc_other) + this_action = BPSTAT_WHAT_SINGLE; } break; case bp_jit_event: @@ -5719,29 +5662,29 @@ bpstat_run_callbacks (bpstat bs_head) } } -/* Nonzero if we should step constantly (e.g. watchpoints on machines - without hardware support). This isn't related to a specific bpstat, - just to things like whether watchpoints are set. */ +/* See breakpoint.h. */ -int -bpstat_should_step (void) +bool +bpstat_should_step () { struct breakpoint *b; ALL_BREAKPOINTS (b) if (breakpoint_enabled (b) && b->type == bp_watchpoint && b->loc != NULL) - return 1; - return 0; + return true; + return false; } -int +/* See breakpoint.h. */ + +bool bpstat_causes_stop (bpstat bs) { for (; bs != NULL; bs = bs->next) if (bs->stop) - return 1; + return true; - return 0; + return false; } @@ -5860,19 +5803,21 @@ print_breakpoint_location (struct breakpoint *b, if (sym) { uiout->text ("in "); - uiout->field_string ("func", SYMBOL_PRINT_NAME (sym)); + uiout->field_string ("func", sym->print_name (), + function_name_style.style ()); uiout->text (" "); uiout->wrap_hint (wrap_indent_at_field (uiout, "what")); uiout->text ("at "); } uiout->field_string ("file", - symtab_to_filename_for_display (loc->symtab)); + symtab_to_filename_for_display (loc->symtab), + file_name_style.style ()); uiout->text (":"); if (uiout->is_mi_like_p ()) uiout->field_string ("fullname", symtab_to_fullname (loc->symtab)); - uiout->field_int ("line", loc->line_number); + uiout->field_signed ("line", loc->line_number); } else if (loc) { @@ -6004,14 +5949,18 @@ output_thread_groups (struct ui_out *uiout, } } -/* Print B to gdb_stdout. */ +/* Print B to gdb_stdout. If RAW_LOC, print raw breakpoint locations + instead of going via breakpoint_ops::print_one. This makes "maint + info breakpoints" show the software breakpoint locations of + catchpoints, which are considered internal implementation + detail. */ static void print_one_breakpoint_location (struct breakpoint *b, struct bp_location *loc, int loc_number, struct bp_location **last_loc, - int allflag) + int allflag, bool raw_loc) { struct command_line *l; static char bpenables[] = "nynny"; @@ -6038,16 +5987,9 @@ print_one_breakpoint_location (struct breakpoint *b, /* 1 */ annotate_field (0); if (part_of_multiple) - { - char *formatted; - formatted = xstrprintf ("%d.%d", b->number, loc_number); - uiout->field_string ("number", formatted); - xfree (formatted); - } + uiout->field_fmt ("number", "%d.%d", b->number, loc_number); else - { - uiout->field_int ("number", b->number); - } + uiout->field_signed ("number", b->number); /* 2 */ annotate_field (1); @@ -6063,37 +6005,19 @@ print_one_breakpoint_location (struct breakpoint *b, else uiout->field_string ("disp", bpdisp_text (b->disposition)); - /* 4 */ annotate_field (3); if (part_of_multiple) uiout->field_string ("enabled", loc->enabled ? "y" : "n"); else uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]); - uiout->spaces (2); - /* 5 and 6 */ - if (b->ops != NULL && b->ops->print_one != NULL) - { - /* Although the print_one can possibly print all locations, - calling it here is not likely to get any nice result. So, - make sure there's just one location. */ - gdb_assert (b->loc == NULL || b->loc->next == NULL); - b->ops->print_one (b, last_loc); - } + if (!raw_loc && b->ops != NULL && b->ops->print_one != 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: + { + if (is_watchpoint (b)) { struct watchpoint *w = (struct watchpoint *) b; @@ -6105,63 +6029,36 @@ print_one_breakpoint_location (struct breakpoint *b, annotate_field (5); uiout->field_string ("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) - uiout->field_string ("addr", ""); - else if (b->loc == NULL || loc->shlib_disabled) - uiout->field_string ("addr", ""); - else - uiout->field_core_addr ("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; - } - + else if (!is_catchpoint (b) || is_exception_catchpoint (b) + || is_ada_exception_catchpoint (b)) + { + if (opts.addressprint) + { + annotate_field (4); + if (header_of_multiple) + uiout->field_string ("addr", "", + metadata_style.style ()); + else if (b->loc == NULL || loc->shlib_disabled) + uiout->field_string ("addr", "", + metadata_style.style ()); + else + uiout->field_core_addr ("addr", + loc->gdbarch, loc->address); + } + annotate_field (5); + if (!header_of_multiple) + print_breakpoint_location (b, loc); + if (b->loc) + *last_loc = b->loc; + } + } if (loc != NULL && !header_of_multiple) { - struct inferior *inf; std::vector inf_nums; int mi_only = 1; - ALL_INFERIORS (inf) + for (inferior *inf : all_inferiors ()) { if (inf->pspace == loc->pspace) inf_nums.push_back (inf->num); @@ -6171,7 +6068,7 @@ print_one_breakpoint_location (struct breakpoint *b, there are several. Always display for MI. */ if (allflag || (!gdbarch_has_global_breakpoints (target_gdbarch ()) - && (number_of_program_spaces () > 1 + && (program_spaces.size () > 1 || number_of_inferiors () > 1) /* LOC is for existing B, it cannot be in moribund_locations and thus having NULL OWNER. */ @@ -6187,12 +6084,12 @@ print_one_breakpoint_location (struct breakpoint *b, /* FIXME: This seems to be redundant and lost here; see the "stop only in" line a little further down. */ uiout->text (" thread "); - uiout->field_int ("thread", b->thread); + uiout->field_signed ("thread", b->thread); } else if (b->task != 0) { uiout->text (" task "); - uiout->field_int ("task", b->task); + uiout->field_signed ("task", b->task); } } @@ -6227,10 +6124,9 @@ print_one_breakpoint_location (struct breakpoint *b, && breakpoint_condition_evaluation_mode () == condition_evaluation_target) { - uiout->text (" ("); - uiout->field_string ("evaluated-by", - bp_condition_evaluator (b)); - uiout->text (" evals)"); + uiout->message (" (%pF evals)", + string_field ("evaluated-by", + bp_condition_evaluator (b))); } uiout->text ("\n"); } @@ -6240,7 +6136,7 @@ print_one_breakpoint_location (struct breakpoint *b, /* FIXME should make an annotation for this. */ uiout->text ("\tstop only in thread "); if (uiout->is_mi_like_p ()) - uiout->field_int ("thread", b->thread); + uiout->field_signed ("thread", b->thread); else { struct thread_info *thr = find_thread_global_id (b->thread); @@ -6262,7 +6158,7 @@ print_one_breakpoint_location (struct breakpoint *b, else uiout->text ("\tbreakpoint"); uiout->text (" already hit "); - uiout->field_int ("times", b->hit_count); + uiout->field_signed ("times", b->hit_count); if (b->hit_count == 1) uiout->text (" time\n"); else @@ -6272,16 +6168,15 @@ print_one_breakpoint_location (struct breakpoint *b, { /* Output the count also if it is zero, but only if this is mi. */ if (uiout->is_mi_like_p ()) - uiout->field_int ("times", b->hit_count); + uiout->field_signed ("times", b->hit_count); } } if (!part_of_multiple && b->ignore_count) { annotate_field (8); - uiout->text ("\tignore next "); - uiout->field_int ("ignore", b->ignore_count); - uiout->text (" hits\n"); + uiout->message ("\tignore next %pF hits\n", + signed_field ("ignore", b->ignore_count)); } /* Note that an enable count of 1 corresponds to "enable once" @@ -6297,7 +6192,7 @@ print_one_breakpoint_location (struct breakpoint *b, uiout->text ("additional "); else uiout->text ("next "); - uiout->field_int ("enable", b->enable_count); + uiout->field_signed ("enable", b->enable_count); uiout->text (" hits\n"); } @@ -6308,7 +6203,7 @@ print_one_breakpoint_location (struct breakpoint *b, if (tp->traceframe_usage) { uiout->text ("\ttrace buffer usage "); - uiout->field_int ("traceframe-usage", tp->traceframe_usage); + uiout->field_signed ("traceframe-usage", tp->traceframe_usage); uiout->text (" bytes\n"); } } @@ -6329,7 +6224,7 @@ print_one_breakpoint_location (struct breakpoint *b, { annotate_field (10); uiout->text ("\tpass count "); - uiout->field_int ("pass", t->pass_count); + uiout->field_signed ("pass", t->pass_count); uiout->text (" \n"); } @@ -6368,23 +6263,34 @@ print_one_breakpoint_location (struct breakpoint *b, } } +/* See breakpoint.h. */ + +bool fix_multi_location_breakpoint_output_globally = false; + static void print_one_breakpoint (struct breakpoint *b, struct bp_location **last_loc, int allflag) { struct ui_out *uiout = current_uiout; + bool use_fixed_output + = (uiout->test_flags (fix_multi_location_breakpoint_output) + || fix_multi_location_breakpoint_output_globally); - { - ui_out_emit_tuple tuple_emitter (uiout, "bkpt"); + gdb::optional bkpt_tuple_emitter (gdb::in_place, uiout, "bkpt"); + print_one_breakpoint_location (b, NULL, 0, last_loc, allflag, false); - print_one_breakpoint_location (b, NULL, 0, last_loc, allflag); - } + /* The mi2 broken format: the main breakpoint tuple ends here, the locations + are outside. */ + if (!use_fixed_output) + bkpt_tuple_emitter.reset (); /* If this breakpoint has custom print function, it's already printed. Otherwise, print individual locations, if any. */ - if (b->ops == NULL || b->ops->print_one == NULL) + if (b->ops == NULL + || b->ops->print_one == NULL + || allflag) { /* If breakpoint has a single location that is disabled, we print it as if it had several locations, since otherwise it's @@ -6392,18 +6298,32 @@ print_one_breakpoint (struct breakpoint *b, situation. Note that while hardware watchpoints have several locations - internally, that's not a property exposed to user. */ - if (b->loc - && !is_hardware_watchpoint (b) - && (b->loc->next || !b->loc->enabled)) - { - struct bp_location *loc; - int n = 1; + internally, that's not a property exposed to users. + + Likewise, while catchpoints may be implemented with + breakpoints (e.g., catch throw), that's not a property + exposed to users. We do however display the internal + breakpoint locations with "maint info breakpoints". */ + if (!is_hardware_watchpoint (b) + && (!is_catchpoint (b) || is_exception_catchpoint (b) + || is_ada_exception_catchpoint (b)) + && (allflag + || (b->loc && (b->loc->next || !b->loc->enabled)))) + { + gdb::optional locations_list; + + /* For MI version <= 2, keep the behavior where GDB outputs an invalid + MI record. For later versions, place breakpoint locations in a + list. */ + if (uiout->is_mi_like_p () && use_fixed_output) + locations_list.emplace (uiout, "locations"); - for (loc = b->loc; loc; loc = loc->next, ++n) + int n = 1; + for (bp_location *loc = b->loc; loc != NULL; loc = loc->next, ++n) { - ui_out_emit_tuple tuple_emitter (uiout, NULL); - print_one_breakpoint_location (b, loc, n, last_loc, allflag); + ui_out_emit_tuple loc_tuple_emitter (uiout, NULL); + print_one_breakpoint_location (b, loc, n, last_loc, + allflag, allflag); } } } @@ -6458,16 +6378,22 @@ pending_breakpoint_p (struct breakpoint *b) return b->loc == NULL; } -/* 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 - FILTER is non-NULL, call it on each breakpoint and only include the - ones for which it returns non-zero. Return the total number of - breakpoints listed. */ +/* Print information on breakpoints (including watchpoints and tracepoints). + + If non-NULL, BP_NUM_LIST is a list of numbers and number ranges as + understood by number_or_range_parser. Only breakpoints included in this + list are then printed. + + If SHOW_INTERNAL is true, print internal breakpoints. + + If FILTER is non-NULL, call it on each breakpoint and only include the + ones for which it returns true. + + Return the total number of breakpoints listed. */ static int -breakpoint_1 (const char *args, int allflag, - int (*filter) (const struct breakpoint *)) +breakpoint_1 (const char *bp_num_list, bool show_internal, + bool (*filter) (const struct breakpoint *)) { struct breakpoint *b; struct bp_location *last_loc = NULL; @@ -6488,17 +6414,17 @@ breakpoint_1 (const char *args, int allflag, if (filter && !filter (b)) continue; - /* If we have an "args" string, it is a list of breakpoints to + /* If we have a BP_NUM_LIST string, it is a list of breakpoints to accept. Skip the others. */ - if (args != NULL && *args != '\0') + if (bp_num_list != NULL && *bp_num_list != '\0') { - if (allflag && parse_and_eval_long (args) != b->number) + if (show_internal && parse_and_eval_long (bp_num_list) != b->number) continue; - if (!allflag && !number_is_in_list (args, b->number)) + if (!show_internal && !number_is_in_list (bp_num_list, b->number)) continue; } - if (allflag || user_breakpoint_p (b)) + if (show_internal || user_breakpoint_p (b)) { int addr_bit, type_len; @@ -6557,26 +6483,26 @@ breakpoint_1 (const char *args, int allflag, if (filter && !filter (b)) continue; - /* If we have an "args" string, it is a list of breakpoints to + /* If we have a BP_NUM_LIST string, it is a list of breakpoints to accept. Skip the others. */ - if (args != NULL && *args != '\0') + if (bp_num_list != NULL && *bp_num_list != '\0') { - if (allflag) /* maintenance info breakpoint */ + if (show_internal) /* maintenance info breakpoint */ { - if (parse_and_eval_long (args) != b->number) + if (parse_and_eval_long (bp_num_list) != b->number) continue; } else /* all others */ { - if (!number_is_in_list (args, b->number)) + if (!number_is_in_list (bp_num_list, 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); + show_internal is set. */ + if (show_internal || user_breakpoint_p (b)) + print_one_breakpoint (b, &last_loc, show_internal); } } @@ -6586,11 +6512,11 @@ breakpoint_1 (const char *args, int allflag, empty list. */ if (!filter) { - if (args == NULL || *args == '\0') + if (bp_num_list == NULL || *bp_num_list == '\0') uiout->message ("No breakpoints or watchpoints.\n"); else uiout->message ("No breakpoint or watchpoint matching '%s'.\n", - args); + bp_num_list); } } else @@ -6630,7 +6556,7 @@ default_collect_info (void) static void info_breakpoints_command (const char *args, int from_tty) { - breakpoint_1 (args, 0, NULL); + breakpoint_1 (args, false, NULL); default_collect_info (); } @@ -6638,7 +6564,7 @@ info_breakpoints_command (const char *args, int from_tty) static void info_watchpoints_command (const char *args, int from_tty) { - int num_printed = breakpoint_1 (args, 0, is_watchpoint); + int num_printed = breakpoint_1 (args, false, is_watchpoint); struct ui_out *uiout = current_uiout; if (num_printed == 0) @@ -6653,7 +6579,7 @@ info_watchpoints_command (const char *args, int from_tty) static void maintenance_info_breakpoints (const char *args, int from_tty) { - breakpoint_1 (args, 1, NULL); + breakpoint_1 (args, true, NULL); default_collect_info (); } @@ -6713,34 +6639,28 @@ describe_other_breakpoints (struct gdbarch *gdbarch, (others > 1) ? "," : ((others == 1) ? " and" : "")); } - printf_filtered (_("also set at pc ")); - fputs_filtered (paddress (gdbarch, pc), gdb_stdout); - printf_filtered (".\n"); + current_uiout->message (_("also set at pc %ps.\n"), + styled_string (address_style.style (), + paddress (gdbarch, pc))); } } -/* Return true iff it is meaningful to use the address member of - BPT locations. For some breakpoint types, the locations' address members - are irrelevant and it makes no sense to attempt to compare them to other - addresses (or use them for any other purpose either). - - More specifically, each of the following breakpoint types will - always have a zero valued location address and we don't want to mark - breakpoints of any of these types to be a duplicate of an actual - breakpoint location at address zero: - - bp_watchpoint - bp_catchpoint +/* Return true iff it is meaningful to use the address member of LOC. + For some breakpoint types, the locations' address members are + irrelevant and it makes no sense to attempt to compare them to + other addresses (or use them for any other purpose either). -*/ + More specifically, software watchpoints and catchpoints that are + not backed by breakpoints always have a zero valued location + address and we don't want to mark breakpoints of any of these types + to be a duplicate of an actual breakpoint location at address + zero. */ -static int -breakpoint_address_is_meaningful (struct breakpoint *bpt) +static bool +bl_address_is_meaningful (bp_location *loc) { - enum bptype type = bpt->type; - - return (type != bp_watchpoint && type != bp_catchpoint); + return loc->loc_type != bp_loc_other; } /* Assuming LOC1 and LOC2's owners are hardware watchpoints, returns @@ -6872,12 +6792,15 @@ tracepoint_locations_match (struct bp_location *loc1, } /* Assuming LOC1 and LOC2's types' have meaningful target addresses - (breakpoint_address_is_meaningful), returns true if LOC1 and LOC2 - represent the same location. */ + (bl_address_is_meaningful), returns true if LOC1 and LOC2 represent + the same location. If SW_HW_BPS_MATCH is true, then software + breakpoint locations and hardware breakpoint locations match, + otherwise they don't. */ static int -breakpoint_locations_match (struct bp_location *loc1, - struct bp_location *loc2) +breakpoint_locations_match (struct bp_location *loc1, + struct bp_location *loc2, + bool sw_hw_bps_match) { int hw_point1, hw_point2; @@ -6895,9 +6818,12 @@ breakpoint_locations_match (struct bp_location *loc1, else if (is_tracepoint (loc1->owner) || is_tracepoint (loc2->owner)) return tracepoint_locations_match (loc1, loc2); else - /* We compare bp_location.length in order to cover ranged breakpoints. */ + /* We compare bp_location.length in order to cover ranged + breakpoints. Keep this in sync with + bp_location_is_less_than. */ return (breakpoint_address_match (loc1->pspace->aspace, loc1->address, loc2->pspace->aspace, loc2->address) + && (loc1->loc_type == loc2->loc_type || sw_hw_bps_match) && loc1->length == loc2->length); } @@ -6971,19 +6897,10 @@ adjust_breakpoint_address (struct gdbarch *gdbarch, } } -bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner) +static bp_loc_type +bp_location_from_bp_type (bptype type) { - bp_location *loc = this; - - gdb_assert (ops != NULL); - - loc->ops = ops; - loc->owner = owner; - loc->cond_bytecode = NULL; - loc->shlib_disabled = 0; - loc->enabled = 1; - - switch (owner->type) + switch (type) { case bp_breakpoint: case bp_single_step: @@ -7009,30 +6926,44 @@ bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner) 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; + return bp_loc_software_breakpoint; case bp_hardware_breakpoint: - loc->loc_type = bp_loc_hardware_breakpoint; - mark_breakpoint_location_modified (loc); - break; + return bp_loc_hardware_breakpoint; case bp_hardware_watchpoint: case bp_read_watchpoint: case bp_access_watchpoint: - loc->loc_type = bp_loc_hardware_watchpoint; - break; + return bp_loc_hardware_watchpoint; case bp_watchpoint: case bp_catchpoint: case bp_tracepoint: case bp_fast_tracepoint: case bp_static_tracepoint: - loc->loc_type = bp_loc_other; - break; + return bp_loc_other; default: internal_error (__FILE__, __LINE__, _("unknown breakpoint type")); } +} + +bp_location::bp_location (breakpoint *owner, bp_loc_type type) +{ + this->owner = owner; + this->cond_bytecode = NULL; + this->shlib_disabled = 0; + this->enabled = 1; - loc->refc = 1; + this->loc_type = type; + + if (this->loc_type == bp_loc_software_breakpoint + || this->loc_type == bp_loc_hardware_breakpoint) + mark_breakpoint_location_modified (this); + + this->refc = 1; +} + +bp_location::bp_location (breakpoint *owner) + : bp_location::bp_location (owner, + bp_location_from_bp_type (owner->type)) +{ } /* Allocate a struct bp_location. */ @@ -7046,7 +6977,6 @@ allocate_bp_location (struct breakpoint *bpt) static void free_bp_location (struct bp_location *loc) { - loc->ops->dtor (loc); delete loc; } @@ -7127,12 +7057,10 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch, return add_to_breakpoint_chain (std::move (b)); } -/* Initialize loc->function_name. EXPLICIT_LOC says no indirect function - resolutions should be made as the user specified the location explicitly - enough. */ +/* Initialize loc->function_name. */ static void -set_breakpoint_location_function (struct bp_location *loc, int explicit_loc) +set_breakpoint_location_function (struct bp_location *loc) { gdb_assert (loc->owner != NULL); @@ -7144,12 +7072,11 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc) if (loc->msymbol != NULL && (MSYMBOL_TYPE (loc->msymbol) == mst_text_gnu_ifunc - || MSYMBOL_TYPE (loc->msymbol) == mst_data_gnu_ifunc) - && !explicit_loc) + || MSYMBOL_TYPE (loc->msymbol) == mst_data_gnu_ifunc)) { struct breakpoint *b = loc->owner; - function_name = MSYMBOL_LINKAGE_NAME (loc->msymbol); + function_name = loc->msymbol->linkage_name (); if (b->type == bp_breakpoint && b->loc == loc && loc->next == NULL && b->related_breakpoint == b) @@ -7175,9 +7102,9 @@ struct gdbarch * get_sal_arch (struct symtab_and_line sal) { if (sal.section) - return get_objfile_arch (sal.section->objfile); + return sal.section->objfile->arch (); if (sal.symtab) - return get_objfile_arch (SYMTAB_OBJFILE (sal.symtab)); + return SYMTAB_OBJFILE (sal.symtab)->arch (); return NULL; } @@ -7749,9 +7676,9 @@ print_it_catch_fork (bpstat bs) uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_FORK)); uiout->field_string ("disp", bpdisp_text (b->disposition)); } - uiout->field_int ("bkptno", b->number); + uiout->field_signed ("bkptno", b->number); uiout->text (" (forked process "); - uiout->field_int ("newpid", c->forked_inferior_pid.pid ()); + uiout->field_signed ("newpid", c->forked_inferior_pid.pid ()); uiout->text ("), "); return PRINT_SRC_AND_LOC; } @@ -7778,7 +7705,7 @@ print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc) if (c->forked_inferior_pid != null_ptid) { uiout->text (", process "); - uiout->field_int ("what", c->forked_inferior_pid.pid ()); + uiout->field_signed ("what", c->forked_inferior_pid.pid ()); uiout->spaces (1); } @@ -7865,9 +7792,9 @@ print_it_catch_vfork (bpstat bs) uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_VFORK)); uiout->field_string ("disp", bpdisp_text (b->disposition)); } - uiout->field_int ("bkptno", b->number); + uiout->field_signed ("bkptno", b->number); uiout->text (" (vforked process "); - uiout->field_int ("newpid", c->forked_inferior_pid.pid ()); + uiout->field_signed ("newpid", c->forked_inferior_pid.pid ()); uiout->text ("), "); return PRINT_SRC_AND_LOC; } @@ -7893,7 +7820,7 @@ print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc) if (c->forked_inferior_pid != null_ptid) { uiout->text (", process "); - uiout->field_int ("what", c->forked_inferior_pid.pid ()); + uiout->field_signed ("what", c->forked_inferior_pid.pid ()); uiout->spaces (1); } @@ -8034,7 +7961,7 @@ print_it_catch_solib (bpstat bs) uiout->text ("Temporary catchpoint "); else uiout->text ("Catchpoint "); - uiout->field_int ("bkptno", b->number); + uiout->field_signed ("bkptno", b->number); uiout->text ("\n"); if (uiout->is_mi_like_p ()) uiout->field_string ("disp", bpdisp_text (b->disposition)); @@ -8048,7 +7975,6 @@ 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); /* Field 4, the address, is omitted (which makes the columns not @@ -8060,23 +7986,23 @@ print_one_catch_solib (struct breakpoint *b, struct bp_location **locs) uiout->field_skip ("addr"); } + std::string msg; annotate_field (5); if (self->is_load) { if (self->regex) - msg = xstrprintf (_("load of library matching %s"), self->regex); + msg = string_printf (_("load of library matching %s"), self->regex); else - msg = xstrdup (_("load of library")); + msg = _("load of library"); } else { if (self->regex) - msg = xstrprintf (_("unload of library matching %s"), self->regex); + msg = string_printf (_("unload of library matching %s"), self->regex); else - msg = xstrdup (_("unload of library")); + msg = _("unload of library"); } uiout->field_string ("what", msg); - xfree (msg); if (uiout->is_mi_like_p ()) uiout->field_string ("catch-type", self->is_load ? "load" : "unload"); @@ -8285,7 +8211,7 @@ print_it_catch_exec (bpstat bs) uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXEC)); uiout->field_string ("disp", bpdisp_text (b->disposition)); } - uiout->field_int ("bkptno", b->number); + uiout->field_signed ("bkptno", b->number); uiout->text (" (exec'd "); uiout->field_string ("new-exec", c->exec_pathname); uiout->text ("), "); @@ -8514,7 +8440,7 @@ momentary_breakpoint_from_master (struct breakpoint *orig, copy = set_raw_breakpoint_without_location (orig->gdbarch, type, ops); copy->loc = allocate_bp_location (copy); - set_breakpoint_location_function (copy->loc, 1); + set_breakpoint_location_function (copy->loc); copy->loc->gdbarch = orig->loc->gdbarch; copy->loc->requested_address = orig->loc->requested_address; @@ -8575,7 +8501,62 @@ mention (struct breakpoint *b) } -static int bp_loc_is_permanent (struct bp_location *loc); +static bool bp_loc_is_permanent (struct bp_location *loc); + +/* Handle "set breakpoint auto-hw on". + + If the explicitly specified breakpoint type is not hardware + breakpoint, check the memory map to see whether the breakpoint + address is in read-only memory. + + - location type is not hardware breakpoint, memory is read-only. + We change the type of the location to hardware breakpoint. + + - location type is hardware breakpoint, memory is read-write. This + means we've previously made the location hardware one, but then the + memory map changed, so we undo. +*/ + +static void +handle_automatic_hardware_breakpoints (bp_location *bl) +{ + if (automatic_hardware_breakpoints + && bl->owner->type != bp_hardware_breakpoint + && (bl->loc_type == bp_loc_software_breakpoint + || bl->loc_type == bp_loc_hardware_breakpoint)) + { + /* When breakpoints are removed, remove_breakpoints will use + location types we've just set here, the only possible problem + is that memory map has changed during running program, but + it's not going to work anyway with current gdb. */ + mem_region *mr = lookup_mem_region (bl->address); + + if (mr != nullptr) + { + 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 bool said = false; + + bl->loc_type = new_type; + if (!said) + { + fprintf_filtered (gdb_stdout, + _("Note: automatically using " + "hardware breakpoints for " + "read-only addresses.\n")); + said = true; + } + } + } + } +} static struct bp_location * add_location_to_breakpoint (struct breakpoint *b, @@ -8619,8 +8600,7 @@ add_location_to_breakpoint (struct breakpoint *b, loc->msymbol = sal->msymbol; loc->objfile = sal->objfile; - set_breakpoint_location_function (loc, - sal->explicit_pc || sal->explicit_line); + set_breakpoint_location_function (loc); /* While by definition, permanent breakpoints are already present in the code, we don't mark the location as inserted. Normally one would expect @@ -8642,56 +8622,25 @@ add_location_to_breakpoint (struct breakpoint *b, } -/* See breakpoint.h. */ - -int -program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address) -{ - int len; - CORE_ADDR addr; - const gdb_byte *bpoint; - gdb_byte *target_mem; - - addr = address; - bpoint = gdbarch_breakpoint_from_pc (gdbarch, &addr, &len); - - /* Software breakpoints unsupported? */ - if (bpoint == NULL) - return 0; - - target_mem = (gdb_byte *) alloca (len); - - /* Enable the automatic memory restoration from breakpoints while - we read the memory. Otherwise we could say about our temporary - breakpoints they are permanent. */ - scoped_restore restore_memory - = make_scoped_restore_show_memory_breakpoints (0); - - if (target_read_memory (address, target_mem, len) == 0 - && memcmp (target_mem, bpoint, len) == 0) - return 1; - - return 0; -} - -/* Return 1 if LOC is pointing to a permanent breakpoint, - return 0 otherwise. */ +/* Return true if LOC is pointing to a permanent breakpoint, + return false otherwise. */ -static int +static bool bp_loc_is_permanent (struct bp_location *loc) { gdb_assert (loc != NULL); - /* If we have a catchpoint or a watchpoint, just return 0. We should not - attempt to read from the addresses the locations of these breakpoint types - point to. program_breakpoint_here_p, below, will attempt to read + /* If we have a non-breakpoint-backed catchpoint or a software + watchpoint, just return 0. We should not attempt to read from + the addresses the locations of these breakpoint types point to. + gdbarch_program_breakpoint_here_p, below, will attempt to read memory. */ - if (!breakpoint_address_is_meaningful (loc->owner)) - return 0; + if (!bl_address_is_meaningful (loc)) + return false; scoped_restore_current_pspace_and_thread restore_pspace_thread; switch_to_program_space_and_thread (loc->pspace); - return program_breakpoint_here_p (loc->gdbarch, loc->address); + return gdbarch_program_breakpoint_here_p (loc->gdbarch, loc->address); } /* Build a command list for the dprintf corresponding to the current @@ -8911,7 +8860,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch, b->location = std::move (location); else b->location = new_address_location (b->loc->address, NULL, 0); - b->filter = filter.release (); + b->filter = std::move (filter); } static void @@ -9228,6 +9177,41 @@ decode_static_tracepoint_spec (const char **arg_p) return sals; } +/* Returns the breakpoint ops appropriate for use with with LOCATION_TYPE and + according to IS_TRACEPOINT. */ + +static const struct breakpoint_ops * +breakpoint_ops_for_event_location_type (enum event_location_type location_type, + bool is_tracepoint) +{ + if (is_tracepoint) + { + if (location_type == PROBE_LOCATION) + return &tracepoint_probe_breakpoint_ops; + else + return &tracepoint_breakpoint_ops; + } + else + { + if (location_type == PROBE_LOCATION) + return &bkpt_probe_breakpoint_ops; + else + return &bkpt_breakpoint_ops; + } +} + +/* See breakpoint.h. */ + +const struct breakpoint_ops * +breakpoint_ops_for_event_location (const struct event_location *location, + bool is_tracepoint) +{ + if (location != nullptr) + return breakpoint_ops_for_event_location_type + (event_location_type (location), is_tracepoint); + return is_tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops; +} + /* See breakpoint.h. */ int @@ -9244,7 +9228,6 @@ create_breakpoint (struct gdbarch *gdbarch, unsigned flags) { struct linespec_result canonical; - struct cleanup *bkpt_chain = NULL; int pending = 0; int task = 0; int prev_bkpt_count = breakpoint_count; @@ -9255,11 +9238,11 @@ create_breakpoint (struct gdbarch *gdbarch, if (extra_string != NULL && *extra_string == '\0') extra_string = NULL; - TRY + try { ops->create_sals_from_location (location, &canonical, type_wanted); } - CATCH (e, RETURN_MASK_ERROR) + catch (const gdb_exception_error &e) { /* If caller is interested in rc value from parse, set value. */ @@ -9269,7 +9252,7 @@ create_breakpoint (struct gdbarch *gdbarch, error. */ if (pending_break_support == AUTO_BOOLEAN_FALSE) - throw_exception (e); + throw; exception_print (gdb_stderr, e); @@ -9287,19 +9270,12 @@ create_breakpoint (struct gdbarch *gdbarch, pending = 1; } else - throw_exception (e); + throw; } - END_CATCH if (!pending && canonical.lsals.empty ()) return 0; - /* ----------------------------- SNIP ----------------------------- - Anything added to the cleanup chain beyond this point is assumed - to be part of a breakpoint. If the breakpoint create succeeds - then the memory is not reclaimed. */ - bkpt_chain = make_cleanup (null_cleanup, 0); - /* Resolve all line numbers to PC's and verify that the addresses are ok for the target. */ if (!pending) @@ -9398,11 +9374,6 @@ create_breakpoint (struct gdbarch *gdbarch, prev_breakpoint_count = prev_bkpt_count; } - /* That's it. Discard the cleanups for data inserted into the - breakpoint. */ - discard_cleanups (bkpt_chain); - - /* error call may happen here - have BKPT_CHAIN already discarded. */ update_global_location_list (UGLL_MAY_INSERT); return 1; @@ -9422,16 +9393,10 @@ break_command_1 (const char *arg, int flag, int from_tty) enum bptype type_wanted = (flag & BP_HARDWAREFLAG ? bp_hardware_breakpoint : bp_breakpoint); - struct breakpoint_ops *ops; event_location_up location = string_to_event_location (&arg, current_language); - - /* Matching breakpoints on probes. */ - if (location != NULL - && event_location_type (location.get ()) == PROBE_LOCATION) - ops = &bkpt_probe_breakpoint_ops; - else - ops = &bkpt_breakpoint_ops; + const struct breakpoint_ops *ops = breakpoint_ops_for_event_location + (location.get (), false /* is_tracepoint */); create_breakpoint (get_current_arch (), location.get (), @@ -9538,7 +9503,7 @@ stopin_command (const char *arg, int from_tty) { int badInput = 0; - if (arg == (char *) NULL) + if (arg == NULL) badInput = 1; else if (*arg != '*') { @@ -9571,7 +9536,7 @@ stopat_command (const char *arg, int from_tty) { int badInput = 0; - if (arg == (char *) NULL || *arg == '*') /* no line number */ + if (arg == NULL || *arg == '*') /* no line number */ badInput = 1; else { @@ -9593,7 +9558,7 @@ stopat_command (const char *arg, int from_tty) } if (badInput) - printf_filtered (_("Usage: stop at \n")); + printf_filtered (_("Usage: stop at LINE\n")); else break_command_1 (arg, 0, from_tty); } @@ -9695,7 +9660,7 @@ print_it_ranged_breakpoint (bpstat bs) async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT)); uiout->field_string ("disp", bpdisp_text (b->disposition)); } - uiout->field_int ("bkptno", b->number); + uiout->field_signed ("bkptno", b->number); uiout->text (", "); return PRINT_SRC_AND_LOC; @@ -10271,7 +10236,7 @@ print_mention_watchpoint (struct breakpoint *b) } ui_out_emit_tuple tuple_emitter (uiout, tuple_name); - uiout->field_int ("number", b->number); + uiout->field_signed ("number", b->number); uiout->text (": "); uiout->field_string ("exp", w->exp_string); } @@ -10464,7 +10429,7 @@ print_mention_masked_watchpoint (struct breakpoint *b) } ui_out_emit_tuple tuple_emitter (uiout, tuple_name); - uiout->field_int ("number", b->number); + uiout->field_signed ("number", b->number); uiout->text (": "); uiout->field_string ("exp", w->exp_string); } @@ -10476,7 +10441,6 @@ 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) { @@ -10494,8 +10458,8 @@ print_recreate_masked_watchpoint (struct breakpoint *b, struct ui_file *fp) _("Invalid hardware watchpoint type.")); } - sprintf_vma (tmp, w->hw_wp_mask); - fprintf_unfiltered (fp, " %s mask 0x%s", w->exp_string, tmp); + fprintf_unfiltered (fp, " %s mask 0x%s", w->exp_string, + phex (w->hw_wp_mask, sizeof (CORE_ADDR))); print_recreate_thread (b, fp); } @@ -10505,7 +10469,7 @@ static struct breakpoint_ops masked_watchpoint_breakpoint_ops; /* Tell whether the given watchpoint is a masked hardware watchpoint. */ -static int +static bool is_masked_watchpoint (const struct breakpoint *b) { return b->ops == &masked_watchpoint_breakpoint_ops; @@ -10520,7 +10484,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty, { struct breakpoint *scope_breakpoint = NULL; const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL; - struct value *mark, *result; + struct value *result; int saved_bitpos = 0, saved_bitsize = 0; const char *exp_start = NULL; const char *exp_end = NULL; @@ -10622,10 +10586,10 @@ watch_command_1 (const char *arg, int accessflag, int from_tty, /* Parse the rest of the arguments. From here on out, everything is in terms of a newly allocated string instead of the original ARG. */ - innermost_block.reset (); std::string expression (arg, exp_end - arg); exp_start = arg = expression.c_str (); - expression_up exp = parse_exp_1 (&arg, 0, 0, 0); + innermost_block_tracker tracker; + expression_up exp = parse_exp_1 (&arg, 0, 0, 0, &tracker); exp_end = arg; /* Remove trailing whitespace from the expression before saving it. This makes the eventual display of the expression string a bit @@ -10644,8 +10608,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty, error (_("Cannot watch constant value `%.*s'."), len, exp_start); } - exp_valid_block = innermost_block.block (); - mark = value_mark (); + exp_valid_block = tracker.block (); + struct value *mark = value_mark (); struct value *val_as_value = nullptr; fetch_subexp_value (exp.get (), &pc, &val_as_value, &result, NULL, just_location); @@ -10684,13 +10648,13 @@ watch_command_1 (const char *arg, int accessflag, int from_tty, toklen = end_tok - tok; if (toklen >= 1 && strncmp (tok, "if", toklen) == 0) { - innermost_block.reset (); tok = cond_start = end_tok + 1; - parse_exp_1 (&tok, 0, 0, 0); + innermost_block_tracker if_tracker; + parse_exp_1 (&tok, 0, 0, 0, &if_tracker); /* The watchpoint expression may not be local, but the condition may still be. E.g.: `watch global if local > 0'. */ - cond_exp_valid_block = innermost_block.block (); + cond_exp_valid_block = if_tracker.block (); cond_end = tok; } @@ -10791,7 +10755,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty, w->val = val; w->val_bitpos = saved_bitpos; w->val_bitsize = saved_bitsize; - w->val_valid = 1; + w->val_valid = true; } if (cond_start) @@ -10885,8 +10849,8 @@ can_use_hardware_watchpoint (const std::vector &vals) explicitly, never if they just happen to appear in a middle of some value chain. */ if (v == head - || (TYPE_CODE (vtype) != TYPE_CODE_STRUCT - && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) + || (vtype->code () != TYPE_CODE_STRUCT + && vtype->code () != TYPE_CODE_ARRAY)) { CORE_ADDR vaddr = value_address (v); int len; @@ -10933,10 +10897,7 @@ watch_maybe_just_location (const char *arg, int accessflag, int from_tty) 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; - } + just_location = 1; watch_command_1 (arg, accessflag, from_tty, just_location, 0); } @@ -10976,106 +10937,66 @@ awatch_command (const char *arg, int from_tty) in infcmd.c. Here because it uses the mechanisms of breakpoints. */ -struct until_break_fsm +struct until_break_fsm : public thread_fsm { - /* The base class. */ - struct thread_fsm thread_fsm; - - /* The thread that as current when the command was executed. */ + /* The thread that was current when the command was executed. */ int thread; /* The breakpoint set at the destination location. */ - struct breakpoint *location_breakpoint; + breakpoint_up location_breakpoint; /* Breakpoint set at the return address in the caller frame. May be NULL. */ - struct breakpoint *caller_breakpoint; -}; - -static void until_break_fsm_clean_up (struct thread_fsm *self, - struct thread_info *thread); -static int until_break_fsm_should_stop (struct thread_fsm *self, - struct thread_info *thread); -static enum async_reply_reason - until_break_fsm_async_reply_reason (struct thread_fsm *self); + breakpoint_up caller_breakpoint; -/* until_break_fsm's vtable. */ + until_break_fsm (struct interp *cmd_interp, int thread, + breakpoint_up &&location_breakpoint, + breakpoint_up &&caller_breakpoint) + : thread_fsm (cmd_interp), + thread (thread), + location_breakpoint (std::move (location_breakpoint)), + caller_breakpoint (std::move (caller_breakpoint)) + { + } -static struct thread_fsm_ops until_break_fsm_ops = -{ - NULL, /* dtor */ - until_break_fsm_clean_up, - until_break_fsm_should_stop, - NULL, /* return_value */ - until_break_fsm_async_reply_reason, + void clean_up (struct thread_info *thread) override; + bool should_stop (struct thread_info *thread) override; + enum async_reply_reason do_async_reply_reason () override; }; -/* Allocate a new until_break_command_fsm. */ - -static struct until_break_fsm * -new_until_break_fsm (struct interp *cmd_interp, int thread, - breakpoint_up &&location_breakpoint, - breakpoint_up &&caller_breakpoint) -{ - struct until_break_fsm *sm; - - sm = XCNEW (struct until_break_fsm); - thread_fsm_ctor (&sm->thread_fsm, &until_break_fsm_ops, cmd_interp); - - sm->thread = thread; - sm->location_breakpoint = location_breakpoint.release (); - sm->caller_breakpoint = caller_breakpoint.release (); - - return sm; -} - /* Implementation of the 'should_stop' FSM method for the until(location)/advance commands. */ -static int -until_break_fsm_should_stop (struct thread_fsm *self, - struct thread_info *tp) +bool +until_break_fsm::should_stop (struct thread_info *tp) { - struct until_break_fsm *sm = (struct until_break_fsm *) self; - if (bpstat_find_breakpoint (tp->control.stop_bpstat, - sm->location_breakpoint) != NULL - || (sm->caller_breakpoint != NULL + location_breakpoint.get ()) != NULL + || (caller_breakpoint != NULL && bpstat_find_breakpoint (tp->control.stop_bpstat, - sm->caller_breakpoint) != NULL)) - thread_fsm_set_finished (self); + caller_breakpoint.get ()) != NULL)) + set_finished (); - return 1; + return true; } /* Implementation of the 'clean_up' FSM method for the until(location)/advance commands. */ -static void -until_break_fsm_clean_up (struct thread_fsm *self, - struct thread_info *thread) +void +until_break_fsm::clean_up (struct thread_info *) { - struct until_break_fsm *sm = (struct until_break_fsm *) self; - /* Clean up our temporary breakpoints. */ - if (sm->location_breakpoint != NULL) - { - delete_breakpoint (sm->location_breakpoint); - sm->location_breakpoint = NULL; - } - if (sm->caller_breakpoint != NULL) - { - delete_breakpoint (sm->caller_breakpoint); - sm->caller_breakpoint = NULL; - } - delete_longjmp_breakpoint (sm->thread); + location_breakpoint.reset (); + caller_breakpoint.reset (); + delete_longjmp_breakpoint (thread); } /* Implementation of the 'async_reply_reason' FSM method for the until(location)/advance commands. */ -static enum async_reply_reason -until_break_fsm_async_reply_reason (struct thread_fsm *self) +enum async_reply_reason +until_break_fsm::do_async_reply_reason () { return EXEC_ASYNC_LOCATION_REACHED; } @@ -11087,10 +11008,8 @@ until_break_command (const char *arg, int from_tty, int anywhere) struct gdbarch *frame_gdbarch; struct frame_id stack_frame_id; struct frame_id caller_frame_id; - struct cleanup *old_chain; int thread; struct thread_info *tp; - struct until_break_fsm *sm; clear_proceed_status (0); @@ -11105,7 +11024,7 @@ until_break_command (const char *arg, int from_tty, int anywhere) get_last_displayed_symtab (), get_last_displayed_line ()) : decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE, - NULL, (struct symtab *) NULL, 0)); + NULL, NULL, 0)); if (sals.size () != 1) error (_("Couldn't get information on specified line.")); @@ -11120,8 +11039,6 @@ until_break_command (const char *arg, int from_tty, int anywhere) tp = inferior_thread (); thread = tp->global_num; - old_chain = make_cleanup (null_cleanup, NULL); - /* Note linespec handling above invalidates the frame chain. Installing a breakpoint also invalidates the frame chain (as it may need to switch threads), so do any frame handling before @@ -11136,6 +11053,9 @@ until_break_command (const char *arg, int from_tty, int anywhere) one. */ breakpoint_up caller_breakpoint; + + gdb::optional lj_deleter; + if (frame_id_p (caller_frame_id)) { struct symtab_and_line sal2; @@ -11150,7 +11070,7 @@ until_break_command (const char *arg, int from_tty, int anywhere) bp_until); set_longjmp_breakpoint (tp, caller_frame_id); - make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); + lj_deleter.emplace (thread); } /* set_momentary_breakpoint could invalidate FRAME. */ @@ -11168,12 +11088,12 @@ until_break_command (const char *arg, int from_tty, int anywhere) location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, stack_frame_id, bp_until); - sm = new_until_break_fsm (command_interp (), tp->global_num, - std::move (location_breakpoint), - std::move (caller_breakpoint)); - tp->thread_fsm = &sm->thread_fsm; + tp->thread_fsm = new until_break_fsm (command_interp (), tp->global_num, + std::move (location_breakpoint), + std::move (caller_breakpoint)); - discard_cleanups (old_chain); + if (lj_deleter) + lj_deleter->release (); proceed (-1, GDB_SIGNAL_DEFAULT); } @@ -11326,7 +11246,7 @@ init_ada_exception_breakpoint (struct breakpoint *b, enough for now, though. */ } - init_raw_breakpoint (b, gdbarch, sal, bp_breakpoint, ops); + init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops); b->enable_state = enabled ? bp_enabled : bp_disabled; b->disposition = tempflag ? disp_del : disp_donttouch; @@ -11335,19 +11255,8 @@ init_ada_exception_breakpoint (struct breakpoint *b, b->language = language_ada; } -static void -catch_command (const char *arg, int from_tty) -{ - error (_("Catch requires an event name.")); -} -static void -tcatch_command (const char *arg, int from_tty) -{ - error (_("Catch requires an event name.")); -} - /* Compare two breakpoints and return a strcmp-like result. */ static int @@ -11496,14 +11405,14 @@ clear_command (const char *arg, int from_tty) /* Remove duplicates from the vec. */ std::sort (found.begin (), found.end (), - [] (const breakpoint *a, const breakpoint *b) + [] (const breakpoint *bp_a, const breakpoint *bp_b) { - return compare_breakpoints (a, b) < 0; + return compare_breakpoints (bp_a, bp_b) < 0; }); found.erase (std::unique (found.begin (), found.end (), - [] (const breakpoint *a, const breakpoint *b) + [] (const breakpoint *bp_a, const breakpoint *bp_b) { - return compare_breakpoints (a, b) == 0; + return compare_breakpoints (bp_a, bp_b) == 0; }), found.end ()); @@ -11550,42 +11459,48 @@ breakpoint_auto_delete (bpstat bs) } /* A comparison function for bp_location AP and BP being interfaced to - qsort. Sort elements primarily by their ADDRESS (no matter what - does breakpoint_address_is_meaningful say for its OWNER), - secondarily by ordering first permanent elements and - terciarily just ensuring the array is sorted stable way despite - qsort being an unstable algorithm. */ + std::sort. Sort elements primarily by their ADDRESS (no matter what + bl_address_is_meaningful says), secondarily by ordering first + permanent elements and terciarily just ensuring the array is sorted + stable way despite std::sort being an unstable algorithm. */ static int -bp_locations_compare (const void *ap, const void *bp) +bp_location_is_less_than (const bp_location *a, const bp_location *b) { - const struct bp_location *a = *(const struct bp_location **) ap; - const struct bp_location *b = *(const struct bp_location **) bp; - if (a->address != b->address) - return (a->address > b->address) - (a->address < b->address); + return a->address < b->address; /* Sort locations at the same address by their pspace number, keeping locations of the same inferior (in a multi-inferior environment) grouped. */ if (a->pspace->num != b->pspace->num) - return ((a->pspace->num > b->pspace->num) - - (a->pspace->num < b->pspace->num)); + return a->pspace->num < b->pspace->num; /* Sort permanent breakpoints first. */ if (a->permanent != b->permanent) - return (a->permanent < b->permanent) - (a->permanent > b->permanent); + return a->permanent > b->permanent; + + /* Sort by type in order to make duplicate determination easier. + See update_global_location_list. This is kept in sync with + breakpoint_locations_match. */ + if (a->loc_type < b->loc_type) + return true; + + /* Likewise, for range-breakpoints, sort by length. */ + if (a->loc_type == bp_loc_hardware_breakpoint + && b->loc_type == bp_loc_hardware_breakpoint + && a->length < b->length) + return true; /* Make the internal GDB representation stable across GDB runs where A and B memory inside GDB can differ. Breakpoint locations of the same type at the same address can be sorted in arbitrary order. */ if (a->owner->number != b->owner->number) - return ((a->owner->number > b->owner->number) - - (a->owner->number < b->owner->number)); + return a->owner->number < b->owner->number; - return (a > b) - (a < b); + return a < b; } /* Set bp_locations_placed_address_before_address_max and @@ -11752,6 +11667,7 @@ force_breakpoint_reinsertion (struct bp_location *bl) loc->cond_bytecode.reset (); } } + /* Called whether new breakpoints are created, or existing breakpoints deleted, to update the global location list and recompute which locations are duplicate of which. @@ -11800,8 +11716,22 @@ update_global_location_list (enum ugll_insert_mode insert_mode) ALL_BREAKPOINTS (b) for (loc = b->loc; loc; loc = loc->next) *locp++ = loc; - qsort (bp_locations, bp_locations_count, sizeof (*bp_locations), - bp_locations_compare); + + /* See if we need to "upgrade" a software breakpoint to a hardware + breakpoint. Do this before deciding whether locations are + duplicates. Also do this before sorting because sorting order + depends on location type. */ + for (locp = bp_locations; + locp < bp_locations + bp_locations_count; + locp++) + { + loc = *locp; + if (!loc->inserted && should_be_inserted (loc)) + handle_automatic_hardware_breakpoints (loc); + } + + std::sort (bp_locations, bp_locations + bp_locations_count, + bp_location_is_less_than); bp_locations_target_extensions_update (); @@ -11894,7 +11824,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode) this one from the target. */ /* OLD_LOC comes from existing struct breakpoint. */ - if (breakpoint_address_is_meaningful (old_loc->owner)) + if (bl_address_is_meaningful (old_loc)) { for (loc2p = locp; (loc2p < bp_locations + bp_locations_count @@ -11903,6 +11833,9 @@ update_global_location_list (enum ugll_insert_mode insert_mode) { struct bp_location *loc2 = *loc2p; + if (loc2 == old_loc) + continue; + if (breakpoint_locations_match (loc2, old_loc)) { /* Read watchpoint locations are switched to @@ -11917,8 +11850,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode) /* loc2 is a duplicated location. We need to check if it should be inserted in case it will be unduplicated. */ - if (loc2 != old_loc - && unduplicated_should_be_inserted (loc2)) + if (unduplicated_should_be_inserted (loc2)) { swap_insertion (old_loc, loc2); keep_in_target = 1; @@ -11999,7 +11931,18 @@ update_global_location_list (enum ugll_insert_mode insert_mode) around. We simply always ignore hardware watchpoint traps we can no longer explain. */ - old_loc->events_till_retirement = 3 * (thread_count () + 1); + process_stratum_target *proc_target = nullptr; + for (inferior *inf : all_inferiors ()) + if (inf->pspace == old_loc->pspace) + { + proc_target = inf->process_target (); + break; + } + if (proc_target != nullptr) + old_loc->events_till_retirement + = 3 * (thread_count (proc_target) + 1); + else + old_loc->events_till_retirement = 1; old_loc->owner = NULL; moribund_locations.push_back (old_loc); @@ -12034,7 +11977,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode) b = loc->owner; if (!unduplicated_should_be_inserted (loc) - || !breakpoint_address_is_meaningful (b) + || !bl_address_is_meaningful (loc) /* Don't detect duplicate for tracepoint locations because they are never duplicated. See the comments in field `duplicate' of `struct bp_location'. */ @@ -12121,14 +12064,13 @@ static void update_global_location_list_nothrow (enum ugll_insert_mode insert_mode) { - TRY + try { update_global_location_list (insert_mode); } - CATCH (e, RETURN_MASK_ERROR) + catch (const gdb_exception_error &e) { } - END_CATCH } /* Clear BKP from a BPS. */ @@ -12195,19 +12137,23 @@ say_where (struct breakpoint *b) else { if (opts.addressprint || b->loc->symtab == NULL) - { - printf_filtered (" at "); - fputs_filtered (paddress (b->loc->gdbarch, b->loc->address), - gdb_stdout); - } + printf_filtered (" at %ps", + styled_string (address_style.style (), + paddress (b->loc->gdbarch, + b->loc->address))); if (b->loc->symtab != NULL) { /* If there is a single location, we can print the location more nicely. */ if (b->loc->next == NULL) - printf_filtered (": file %s, line %d.", - symtab_to_filename_for_display (b->loc->symtab), - b->loc->line_number); + { + const char *filename + = symtab_to_filename_for_display (b->loc->symtab); + printf_filtered (": file %ps, line %d.", + styled_string (file_name_style.style (), + filename), + b->loc->line_number); + } else /* This is not ideal, but each location may have a different file name, and this at least reflects the @@ -12227,32 +12173,23 @@ say_where (struct breakpoint *b) } } -/* Default bp_location_ops methods. */ - -static void -bp_location_dtor (struct bp_location *self) +bp_location::~bp_location () { - xfree (self->function_name); + xfree (function_name); } -static const struct bp_location_ops bp_location_ops = -{ - bp_location_dtor -}; - /* Destructor for the breakpoint base class. */ breakpoint::~breakpoint () { xfree (this->cond_string); xfree (this->extra_string); - xfree (this->filter); } static struct bp_location * base_breakpoint_allocate_location (struct breakpoint *self) { - return new bp_location (&bp_location_ops, self); + return new bp_location (self); } static void @@ -12512,18 +12449,18 @@ bkpt_print_it (bpstat bs) annotate_breakpoint (b->number); maybe_print_thread_hit_breakpoint (uiout); - if (bp_temp) - uiout->text ("Temporary breakpoint "); - else - uiout->text ("Breakpoint "); if (uiout->is_mi_like_p ()) { uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT)); uiout->field_string ("disp", bpdisp_text (b->disposition)); } - uiout->field_int ("bkptno", b->number); - uiout->text (", "); + if (bp_temp) + uiout->message ("Temporary breakpoint %pF, ", + signed_field ("bkptno", b->number)); + else + uiout->message ("Breakpoint %pF, ", + signed_field ("bkptno", b->number)); return PRINT_SRC_AND_LOC; } @@ -12839,10 +12776,9 @@ tracepoint_print_one_detail (const struct breakpoint *self, { gdb_assert (self->type == bp_static_tracepoint); - uiout->text ("\tmarker id is "); - uiout->field_string ("static-tracepoint-marker-string-id", - tp->static_trace_marker_id); - uiout->text ("\n"); + uiout->message ("\tmarker id is %pF\n", + string_field ("static-tracepoint-marker-string-id", + tp->static_trace_marker_id.c_str ())); } } @@ -12937,8 +12873,7 @@ tracepoint_decode_location (struct breakpoint *b, struct breakpoint_ops tracepoint_breakpoint_ops; -/* The breakpoint_ops structure to be use on tracepoints placed in a - static probe. */ +/* Virtual table for tracepoints on static probes. */ static void tracepoint_probe_create_sals_from_location @@ -12959,8 +12894,6 @@ tracepoint_probe_decode_location (struct breakpoint *b, return bkpt_probe_decode_location (b, location, search_pspace); } -static struct breakpoint_ops tracepoint_probe_breakpoint_ops; - /* Dprintf breakpoint_ops methods. */ static void @@ -13292,9 +13225,9 @@ delete_command (const char *arg, int from_tty) } else map_breakpoint_numbers - (arg, [&] (breakpoint *b) + (arg, [&] (breakpoint *br) { - iterate_over_related_breakpoints (b, delete_breakpoint); + iterate_over_related_breakpoints (br, delete_breakpoint); }); } @@ -13439,11 +13372,13 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal) uiout->text ("Now in "); if (sym) { - uiout->field_string ("func", SYMBOL_PRINT_NAME (sym)); + uiout->field_string ("func", sym->print_name (), + function_name_style.style ()); uiout->text (" at "); } uiout->field_string ("file", - symtab_to_filename_for_display (sal2.symtab)); + symtab_to_filename_for_display (sal2.symtab), + file_name_style.style ()); uiout->text (":"); if (uiout->is_mi_like_p ()) @@ -13453,7 +13388,7 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal) uiout->field_string ("fullname", fullname); } - uiout->field_int ("line", sal2.line); + uiout->field_signed ("line", sal2.line); uiout->text ("\n"); b->loc->line_number = sal2.line; @@ -13590,20 +13525,19 @@ update_breakpoint_locations (struct breakpoint *b, const char *s; s = b->cond_string; - TRY + try { new_loc->cond = parse_exp_1 (&s, sal.pc, block_for_pc (sal.pc), 0); } - CATCH (e, RETURN_MASK_ERROR) + catch (const gdb_exception_error &e) { warning (_("failed to reevaluate condition " "for breakpoint %d: %s"), - b->number, e.message); + b->number, e.what ()); new_loc->enabled = 0; } - END_CATCH } if (!sals_end.empty ()) @@ -13633,11 +13567,20 @@ update_breakpoint_locations (struct breakpoint *b, if (have_ambiguous_names) { for (; l; l = l->next) - if (breakpoint_locations_match (e, l)) - { - l->enabled = 0; - break; - } + { + /* Ignore software vs hardware location type at + this point, because with "set breakpoint + auto-hw", after a re-set, locations that were + hardware can end up as software, or vice versa. + As mentioned above, this is an heuristic and in + practice should give the correct answer often + enough. */ + if (breakpoint_locations_match (e, l, true)) + { + l->enabled = 0; + break; + } + } } else { @@ -13664,22 +13607,20 @@ static std::vector location_to_sals (struct breakpoint *b, struct event_location *location, struct program_space *search_pspace, int *found) { - struct gdb_exception exception = exception_none; + struct gdb_exception exception; gdb_assert (b->ops != NULL); std::vector sals; - TRY + try { sals = b->ops->decode_location (b, location, search_pspace); } - CATCH (e, RETURN_MASK_ERROR) + catch (gdb_exception_error &e) { int not_found_and_ok = 0; - exception = e; - /* For pending breakpoints, it's expected that parsing will fail until the right shared library is loaded. User has already told to create pending breakpoints and don't need @@ -13706,10 +13647,11 @@ location_to_sals (struct breakpoint *b, struct event_location *location, happens only when a binary has changed, I don't know which approach is better. */ b->enable_state = bp_disabled; - throw_exception (e); + throw; } + + exception = std::move (e); } - END_CATCH if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR) { @@ -13822,9 +13764,8 @@ decode_location_default (struct breakpoint *b, struct linespec_result canonical; decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace, - (struct symtab *) NULL, 0, - &canonical, multiple_symbols_all, - b->filter); + NULL, 0, &canonical, multiple_symbols_all, + b->filter.get ()); /* We should get 0 or 1 resulting SALs. */ gdb_assert (canonical.lsals.size () < 2); @@ -13881,17 +13822,16 @@ breakpoint_re_set (void) ALL_BREAKPOINTS_SAFE (b, b_tmp) { - TRY + try { breakpoint_re_set_one (b); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { exception_fprintf (gdb_stderr, ex, "Error in re-setting breakpoint %d: ", b->number); } - END_CATCH } jit_breakpoint_re_set (); @@ -14358,7 +14298,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition, /* Initialize it just to avoid a GCC false warning. */ enum enable_state orig_enable_state = bp_disabled; - TRY + try { struct watchpoint *w = (struct watchpoint *) bpt; @@ -14366,14 +14306,13 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition, bpt->enable_state = bp_enabled; update_watchpoint (w, 1 /* reparse */); } - CATCH (e, RETURN_MASK_ALL) + catch (const gdb_exception &e) { bpt->enable_state = orig_enable_state; exception_fprintf (gdb_stderr, e, _("Cannot enable watchpoint %d: "), bpt->number); return; } - END_CATCH } bpt->enable_state = bp_enabled; @@ -14464,16 +14403,6 @@ enable_delete_command (const char *args, int from_tty) }); } -static void -set_breakpoint_cmd (const char *args, int from_tty) -{ -} - -static void -show_breakpoint_cmd (const char *args, int from_tty) -{ -} - /* Invalidate last known value of any hardware watchpoint if the memory which that value represents has been written to by GDB itself. */ @@ -14501,7 +14430,7 @@ invalidate_bp_value_on_memory_change (struct inferior *inferior, && addr + len > loc->address) { wp->val = NULL; - wp->val_valid = 0; + wp->val_valid = false; } } } @@ -14605,15 +14534,10 @@ set_tracepoint_count (int num) static void trace_command (const char *arg, int from_tty) { - struct breakpoint_ops *ops; - event_location_up location = string_to_event_location (&arg, current_language); - if (location != NULL - && event_location_type (location.get ()) == PROBE_LOCATION) - ops = &tracepoint_probe_breakpoint_ops; - else - ops = &tracepoint_breakpoint_ops; + const struct breakpoint_ops *ops = breakpoint_ops_for_event_location + (location.get (), true /* is_tracepoint */); create_breakpoint (get_current_arch (), location.get (), @@ -14693,7 +14617,7 @@ read_uploaded_action (void) if (next_cmd < this_utp->cmd_strings.size ()) { - rslt = this_utp->cmd_strings[next_cmd]; + rslt = this_utp->cmd_strings[next_cmd].get (); next_cmd++; } @@ -14714,7 +14638,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) struct tracepoint *tp; if (utp->at_string) - addr_str = utp->at_string; + addr_str = utp->at_string.get (); else { /* In the absence of a source location, fall back to raw @@ -14738,7 +14662,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp) current_language); if (!create_breakpoint (get_current_arch (), location.get (), - utp->cond_string, -1, addr_str, + utp->cond_string.get (), -1, addr_str, 0 /* parse cond/thread */, 0 /* tempflag */, utp->type /* type_wanted */, @@ -14800,7 +14724,7 @@ info_tracepoints_command (const char *args, int from_tty) struct ui_out *uiout = current_uiout; int num_printed; - num_printed = breakpoint_1 (args, 0, is_tracepoint); + num_printed = breakpoint_1 (args, false, is_tracepoint); if (num_printed == 0) { @@ -14863,9 +14787,9 @@ delete_trace_command (const char *arg, int from_tty) } else map_breakpoint_numbers - (arg, [&] (breakpoint *b) + (arg, [&] (breakpoint *br) { - iterate_over_related_breakpoints (b, delete_breakpoint); + iterate_over_related_breakpoints (br, delete_breakpoint); }); } @@ -15022,11 +14946,11 @@ print_recreate_thread (struct breakpoint *b, struct ui_file *fp) /* Save information on user settable breakpoints (watchpoints, etc) to a new script file named FILENAME. If FILTER is non-NULL, call it on each breakpoint and only include the ones for which it returns - non-zero. */ + true. */ static void save_breakpoints (const char *filename, int from_tty, - int (*filter) (const struct breakpoint *)) + bool (*filter) (const struct breakpoint *)) { struct breakpoint *tp; int any = 0; @@ -15101,16 +15025,15 @@ save_breakpoints (const char *filename, int from_tty, fp.puts (" commands\n"); current_uiout->redirect (&fp); - TRY + try { print_command_lines (current_uiout, tp->commands.get (), 2); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { current_uiout->redirect (NULL); - throw_exception (ex); + throw; } - END_CATCH current_uiout->redirect (NULL); fp.puts (" end\n"); @@ -15198,7 +15121,7 @@ functions in all scopes. For C++, this means in all namespaces and\n\ classes. For Ada, this means in all packages. E.g., in C++,\n\ \"func()\" matches \"A::func()\", \"A::B::func()\", etc. The\n\ \"-qualified\" flag overrides this behavior, making GDB interpret the\n\ -specified name as a complete fully-qualified name instead.\n" +specified name as a complete fully-qualified name instead." /* This help string is used for the break, hbreak, tbreak and thbreak commands. It is defined as a macro to prevent duplication. @@ -15219,7 +15142,7 @@ 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" LOCATION_HELP_STRING "\n\ +\n" LOCATION_HELP_STRING "\n\n\ Multiple breakpoints at one place are permitted, and useful if their\n\ conditions are different.\n\ \n\ @@ -15253,23 +15176,14 @@ add_catch_command (const char *name, const char *docstring, set_cmd_completer (command, completer); } -static void -save_command (const 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) +iterate_over_breakpoints (gdb::function_view callback) { struct breakpoint *b, *b_tmp; ALL_BREAKPOINTS_SAFE (b, b_tmp) { - if ((*callback) (b, data)) + if (callback (b)) return b; } @@ -15508,8 +15422,13 @@ initialize_breakpoint_ops (void) static struct cmd_list_element *enablebreaklist = NULL; +/* See breakpoint.h. */ + +cmd_list_element *commands_cmd_element = nullptr; + +void _initialize_breakpoint (); void -_initialize_breakpoint (void) +_initialize_breakpoint () { struct cmd_list_element *c; @@ -15519,9 +15438,6 @@ _initialize_breakpoint (void) gdb::observers::free_objfile.attach (disable_breakpoints_in_freed_objfile); gdb::observers::memory_changed.attach (invalidate_bp_value_on_memory_change); - breakpoint_objfile_key - = register_objfile_data_with_cleanup (NULL, free_breakpoint_objfile_data); - breakpoint_chain = 0; /* Don't bother to call set_breakpoint_count. $bpnum isn't useful before a breakpoint is set. */ @@ -15533,7 +15449,8 @@ _initialize_breakpoint (void) Set ignore-count of breakpoint number N to COUNT.\n\ Usage is `ignore N COUNT'.")); - add_com ("commands", class_breakpoint, commands_command, _("\ + commands_cmd_element = add_com ("commands", class_breakpoint, + commands_command, _("\ Set commands to be executed when the given breakpoints are hit.\n\ Give a space-separated breakpoint list as argument after \"commands\".\n\ A list element can be a breakpoint number (e.g. `5') or a range of numbers\n\ @@ -15576,7 +15493,8 @@ BREAK_ARGS_HELP ("thbreak"))); set_cmd_completer (c, location_completer); add_prefix_cmd ("enable", class_breakpoint, enable_command, _("\ -Enable some breakpoints.\n\ +Enable all or some breakpoints.\n\ +Usage: enable [BREAKPOINTNUM]...\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\ @@ -15586,46 +15504,54 @@ 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\ +Enable all or some breakpoints.\n\ +Usage: enable breakpoints [BREAKPOINTNUM]...\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"), +May be abbreviated to simply \"enable\"."), &enablebreaklist, "enable breakpoints ", 1, &enablelist); add_cmd ("once", no_class, enable_once_command, _("\ -Enable breakpoints for one hit. Give breakpoint numbers.\n\ +Enable some breakpoints for one hit.\n\ +Usage: enable breakpoints once BREAKPOINTNUM...\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\ +Enable some breakpoints and delete when hit.\n\ +Usage: enable breakpoints delete BREAKPOINTNUM...\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\ +Enable some breakpoints for COUNT hits.\n\ +Usage: enable breakpoints count COUNT BREAKPOINTNUM...\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\ +Enable some breakpoints and delete when hit.\n\ +Usage: enable delete BREAKPOINTNUM...\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\ +Enable some breakpoints for one hit.\n\ +Usage: enable once BREAKPOINTNUM...\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\ +Enable some breakpoints for COUNT hits.\n\ +Usage: enable count COUNT BREAKPOINTNUM...\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\ +Disable all or some breakpoints.\n\ +Usage: disable [BREAKPOINTNUM]...\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."), @@ -15633,8 +15559,9 @@ A disabled breakpoint is not forgotten, but has no effect until re-enabled."), add_com_alias ("dis", "disable", class_breakpoint, 1); add_com_alias ("disa", "disable", class_breakpoint, 1); - add_cmd ("breakpoints", class_alias, disable_command, _("\ -Disable some breakpoints.\n\ + add_cmd ("breakpoints", class_breakpoint, disable_command, _("\ +Disable all or some breakpoints.\n\ +Usage: disable breakpoints [BREAKPOINTNUM]...\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\ @@ -15642,18 +15569,19 @@ This command may be abbreviated \"disable\"."), &disablelist); add_prefix_cmd ("delete", class_breakpoint, delete_command, _("\ -Delete some breakpoints or auto-display expressions.\n\ +Delete all or some breakpoints.\n\ +Usage: delete [BREAKPOINTNUM]...\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\"."), +Also a prefix command for deletion of other GDB objects."), &deletelist, "delete ", 1, &cmdlist); add_com_alias ("d", "delete", class_breakpoint, 1); add_com_alias ("del", "delete", class_breakpoint, 1); - add_cmd ("breakpoints", class_alias, delete_command, _("\ -Delete some breakpoints or auto-display expressions.\n\ + add_cmd ("breakpoints", class_breakpoint, delete_command, _("\ +Delete all or some breakpoints or auto-display expressions.\n\ +Usage: delete breakpoints [BREAKPOINTNUM]...\n\ Arguments are breakpoint numbers with spaces in between.\n\ To delete all breakpoints, give no argument.\n\ This command may be abbreviated \"delete\"."), @@ -15665,7 +15593,7 @@ Argument may be a linespec, explicit, or address location as described below.\n\ \n\ With no argument, clears all breakpoints in the line that the selected frame\n\ is executing in.\n" -"\n" LOCATION_HELP_STRING "\n\ +"\n" LOCATION_HELP_STRING "\n\n\ See also the \"delete\" command which clears breakpoints by number.")); add_com_alias ("cl", "clear", class_breakpoint, 1); @@ -15744,15 +15672,15 @@ Convenience variable \"$bpnum\" contains the number of the last\n\ breakpoint set."), &maintenanceinfolist); - add_prefix_cmd ("catch", class_breakpoint, catch_command, _("\ + add_basic_prefix_cmd ("catch", class_breakpoint, _("\ Set catchpoints to catch events."), - &catch_cmdlist, "catch ", - 0/*allow-unknown*/, &cmdlist); + &catch_cmdlist, "catch ", + 0/*allow-unknown*/, &cmdlist); - add_prefix_cmd ("tcatch", class_breakpoint, tcatch_command, _("\ + add_basic_prefix_cmd ("tcatch", class_breakpoint, _("\ Set temporary catchpoints to catch events."), - &tcatch_cmdlist, "tcatch ", - 0/*allow-unknown*/, &cmdlist); + &tcatch_cmdlist, "tcatch ", + 0/*allow-unknown*/, &cmdlist); add_catch_command ("fork", _("Catch calls to fork."), catch_fork_command_1, @@ -15839,10 +15767,10 @@ 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); + add_com_alias ("tp", "trace", class_breakpoint, 0); + add_com_alias ("tr", "trace", class_breakpoint, 1); + add_com_alias ("tra", "trace", class_breakpoint, 1); + add_com_alias ("trac", "trace", class_breakpoint, 1); c = add_com ("ftrace", class_breakpoint, ftrace_command, _("\ Set a fast tracepoint at specified location.\n\ @@ -15865,7 +15793,7 @@ 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" LOCATION_HELP_STRING "\n\ +\n" LOCATION_HELP_STRING "\n\n\ Multiple tracepoints at one place are permitted, and useful if their\n\ conditions are different.\n\ \n\ @@ -15907,10 +15835,10 @@ 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/*allow-unknown*/, &cmdlist); + add_basic_prefix_cmd ("save", class_breakpoint, + _("Save breakpoint definitions as a script."), + &save_cmdlist, "save ", + 0/*allow-unknown*/, &cmdlist); c = add_cmd ("breakpoints", class_breakpoint, save_breakpoints_command, _("\ Save current breakpoint definitions as a script.\n\ @@ -15929,18 +15857,18 @@ Use the 'source' command in another debug session to restore them."), 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\ + add_basic_prefix_cmd ("breakpoint", class_maintenance, _("\ +Breakpoint specific settings.\n\ Configure various breakpoint-specific variables such as\n\ -pending breakpoint behavior"), - &breakpoint_set_cmdlist, "set breakpoint ", - 0/*allow-unknown*/, &setlist); - add_prefix_cmd ("breakpoint", class_maintenance, show_breakpoint_cmd, _("\ -Breakpoint specific settings\n\ +pending breakpoint behavior."), + &breakpoint_set_cmdlist, "set breakpoint ", + 0/*allow-unknown*/, &setlist); + add_show_prefix_cmd ("breakpoint", class_maintenance, _("\ +Breakpoint specific settings.\n\ Configure various breakpoint-specific variables such as\n\ -pending breakpoint behavior"), - &breakpoint_show_cmdlist, "show breakpoint ", - 0/*allow-unknown*/, &showlist); +pending breakpoint behavior."), + &breakpoint_show_cmdlist, "show breakpoint ", + 0/*allow-unknown*/, &showlist); add_setshow_auto_boolean_cmd ("pending", no_class, &pending_break_support, _("\ @@ -16039,16 +15967,16 @@ output stream by setting dprintf-function and dprintf-channel."), 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, +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, +Set the channel to use for dynamic printf."), _("\ +Show the channel to use for dynamic printf."), NULL, update_dprintf_commands, NULL, &setlist, &showlist); @@ -16063,10 +15991,12 @@ even if GDB disconnects or detaches from the target."), &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.")); +Target agent only formatted printing, like the C \"printf\" function.\n\ +Usage: agent-printf \"format string\", ARG1, ARG2, ARG3, ..., ARGN\n\ +This supports most C printf format specifications, like %s, %d, etc.\n\ +This is useful for formatted output in user-defined commands.")); - automatic_hardware_breakpoints = 1; + automatic_hardware_breakpoints = true; gdb::observers::about_to_proceed.attach (breakpoint_about_to_proceed); gdb::observers::thread_exit.attach (remove_threaded_breakpoints);