summaryrefslogtreecommitdiffstats
path: root/translate.cxx
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2009-07-07 14:36:53 -0400
committerFrank Ch. Eigler <fche@elastic.org>2009-07-07 14:44:05 -0400
commitae2552daf405ab1f59ddc862cfe0fcb4d90f8174 (patch)
tree6efba280061591879c759e7caf828d2d06700894 /translate.cxx
parent5cc5056844a402c6cf466c8ca45119a4540b5900 (diff)
downloadsystemtap-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.cxx59
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);