X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fbreakpoint.c;h=3908dabffecdbc375dfdfbeeb298a89e943a838b;hb=833b7ab5008b769dca6db6d5ee1d21d33e730132;hp=bffff23d5262441d73e97ffa8f37c9679f1ebd06;hpb=629500fae69737a6230a564e8fef1f42c3ef1116;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index bffff23d52..3908dabffe 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1,6 +1,6 @@ /* Everything about breakpoints, for GDB. - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -68,6 +68,8 @@ #include "interps.h" #include "format.h" #include "location.h" +#include "thread-fsm.h" +#include "tid-parse.h" /* readline include files */ #include "readline/readline.h" @@ -78,6 +80,7 @@ #include "mi/mi-common.h" #include "extension.h" +#include /* Enums for exception-handling support. */ enum exception_event_kind @@ -124,6 +127,7 @@ static void create_breakpoints_sal_default (struct gdbarch *, static void decode_location_default (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals); static void clear_command (char *, int); @@ -172,6 +176,10 @@ static int breakpoint_location_address_match (struct bp_location *bl, struct address_space *aspace, CORE_ADDR addr); +static int breakpoint_location_address_range_overlap (struct bp_location *, + struct address_space *, + CORE_ADDR, int); + static void breakpoints_info (char *, int); static void watchpoints_info (char *, int); @@ -187,15 +195,8 @@ static void commands_command (char *, int); static void condition_command (char *, int); -typedef enum - { - mark_inserted, - mark_uninserted - } -insertion_state_t; - -static int remove_breakpoint (struct bp_location *, insertion_state_t); -static int remove_breakpoint_1 (struct bp_location *, insertion_state_t); +static int remove_breakpoint (struct bp_location *); +static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason); static enum print_stop_action print_bp_stop_message (bpstat bs); @@ -725,11 +726,11 @@ clear_breakpoint_hit_counts (void) static struct counted_command_line * alloc_counted_command_line (struct command_line *commands) { - struct counted_command_line *result - = xmalloc (sizeof (struct counted_command_line)); + struct counted_command_line *result = XNEW (struct counted_command_line); result->refc = 1; result->commands = commands; + return result; } @@ -765,7 +766,7 @@ decref_counted_command_line (struct counted_command_line **cmdp) static void do_cleanup_counted_command_line (void *arg) { - decref_counted_command_line (arg); + decref_counted_command_line ((struct counted_command_line **) arg); } /* Create a cleanup that calls decref_counted_command_line on the @@ -924,8 +925,8 @@ show_condition_evaluation_mode (struct ui_file *file, int from_tty, static int bp_location_compare_addrs (const void *ap, const void *bp) { - struct bp_location *a = *(void **) ap; - struct bp_location *b = *(void **) bp; + const struct bp_location *a = *(const struct bp_location **) ap; + const struct bp_location *b = *(const struct bp_location **) bp; if (a->address == b->address) return 0; @@ -950,9 +951,10 @@ get_first_locp_gte_addr (CORE_ADDR address) dummy_loc.address = address; /* Find a close match to the first location at ADDRESS. */ - locp_found = bsearch (&dummy_locp, bp_location, bp_location_count, - sizeof (struct bp_location **), - bp_location_compare_addrs); + locp_found = ((struct bp_location **) + bsearch (&dummy_locp, bp_location, bp_location_count, + sizeof (struct bp_location **), + bp_location_compare_addrs)); /* Nothing was found, nothing left to do. */ if (locp_found == NULL) @@ -1322,7 +1324,7 @@ breakpoint_set_task (struct breakpoint *b, int task) void check_tracepoint_command (char *line, void *closure) { - struct breakpoint *b = closure; + struct breakpoint *b = (struct breakpoint *) closure; validate_actionline (line, b); } @@ -1353,7 +1355,7 @@ struct commands_info static void do_map_commands_command (struct breakpoint *b, void *data) { - struct commands_info *info = data; + struct commands_info *info = (struct commands_info *) data; if (info->cmd == NULL) { @@ -1596,7 +1598,6 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf, /* Left boundary, right boundary and median element of our binary search. */ unsigned bc_l, bc_r, bc; - size_t i; /* Find BC_L which is a leftmost element which may affect BUF content. It is safe to report lower value but a failure to @@ -1651,9 +1652,6 @@ breakpoint_xfer_memory (gdb_byte *readbuf, gdb_byte *writebuf, for (bc = bc_l; bc < bp_location_count; bc++) { struct bp_location *bl = bp_location[bc]; - CORE_ADDR bp_addr = 0; - int bp_size = 0; - int bptoffset = 0; /* bp_location array has BL->OWNER always non-NULL. */ if (bl->owner->type == bp_none) @@ -1769,6 +1767,36 @@ extract_bitfield_from_watchpoint_value (struct watchpoint *w, struct value *val) return bit_val; } +/* Allocate a dummy location and add it to B, which must be a software + watchpoint. This is required because even if a software watchpoint + is not watching any memory, bpstat_stop_status requires a location + to be able to report stops. */ + +static void +software_watchpoint_add_no_memory_location (struct breakpoint *b, + struct program_space *pspace) +{ + gdb_assert (b->type == bp_watchpoint && b->loc == NULL); + + b->loc = allocate_bp_location (b); + b->loc->pspace = pspace; + b->loc->address = -1; + b->loc->length = -1; +} + +/* Returns true if B is a software watchpoint that is not watching any + memory (e.g., "watch $pc"). */ + +static int +is_no_memory_software_watchpoint (struct breakpoint *b) +{ + return (b->type == bp_watchpoint + && b->loc != NULL + && b->loc->next == NULL + && b->loc->address == -1 + && b->loc->length == -1); +} + /* Assuming that B is a watchpoint: - Reparse watchpoint expression, if REPARSE is non-zero - Evaluate expression and store the result in B->val @@ -2132,14 +2160,7 @@ update_watchpoint (struct watchpoint *b, int reparse) bpstat_stop_status requires a location to be able to report stops, so make sure there's at least a dummy one. */ if (b->base.type == bp_watchpoint && b->base.loc == NULL) - { - struct breakpoint *base = &b->base; - base->loc = allocate_bp_location (base); - base->loc->pspace = frame_pspace; - base->loc->address = -1; - base->loc->length = -1; - base->loc->watchpoint_type = -1; - } + software_watchpoint_add_no_memory_location (&b->base, frame_pspace); } else if (!within_current_scope) { @@ -2188,11 +2209,22 @@ should_be_inserted (struct bp_location *bl) return 0; /* Don't insert a breakpoint if we're trying to step past its - location. */ + location, except if the breakpoint is a single-step breakpoint, + and the breakpoint's thread is the thread which is stepping past + a breakpoint. */ if ((bl->loc_type == bp_loc_software_breakpoint || bl->loc_type == bp_loc_hardware_breakpoint) && stepping_past_instruction_at (bl->pspace->aspace, - bl->address)) + bl->address) + /* The single-step breakpoint may be inserted at the location + we're trying to step if the instruction branches to itself. + However, the instruction won't be executed at all and it may + break the semantics of the instruction, for example, the + instruction is a conditional branch or updates some flags. + We can't fix it unless GDB is able to emulate the instruction + or switch to displaced stepping. */ + && !(bl->owner->type == bp_single_step + && thread_is_stepping_over_breakpoint (bl->owner->thread))) { if (debug_infrun) { @@ -2316,12 +2348,6 @@ build_target_condition_list (struct bp_location *bl) need to parse the condition to bytecodes again. */ aexpr = parse_cond_to_aexpr (bl->address, loc->cond); loc->cond_bytecode = aexpr; - - /* Check if we managed to parse the conditional expression - correctly. If not, we will not send this condition - to the target. */ - if (aexpr) - continue; } /* If we have a NULL bytecode expression, it means something @@ -2522,9 +2548,6 @@ build_target_command_list (struct bp_location *bl) aexpr = parse_cmd_to_aexpr (bl->address, loc->owner->extra_string); loc->cmd_bytecode = aexpr; - - if (!aexpr) - continue; } /* If we have a NULL bytecode expression, it means something @@ -2580,6 +2603,28 @@ build_target_command_list (struct bp_location *bl) bl->target_info.persist = 1; } +/* Return the kind of breakpoint on address *ADDR. Get the kind + of breakpoint according to ADDR except single-step breakpoint. + Get the kind of single-step breakpoint according to the current + registers state. */ + +static int +breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr) +{ + if (bl->owner->type == bp_single_step) + { + struct thread_info *thr = find_thread_global_id (bl->owner->thread); + struct regcache *regcache; + + regcache = get_thread_regcache (thr->ptid); + + return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch, + regcache, addr); + } + else + return gdbarch_breakpoint_kind_from_pc (bl->gdbarch, addr); +} + /* Insert a low-level "breakpoint" of some type. BL is the breakpoint location. Any error messages are printed to TMP_ERROR_STREAM; and DISABLED_BREAKS, and HW_BREAKPOINT_ERROR are used to report problems. @@ -2739,6 +2784,9 @@ insert_bp_location (struct bp_location *bl, { int val; + bl->overlay_target_info.kind + = breakpoint_kind (bl, &addr); + bl->overlay_target_info.placed_address = addr; val = target_insert_breakpoint (bl->gdbarch, &bl->overlay_target_info); if (val) @@ -3115,7 +3163,7 @@ insert_breakpoint_locations (void) the thread no longer exists. ALL_BP_LOCATIONS bp_location has BL->OWNER always non-NULL. */ if (bl->owner->thread != -1 - && !valid_thread_id (bl->owner->thread)) + && !valid_global_thread_id (bl->owner->thread)) continue; switch_to_program_space_and_thread (bl->pspace); @@ -3160,7 +3208,7 @@ insert_breakpoint_locations (void) { for (loc = bpt->loc; loc; loc = loc->next) if (loc->inserted) - remove_breakpoint (loc, mark_uninserted); + remove_breakpoint (loc); hw_breakpoint_error = 1; fprintf_unfiltered (tmp_error_stream, @@ -3200,7 +3248,7 @@ remove_breakpoints (void) ALL_BP_LOCATIONS (bl, blp_tmp) { if (bl->inserted && !is_tracepoint (bl->owner)) - val |= remove_breakpoint (bl, mark_uninserted); + val |= remove_breakpoint (bl); } return val; } @@ -3215,13 +3263,13 @@ remove_threaded_breakpoints (struct thread_info *tp, int silent) ALL_BREAKPOINTS_SAFE (b, b_tmp) { - if (b->thread == tp->num && user_breakpoint_p (b)) + if (b->thread == tp->global_num && user_breakpoint_p (b)) { b->disposition = disp_del_at_next_stop; printf_filtered (_("\ -Thread-specific breakpoint %d deleted - thread %d no longer in the thread list.\n"), - b->number, tp->num); +Thread-specific breakpoint %d deleted - thread %s no longer in the thread list.\n"), + b->number, print_thread_id (tp)); /* Hide it from the user. */ b->number = 0; @@ -3245,7 +3293,7 @@ remove_breakpoints_pid (int pid) if (bl->inserted && !bl->target_info.persist) { - val = remove_breakpoint (bl, mark_uninserted); + val = remove_breakpoint (bl); if (val != 0) return val; } @@ -3392,11 +3440,12 @@ get_breakpoint_objfile_data (struct objfile *objfile) { struct breakpoint_objfile_data *bp_objfile_data; - bp_objfile_data = objfile_data (objfile, breakpoint_objfile_key); + bp_objfile_data = ((struct breakpoint_objfile_data *) + objfile_data (objfile, breakpoint_objfile_key)); if (bp_objfile_data == NULL) { - bp_objfile_data = obstack_alloc (&objfile->objfile_obstack, - sizeof (*bp_objfile_data)); + bp_objfile_data = + XOBNEW (&objfile->objfile_obstack, struct breakpoint_objfile_data); memset (bp_objfile_data, 0, sizeof (*bp_objfile_data)); set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data); @@ -3407,7 +3456,8 @@ get_breakpoint_objfile_data (struct objfile *objfile) static void free_breakpoint_probes (struct objfile *obj, void *data) { - struct breakpoint_objfile_data *bp_objfile_data = data; + struct breakpoint_objfile_data *bp_objfile_data + = (struct breakpoint_objfile_data *) data; VEC_free (probe_p, bp_objfile_data->longjmp_probes); VEC_free (probe_p, bp_objfile_data->exception_probes); @@ -3424,7 +3474,7 @@ create_overlay_event_breakpoint (void) struct breakpoint *b; struct breakpoint_objfile_data *bp_objfile_data; CORE_ADDR addr; - struct explicit_location explicit; + struct explicit_location explicit_loc; bp_objfile_data = get_breakpoint_objfile_data (objfile); @@ -3449,9 +3499,9 @@ create_overlay_event_breakpoint (void) b = create_internal_breakpoint (get_objfile_arch (objfile), addr, bp_overlay_event, &internal_breakpoint_ops); - initialize_explicit_location (&explicit); - explicit.function_name = ASTRDUP (func_name); - b->location = new_explicit_location (&explicit); + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (func_name); + b->location = new_explicit_location (&explicit_loc); if (overlay_debugging == ovly_auto) { @@ -3464,7 +3514,6 @@ create_overlay_event_breakpoint (void) overlay_events_enabled = 0; } } - update_global_location_list (UGLL_MAY_INSERT); } static void @@ -3548,7 +3597,7 @@ create_longjmp_master_breakpoint (void) struct breakpoint *b; const char *func_name; CORE_ADDR addr; - struct explicit_location explicit; + struct explicit_location explicit_loc; if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym)) continue; @@ -3571,14 +3620,13 @@ create_longjmp_master_breakpoint (void) 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); - explicit.function_name = ASTRDUP (func_name); - b->location = new_explicit_location (&explicit); + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (func_name); + b->location = new_explicit_location (&explicit_loc); b->enable_state = bp_disabled; } } } - update_global_location_list (UGLL_MAY_INSERT); do_cleanups (old_chain); } @@ -3604,7 +3652,7 @@ create_std_terminate_master_breakpoint (void) { struct breakpoint *b; struct breakpoint_objfile_data *bp_objfile_data; - struct explicit_location explicit; + struct explicit_location explicit_loc; bp_objfile_data = get_breakpoint_objfile_data (objfile); @@ -3630,15 +3678,13 @@ create_std_terminate_master_breakpoint (void) b = create_internal_breakpoint (get_objfile_arch (objfile), addr, bp_std_terminate_master, &internal_breakpoint_ops); - initialize_explicit_location (&explicit); - explicit.function_name = ASTRDUP (func_name); - b->location = new_explicit_location (&explicit); + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (func_name); + b->location = new_explicit_location (&explicit_loc); b->enable_state = bp_disabled; } } - update_global_location_list (UGLL_MAY_INSERT); - do_cleanups (old_chain); } @@ -3656,7 +3702,7 @@ create_exception_master_breakpoint (void) struct gdbarch *gdbarch; struct breakpoint_objfile_data *bp_objfile_data; CORE_ADDR addr; - struct explicit_location explicit; + struct explicit_location explicit_loc; bp_objfile_data = get_breakpoint_objfile_data (objfile); @@ -3737,13 +3783,19 @@ create_exception_master_breakpoint (void) ¤t_target); b = create_internal_breakpoint (gdbarch, addr, bp_exception_master, &internal_breakpoint_ops); - initialize_explicit_location (&explicit); - explicit.function_name = ASTRDUP (func_name); - b->location = new_explicit_location (&explicit); + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (func_name); + b->location = new_explicit_location (&explicit_loc); b->enable_state = bp_disabled; } +} - update_global_location_list (UGLL_MAY_INSERT); +/* Does B have a location spec? */ + +static int +breakpoint_event_location_empty_p (const struct breakpoint *b) +{ + return b->location != NULL && event_location_empty_p (b->location); } void @@ -3860,7 +3912,7 @@ update_breakpoints_after_exec (void) /* Without a symbolic address, we have little hope of the pre-exec() address meaning the same thing in the post-exec() a.out. */ - if (event_location_empty_p (b->location)) + if (breakpoint_event_location_empty_p (b)) { delete_breakpoint (b); continue; @@ -3896,7 +3948,7 @@ detach_breakpoints (ptid_t ptid) continue; if (bl->inserted) - val |= remove_breakpoint_1 (bl, mark_inserted); + val |= remove_breakpoint_1 (bl, DETACH_BREAKPOINT); } do_cleanups (old_chain); @@ -3910,7 +3962,7 @@ detach_breakpoints (ptid_t ptid) *not* look at bl->pspace->aspace here. */ static int -remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) +remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason) { int val; @@ -3958,7 +4010,7 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) && !memory_validate_breakpoint (bl->gdbarch, &bl->target_info)) val = 0; else - val = bl->owner->ops->remove_location (bl); + val = bl->owner->ops->remove_location (bl, reason); } else { @@ -3976,7 +4028,8 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) &bl->overlay_target_info); else target_remove_breakpoint (bl->gdbarch, - &bl->overlay_target_info); + &bl->overlay_target_info, + reason); } /* Did we set a breakpoint at the VMA? If so, we will have marked the breakpoint 'inserted'. */ @@ -3992,7 +4045,7 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) wrong code with the saved shadow contents. */ if (bl->loc_type == bp_loc_hardware_breakpoint || section_is_mapped (bl->section)) - val = bl->owner->ops->remove_location (bl); + val = bl->owner->ops->remove_location (bl, reason); else val = 0; } @@ -4022,18 +4075,18 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) if (val) return val; - bl->inserted = (is == mark_inserted); + bl->inserted = (reason == DETACH_BREAKPOINT); } else if (bl->loc_type == bp_loc_hardware_watchpoint) { gdb_assert (bl->owner->ops != NULL && bl->owner->ops->remove_location != NULL); - bl->inserted = (is == mark_inserted); - bl->owner->ops->remove_location (bl); + bl->inserted = (reason == DETACH_BREAKPOINT); + bl->owner->ops->remove_location (bl, reason); /* Failure to remove any of the hardware watchpoints comes here. */ - if ((is == mark_uninserted) && (bl->inserted)) + if (reason == REMOVE_BREAKPOINT && bl->inserted) warning (_("Could not remove hardware watchpoint %d."), bl->owner->number); } @@ -4044,18 +4097,18 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is) gdb_assert (bl->owner->ops != NULL && bl->owner->ops->remove_location != NULL); - val = bl->owner->ops->remove_location (bl); + val = bl->owner->ops->remove_location (bl, reason); if (val) return val; - bl->inserted = (is == mark_inserted); + bl->inserted = (reason == DETACH_BREAKPOINT); } return 0; } static int -remove_breakpoint (struct bp_location *bl, insertion_state_t is) +remove_breakpoint (struct bp_location *bl) { int ret; struct cleanup *old_chain; @@ -4071,7 +4124,7 @@ remove_breakpoint (struct bp_location *bl, insertion_state_t is) switch_to_program_space_and_thread (bl->pspace); - ret = remove_breakpoint_1 (bl, is); + ret = remove_breakpoint_1 (bl, REMOVE_BREAKPOINT); do_cleanups (old_chain); return ret; @@ -4105,7 +4158,7 @@ void breakpoint_init_inferior (enum inf_context context) { struct breakpoint *b, *b_tmp; - struct bp_location *bl, **blp_tmp; + struct bp_location *bl; int ix; struct program_space *pspace = current_program_space; @@ -4171,15 +4224,25 @@ breakpoint_init_inferior (enum inf_context context) /* Likewise for watchpoints on local expressions. */ if (w->exp_valid_block != NULL) delete_breakpoint (b); - else if (context == inf_starting) + else { - /* Reset val field to force reread of starting value in - insert_breakpoints. */ - if (w->val) - value_free (w->val); - w->val = NULL; - w->val_valid = 0; - } + /* Get rid of existing locations, which are no longer + valid. New ones will be created in + update_watchpoint, when the inferior is restarted. + The next update_global_location_list call will + garbage collect them. */ + b->loc = NULL; + + if (context == inf_starting) + { + /* Reset val field to force reread of starting value in + insert_breakpoints. */ + if (w->val) + value_free (w->val); + w->val = NULL; + w->val_valid = 0; + } + } } break; default: @@ -4239,6 +4302,40 @@ breakpoint_here_p (struct address_space *aspace, CORE_ADDR pc) return any_breakpoint_here ? ordinary_breakpoint_here : no_breakpoint_here; } +/* See breakpoint.h. */ + +int +breakpoint_in_range_p (struct address_space *aspace, + CORE_ADDR addr, ULONGEST len) +{ + struct bp_location *bl, **blp_tmp; + + ALL_BP_LOCATIONS (bl, blp_tmp) + { + if (bl->loc_type != bp_loc_software_breakpoint + && bl->loc_type != bp_loc_hardware_breakpoint) + continue; + + if ((breakpoint_enabled (bl->owner) + || bl->permanent) + && breakpoint_location_address_range_overlap (bl, aspace, + addr, len)) + { + if (overlay_debugging + && section_is_overlay (bl->section) + && !section_is_mapped (bl->section)) + { + /* Unmapped overlay -- can't be a match. */ + continue; + } + + return 1; + } + } + + return 0; +} + /* Return true if there's a moribund breakpoint at PC. */ int @@ -4281,7 +4378,6 @@ int breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc) { struct bp_location **blp, **blp_tmp = NULL; - struct bp_location *bl; ALL_BP_LOCATIONS_AT_ADDR (blp, blp_tmp, pc) { @@ -4305,7 +4401,6 @@ software_breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc) { struct bp_location **blp, **blp_tmp = NULL; - struct bp_location *bl; ALL_BP_LOCATIONS_AT_ADDR (blp, blp_tmp, pc) { @@ -4328,7 +4423,6 @@ hardware_breakpoint_inserted_here_p (struct address_space *aspace, CORE_ADDR pc) { struct bp_location **blp, **blp_tmp = NULL; - struct bp_location *bl; ALL_BP_LOCATIONS_AT_ADDR (blp, blp_tmp, pc) { @@ -4367,8 +4461,8 @@ hardware_watchpoint_inserted_in_range (struct address_space *aspace, CORE_ADDR l, h; /* Check for intersection. */ - l = max (loc->address, addr); - h = min (loc->address + loc->length, addr + len); + l = std::max (loc->address, addr); + h = std::min (loc->address + loc->length, addr + len); if (l < h) return 1; } @@ -4662,7 +4756,7 @@ bpstat_do_actions_1 (bpstat *bsp) if (breakpoint_proceeded) { - if (interpreter_async && target_can_async_p ()) + if (current_ui->async) /* If we are in async mode, then the target might be still running, not stopped at any breakpoint, so nothing for us to do here -- just return to the event loop. */ @@ -4724,6 +4818,37 @@ watchpoint_value_print (struct value *val, struct ui_file *stream) } } +/* Print the "Thread ID hit" part of "Thread ID hit Breakpoint N" if + debugging multiple threads. */ + +void +maybe_print_thread_hit_breakpoint (struct ui_out *uiout) +{ + if (ui_out_is_mi_like_p (uiout)) + return; + + ui_out_text (uiout, "\n"); + + if (show_thread_that_caused_stop ()) + { + const char *name; + struct thread_info *thr = inferior_thread (); + + ui_out_text (uiout, "Thread "); + ui_out_field_fmt (uiout, "thread-id", "%s", print_thread_id (thr)); + + name = thr->name != NULL ? thr->name : target_thread_name (thr); + if (name != NULL) + { + ui_out_text (uiout, " \""); + ui_out_field_fmt (uiout, "name", "%s", name); + ui_out_text (uiout, "\""); + } + + ui_out_text (uiout, " hit "); + } +} + /* Generic routine for printing messages indicating why we stopped. The behavior of this function depends on the value 'print_it' in the bpstat structure. Under some circumstances we @@ -5138,8 +5263,6 @@ watchpoint_check (void *p) } else { - struct ui_out *uiout = current_uiout; - /* This seems like the only logical thing to do because if we temporarily ignored the watchpoint, then when we reenter the block in which it is valid it contains @@ -5153,14 +5276,20 @@ watchpoint_check (void *p) call breakpoint_ops->print_it this bp will be deleted already. So we have no choice but print the information here. */ - if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string - (uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE)); - ui_out_text (uiout, "\nWatchpoint "); - ui_out_field_int (uiout, "wpnum", b->base.number); - ui_out_text (uiout, - " deleted because the program has left the block in\n\ -which its expression is valid.\n"); + + SWITCH_THRU_ALL_UIS () + { + struct ui_out *uiout = current_uiout; + + if (ui_out_is_mi_like_p (uiout)) + ui_out_field_string + (uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE)); + ui_out_text (uiout, "\nWatchpoint "); + ui_out_field_int (uiout, "wpnum", b->base.number); + ui_out_text (uiout, + " deleted because the program has left the block in\n" + "which its expression is valid.\n"); + } /* Make sure the watchpoint's commands aren't executed. */ decref_counted_command_line (&b->base.commands); @@ -5328,10 +5457,16 @@ bpstat_check_watchpoint (bpstat bs) /* Can't happen. */ case 0: /* Error from catch_errors. */ - printf_filtered (_("Watchpoint %d deleted.\n"), b->base.number); - watchpoint_del_at_next_stop (b); - /* We've already printed what needs to be printed. */ - bs->print_it = print_it_done; + { + SWITCH_THRU_ALL_UIS () + { + printf_filtered (_("Watchpoint %d deleted.\n"), + b->base.number); + } + watchpoint_del_at_next_stop (b); + /* We've already printed what needs to be printed. */ + bs->print_it = print_it_done; + } break; } } @@ -5382,7 +5517,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid) /* If this is a thread/task-specific breakpoint, don't waste cpu evaluating the condition if this isn't the specified thread/task. */ - if ((b->thread != -1 && b->thread != pid_to_thread_id (ptid)) + if ((b->thread != -1 && b->thread != ptid_to_global_thread_id (ptid)) || (b->task != 0 && b->task != ada_get_task_number (ptid))) { @@ -5694,6 +5829,9 @@ handle_jit_event (void) struct frame_info *frame; struct gdbarch *gdbarch; + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, "handling bp_jit_event\n"); + /* Switch terminal for any messages produced by breakpoint_re_set. */ target_terminal_ours_for_output (); @@ -5714,7 +5852,6 @@ struct bpstat_what bpstat_what (bpstat bs_head) { struct bpstat_what retval; - int jit_event = 0; bpstat bs; retval.main_action = BPSTAT_WHAT_KEEP_CHECKING; @@ -5836,7 +5973,6 @@ bpstat_what (bpstat bs_head) } break; case bp_jit_event: - jit_event = 1; this_action = BPSTAT_WHAT_SINGLE; break; case bp_call_dummy: @@ -5882,19 +6018,16 @@ bpstat_what (bpstat bs_head) _("bpstat_what: unhandled bptype %d"), (int) bptype); } - retval.main_action = max (retval.main_action, this_action); + retval.main_action = std::max (retval.main_action, this_action); } - /* These operations may affect the bs->breakpoint_at state so they are - delayed after MAIN_ACTION is decided above. */ - - if (jit_event) - { - if (debug_infrun) - fprintf_unfiltered (gdb_stdlog, "bpstat_what: bp_jit_event\n"); + return retval; +} - handle_jit_event (); - } +void +bpstat_run_callbacks (bpstat bs_head) +{ + bpstat bs; for (bs = bs_head; bs != NULL; bs = bs->next) { @@ -5904,6 +6037,9 @@ bpstat_what (bpstat bs_head) continue; switch (b->type) { + case bp_jit_event: + handle_jit_event (); + break; case bp_gnu_ifunc_resolver: gnu_ifunc_resolver_stop (b); break; @@ -5912,8 +6048,6 @@ bpstat_what (bpstat bs_head) break; } } - - return retval; } /* Nonzero if we should step constantly (e.g. watchpoints on machines @@ -6450,7 +6584,14 @@ print_one_breakpoint_location (struct breakpoint *b, { /* FIXME should make an annotation for this. */ ui_out_text (uiout, "\tstop only in thread "); - ui_out_field_int (uiout, "thread", b->thread); + if (ui_out_is_mi_like_p (uiout)) + ui_out_field_int (uiout, "thread", b->thread); + else + { + struct thread_info *thr = find_thread_global_id (b->thread); + + ui_out_field_string (uiout, "thread", print_thread_id (thr)); + } ui_out_text (uiout, "\n"); } @@ -6624,15 +6765,15 @@ breakpoint_address_bits (struct breakpoint *b) int print_address_bits = 0; struct bp_location *loc; + /* Software watchpoints that aren't watching memory don't have an + address to print. */ + if (is_no_memory_software_watchpoint (b)) + return 0; + for (loc = b->loc; loc; loc = loc->next) { int addr_bit; - /* Software watchpoints that aren't watching memory don't have - an address to print. */ - if (b->type == bp_watchpoint && loc->watchpoint_type == -1) - continue; - addr_bit = gdbarch_addr_bit (loc->gdbarch); if (addr_bit > print_address_bits) print_address_bits = addr_bit; @@ -6649,7 +6790,8 @@ struct captured_breakpoint_query_args static int do_captured_breakpoint_query (struct ui_out *uiout, void *data) { - struct captured_breakpoint_query_args *args = data; + struct captured_breakpoint_query_args *args + = (struct captured_breakpoint_query_args *) data; struct breakpoint *b; struct bp_location *dummy_loc = NULL; @@ -6689,6 +6831,14 @@ user_breakpoint_p (struct breakpoint *b) return b->number > 0; } +/* See breakpoint.h. */ + +int +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 @@ -6963,14 +7113,14 @@ describe_other_breakpoints (struct gdbarch *gdbarch, /* Return true iff it is meaningful to use the address member of - BPT. For some breakpoint types, the address member is irrelevant - and it makes no sense to attempt to compare it to other addresses - (or use it for any other purpose either). + 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 address and we don't want to mark + 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 at address zero: + breakpoint location at address zero: bp_watchpoint bp_catchpoint @@ -7073,6 +7223,28 @@ breakpoint_location_address_match (struct bp_location *bl, aspace, addr))); } +/* Returns true if the [ADDR,ADDR+LEN) range in ASPACE overlaps + breakpoint BL. BL may be a ranged breakpoint. In most targets, a + match happens only if ASPACE matches the breakpoint's address + space. On targets that have global breakpoints, the address space + doesn't really matter. */ + +static int +breakpoint_location_address_range_overlap (struct bp_location *bl, + struct address_space *aspace, + CORE_ADDR addr, int len) +{ + if (gdbarch_has_global_breakpoints (target_gdbarch ()) + || bl->pspace->aspace == aspace) + { + int bl_len = bl->length != 0 ? bl->length : 1; + + if (mem_ranges_overlap (addr, len, bl->address, bl_len)) + return 1; + } + return 0; +} + /* If LOC1 and LOC2's owners are not tracepoints, returns false directly. Then, if LOC1 and LOC2 represent the same tracepoint location, returns true, otherwise returns false. */ @@ -7483,7 +7655,7 @@ void set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame) { struct breakpoint *b, *b_tmp; - int thread = tp->num; + int thread = tp->global_num; /* To avoid having to rescan all objfile symbols at every step, we maintain a list of continually-inserted but always disabled @@ -7552,7 +7724,7 @@ set_longjmp_breakpoint_for_call_dummy (void) new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy, &momentary_breakpoint_ops, 1); - new_b->thread = pid_to_thread_id (inferior_ptid); + new_b->thread = ptid_to_global_thread_id (inferior_ptid); /* Link NEW_B into the chain of RETVAL breakpoints. */ @@ -7582,7 +7754,7 @@ check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp) struct breakpoint *b, *b_tmp; ALL_BREAKPOINTS_SAFE (b, b_tmp) - if (b->type == bp_longjmp_call_dummy && b->thread == tp->num) + if (b->type == bp_longjmp_call_dummy && b->thread == tp->global_num) { struct breakpoint *dummy_b = b->related_breakpoint; @@ -7669,24 +7841,13 @@ create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address) b->enable_state = bp_enabled; /* location has to be used or breakpoint_re_set will delete me. */ - b->location = new_address_location (b->loc->address); + b->location = new_address_location (b->loc->address, NULL, 0); update_global_location_list_nothrow (UGLL_MAY_INSERT); return b; } -void -remove_thread_event_breakpoints (void) -{ - struct breakpoint *b, *b_tmp; - - ALL_BREAKPOINTS_SAFE (b, b_tmp) - if (b->type == bp_thread_event - && b->loc->pspace == current_program_space) - delete_breakpoint (b); -} - struct lang_and_radix { enum language lang; @@ -7698,12 +7859,8 @@ struct lang_and_radix struct breakpoint * create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address) { - struct breakpoint *b; - - b = create_internal_breakpoint (gdbarch, address, bp_jit_event, - &internal_breakpoint_ops); - update_global_location_list_nothrow (UGLL_MAY_INSERT); - return b; + return create_internal_breakpoint (gdbarch, address, bp_jit_event, + &internal_breakpoint_ops); } /* Remove JIT code registration and unregistration breakpoint(s). */ @@ -7974,7 +8131,7 @@ insert_catch_fork (struct bp_location *bl) catchpoints. */ static int -remove_catch_fork (struct bp_location *bl) +remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason) { return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid)); } @@ -8007,10 +8164,11 @@ print_it_catch_fork (bpstat bs) struct fork_catchpoint *c = (struct fork_catchpoint *) bs->breakpoint_at; annotate_catchpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); if (b->disposition == disp_del) - ui_out_text (uiout, "\nTemporary catchpoint "); + ui_out_text (uiout, "Temporary catchpoint "); else - ui_out_text (uiout, "\nCatchpoint "); + ui_out_text (uiout, "Catchpoint "); if (ui_out_is_mi_like_p (uiout)) { ui_out_field_string (uiout, "reason", @@ -8091,7 +8249,7 @@ insert_catch_vfork (struct bp_location *bl) catchpoints. */ static int -remove_catch_vfork (struct bp_location *bl) +remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason) { return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid)); } @@ -8124,10 +8282,11 @@ print_it_catch_vfork (bpstat bs) struct fork_catchpoint *c = (struct fork_catchpoint *) b; annotate_catchpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); if (b->disposition == disp_del) - ui_out_text (uiout, "\nTemporary catchpoint "); + ui_out_text (uiout, "Temporary catchpoint "); else - ui_out_text (uiout, "\nCatchpoint "); + ui_out_text (uiout, "Catchpoint "); if (ui_out_is_mi_like_p (uiout)) { ui_out_field_string (uiout, "reason", @@ -8233,7 +8392,7 @@ insert_catch_solib (struct bp_location *ignore) } static int -remove_catch_solib (struct bp_location *ignore) +remove_catch_solib (struct bp_location *ignore, enum remove_bp_reason reason) { return 0; } @@ -8320,10 +8479,11 @@ print_it_catch_solib (bpstat bs) struct ui_out *uiout = current_uiout; annotate_catchpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); if (b->disposition == disp_del) - ui_out_text (uiout, "\nTemporary catchpoint "); + ui_out_text (uiout, "Temporary catchpoint "); else - ui_out_text (uiout, "\nCatchpoint "); + ui_out_text (uiout, "Catchpoint "); ui_out_field_int (uiout, "bkptno", b->number); ui_out_text (uiout, "\n"); if (ui_out_is_mi_like_p (uiout)) @@ -8562,7 +8722,7 @@ insert_catch_exec (struct bp_location *bl) } static int -remove_catch_exec (struct bp_location *bl) +remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason) { return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid)); } @@ -8589,10 +8749,11 @@ print_it_catch_exec (bpstat bs) struct exec_catchpoint *c = (struct exec_catchpoint *) b; annotate_catchpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); if (b->disposition == disp_del) - ui_out_text (uiout, "\nTemporary catchpoint "); + ui_out_text (uiout, "Temporary catchpoint "); else - ui_out_text (uiout, "\nCatchpoint "); + ui_out_text (uiout, "Catchpoint "); if (ui_out_is_mi_like_p (uiout)) { ui_out_field_string (uiout, "reason", @@ -8813,7 +8974,7 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal, momentary breakpoints to be active in only a single thread of control. */ if (in_thread_list (inferior_ptid)) - b->thread = pid_to_thread_id (inferior_ptid); + b->thread = ptid_to_global_thread_id (inferior_ptid); update_global_location_list_nothrow (UGLL_MAY_INSERT); @@ -8980,7 +9141,7 @@ program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address) if (bpoint == NULL) return 0; - target_mem = alloca (len); + 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 @@ -9007,6 +9168,13 @@ 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 + memory. */ + if (!breakpoint_address_is_meaningful (loc->owner)) + return 0; + cleanup = save_current_space_and_thread (); switch_to_program_space_and_thread (loc->pspace); @@ -9074,8 +9242,7 @@ update_dprintf_command_list (struct breakpoint *b) gdb_assert (printf_line != NULL); /* Manufacture a printf sequence. */ { - struct command_line *printf_cmd_line - = xmalloc (sizeof (struct command_line)); + struct command_line *printf_cmd_line = XNEW (struct command_line); printf_cmd_line->control_type = simple_control; printf_cmd_line->body_count = 0; @@ -9105,7 +9272,8 @@ update_dprintf_commands (char *args, int from_tty, /* Create a breakpoint with SAL as location. Use LOCATION as a description of the location, and COND_STRING - as condition expression. */ + as condition expression. If LOCATION is NULL then create an + "address location" from the address in the SAL. */ static void init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch, @@ -9241,7 +9409,18 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch, if (location != NULL) b->location = location; else - b->location = new_address_location (b->loc->address); + { + const char *addr_string = NULL; + int addr_string_len = 0; + + if (location != NULL) + addr_string = event_location_to_string (location); + if (addr_string != NULL) + addr_string_len = strlen (addr_string); + + b->location = new_address_location (b->loc->address, + addr_string, addr_string_len); + } b->filter = filter; } @@ -9367,8 +9546,7 @@ parse_breakpoint_sals (const struct event_location *location, CORE_ADDR pc; init_sal (&sal); /* Initialize to zeroes. */ - lsal.sals.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); + lsal.sals.sals = XNEW (struct symtab_and_line); /* Set sal's pspace, pc, symtab, and line to the values corresponding to the last call to print_frame_info. @@ -9419,7 +9597,7 @@ parse_breakpoint_sals (const struct event_location *location, && strchr ("+-", address[0]) != NULL && address[1] != '[')) { - decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, + decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL, get_last_displayed_symtab (), get_last_displayed_line (), canonical, NULL, NULL); @@ -9427,7 +9605,7 @@ parse_breakpoint_sals (const struct event_location *location, } } - decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, + decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL, cursal.symtab, cursal.line, canonical, NULL, NULL); } @@ -9482,14 +9660,6 @@ check_fast_tracepoint_sals (struct gdbarch *gdbarch, } } -/* Issue an invalid thread ID error. */ - -static void ATTRIBUTE_NORETURN -invalid_thread_id_error (int id) -{ - error (_("Unknown thread %d."), id); -} - /* Given TOK, a string specification of condition and thread, as accepted by the 'break' command, extract the condition string and thread number and set *COND_STRING and *THREAD. @@ -9538,14 +9708,14 @@ find_condition_and_thread (const char *tok, CORE_ADDR pc, } else if (toklen >= 1 && strncmp (tok, "thread", toklen) == 0) { - char *tmptok; + const char *tmptok; + struct thread_info *thr; tok = end_tok + 1; - *thread = strtol (tok, &tmptok, 0); + thr = parse_thread_id (tok, &tmptok); if (tok == tmptok) error (_("Junk after thread keyword.")); - if (!valid_thread_id (*thread)) - invalid_thread_id_error (*thread); + *thread = thr->global_num; tok = tmptok; } else if (toklen >= 1 && strncmp (tok, "task", toklen) == 0) @@ -9595,7 +9765,7 @@ decode_static_tracepoint_spec (const char **arg_p) error (_("No known static tracepoint marker named %s"), marker_str); sals.nelts = VEC_length(static_tracepoint_marker_p, markers); - sals.sals = xmalloc (sizeof *sals.sals * sals.nelts); + sals.sals = XNEWVEC (struct symtab_and_line, sals.nelts); for (i = 0; i < sals.nelts; i++) { @@ -10124,10 +10294,13 @@ print_it_ranged_breakpoint (bpstat bs) gdb_assert (bl && bl->next == NULL); annotate_breakpoint (b->number); + + maybe_print_thread_hit_breakpoint (uiout); + if (b->disposition == disp_del) - ui_out_text (uiout, "\nTemporary ranged breakpoint "); + ui_out_text (uiout, "Temporary ranged breakpoint "); else - ui_out_text (uiout, "\nRanged breakpoint "); + ui_out_text (uiout, "Ranged breakpoint "); if (ui_out_is_mi_like_p (uiout)) { ui_out_field_string (uiout, "reason", @@ -10263,7 +10436,7 @@ find_breakpoint_range_end (struct symtab_and_line sal) static void break_range_command (char *arg, int from_tty) { - char *arg_start, *addr_string_start, *addr_string_end; + char *arg_start, *addr_string_start; struct linespec_result canonical_start, canonical_end; int bp_count, can_use_bp, length; CORE_ADDR end; @@ -10326,7 +10499,7 @@ break_range_command (char *arg, int from_tty) where +14 means 14 lines from the start location. */ end_location = string_to_event_location (&arg, current_language); make_cleanup_delete_event_location (end_location); - decode_line_full (end_location, DECODE_LINE_FUNFIRSTLINE, + decode_line_full (end_location, DECODE_LINE_FUNFIRSTLINE, NULL, sal_start.symtab, sal_start.line, &canonical_end, NULL, NULL); @@ -10558,7 +10731,7 @@ insert_watchpoint (struct bp_location *bl) /* Implement the "remove" breakpoint_ops method for hardware watchpoints. */ static int -remove_watchpoint (struct bp_location *bl) +remove_watchpoint (struct bp_location *bl, enum remove_bp_reason reason) { struct watchpoint *w = (struct watchpoint *) bl->owner; int length = w->exact ? 1 : bl->length; @@ -10636,11 +10809,13 @@ print_it_watchpoint (bpstat bs) stb = mem_fileopen (); old_chain = make_cleanup_ui_file_delete (stb); + annotate_watchpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); + switch (b->type) { case bp_watchpoint: case bp_hardware_watchpoint: - annotate_watchpoint (b->number); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", @@ -10675,7 +10850,6 @@ print_it_watchpoint (bpstat bs) case bp_access_watchpoint: if (bs->old_val != NULL) { - annotate_watchpoint (b->number); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", @@ -10812,7 +10986,7 @@ insert_masked_watchpoint (struct bp_location *bl) masked hardware watchpoints. */ static int -remove_masked_watchpoint (struct bp_location *bl) +remove_masked_watchpoint (struct bp_location *bl, enum remove_bp_reason reason) { struct watchpoint *w = (struct watchpoint *) bl->owner; @@ -10852,10 +11026,12 @@ print_it_masked_watchpoint (bpstat bs) /* Masked watchpoints have only one location. */ gdb_assert (b->loc && b->loc->next == NULL); + annotate_watchpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); + switch (b->type) { case bp_hardware_watchpoint: - annotate_watchpoint (b->number); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", @@ -11050,25 +11226,23 @@ watch_command_1 (const char *arg, int accessflag, int from_tty, if (toklen == 6 && startswith (tok, "thread")) { + struct thread_info *thr; /* At this point we've found a "thread" token, which means the user is trying to set a watchpoint that triggers only in a specific thread. */ - char *endp; + const char *endp; if (thread != -1) error(_("You can specify only one thread.")); /* Extract the thread ID from the next token. */ - thread = strtol (value_start, &endp, 0); + thr = parse_thread_id (value_start, &endp); - /* Check if the user provided a valid numeric value for the - thread ID. */ + /* Check if the user provided a valid thread ID. */ if (*endp != ' ' && *endp != '\t' && *endp != '\0') - error (_("Invalid thread ID specification %s."), value_start); + invalid_thread_id_error (value_start); - /* Check if the thread actually exists. */ - if (!valid_thread_id (thread)) - invalid_thread_id_error (thread); + thread = thr->global_num; } else if (toklen == 4 && startswith (tok, "mask")) { @@ -11459,29 +11633,112 @@ awatch_command (char *arg, int from_tty) } -/* Helper routines for the until_command routine in infcmd.c. Here - because it uses the mechanisms of breakpoints. */ +/* Data for the FSM that manages the until(location)/advance commands + in infcmd.c. Here because it uses the mechanisms of + breakpoints. */ -struct until_break_command_continuation_args +struct until_break_fsm { - struct breakpoint *breakpoint; - struct breakpoint *breakpoint2; - int thread_num; + /* The base class. */ + struct thread_fsm thread_fsm; + + /* The thread that as current when the command was executed. */ + int thread; + + /* The breakpoint set at the destination location. */ + struct breakpoint *location_breakpoint; + + /* Breakpoint set at the return address in the caller frame. May be + NULL. */ + struct breakpoint *caller_breakpoint; }; -/* This function is called by fetch_inferior_event via the - cmd_continuation pointer, to complete the until command. It takes - care of cleaning up the temporary breakpoints set up by the until - command. */ +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); + +/* until_break_fsm's vtable. */ + +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, +}; + +/* Allocate a new until_break_command_fsm. */ + +static struct until_break_fsm * +new_until_break_fsm (struct interp *cmd_interp, int thread, + struct breakpoint *location_breakpoint, + struct breakpoint *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; + sm->caller_breakpoint = caller_breakpoint; + + 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) +{ + 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 + && bpstat_find_breakpoint (tp->control.stop_bpstat, + sm->caller_breakpoint) != NULL)) + thread_fsm_set_finished (self); + + return 1; +} + +/* Implementation of the 'clean_up' FSM method for the + until(location)/advance commands. */ + static void -until_break_command_continuation (void *arg, int err) +until_break_fsm_clean_up (struct thread_fsm *self, + struct thread_info *thread) { - struct until_break_command_continuation_args *a = arg; + struct until_break_fsm *sm = (struct until_break_fsm *) self; - delete_breakpoint (a->breakpoint); - if (a->breakpoint2) - delete_breakpoint (a->breakpoint2); - delete_longjmp_breakpoint (a->thread_num); + /* 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); +} + +/* 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) +{ + return EXEC_ASYNC_LOCATION_REACHED; } void @@ -11493,12 +11750,13 @@ until_break_command (char *arg, int from_tty, int anywhere) struct gdbarch *frame_gdbarch; struct frame_id stack_frame_id; struct frame_id caller_frame_id; - struct breakpoint *breakpoint; - struct breakpoint *breakpoint2 = NULL; + struct breakpoint *location_breakpoint; + struct breakpoint *caller_breakpoint = NULL; struct cleanup *old_chain, *cleanup; int thread; struct thread_info *tp; struct event_location *location; + struct until_break_fsm *sm; clear_proceed_status (0); @@ -11509,12 +11767,12 @@ until_break_command (char *arg, int from_tty, int anywhere) cleanup = make_cleanup_delete_event_location (location); if (last_displayed_sal_is_valid ()) - sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE, + sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE, NULL, get_last_displayed_symtab (), get_last_displayed_line ()); else sals = decode_line_1 (location, DECODE_LINE_FUNFIRSTLINE, - (struct symtab *) NULL, 0); + NULL, (struct symtab *) NULL, 0); if (sals.nelts != 1) error (_("Couldn't get information on specified line.")); @@ -11528,7 +11786,7 @@ until_break_command (char *arg, int from_tty, int anywhere) resolve_sal_pc (&sal); tp = inferior_thread (); - thread = tp->num; + thread = tp->global_num; old_chain = make_cleanup (null_cleanup, NULL); @@ -11548,14 +11806,16 @@ until_break_command (char *arg, int from_tty, int anywhere) if (frame_id_p (caller_frame_id)) { struct symtab_and_line sal2; + struct gdbarch *caller_gdbarch; sal2 = find_pc_line (frame_unwind_caller_pc (frame), 0); sal2.pc = frame_unwind_caller_pc (frame); - breakpoint2 = set_momentary_breakpoint (frame_unwind_caller_arch (frame), - sal2, - caller_frame_id, - bp_until); - make_cleanup_delete_breakpoint (breakpoint2); + caller_gdbarch = frame_unwind_caller_arch (frame); + caller_breakpoint = set_momentary_breakpoint (caller_gdbarch, + sal2, + caller_frame_id, + bp_until); + make_cleanup_delete_breakpoint (caller_breakpoint); set_longjmp_breakpoint (tp, caller_frame_id); make_cleanup (delete_longjmp_breakpoint_cleanup, &thread); @@ -11567,38 +11827,22 @@ until_break_command (char *arg, int from_tty, int anywhere) if (anywhere) /* If the user told us to continue until a specified location, we don't specify a frame at which we need to stop. */ - breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, - null_frame_id, bp_until); + location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, + null_frame_id, bp_until); else /* Otherwise, specify the selected frame, because we want to stop only at the very same frame. */ - breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, - stack_frame_id, bp_until); - make_cleanup_delete_breakpoint (breakpoint); - - proceed (-1, GDB_SIGNAL_DEFAULT); + location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, + stack_frame_id, bp_until); + make_cleanup_delete_breakpoint (location_breakpoint); - /* If we are running asynchronously, and proceed call above has - actually managed to start the target, arrange for breakpoints to - be deleted when the target stops. Otherwise, we're already - stopped and delete breakpoints via cleanup chain. */ - - if (target_can_async_p () && is_running (inferior_ptid)) - { - struct until_break_command_continuation_args *args; - args = xmalloc (sizeof (*args)); + sm = new_until_break_fsm (command_interp (), tp->global_num, + location_breakpoint, caller_breakpoint); + tp->thread_fsm = &sm->thread_fsm; - args->breakpoint = breakpoint; - args->breakpoint2 = breakpoint2; - args->thread_num = thread; + discard_cleanups (old_chain); - discard_cleanups (old_chain); - add_continuation (inferior_thread (), - until_break_command_continuation, args, - xfree); - } - else - do_cleanups (old_chain); + proceed (-1, GDB_SIGNAL_DEFAULT); do_cleanups (cleanup); } @@ -11779,9 +12023,9 @@ tcatch_command (char *arg, int from_tty) static int compare_breakpoints (const void *a, const void *b) { - const breakpoint_p *ba = a; + const breakpoint_p *ba = (const breakpoint_p *) a; uintptr_t ua = (uintptr_t) *ba; - const breakpoint_p *bb = b; + const breakpoint_p *bb = (const breakpoint_p *) b; uintptr_t ub = (uintptr_t) *bb; if ((*ba)->number < (*bb)->number) @@ -11820,8 +12064,7 @@ clear_command (char *arg, int from_tty) } else { - sals.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); + sals.sals = XNEW (struct symtab_and_line); make_cleanup (xfree, sals.sals); init_sal (&sal); /* Initialize to zeroes. */ @@ -12002,8 +12245,8 @@ breakpoint_auto_delete (bpstat bs) static int bp_location_compare (const void *ap, const void *bp) { - struct bp_location *a = *(void **) ap; - struct bp_location *b = *(void **) bp; + const struct bp_location *a = *(const struct bp_location **) ap; + const struct bp_location *b = *(const struct bp_location **) bp; if (a->address != b->address) return (a->address > b->address) - (a->address < b->address); @@ -12074,9 +12317,7 @@ download_tracepoint_locations (void) { struct breakpoint *b; struct cleanup *old_chain; - - if (!target_can_download_tracepoint ()) - return; + enum tribool can_download_tracepoint = TRIBOOL_UNKNOWN; old_chain = save_current_space_and_thread (); @@ -12091,6 +12332,17 @@ download_tracepoint_locations (void) : !may_insert_tracepoints)) continue; + if (can_download_tracepoint == TRIBOOL_UNKNOWN) + { + if (target_can_download_tracepoint ()) + can_download_tracepoint = TRIBOOL_TRUE; + else + can_download_tracepoint = TRIBOOL_FALSE; + } + + if (can_download_tracepoint == TRIBOOL_FALSE) + break; + for (bl = b->loc; bl; bl = bl->next) { /* In tracepoint, locations are _never_ duplicated, so @@ -12238,7 +12490,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode) for (loc = b->loc; loc; loc = loc->next) bp_location_count++; - bp_location = xmalloc (sizeof (*bp_location) * bp_location_count); + bp_location = XNEWVEC (struct bp_location *, bp_location_count); locp = bp_location; ALL_BREAKPOINTS (b) for (loc = b->loc; loc; loc = loc->next) @@ -12373,7 +12625,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode) if (!keep_in_target) { - if (remove_breakpoint (old_loc, mark_uninserted)) + if (remove_breakpoint (old_loc)) { /* This is just about all we can do. We could keep this location on the global list, and try to @@ -12595,7 +12847,7 @@ bpstat_remove_bp_location (bpstat bps, struct breakpoint *bpt) static int bpstat_remove_breakpoint_callback (struct thread_info *th, void *data) { - struct breakpoint *bpt = data; + struct breakpoint *bpt = (struct breakpoint *) data; bpstat_remove_bp_location (th->control.stop_bpstat, bpt); return 0; @@ -12730,7 +12982,8 @@ base_breakpoint_insert_location (struct bp_location *bl) } static int -base_breakpoint_remove_location (struct bp_location *bl) +base_breakpoint_remove_location (struct bp_location *bl, + enum remove_bp_reason reason) { internal_error_pure_virtual_called (); } @@ -12821,6 +13074,7 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch, static void base_breakpoint_decode_location (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals) { internal_error_pure_virtual_called (); @@ -12871,7 +13125,7 @@ static void bkpt_re_set (struct breakpoint *b) { /* FIXME: is this still reachable? */ - if (event_location_empty_p (b->location)) + if (breakpoint_event_location_empty_p (b)) { /* Anything without a location can't be re-set. */ delete_breakpoint (b); @@ -12884,6 +13138,11 @@ bkpt_re_set (struct breakpoint *b) static int bkpt_insert_location (struct bp_location *bl) { + CORE_ADDR addr = bl->target_info.reqstd_address; + + bl->target_info.kind = breakpoint_kind (bl, &addr); + bl->target_info.placed_address = addr; + if (bl->loc_type == bp_loc_hardware_breakpoint) return target_insert_hw_breakpoint (bl->gdbarch, &bl->target_info); else @@ -12891,12 +13150,12 @@ bkpt_insert_location (struct bp_location *bl) } static int -bkpt_remove_location (struct bp_location *bl) +bkpt_remove_location (struct bp_location *bl, enum remove_bp_reason reason) { if (bl->loc_type == bp_loc_hardware_breakpoint) return target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info); else - return target_remove_breakpoint (bl->gdbarch, &bl->target_info); + return target_remove_breakpoint (bl->gdbarch, &bl->target_info, reason); } static int @@ -12964,10 +13223,12 @@ bkpt_print_it (bpstat bs) bl->address, b->number, 1); annotate_breakpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); + if (bp_temp) - ui_out_text (uiout, "\nTemporary breakpoint "); + ui_out_text (uiout, "Temporary breakpoint "); else - ui_out_text (uiout, "\nBreakpoint "); + ui_out_text (uiout, "Breakpoint "); if (ui_out_is_mi_like_p (uiout)) { ui_out_field_string (uiout, "reason", @@ -13068,9 +13329,10 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch, static void bkpt_decode_location (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals) { - decode_location_default (b, location, sals); + decode_location_default (b, location, search_pspace, sals); } /* Virtual table for internal breakpoints. */ @@ -13190,28 +13452,6 @@ momentary_bkpt_check_status (bpstat bs) static enum print_stop_action momentary_bkpt_print_it (bpstat bs) { - struct ui_out *uiout = current_uiout; - - if (ui_out_is_mi_like_p (uiout)) - { - struct breakpoint *b = bs->breakpoint_at; - - switch (b->type) - { - case bp_finish: - ui_out_field_string - (uiout, "reason", - async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED)); - break; - - case bp_until: - ui_out_field_string - (uiout, "reason", - async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED)); - break; - } - } - return PRINT_UNKNOWN; } @@ -13229,7 +13469,7 @@ momentary_bkpt_print_mention (struct breakpoint *b) static void longjmp_bkpt_dtor (struct breakpoint *self) { - struct thread_info *tp = find_thread_id (self->thread); + struct thread_info *tp = find_thread_global_id (self->thread); if (tp) tp->initiating_frame = null_frame_id; @@ -13258,7 +13498,8 @@ bkpt_probe_insert_location (struct bp_location *bl) } static int -bkpt_probe_remove_location (struct bp_location *bl) +bkpt_probe_remove_location (struct bp_location *bl, + enum remove_bp_reason reason) { /* Let's clear the semaphore before removing the location. */ if (bl->probe.probe->pops->clear_semaphore != NULL) @@ -13266,7 +13507,7 @@ bkpt_probe_remove_location (struct bp_location *bl) bl->probe.objfile, bl->gdbarch); - return bkpt_remove_location (bl); + return bkpt_remove_location (bl, reason); } static void @@ -13276,7 +13517,7 @@ bkpt_probe_create_sals_from_location (const struct event_location *location, { struct linespec_sals lsal; - lsal.sals = parse_probes (location, canonical); + lsal.sals = parse_probes (location, NULL, canonical); lsal.canonical = xstrdup (event_location_to_string (canonical->location)); VEC_safe_push (linespec_sals, canonical->sals, &lsal); } @@ -13284,9 +13525,10 @@ bkpt_probe_create_sals_from_location (const struct event_location *location, static void bkpt_probe_decode_location (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals) { - *sals = parse_probes (location, NULL); + *sals = parse_probes (location, search_pspace, NULL); if (!sals->sals) error (_("probe not found")); } @@ -13360,7 +13602,7 @@ tracepoint_print_recreate (struct breakpoint *self, struct ui_file *fp) if (self->type == bp_fast_tracepoint) fprintf_unfiltered (fp, "ftrace"); - if (self->type == bp_static_tracepoint) + else if (self->type == bp_static_tracepoint) fprintf_unfiltered (fp, "strace"); else if (self->type == bp_tracepoint) fprintf_unfiltered (fp, "trace"); @@ -13408,9 +13650,10 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch, static void tracepoint_decode_location (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals) { - decode_location_default (b, location, sals); + decode_location_default (b, location, search_pspace, sals); } struct breakpoint_ops tracepoint_breakpoint_ops; @@ -13431,10 +13674,11 @@ tracepoint_probe_create_sals_from_location static void tracepoint_probe_decode_location (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals) { /* We use the same method for breakpoint on probes. */ - bkpt_probe_decode_location (b, location, sals); + bkpt_probe_decode_location (b, location, search_pspace, sals); } static struct breakpoint_ops tracepoint_probe_breakpoint_ops; @@ -13599,6 +13843,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch, static void strace_marker_decode_location (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals) { struct tracepoint *tp = (struct tracepoint *) b; @@ -13721,7 +13966,7 @@ delete_breakpoint (struct breakpoint *bpt) static void do_delete_breakpoint_cleanup (void *b) { - delete_breakpoint (b); + delete_breakpoint ((struct breakpoint *) b); } struct cleanup * @@ -13816,11 +14061,19 @@ delete_command (char *arg, int from_tty) map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL); } +/* Return true if all locations of B bound to PSPACE are pending. If + PSPACE is NULL, all locations of all program spaces are + considered. */ + static int -all_locations_are_pending (struct bp_location *loc) +all_locations_are_pending (struct breakpoint *b, struct program_space *pspace) { - for (; loc; loc = loc->next) - if (!loc->shlib_disabled + struct bp_location *loc; + + for (loc = b->loc; loc != NULL; loc = loc->next) + if ((pspace == NULL + || loc->pspace == pspace) + && !loc->shlib_disabled && !loc->pspace->executing_startup) return 0; return 1; @@ -13940,7 +14193,7 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal) struct symbol *sym; struct static_tracepoint_marker *tpmarker; struct ui_out *uiout = current_uiout; - struct explicit_location explicit; + struct explicit_location explicit_loc; tpmarker = VEC_index (static_tracepoint_marker_p, markers, 0); @@ -13982,12 +14235,12 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal) b->loc->symtab = sym != NULL ? sal2.symtab : NULL; delete_event_location (b->location); - initialize_explicit_location (&explicit); - explicit.source_filename + initialize_explicit_location (&explicit_loc); + explicit_loc.source_filename = ASTRDUP (symtab_to_filename_for_display (sal2.symtab)); - explicit.line_offset.offset = b->loc->line_number; - explicit.line_offset.sign = LINE_OFFSET_NONE; - b->location = new_explicit_location (&explicit); + explicit_loc.line_offset.offset = b->loc->line_number; + explicit_loc.line_offset.sign = LINE_OFFSET_NONE; + b->location = new_explicit_location (&explicit_loc); /* Might be nice to check if function changed, and warn if so. */ @@ -14025,24 +14278,64 @@ locations_are_equal (struct bp_location *a, struct bp_location *b) return 1; } -/* Create new breakpoint locations for B (a hardware or software breakpoint) - based on SALS and SALS_END. If SALS_END.NELTS is not zero, then B is - a ranged breakpoint. */ +/* Split all locations of B that are bound to PSPACE out of B's + location list to a separate list and return that list's head. If + PSPACE is NULL, hoist out all locations of B. */ + +static struct bp_location * +hoist_existing_locations (struct breakpoint *b, struct program_space *pspace) +{ + struct bp_location head; + struct bp_location *i = b->loc; + struct bp_location **i_link = &b->loc; + struct bp_location *hoisted = &head; + + if (pspace == NULL) + { + i = b->loc; + b->loc = NULL; + return i; + } + + head.next = NULL; + + while (i != NULL) + { + if (i->pspace == pspace) + { + *i_link = i->next; + i->next = NULL; + hoisted->next = i; + hoisted = i; + } + else + i_link = &i->next; + i = *i_link; + } + + return head.next; +} + +/* Create new breakpoint locations for B (a hardware or software + breakpoint) based on SALS and SALS_END. If SALS_END.NELTS is not + zero, then B is a ranged breakpoint. Only recreates locations for + FILTER_PSPACE. Locations of other program spaces are left + untouched. */ void update_breakpoint_locations (struct breakpoint *b, + struct program_space *filter_pspace, struct symtabs_and_lines sals, struct symtabs_and_lines sals_end) { int i; - struct bp_location *existing_locations = b->loc; + struct bp_location *existing_locations; if (sals_end.nelts != 0 && (sals.nelts != 1 || sals_end.nelts != 1)) { /* Ranged breakpoints have only one start location and one end location. */ b->enable_state = bp_disabled; - update_global_location_list (UGLL_MAY_INSERT); printf_unfiltered (_("Could not reset ranged breakpoint %d: " "multiple locations found\n"), b->number); @@ -14055,10 +14348,10 @@ update_breakpoint_locations (struct breakpoint *b, We'd like to retain the location, so that when the library is loaded again, we don't loose the enabled/disabled status of the individual locations. */ - if (all_locations_are_pending (existing_locations) && sals.nelts == 0) + if (all_locations_are_pending (b, filter_pspace) && sals.nelts == 0) return; - b->loc = NULL; + existing_locations = hoist_existing_locations (b, filter_pspace); for (i = 0; i < sals.nelts; ++i) { @@ -14140,8 +14433,6 @@ update_breakpoint_locations (struct breakpoint *b, if (!locations_are_equal (existing_locations, b->loc)) observer_notify_breakpoint_modified (b); - - update_global_location_list (UGLL_MAY_INSERT); } /* Find the SaL locations corresponding to the given LOCATION. @@ -14149,7 +14440,7 @@ update_breakpoint_locations (struct breakpoint *b, static struct symtabs_and_lines location_to_sals (struct breakpoint *b, struct event_location *location, - int *found) + struct program_space *search_pspace, int *found) { struct symtabs_and_lines sals = {0}; struct gdb_exception exception = exception_none; @@ -14158,7 +14449,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location, TRY { - b->ops->decode_location (b, location, &sals); + b->ops->decode_location (b, location, search_pspace, &sals); } CATCH (e, RETURN_MASK_ERROR) { @@ -14174,7 +14465,10 @@ location_to_sals (struct breakpoint *b, struct event_location *location, breakpoint being disabled, and don't want to see more errors. */ if (e.error == NOT_FOUND_ERROR - && (b->condition_not_parsed + && (b->condition_not_parsed + || (b->loc != NULL + && search_pspace != NULL + && b->loc->pspace != search_pspace) || (b->loc && b->loc->shlib_disabled) || (b->loc && b->loc->pspace->executing_startup) || b->enable_state == bp_disabled)) @@ -14243,8 +14537,9 @@ breakpoint_re_set_default (struct breakpoint *b) struct symtabs_and_lines sals, sals_end; struct symtabs_and_lines expanded = {0}; struct symtabs_and_lines expanded_end = {0}; + struct program_space *filter_pspace = current_program_space; - sals = location_to_sals (b, b->location, &found); + sals = location_to_sals (b, b->location, filter_pspace, &found); if (found) { make_cleanup (xfree, sals.sals); @@ -14253,7 +14548,8 @@ breakpoint_re_set_default (struct breakpoint *b) if (b->location_range_end != NULL) { - sals_end = location_to_sals (b, b->location_range_end, &found); + sals_end = location_to_sals (b, b->location_range_end, + filter_pspace, &found); if (found) { make_cleanup (xfree, sals_end.sals); @@ -14261,7 +14557,7 @@ breakpoint_re_set_default (struct breakpoint *b) } } - update_breakpoint_locations (b, expanded, expanded_end); + update_breakpoint_locations (b, filter_pspace, expanded, expanded_end); } /* Default method for creating SALs from an address string. It basically @@ -14305,12 +14601,13 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch, static void decode_location_default (struct breakpoint *b, const struct event_location *location, + struct program_space *search_pspace, struct symtabs_and_lines *sals) { struct linespec_result canonical; init_linespec_result (&canonical); - decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, + decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace, (struct symtab *) NULL, 0, &canonical, multiple_symbols_all, b->filter); @@ -14337,15 +14634,10 @@ decode_location_default (struct breakpoint *b, static struct cleanup * prepare_re_set_context (struct breakpoint *b) { - struct cleanup *cleanups; - input_radix = b->input_radix; - cleanups = save_current_space_and_thread (); - if (b->pspace != NULL) - switch_to_program_space_and_thread (b->pspace); set_language (b->language); - return cleanups; + return make_cleanup (null_cleanup, NULL); } /* Reset a breakpoint given it's struct breakpoint * BINT. @@ -14365,7 +14657,9 @@ breakpoint_re_set_one (void *bint) return 0; } -/* Re-set all breakpoints after symbols have been re-loaded. */ +/* Re-set breakpoint locations for the current program space. + Locations bound to other program spaces are left untouched. */ + void breakpoint_re_set (void) { @@ -14376,7 +14670,12 @@ breakpoint_re_set (void) save_language = current_language->la_language; save_input_radix = input_radix; - old_chain = save_current_program_space (); + old_chain = save_current_space_and_thread (); + + /* Note: we must not try to insert locations until after all + breakpoints have been re-set. Otherwise, e.g., when re-setting + breakpoint 1, we'd insert the locations of breakpoint 2, which + hadn't been re-set yet, and thus may have stale locations. */ ALL_BREAKPOINTS_SAFE (b, b_tmp) { @@ -14398,6 +14697,9 @@ breakpoint_re_set (void) create_longjmp_master_breakpoint (); create_std_terminate_master_breakpoint (); create_exception_master_breakpoint (); + + /* Now we can insert. */ + update_global_location_list (UGLL_MAY_INSERT); } /* Reset the thread number of this breakpoint: @@ -14410,7 +14712,7 @@ breakpoint_re_set_thread (struct breakpoint *b) if (b->thread != -1) { if (in_thread_list (inferior_ptid)) - b->thread = pid_to_thread_id (inferior_ptid); + b->thread = ptid_to_global_thread_id (inferior_ptid); /* We're being called after following a fork. The new fork is selected as current, and unless this was a vfork will have a @@ -14499,21 +14801,18 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *, { int num; struct breakpoint *b, *tmp; - int match; - struct get_number_or_range_state state; if (args == 0 || *args == '\0') error_no_arg (_("one or more breakpoint numbers")); - init_number_or_range (&state, args); + number_or_range_parser parser (args); - while (!state.finished) + while (!parser.finished ()) { - const char *p = state.string; - - match = 0; + const char *p = parser.cur_tok (); + bool match = false; - num = get_number_or_range (&state); + num = parser.get_number (); if (num == 0) { warning (_("bad breakpoint number at or near '%s'"), p); @@ -14523,11 +14822,11 @@ map_breakpoint_numbers (char *args, void (*function) (struct breakpoint *, ALL_BREAKPOINTS_SAFE (b, tmp) if (b->number == num) { - match = 1; + match = true; function (b, data); break; } - if (match == 0) + if (!match) printf_unfiltered (_("No breakpoint number %d.\n"), num); } } @@ -14921,7 +15220,7 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch, if (tp->control.single_step_breakpoints == NULL) { tp->control.single_step_breakpoints - = new_single_step_breakpoint (tp->num, gdbarch); + = new_single_step_breakpoint (tp->global_num, gdbarch); } sal = find_pc_line (pc, 0); @@ -15308,12 +15607,10 @@ trace_pass_command (char *args, int from_tty) } else { - struct get_number_or_range_state state; - - init_number_or_range (&state, args); - while (!state.finished) + number_or_range_parser parser (args); + while (!parser.finished ()) { - t1 = get_tracepoint_by_number (&args, &state); + t1 = get_tracepoint_by_number (&args, &parser); if (t1) trace_pass_set_count (t1, count, from_tty); } @@ -15359,16 +15656,16 @@ get_tracepoint_by_number_on_target (int num) struct tracepoint * get_tracepoint_by_number (char **arg, - struct get_number_or_range_state *state) + number_or_range_parser *parser) { struct breakpoint *t; int tpnum; char *instring = arg == NULL ? NULL : *arg; - if (state) + if (parser != NULL) { - gdb_assert (!state->finished); - tpnum = get_number_or_range (state); + gdb_assert (!parser->finished ()); + tpnum = parser->get_number (); } else if (arg == NULL || *arg == NULL || ! **arg) tpnum = tracepoint_count; @@ -15488,8 +15785,6 @@ save_breakpoints (char *filename, int from_tty, if (tp->type != bp_dprintf && tp->commands) { - struct gdb_exception exception; - fprintf_unfiltered (fp, " commands\n"); ui_out_redirect (current_uiout, fp);