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);
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
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
overlay_events_enabled = 0;
}
}
- update_global_location_list (UGLL_MAY_INSERT);
}
static void
}
}
}
- update_global_location_list (UGLL_MAY_INSERT);
do_cleanups (old_chain);
}
}
}
- update_global_location_list (UGLL_MAY_INSERT);
-
do_cleanups (old_chain);
}
b->location = new_explicit_location (&explicit_loc);
b->enable_state = bp_disabled;
}
-
- update_global_location_list (UGLL_MAY_INSERT);
}
void
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);
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). */
/* 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,
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;
}
&& 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);
}
}
- decode_line_full (location, DECODE_LINE_FUNFIRSTLINE,
+ decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
cursal.symtab, cursal.line, canonical, NULL, NULL);
}
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);
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."));
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 ();
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. */
{
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);
}
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"));
}
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;
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;
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;
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;
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);
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)
{
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.
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;
TRY
{
- b->ops->decode_location (b, location, &sals);
+ b->ops->decode_location (b, location, search_pspace, &sals);
}
CATCH (e, RETURN_MASK_ERROR)
{
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))
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);
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);
}
}
- 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
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);
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.
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)
{
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)
{
create_longjmp_master_breakpoint ();
create_std_terminate_master_breakpoint ();
create_exception_master_breakpoint ();
+
+ /* Now we can insert. */
+ update_global_location_list (UGLL_MAY_INSERT);
}
\f
/* Reset the thread number of this breakpoint: