aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2016-04-01 15:28:42 +0100
committerPedro Alves <palves@redhat.com>2016-09-19 15:44:42 +0100
commit31ac74b0b3301d396b3039d869a17c620c1cb552 (patch)
tree51ab3d3ae05969a994584ac777d7e30a43bbe2d7
parent0d2b53cc3e99a03733fbf9d3dc176cbb3aba8154 (diff)
downloadfsf-binutils-gdb-31ac74b0b3301d396b3039d869a17c620c1cb552.zip
fsf-binutils-gdb-31ac74b0b3301d396b3039d869a17c620c1cb552.tar.gz
fsf-binutils-gdb-31ac74b0b3301d396b3039d869a17c620c1cb552.tar.bz2
Incremental breakpoint_re_set for longjmp, etc. master breakpoints
perf shows the next bottleneck is breakpoint_re_set. Even when you don't have user-visible pending breakpoints, gdb still needs to re-set _internal_ breakpoints on every objfile loaded. Specifically, time is spent re-setting the longjmp/terminate, etc. master breakpoints of _all_ objfiles... So start implementing limiting breakpoint_re_set to the objfile that was just loaded. Introduce a struct sym_search_scope and generalize the ALL_SEARCH_OBJFILES approach added by a previous patch. Then when an objfile is loaded, pass a sym_search_scope to breakpoint_re_set that indicates that the scope is a single objfile. For cases where we want to reset the whole program space, we pass a sym_search_scope to breakpoint_re_set that indicates that the scope is the whole program space (i.e., all objfiles in that program space). Then we need to plumb passing that sym_search_scope to all the breakpoint_ops->re_set methods. In the internal breakpoints implementation, it's used to know to only delete the master breakpoint of the just re-loaded objfile, leaving others alone. Other breakpoint types are left to subsequent patches. This is another huge speed up for the normal case you don't have pending breakpoints. Note we need to store the objfile a breakpoint location is set at in bp_location, in order to be able to know whether we should re-set it or not when a single-objfile re-set comes along. And that requires passing down the objfile the internal breakpoint was set at in the first place, thus the create_*_breakpoint changes in this patch.
-rw-r--r--gdb/ada-lang.c29
-rw-r--r--gdb/aix-thread.c3
-rw-r--r--gdb/break-catch-throw.c9
-rw-r--r--gdb/breakpoint.c236
-rw-r--r--gdb/breakpoint.h22
-rw-r--r--gdb/infcmd.c2
-rw-r--r--gdb/infrun.c4
-rw-r--r--gdb/jit.c4
-rw-r--r--gdb/minsyms.c30
-rw-r--r--gdb/objfiles.c4
-rw-r--r--gdb/objfiles.h24
-rw-r--r--gdb/progspace.h35
-rw-r--r--gdb/solib-svr4.c15
-rw-r--r--gdb/solib.c4
-rw-r--r--gdb/symfile.c6
-rw-r--r--gdb/symtab.c4
-rw-r--r--gdb/symtab.h20
17 files changed, 304 insertions, 147 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index be2f47a..9eda7a8 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12346,7 +12346,8 @@ struct ada_catchpoint
catchpoint's locations, and store them for later evaluation. */
static void
-create_excep_cond_exprs (struct ada_catchpoint *c)
+create_excep_cond_exprs (struct ada_catchpoint *c,
+ struct sym_search_scope *search_scope)
{
struct cleanup *old_chain;
struct bp_location *bl;
@@ -12437,17 +12438,18 @@ allocate_location_exception (enum ada_exception_catchpoint_kind ex,
exception catchpoint kinds. */
static void
-re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
+re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
/* Call the base class's method. This updates the catchpoint's
locations. */
- bkpt_breakpoint_ops.re_set (b);
+ bkpt_breakpoint_ops.re_set (b, search_scope);
/* Reparse the exception conditional expressions. One for each
location. */
- create_excep_cond_exprs (c);
+ create_excep_cond_exprs (c, search_scope);
}
/* Returns true if we should stop for this breakpoint hit. If the
@@ -12720,9 +12722,10 @@ allocate_location_catch_exception (struct breakpoint *self)
}
static void
-re_set_catch_exception (struct breakpoint *b)
+re_set_catch_exception (struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
- re_set_exception (ada_catch_exception, b);
+ re_set_exception (ada_catch_exception, b, search_scope);
}
static void
@@ -12772,9 +12775,10 @@ allocate_location_catch_exception_unhandled (struct breakpoint *self)
}
static void
-re_set_catch_exception_unhandled (struct breakpoint *b)
+re_set_catch_exception_unhandled (struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
- re_set_exception (ada_catch_exception_unhandled, b);
+ re_set_exception (ada_catch_exception_unhandled, b, search_scope);
}
static void
@@ -12826,9 +12830,10 @@ allocate_location_catch_assert (struct breakpoint *self)
}
static void
-re_set_catch_assert (struct breakpoint *b)
+re_set_catch_assert (struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
- re_set_exception (ada_catch_assert, b);
+ re_set_exception (ada_catch_assert, b, search_scope);
}
static void
@@ -13142,12 +13147,14 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
const struct breakpoint_ops *ops = NULL;
struct symtab_and_line sal
= ada_exception_sal (ex_kind, excep_string, &addr_string, &ops);
+ struct sym_search_scope search_scope = null_search_scope ();
c = XNEW (struct ada_catchpoint);
init_ada_exception_breakpoint (&c->base, gdbarch, sal, addr_string,
ops, tempflag, disabled, from_tty);
c->excep_string = excep_string;
- create_excep_cond_exprs (c);
+ search_scope.pspace = current_program_space;
+ create_excep_cond_exprs (c, &search_scope);
if (cond_string != NULL)
set_breakpoint_condition (&c->base, cond_string, from_tty);
install_breakpoint (0, &c->base, 1);
diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 693d6f6..67ce1a6 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -912,7 +912,8 @@ pd_enable (void)
if (ms.minsym == NULL)
return;
pd_brk_addr = BMSYMBOL_VALUE_ADDRESS (ms);
- if (!create_thread_event_breakpoint (target_gdbarch (), pd_brk_addr))
+ if (!create_thread_event_breakpoint (target_gdbarch (),
+ ms.objfile, pd_brk_addr))
return;
/* Prepare for thread debugging. */
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 153db71..5ffad94 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -204,14 +204,15 @@ check_status_exception_catchpoint (struct bpstats *bs)
/* Implement the 're_set' method. */
static void
-re_set_exception_catchpoint (struct breakpoint *self)
+re_set_exception_catchpoint (struct breakpoint *self,
+ struct sym_search_scope *search_scope)
{
struct symtabs_and_lines sals = {0};
struct symtabs_and_lines sals_end = {0};
struct cleanup *cleanup;
enum exception_event_kind kind = classify_exception_breakpoint (self);
struct event_location *location;
- struct program_space *filter_pspace = current_program_space;
+ struct program_space *filter_pspace = search_scope->pspace;
/* We first try to use the probe interface. */
TRY
@@ -396,6 +397,7 @@ handle_gnu_v3_exceptions (int tempflag, char *except_rx, char *cond_string,
struct exception_catchpoint *cp;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
regex_t *pattern = NULL;
+ struct sym_search_scope search_scope = null_search_scope ();
if (except_rx != NULL)
{
@@ -418,7 +420,8 @@ handle_gnu_v3_exceptions (int tempflag, char *except_rx, char *cond_string,
cp->exception_rx = except_rx;
cp->pattern = pattern;
- re_set_exception_catchpoint (&cp->base);
+ search_scope.pspace = current_program_space;
+ re_set_exception_catchpoint (&cp->base, &search_scope);
install_breakpoint (0, &cp->base, 1);
discard_cleanups (cleanup);
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 5b0204e..73295f0 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -108,9 +108,8 @@ static void map_breakpoint_numbers (char *, void (*) (struct breakpoint *,
static void ignore_command (char *, int);
-static int breakpoint_re_set_one (void *);
-
-static void breakpoint_re_set_default (struct breakpoint *);
+static void breakpoint_re_set_default (struct breakpoint *b,
+ struct sym_search_scope *search_scope);
static void
create_sals_from_location_default (const struct event_location *location,
@@ -3341,6 +3340,7 @@ set_breakpoint_number (int internal, struct breakpoint *b)
static struct breakpoint *
create_internal_breakpoint (struct gdbarch *gdbarch,
+ struct objfile *objfile,
CORE_ADDR address, enum bptype type,
const struct breakpoint_ops *ops)
{
@@ -3352,6 +3352,7 @@ create_internal_breakpoint (struct gdbarch *gdbarch,
sal.pc = address;
sal.section = find_pc_overlay (sal.pc);
sal.pspace = current_program_space;
+ sal.objfile = objfile;
b = set_raw_breakpoint (gdbarch, sal, type, ops);
b->number = internal_breakpoint_number--;
@@ -3439,12 +3440,13 @@ free_breakpoint_probes (struct objfile *obj, void *data)
}
static void
-create_overlay_event_breakpoint (void)
+create_overlay_event_breakpoint (struct sym_search_scope *search_scope)
{
+ struct program_space *pspace;
struct objfile *objfile;
const char *const func_name = "_ovly_debug_event";
- ALL_OBJFILES (objfile)
+ ALL_SEARCH_SCOPE_OBJFILES (search_scope, pspace, objfile)
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
@@ -3471,8 +3473,8 @@ create_overlay_event_breakpoint (void)
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym);
- b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
- bp_overlay_event,
+ b = create_internal_breakpoint (get_objfile_arch (objfile), objfile,
+ addr, bp_overlay_event,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
explicit_loc.function_name = ASTRDUP (func_name);
@@ -3492,20 +3494,12 @@ create_overlay_event_breakpoint (void)
}
static void
-create_longjmp_master_breakpoint (void)
+create_longjmp_master_breakpoint (struct sym_search_scope *search_scope)
{
struct program_space *pspace;
- struct cleanup *old_chain;
-
- old_chain = save_current_program_space ();
-
- ALL_PSPACES (pspace)
- {
- struct objfile *objfile;
-
- set_current_program_space (pspace);
+ struct objfile *objfile;
- ALL_OBJFILES (objfile)
+ ALL_SEARCH_SCOPE_OBJFILES (search_scope, pspace, objfile)
{
int i;
struct gdbarch *gdbarch;
@@ -3551,7 +3545,7 @@ create_longjmp_master_breakpoint (void)
{
struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch,
+ b = create_internal_breakpoint (gdbarch, objfile,
get_probe_address (probe,
objfile),
bp_longjmp_master,
@@ -3593,7 +3587,8 @@ create_longjmp_master_breakpoint (void)
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
- b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
+ b = create_internal_breakpoint (gdbarch, objfile,
+ addr, bp_longjmp_master,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
explicit_loc.function_name = ASTRDUP (func_name);
@@ -3601,33 +3596,23 @@ create_longjmp_master_breakpoint (void)
b->enable_state = bp_disabled;
}
}
- }
-
- do_cleanups (old_chain);
}
/* Create a master std::terminate breakpoint. */
+
static void
-create_std_terminate_master_breakpoint (void)
+create_std_terminate_master_breakpoint (struct sym_search_scope *search_scope)
{
struct program_space *pspace;
- struct cleanup *old_chain;
+ struct objfile *objfile;
const char *const func_name = "std::terminate()";
- old_chain = save_current_program_space ();
-
- ALL_PSPACES (pspace)
- {
- struct objfile *objfile;
- CORE_ADDR addr;
-
- set_current_program_space (pspace);
-
- ALL_OBJFILES (objfile)
+ ALL_SEARCH_SCOPE_OBJFILES (search_scope, pspace, objfile)
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
struct explicit_location explicit_loc;
+ CORE_ADDR addr;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
@@ -3650,7 +3635,8 @@ create_std_terminate_master_breakpoint (void)
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
- b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
+ b = create_internal_breakpoint (get_objfile_arch (objfile),
+ objfile, addr,
bp_std_terminate_master,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
@@ -3658,20 +3644,18 @@ create_std_terminate_master_breakpoint (void)
b->location = new_explicit_location (&explicit_loc);
b->enable_state = bp_disabled;
}
- }
-
- do_cleanups (old_chain);
}
/* Install a master breakpoint on the unwinder's debug hook. */
static void
-create_exception_master_breakpoint (void)
+create_exception_master_breakpoint (struct sym_search_scope *search_scope)
{
+ struct program_space *pspace;
struct objfile *objfile;
const char *const func_name = "_Unwind_DebugHook";
- ALL_OBJFILES (objfile)
+ ALL_SEARCH_SCOPE_OBJFILES (search_scope, pspace, objfile)
{
struct breakpoint *b;
struct gdbarch *gdbarch;
@@ -3719,7 +3703,7 @@ create_exception_master_breakpoint (void)
{
struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch,
+ b = create_internal_breakpoint (gdbarch, objfile,
get_probe_address (probe,
objfile),
bp_exception_master,
@@ -3756,7 +3740,8 @@ create_exception_master_breakpoint (void)
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
&current_target);
- b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
+ b = create_internal_breakpoint (gdbarch, objfile,
+ addr, bp_exception_master,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
explicit_loc.function_name = ASTRDUP (func_name);
@@ -7810,11 +7795,13 @@ delete_std_terminate_breakpoint (void)
}
struct breakpoint *
-create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+create_thread_event_breakpoint (struct gdbarch *gdbarch,
+ struct objfile *objfile,
+ CORE_ADDR address)
{
struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch, address, bp_thread_event,
+ b = create_internal_breakpoint (gdbarch, objfile, address, bp_thread_event,
&internal_breakpoint_ops);
b->enable_state = bp_enabled;
@@ -7835,9 +7822,10 @@ struct lang_and_radix
/* Create a breakpoint for JIT code registration and unregistration. */
struct breakpoint *
-create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+create_jit_event_breakpoint (struct gdbarch *gdbarch, struct objfile *objfile,
+ CORE_ADDR address)
{
- return create_internal_breakpoint (gdbarch, address, bp_jit_event,
+ return create_internal_breakpoint (gdbarch, objfile, address, bp_jit_event,
&internal_breakpoint_ops);
}
@@ -7883,33 +7871,40 @@ remove_solib_event_breakpoints_at_next_stop (void)
INSERT_MODE to pass through to update_global_location_list. */
static struct breakpoint *
-create_solib_event_breakpoint_1 (struct gdbarch *gdbarch, CORE_ADDR address,
+create_solib_event_breakpoint_1 (struct gdbarch *gdbarch,
+ struct objfile *objfile,
+ CORE_ADDR address,
enum ugll_insert_mode insert_mode)
{
struct breakpoint *b;
- b = create_internal_breakpoint (gdbarch, address, bp_shlib_event,
+ b = create_internal_breakpoint (gdbarch, objfile, address, bp_shlib_event,
&internal_breakpoint_ops);
update_global_location_list_nothrow (insert_mode);
return b;
}
struct breakpoint *
-create_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+create_solib_event_breakpoint (struct gdbarch *gdbarch,
+ struct objfile *objfile,
+ CORE_ADDR address)
{
- return create_solib_event_breakpoint_1 (gdbarch, address, UGLL_MAY_INSERT);
+ return create_solib_event_breakpoint_1 (gdbarch, objfile,
+ address, UGLL_MAY_INSERT);
}
/* See breakpoint.h. */
struct breakpoint *
-create_and_insert_solib_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
+create_and_insert_solib_event_breakpoint (struct gdbarch *gdbarch,
+ struct objfile *objfile,
+ CORE_ADDR address)
{
struct breakpoint *b;
/* Explicitly tell update_global_location_list to insert
locations. */
- b = create_solib_event_breakpoint_1 (gdbarch, address, UGLL_INSERT);
+ b = create_solib_event_breakpoint_1 (gdbarch, objfile, address, UGLL_INSERT);
if (!b->loc->inserted)
{
delete_breakpoint (b);
@@ -8904,7 +8899,7 @@ void
enable_breakpoints_after_startup (void)
{
current_program_space->executing_startup = 0;
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
}
/* Create a new single-step breakpoint for thread THREAD, with no
@@ -9069,6 +9064,8 @@ add_location_to_breakpoint (struct breakpoint *b,
loc->requested_address = sal->pc;
loc->address = adjusted_address;
loc->pspace = sal->pspace;
+ loc->objfile = sal->objfile;
+ loc->sal = *sal;
loc->probe.probe = sal->probe;
loc->probe.objfile = sal->objfile;
gdb_assert (loc->pspace != NULL);
@@ -10662,7 +10659,7 @@ dtor_watchpoint (struct breakpoint *self)
/* Implement the "re_set" breakpoint_ops method for watchpoints. */
static void
-re_set_watchpoint (struct breakpoint *b)
+re_set_watchpoint (struct breakpoint *b, struct sym_search_scope *search_scope)
{
struct watchpoint *w = (struct watchpoint *) b;
@@ -11343,6 +11340,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
{
scope_breakpoint
= create_internal_breakpoint (frame_unwind_caller_arch (frame),
+ NULL,
frame_unwind_caller_pc (frame),
bp_watchpoint_scope,
&momentary_breakpoint_ops);
@@ -12945,7 +12943,8 @@ base_breakpoint_allocate_location (struct breakpoint *self)
}
static void
-base_breakpoint_re_set (struct breakpoint *b)
+base_breakpoint_re_set (struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
/* Nothing to re-set. */
}
@@ -13052,7 +13051,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 program_space *filter_pspace,
struct symtabs_and_lines *sals)
{
internal_error_pure_virtual_called ();
@@ -13100,7 +13099,7 @@ struct breakpoint_ops base_breakpoint_ops =
/* Default breakpoint_ops methods. */
static void
-bkpt_re_set (struct breakpoint *b)
+bkpt_re_set (struct breakpoint *b, struct sym_search_scope *search_scope)
{
/* FIXME: is this still reachable? */
if (breakpoint_event_location_empty_p (b))
@@ -13110,7 +13109,7 @@ bkpt_re_set (struct breakpoint *b)
return;
}
- breakpoint_re_set_default (b);
+ breakpoint_re_set_default (b, search_scope);
}
static int
@@ -13311,7 +13310,8 @@ bkpt_decode_location (struct breakpoint *b,
/* Virtual table for internal breakpoints. */
static void
-internal_bkpt_re_set (struct breakpoint *b)
+internal_bkpt_re_set (struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
switch (b->type)
{
@@ -13321,7 +13321,9 @@ internal_bkpt_re_set (struct breakpoint *b)
case bp_longjmp_master:
case bp_std_terminate_master:
case bp_exception_master:
- delete_breakpoint (b);
+ gdb_assert (b->loc != NULL && b->loc->next == NULL);
+ if (bp_location_matches_search_scope (b->loc, search_scope))
+ delete_breakpoint (b);
break;
/* This breakpoint is special, it's set up when the inferior
@@ -13408,7 +13410,8 @@ internal_bkpt_print_mention (struct breakpoint *b)
/* Virtual table for momentary breakpoints */
static void
-momentary_bkpt_re_set (struct breakpoint *b)
+momentary_bkpt_re_set (struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
/* Keep temporary breakpoints, which can be encountered when we step
over a dlopen call and solib_add is resetting the breakpoints.
@@ -13509,9 +13512,9 @@ bkpt_probe_decode_location (struct breakpoint *b,
/* The breakpoint_ops structure to be used in tracepoints. */
static void
-tracepoint_re_set (struct breakpoint *b)
+tracepoint_re_set (struct breakpoint *b, struct sym_search_scope *search_scope)
{
- breakpoint_re_set_default (b);
+ breakpoint_re_set_default (b, search_scope);
}
static int
@@ -13659,9 +13662,9 @@ static struct breakpoint_ops tracepoint_probe_breakpoint_ops;
/* Dprintf breakpoint_ops methods. */
static void
-dprintf_re_set (struct breakpoint *b)
+dprintf_re_set (struct breakpoint *b, struct sym_search_scope *search_scope)
{
- breakpoint_re_set_default (b);
+ breakpoint_re_set_default (b, search_scope);
/* extra_string should never be non-NULL for dprintf. */
gdb_assert (b->extra_string != NULL);
@@ -14034,6 +14037,31 @@ delete_command (char *arg, int from_tty)
map_breakpoint_numbers (arg, do_map_delete_breakpoint, NULL);
}
+int
+bp_location_matches_search_scope (struct bp_location *bl,
+ struct sym_search_scope *search_scope)
+{
+ struct objfile *objfile;
+
+ if (search_scope->pspace == NULL)
+ return 1;
+
+ if (bl->pspace != search_scope->pspace)
+ return 0;
+
+ if (search_scope->objfile == NULL)
+ return 1;
+
+ ALL_SEARCH_OBJFILES (search_scope->pspace,
+ search_scope->objfile, objfile)
+ {
+ if (objfile == bl->objfile)
+ return 1;
+ }
+
+ return 0;
+}
+
/* Return true if all locations of B bound to PSPACE are pending. If
PSPACE is NULL, all locations of all program spaces are
considered. */
@@ -14504,13 +14532,14 @@ location_to_sals (struct breakpoint *b, struct event_location *location,
locations. */
static void
-breakpoint_re_set_default (struct breakpoint *b)
+breakpoint_re_set_default (struct breakpoint *b,
+ struct sym_search_scope *search_scope)
{
int found;
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;
+ struct program_space *filter_pspace = search_scope->pspace;
sals = location_to_sals (b, b->location, filter_pspace, &found);
if (found)
@@ -14618,23 +14647,22 @@ prepare_re_set_context (struct breakpoint *b)
Unused in this case. */
static int
-breakpoint_re_set_one (void *bint)
+breakpoint_re_set_one (struct breakpoint *b, struct sym_search_scope *search_scope)
{
/* Get past catch_errs. */
- struct breakpoint *b = (struct breakpoint *) bint;
struct cleanup *cleanups;
cleanups = prepare_re_set_context (b);
- b->ops->re_set (b);
+ b->ops->re_set (b, search_scope);
do_cleanups (cleanups);
return 0;
}
-/* Re-set breakpoint locations for the current program space.
- Locations bound to other program spaces are left untouched. */
+/* Re-set breakpoint locations that match SEARCH_SCOPE. Other
+ locations are left untouched. */
-void
-breakpoint_re_set (void)
+static void
+breakpoint_re_set (struct sym_search_scope *search_scope)
{
struct breakpoint *b, *b_tmp;
enum language save_language;
@@ -14651,14 +14679,20 @@ breakpoint_re_set (void)
hadn't been re-set yet, and thus may have stale locations. */
ALL_BREAKPOINTS_SAFE (b, b_tmp)
- {
- /* Format possible error msg. */
- char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
- b->number);
- struct cleanup *cleanups = make_cleanup (xfree, message);
- catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
- do_cleanups (cleanups);
- }
+ {
+ TRY
+ {
+ breakpoint_re_set_one (b, search_scope);
+ }
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ exception_fprintf (gdb_stderr, ex,
+ _("Error in re-setting breakpoint %d: "),
+ b->number);
+ }
+ END_CATCH
+ }
+
set_language (save_language);
input_radix = save_input_radix;
@@ -14666,14 +14700,34 @@ breakpoint_re_set (void)
do_cleanups (old_chain);
- create_overlay_event_breakpoint ();
- create_longjmp_master_breakpoint ();
- create_std_terminate_master_breakpoint ();
- create_exception_master_breakpoint ();
+ create_overlay_event_breakpoint (search_scope);
+ create_longjmp_master_breakpoint (search_scope);
+ create_std_terminate_master_breakpoint (search_scope);
+ create_exception_master_breakpoint (search_scope);
/* Now we can insert. */
update_global_location_list (UGLL_MAY_INSERT);
}
+
+void
+breakpoint_re_set_program_space (struct program_space *pspace)
+{
+ struct sym_search_scope search_scope = null_search_scope ();
+
+ search_scope.pspace = current_program_space;
+ breakpoint_re_set (&search_scope);
+}
+
+void
+breakpoint_re_set_objfile (struct objfile *objfile)
+{
+ struct sym_search_scope search_scope = null_search_scope ();
+
+ search_scope.pspace = objfile->pspace;
+ search_scope.objfile = objfile;
+ breakpoint_re_set (&search_scope);
+}
+
/* Reset the thread number of this breakpoint:
@@ -15983,8 +16037,12 @@ breakpoint_free_objfile (struct objfile *objfile)
struct bp_location **locp, *loc;
ALL_BP_LOCATIONS (loc, locp)
- if (loc->symtab != NULL && SYMTAB_OBJFILE (loc->symtab) == objfile)
- loc->symtab = NULL;
+ {
+ if (loc->symtab != NULL && SYMTAB_OBJFILE (loc->symtab) == objfile)
+ loc->symtab = NULL;
+ if (loc->objfile == objfile)
+ loc->objfile = NULL;
+ }
}
void
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 4bdf0d5..891f763 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -449,7 +449,7 @@ struct bp_location
CORE_ADDR related_address;
/* If the location comes from a probe point, this is the probe associated
- with it. */
+ with it. XXX */
struct bound_probe probe;
char *function_name;
@@ -482,6 +482,10 @@ struct bp_location
to find the corresponding source file name. */
struct symtab *symtab;
+
+ struct objfile *objfile;
+
+ struct symtab_and_line sal;
};
/* The possible return values for print_bpstat, print_it_normal,
@@ -520,7 +524,8 @@ struct breakpoint_ops
/* Reevaluate a breakpoint. This is necessary after symbols change
(e.g., an executable or DSO was loaded, or the inferior just
started). */
- void (*re_set) (struct breakpoint *self);
+ void (*re_set) (struct breakpoint *self,
+ struct sym_search_scope *search_scope);
/* Insert the breakpoint or watchpoint or activate the catchpoint.
Return 0 for success, 1 if the breakpoint, watchpoint or
@@ -1218,7 +1223,13 @@ extern void update_breakpoint_locations (struct breakpoint *b,
struct symtabs_and_lines sals,
struct symtabs_and_lines sals_end);
-extern void breakpoint_re_set (void);
+extern int bp_location_matches_search_scope
+ (struct bp_location *bl,
+ struct sym_search_scope *search_scope);
+
+extern void breakpoint_re_set_objfile (struct objfile *objfile);
+
+extern void breakpoint_re_set_program_space (struct program_space *pspace);
extern void breakpoint_re_set_thread (struct breakpoint *);
@@ -1490,9 +1501,11 @@ extern void breakpoint_set_task (struct breakpoint *b, int task);
extern void mark_breakpoints_out (void);
extern struct breakpoint *create_jit_event_breakpoint (struct gdbarch *,
+ struct objfile *objfile,
CORE_ADDR);
extern struct breakpoint *create_solib_event_breakpoint (struct gdbarch *,
+ struct objfile *objfile,
CORE_ADDR);
/* Create an solib event breakpoint at ADDRESS in the current program
@@ -1500,9 +1513,10 @@ extern struct breakpoint *create_solib_event_breakpoint (struct gdbarch *,
breakpoint on success. Deletes the new breakpoint and returns NULL
if inserting the breakpoint fails. */
extern struct breakpoint *create_and_insert_solib_event_breakpoint
- (struct gdbarch *gdbarch, CORE_ADDR address);
+ (struct gdbarch *gdbarch, struct objfile *objfile, CORE_ADDR address);
extern struct breakpoint *create_thread_event_breakpoint (struct gdbarch *,
+ struct objfile *,
CORE_ADDR);
extern void remove_jit_event_breakpoints (void);
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 064f7bc..5f6effc 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -479,7 +479,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
breakpoint_re_set is never called. Call it now so that software
watchpoints get a chance to be promoted to hardware watchpoints
if the now pushed target supports hardware watchpoints. */
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
observer_notify_inferior_created (target, from_tty);
}
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 03be3d9..598a99a 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -862,7 +862,7 @@ follow_inferior_reset_breakpoints (void)
were never set in the child, but only in the parent. This makes
sure the inserted breakpoints match the breakpoint list. */
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
insert_breakpoints ();
}
@@ -1240,7 +1240,7 @@ follow_exec (ptid_t ptid, char *execd_pathname)
jit_inferior_created_hook ();
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
/* Reinsert all breakpoints. (Those which were symbolic have
been reset to the proper address in the new a.out, thanks
diff --git a/gdb/jit.c b/gdb/jit.c
index ba6daed..15e2cac 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -1162,7 +1162,9 @@ jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
/* Put a breakpoint in the registration symbol. */
ps_data->cached_code_address = addr;
- ps_data->jit_breakpoint = create_jit_event_breakpoint (gdbarch, addr);
+ ps_data->jit_breakpoint = create_jit_event_breakpoint (gdbarch,
+ ps_data->objfile,
+ addr);
return 0;
}
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index e0200a8..0d66157 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -139,26 +139,12 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
}
}
-/* Traverse through all search objfiles. */
-#define ALL_SEARCH_OBJFILES(SEARCH, ITER) \
- for (ITER = all_search_objfiles_init (SEARCH); \
- ITER != NULL; \
- ITER = all_search_objfiles_next (SEARCH, ITER)) \
-
-/* Iterator on PARENT and every separate debug objfile of PARENT.
- The usage pattern is:
- for (iter = search;
- iter;
- iter = all_search_objfiles_next (search, iter))
- ...
-*/
-
-static struct objfile *
-all_search_objfiles_init (struct objfile *search)
+struct objfile *
+all_search_objfiles_init (struct program_space *pspace, struct objfile *search)
{
if (search == NULL)
{
- return object_files;
+ return pspace->objfiles;
}
else
{
@@ -166,7 +152,7 @@ all_search_objfiles_init (struct objfile *search)
}
}
-static struct objfile *
+struct objfile *
all_search_objfiles_next (struct objfile *search, struct objfile *iter)
{
if (search == NULL)
@@ -230,7 +216,7 @@ lookup_minimal_symbol (const char *name, const char *sfile,
}
}
- ALL_SEARCH_OBJFILES (objf, objfile)
+ ALL_SEARCH_OBJFILES (current_program_space, objf, objfile)
{
struct minimal_symbol *msymbol;
@@ -435,7 +421,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
- ALL_SEARCH_OBJFILES (objf, objfile)
+ ALL_SEARCH_OBJFILES (current_program_space, objf, objfile)
{
struct minimal_symbol *msymbol;
@@ -476,7 +462,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
- ALL_SEARCH_OBJFILES (objf, objfile)
+ ALL_SEARCH_OBJFILES (current_program_space, objf, objfile)
{
for (msymbol = objfile->per_bfd->msymbol_hash[hash];
msymbol != NULL;
@@ -503,7 +489,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
- ALL_SEARCH_OBJFILES (objf, objfile)
+ ALL_SEARCH_OBJFILES (current_program_space, objf, objfile)
{
for (msymbol = objfile->per_bfd->msymbol_hash[hash];
msymbol != NULL;
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index ddefd12..2e3f9e8 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -971,7 +971,7 @@ objfile_relocate (struct objfile *objfile,
/* Relocate breakpoints as necessary, after things are relocated. */
if (changed)
- breakpoint_re_set ();
+ breakpoint_re_set_objfile (objfile);
}
/* Rebase (add to the offsets) OBJFILE by SLIDE. SEPARATE_DEBUG_OBJFILE is
@@ -1010,7 +1010,7 @@ objfile_rebase (struct objfile *objfile, CORE_ADDR slide)
/* Relocate breakpoints as necessary, after things are relocated. */
if (changed)
- breakpoint_re_set ();
+ breakpoint_re_set_objfile (objfile);
}
/* Return non-zero if OBJFILE has partial symbols. */
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index bfb7781..f685a1f 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -753,4 +753,28 @@ extern const struct dynamic_prop *objfile_lookup_static_link
extern void obj_section_map_add_objfile (struct objfile *obj);
extern void obj_section_map_remove_objfile (struct objfile *obj);
+/* Traverse through all search objfiles. */
+#define ALL_SEARCH_OBJFILES(SEARCH_PSPACE, SEARCH_OBJF, OBJF_ITER) \
+ for ((OBJF_ITER) = all_search_objfiles_init (SEARCH_PSPACE, SEARCH_OBJF); \
+ (OBJF_ITER) != NULL; \
+ OBJF_ITER = all_search_objfiles_next (SEARCH_OBJF, OBJF_ITER)) \
+
+/* Traverse through all SEARCH_SCOPE objfiles. */
+#define ALL_SEARCH_SCOPE_OBJFILES(SEARCH_SCOPE, PSPACE_ITER, OBJF_ITER) \
+ ALL_SEARCH_PSPACES ((SEARCH_SCOPE)->pspace, PSPACE_ITER) \
+ ALL_SEARCH_OBJFILES (PSPACE_ITER, (SEARCH_SCOPE)->objfile, OBJF_ITER) \
+
+/* Iterator on PARENT and every separate debug objfile of PARENT.
+ The usage pattern is:
+ for (iter = search;
+ iter;
+ iter = all_search_objfiles_next (search, iter))
+ ...
+*/
+
+struct objfile *all_search_objfiles_init (struct program_space *pspace,
+ struct objfile *search);
+struct objfile *all_search_objfiles_next (struct objfile *search,
+ struct objfile *iter);
+
#endif /* !defined (OBJFILES_H) */
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 446dfc6..155b54c 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -233,6 +233,41 @@ extern struct program_space *current_program_space;
#define ALL_PSPACES(pspace) \
for ((pspace) = program_spaces; (pspace) != NULL; (pspace) = (pspace)->next)
+/* Traverse through all search program spaces. */
+#define ALL_SEARCH_PSPACES(SEARCH, ITER) \
+ for (ITER = all_search_program_spaces_init (SEARCH); \
+ ITER != NULL; \
+ ITER = all_search_program_spaces_next (SEARCH, ITER)) \
+
+static inline struct program_space *
+all_search_program_spaces_init (struct program_space *search)
+{
+ if (search == NULL)
+ return program_spaces;
+ else
+ return search;
+}
+
+static inline struct program_space *
+all_search_program_spaces_next (struct program_space *search,
+ struct program_space *iter)
+{
+ if (search == NULL)
+ return iter->next;
+ else
+ return NULL;
+}
+
+static inline int
+search_pspace_matches_pspace (struct program_space *search,
+ struct program_space *pspace)
+{
+ if (search == NULL)
+ return 1;
+ else
+ return search == pspace;
+}
+
/* Add a new empty program space, and assign ASPACE to it. Returns the
pointer to the new object. */
extern struct program_space *add_program_space (struct address_space *aspace);
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 3dedbb8..3e1e1c7 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -2107,7 +2107,7 @@ svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
{
CORE_ADDR address = get_probe_address (probe, objfile);
- create_solib_event_breakpoint (gdbarch, address);
+ create_solib_event_breakpoint (gdbarch, objfile, address);
register_solib_event_probe (probe, address, action);
}
}
@@ -2129,6 +2129,7 @@ svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
static void
svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
+ struct objfile *objfile,
CORE_ADDR address)
{
struct obj_section *os;
@@ -2203,7 +2204,7 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
}
}
- create_solib_event_breakpoint (gdbarch, address);
+ create_solib_event_breakpoint (gdbarch, objfile, address);
}
/* Helper function for gdb_bfd_lookup_symbol. */
@@ -2333,7 +2334,8 @@ enable_break (struct svr4_info *info, int from_tty)
+ bfd_section_size (tmp_bfd, interp_sect);
}
- svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr);
+ svr4_create_solib_event_breakpoints (target_gdbarch (), os->objfile,
+ sym_addr);
return 1;
}
}
@@ -2496,6 +2498,7 @@ enable_break (struct svr4_info *info, int from_tty)
if (sym_addr != 0)
{
svr4_create_solib_event_breakpoints (target_gdbarch (),
+ symfile_objfile,
load_addr + sym_addr);
xfree (interp_name);
return 1;
@@ -2523,7 +2526,8 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
sym_addr,
&current_target);
- svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr);
+ svr4_create_solib_event_breakpoints (target_gdbarch (),
+ msymbol.objfile, sym_addr);
return 1;
}
}
@@ -2540,7 +2544,8 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
sym_addr,
&current_target);
- svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr);
+ svr4_create_solib_event_breakpoints (target_gdbarch (),
+ msymbol.objfile, sym_addr);
return 1;
}
}
diff --git a/gdb/solib.c b/gdb/solib.c
index 32a490d..85ea943 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1033,7 +1033,7 @@ solib_add (const char *pattern, symfile_add_flags add_flags,
if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0
&& loaded_any_symbols)
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
if (from_tty && pattern && ! any_matches)
printf_unfiltered
@@ -1478,7 +1478,7 @@ reload_shared_libraries (char *ignored, int from_tty,
solib_add (NULL, add_flags, NULL);
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
/* We may have loaded or unloaded debug info for some (or all)
shared libraries. However, frames may still reference them. For
diff --git a/gdb/symfile.c b/gdb/symfile.c
index bee7cdb..67a931b 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1112,7 +1112,7 @@ finish_new_objfile (struct objfile *objfile, int add_flags)
}
else if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
{
- breakpoint_re_set ();
+ breakpoint_re_set_objfile (objfile);
}
/* We're done reading the symbol file; finish off complaints. */
@@ -2149,7 +2149,7 @@ generic_load (const char *args, int from_tty)
breakpoint locations. Loading has changed the contents of that
memory. */
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
print_transfer_performance (gdb_stdout, total_progress.data_count,
total_progress.write_count,
@@ -2976,7 +2976,7 @@ clear_symtab_users (int add_flags)
/* Now that the various caches have been cleared, we can re_set
our breakpoints without risking it using stale data. */
if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
- breakpoint_re_set ();
+ breakpoint_re_set_program_space (current_program_space);
}
static void
diff --git a/gdb/symtab.c b/gdb/symtab.c
index e776a0c..9ad407d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3171,6 +3171,8 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
}
+ if (msymbol.minsym != NULL)
+ val.objfile = msymbol.objfile;
cust = find_pc_sect_compunit_symtab (pc, section);
if (cust == NULL)
@@ -3270,6 +3272,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
val.symtab = best_symtab;
val.line = best->line;
val.pc = best->pc;
+ val.objfile = SYMTAB_OBJFILE (best_symtab);
if (best_end && (!alt || best_end < alt->pc))
val.end = best_end;
else if (alt)
@@ -3613,6 +3616,7 @@ find_function_start_sal (struct symbol *sym, int funfirstline)
sal.pspace = current_program_space;
sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
sal.section = section;
+ sal.objfile = section->objfile;
}
if (funfirstline)
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 9df4efb..15fe601 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -497,6 +497,24 @@ enum search_domain
extern const char *search_domain_name (enum search_domain);
+struct sym_search_scope
+{
+ /* If not NULL, the search is restricted to just this program
+ space. */
+ struct program_space *pspace;
+
+ /* If not NULL, the search is restricted to just this objfile. */
+ struct objfile *objfile;
+};
+
+static inline struct sym_search_scope
+null_search_scope (void)
+{
+ return (struct sym_search_scope) { NULL, NULL };
+}
+
+
+
/* An address-class says where to find the value of a symbol. */
enum address_class
@@ -1432,7 +1450,7 @@ struct symtab_and_line
/* The probe associated with this symtab_and_line. */
struct probe *probe;
- /* If PROBE is not NULL, then this is the objfile in which the probe
+ /* XXX If PROBE is not NULL, then this is the objfile in which the probe
originated. */
struct objfile *objfile;
};