diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2009-07-07 14:36:53 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2009-07-07 14:44:05 -0400 |
commit | ae2552daf405ab1f59ddc862cfe0fcb4d90f8174 (patch) | |
tree | 6efba280061591879c759e7caf828d2d06700894 /translate.cxx | |
parent | 5cc5056844a402c6cf466c8ca45119a4540b5900 (diff) | |
download | systemtap-steved-ae2552daf405ab1f59ddc862cfe0fcb4d90f8174.tar.gz systemtap-steved-ae2552daf405ab1f59ddc862cfe0fcb4d90f8174.tar.xz systemtap-steved-ae2552daf405ab1f59ddc862cfe0fcb4d90f8174.zip |
PR3498: speed up pass-2 and pass-3 for kernel offline dwfl module searching
* dwflpp.cxx (dwflpp ctor): Parametrize for user/kernel modes.
Update callers.
(dwfl_report_offline_predicate): New function. Filter and
abort searches early if possible.
(setup_kernel): Use new predicate.
* dwflpp.h: Corresponding changes.
* tapsets.cxx (dwfl_report_offline_predicate): Remove this shared
implementation.
(dwarf_builder): Turn kern_dw into module_name->dwflpp* map, just
like user_dw.
(get_kern_dw): Adapt.
(dwarf_build_no_more): Adapt.
* tapsets.h: Remove old shared predicate.
* translate.cxx (dwfl_report_offline_predicate2): New function.
Filter and abort searches early if possible.
(emit_symbol_data): Use it.
Diffstat (limited to 'translate.cxx')
-rw-r--r-- | translate.cxx | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/translate.cxx b/translate.cxx index 378395b8..9c901065 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4907,6 +4907,27 @@ dump_unwindsyms (Dwfl_Module *m, // them with the runtime. void emit_symbol_data_done (unwindsym_dump_context*, systemtap_session&); + +static set<string> offline_search_modules; +static int dwfl_report_offline_predicate2 (const char* modname, const char* filename) +{ + if (pending_interrupts) + return -1; + + if (offline_search_modules.empty()) + return -1; + + /* Reject mismatching module names */ + if (offline_search_modules.find(modname) == offline_search_modules.end()) + return 0; + else + { + offline_search_modules.erase(modname); + return 1; + } +} + + void emit_symbol_data (systemtap_session& s) { @@ -4959,22 +4980,38 @@ emit_symbol_data (systemtap_session& s) else elfutils_kernel_path = s.kernel_build_tree; + + // Set up our offline search for kernel modules. As in dwflpp.cxx, + // we don't want the offline search iteration to do a complete search + // of the kernel build tree, since that's wasteful. + offline_search_modules.erase (offline_search_modules.begin(), + offline_search_modules.end()); + for (set<string>::iterator it = s.unwindsym_modules.begin(); + it != s.unwindsym_modules.end(); + it++) + { + string foo = *it; + if (foo[0] != '/') /* Omit user-space, since we're only using this for + kernel space offline searches. */ + offline_search_modules.insert (foo); + } + int rc = dwfl_linux_kernel_report_offline (dwfl, elfutils_kernel_path.c_str(), - &dwfl_report_offline_predicate); + & dwfl_report_offline_predicate2); + + (void) rc; // As in dwflpp.cxx, we ignore rc here. + dwfl_report_end (dwfl, NULL, NULL); - if (rc == 0) // tolerate missing data; will warn user about it anyway + ptrdiff_t off = 0; + do { - ptrdiff_t off = 0; - do - { - if (pending_interrupts) return; - if (ctx.undone_unwindsym_modules.empty()) break; - off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); - } - while (off > 0); - dwfl_assert("dwfl_getmodules", off == 0); + if (pending_interrupts) return; + if (ctx.undone_unwindsym_modules.empty()) break; + off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); } + while (off > 0); + dwfl_assert("dwfl_getmodules", off == 0); dwfl_end(dwfl); |