gdb/gdb-dlopen-stap-probe-7of7....

148 lines
5.6 KiB
Diff

2012-07-30 Gary Benson <gbenson@redhat.com>
* objfiles.h (inhibit_section_map_updates): New function
declaration.
(resume_section_map_updates): Likewise.
(resume_section_map_updates_cleanup): Likewise.
* objfiles.c (objfile_pspace_info): New field "inhibit_updates".
(find_pc_section): Do not update the section map if
inhibit_updates is set.
(inhibit_section_map_updates): New function.
(resume_section_map_updates): Likewise.
(resume_section_map_updates_cleanup): Likewise.
* solib-svr4.c (svr4_handle_solib_event): Inhibit section map
updates for calls to evaluate_probe_argument.
Index: gdb-7.5.50.20130118/gdb/objfiles.h
===================================================================
--- gdb-7.5.50.20130118.orig/gdb/objfiles.h 2013-01-18 23:18:16.862315673 +0100
+++ gdb-7.5.50.20130118/gdb/objfiles.h 2013-01-18 23:18:36.702343482 +0100
@@ -508,6 +508,22 @@ extern int in_plt_section (CORE_ADDR, ch
modules. */
DECLARE_REGISTRY(objfile);
+/* In normal use, the section map will be rebuilt by FIND_PC_SECTION
+ if objfiles have been added, removed or relocated since it was last
+ called. Calling INHIBIT_SECTION_MAP_UPDATES will inhibit this
+ behavior until RESUME_SECTION_MAP_UPDATES is called. If you call
+ INHIBIT_SECTION_MAP_UPDATES you must ensure that every call to
+ FIND_PC_SECTION in the inhibited region relates to a section that
+ is already in the section map and has not since been removed or
+ relocated. */
+extern void inhibit_section_map_updates (void);
+
+/* Resume automatically rebuilding the section map as required. */
+extern void resume_section_map_updates (void);
+
+/* Version of the above suitable for use as a cleanup. */
+extern void resume_section_map_updates_cleanup (void *arg);
+
extern void default_iterate_over_objfiles_in_search_order
(struct gdbarch *gdbarch,
iterate_over_objfiles_in_search_order_cb_ftype *cb,
Index: gdb-7.5.50.20130118/gdb/objfiles.c
===================================================================
--- gdb-7.5.50.20130118.orig/gdb/objfiles.c 2013-01-18 23:18:13.647311006 +0100
+++ gdb-7.5.50.20130118/gdb/objfiles.c 2013-01-18 23:18:16.862315673 +0100
@@ -69,6 +69,9 @@ struct objfile_pspace_info
int objfiles_changed_p;
struct obj_section **sections;
int num_sections;
+
+ /* Nonzero if section map updates should be inhibited. */
+ int inhibit_updates;
};
/* Per-program-space data key. */
@@ -1356,7 +1359,7 @@ find_pc_section (CORE_ADDR pc)
return s;
pspace_info = get_objfile_pspace_data (current_program_space);
- if (pspace_info->objfiles_changed_p != 0)
+ if (pspace_info->objfiles_changed_p && !pspace_info->inhibit_updates)
{
update_section_map (current_program_space,
&pspace_info->sections,
@@ -1415,6 +1418,30 @@ objfiles_changed (void)
get_objfile_pspace_data (current_program_space)->objfiles_changed_p = 1;
}
+/* See comments in objfiles.h. */
+
+void
+inhibit_section_map_updates (void)
+{
+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 1;
+}
+
+/* See comments in objfiles.h. */
+
+void
+resume_section_map_updates (void)
+{
+ get_objfile_pspace_data (current_program_space)->inhibit_updates = 0;
+}
+
+/* See comments in objfiles.h. */
+
+void
+resume_section_map_updates_cleanup (void *arg)
+{
+ resume_section_map_updates ();
+}
+
/* The default implementation for the "iterate_over_objfiles_in_search_order"
gdbarch method. It is equivalent to use the ALL_OBJFILES macro,
searching the objfiles in the order they are stored internally,
Index: gdb-7.5.50.20130118/gdb/solib-svr4.c
===================================================================
--- gdb-7.5.50.20130118.orig/gdb/solib-svr4.c 2013-01-18 23:18:13.649311010 +0100
+++ gdb-7.5.50.20130118/gdb/solib-svr4.c 2013-01-18 23:18:16.863315675 +0100
@@ -1849,6 +1849,7 @@ svr4_handle_solib_event (bpstat bs)
struct svr4_info *info = get_svr4_info ();
struct probe_and_info buf, *pi = &buf;
enum probe_action action;
+ struct cleanup *cleanups = NULL;
struct value *val;
LONGEST lmid;
CORE_ADDR debug_base, lm = 0;
@@ -1872,6 +1873,19 @@ svr4_handle_solib_event (bpstat bs)
if (action == NAMESPACE_NO_ACTION)
return;
+ /* EVALUATE_PROBE_ARGUMENT looks up symbols in the dynamic linker
+ using FIND_PC_SECTION. FIND_PC_SECTION is accelerated by a cache
+ called the section map. The section map is invalidated every
+ time a shared library is loaded or unloaded, and if the inferior
+ is generating a lot of shared library events then the section map
+ will be updated every time SVR4_HANDLE_SOLIB_EVENT is called.
+ We called FIND_PC_SECTION in SVR4_CREATE_SOLIB_EVENT_BREAKPOINTS,
+ so we can guarantee that the dynamic linker's sections are in the
+ section map. We can therefore inhibit section map updates across
+ these calls to EVALUATE_PROBE_ARGUMENT and save a lot of time. */
+ inhibit_section_map_updates ();
+ cleanups = make_cleanup (resume_section_map_updates_cleanup, NULL);
+
val = evaluate_probe_argument (pi->probe, 0);
if (val == NULL)
goto error;
@@ -1903,6 +1917,9 @@ svr4_handle_solib_event (bpstat bs)
action = NAMESPACE_RELOAD;
}
+ do_cleanups (cleanups);
+ cleanups = NULL;
+
if (action == NAMESPACE_UPDATE_OR_RELOAD)
{
if (namespace_update_incremental (info, lmid, lm, is_initial_ns))
@@ -1925,6 +1942,8 @@ svr4_handle_solib_event (bpstat bs)
warning (_("Probes-based dynamic linker interface failed.\n"
"Reverting to original interface.\n"));
+ if (cleanups != NULL)
+ do_cleanups (cleanups);
free_namespace_table (info);
free_probes (info);
info->using_probes = 0;