2012-07-30 Gary Benson * 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;