]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Incremental breakpoint_re_set for longjmp, etc. master breakpoints
authorPedro Alves <palves@redhat.com>
Fri, 1 Apr 2016 14:28:42 +0000 (15:28 +0100)
committerPedro Alves <palves@redhat.com>
Mon, 19 Sep 2016 14:44:42 +0000 (15:44 +0100)
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.

17 files changed:
gdb/ada-lang.c
gdb/aix-thread.c
gdb/break-catch-throw.c
gdb/breakpoint.c
gdb/breakpoint.h
gdb/infcmd.c
gdb/infrun.c
gdb/jit.c
gdb/minsyms.c
gdb/objfiles.c
gdb/objfiles.h
gdb/progspace.h
gdb/solib-svr4.c
gdb/solib.c
gdb/symfile.c
gdb/symtab.c
gdb/symtab.h

index be2f47a6bc964d0bda001e57c9e344612055a35e..9eda7a84828f414920aa9ecb2a0b9470f523acf4 100644 (file)
@@ -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);
index 693d6f6fae7c7852c74f63b2f72a7491a83deebb..67ce1a6b77ecc058236ef0779bc8dc3d91bd1231 100644 (file)
@@ -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.  */
index 153db713eb0cecf8856e36d83837ae612445b9e0..5ffad947899eb288d032adfb6b8146dc050fea7a 100644 (file)
@@ -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);
index 5b0204ef69754f7b1a449522bf1551a64eede342..73295f0b8c7ff672097ac8e528d3362b46460788 100644 (file)
@@ -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);
+}
+
 \f
 /* 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
index 4bdf0d5b40dd8e409d2477ab50a4d5144642660f..891f7631f59b9e1e6631720549d38ae8803a77d3 100644 (file)
@@ -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);
index 064f7bcdeaa81b34c17943e429ea60495b211c35..5f6effc3baae65ae04aa23ba6724f8806d210b38 100644 (file)
@@ -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);
 }
index 03be3d9e30d396c3af642969697b025406cd30f6..598a99a1edff87d3c731552f573e63bb34f0c433 100644 (file)
@@ -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
index ba6daed896c9e4845977d5baa859e023c124b96a..15e2cacd867e6569a814a476de900f7d22188e92 100644 (file)
--- 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;
 }
index e0200a8001de2da19a5e0b0f3ea45e8fbcd9cbb9..0d66157f5fd1ec1dbbffa986e0cd63f49ec2b6d0 100644 (file)
@@ -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;
index ddefd1277f3ebd0047c556b4f071ee77883be58f..2e3f9e848387eb983507b53a4c44fee73d47f39b 100644 (file)
@@ -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);
 }
 \f
 /* Return non-zero if OBJFILE has partial symbols.  */
index bfb77819ccf0e242dca52bc4b8396a5c925829a6..f685a1fb3e486082f23b34aef4604c4c4cb7d26b 100644 (file)
@@ -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) */
index 446dfc6621e2683b7c41d38572315c558c5a4905..155b54cc0cadb9977d70d5dd723464d208baf7bc 100644 (file)
@@ -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);
index 3dedbb84ffe507c882e96f6226bfece3438b2093..3e1e1c73e686d348af0b8e723d947f544bb989af 100644 (file)
@@ -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;
            }
        }
index 32a490df3c37310fb987c05bcae548e3bf7a97b1..85ea943db137c501ccce75201acb53c378cc13d6 100644 (file)
@@ -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
index bee7cdb007362bf2e58999e2034006b6c782070c..67a931ba0c180972c23e00177d30da2e4769d657 100644 (file)
@@ -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
index e776a0c9966503bdf7aecaa19522b2057e430139..9ad407dc9d90ee7e25cc227fcc1caae7e2cebe03 100644 (file)
@@ -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)
index 9df4efbf2cc252e376ff90d7839cf8cdb07d596d..15fe6016708518afa31cc6f4421c9bec0d75303f 100644 (file)
@@ -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;
 };