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 /dwflpp.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 'dwflpp.cxx')
-rw-r--r-- | dwflpp.cxx | 64 |
1 files changed, 49 insertions, 15 deletions
@@ -63,16 +63,16 @@ using namespace __gnu_cxx; static string TOK_KERNEL("kernel"); -dwflpp::dwflpp(systemtap_session & session, const string& user_module): +dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p): sess(session), module(NULL), module_bias(0), mod_info(NULL), module_start(0), module_end(0), cu(NULL), dwfl(NULL), module_dwarf(NULL), function(NULL), blacklist_enabled(false), pc_cached_scopes(0), num_cached_scopes(0), cached_scopes(NULL) { - if (user_module.empty()) - setup_kernel(); + if (kernel_p) + setup_kernel(name); else - setup_user(user_module); + setup_user(name); } @@ -250,8 +250,32 @@ dwflpp::function_name_final_match(const string& pattern) } +static const char *offline_search_modname = NULL; +static int offline_search_match_p = 0; + +static int dwfl_report_offline_predicate (const char* modname, const char* filename) +{ + if (pending_interrupts) + return -1; + + if (offline_search_match_p) + return -1; + + assert (offline_search_modname); + + /* Reject mismatching module names */ + if (strcmp(modname, offline_search_modname)) + return 0; + else + { + offline_search_match_p ++; + return 1; + } +} + + void -dwflpp::setup_kernel(bool debuginfo_needed) +dwflpp::setup_kernel(const string& name, bool debuginfo_needed) { // XXX: See also translate.cxx:emit_symbol_data @@ -289,21 +313,31 @@ dwflpp::setup_kernel(bool debuginfo_needed) else elfutils_kernel_path = sess.kernel_build_tree; + offline_search_modname = name.c_str(); + offline_search_match_p = 0; int rc = dwfl_linux_kernel_report_offline (dwfl, elfutils_kernel_path.c_str(), &dwfl_report_offline_predicate); + offline_search_modname = NULL; + + (void) rc; /* Ignore since the predicate probably returned -1 at some point, + And libdwfl interprets that as "whole query failed" rather than + "found it already, stop looking". */ - if (debuginfo_needed) { - if (rc) { - // Suggest a likely kernel dir to find debuginfo rpm for - string dir = string("/lib/modules/" + sess.kernel_release ); - find_debug_rpms(sess, dir.c_str()); + /* But we still need to check whether the module was itself found. One could + do an iterate_modules() search over the resulting dwfl and count hits. Or + one could rely on the match_p flag being set just before. */ + if (! offline_search_match_p) + { + if (debuginfo_needed) { + // Suggest a likely kernel dir to find debuginfo rpm for + string dir = string("/lib/modules/" + sess.kernel_release ); + find_debug_rpms(sess, dir.c_str()); + } + throw semantic_error (string("missing ") + sess.architecture + + string(" kernel/module debuginfo under '") + + sess.kernel_build_tree + string("'")); } - dwfl_assert (string("missing ") + sess.architecture + - string(" kernel/module debuginfo under '") + - sess.kernel_build_tree + string("'"), - rc); - } // XXX: it would be nice if we could do a single // ..._report_offline call for an entire systemtap script, so |