From 9fdf787d2e57f77cfc4df0af8dfdadb8a5582847 Mon Sep 17 00:00:00 2001 From: David Smith Date: Wed, 18 Jul 2012 13:30:59 -0500 Subject: [PATCH] Fixed PR11424 by using System.map data to validate dwarfless kprobe probes. * tapsets.cxx (kprobe_builder::load_function_name_cache): New function. (kprobe_builder::build): Use parsed System.map data to validate kprobe.function probe names. --- tapsets.cxx | 115 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 13 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index 354b40d1d..9280032cf 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8119,7 +8119,25 @@ kprobe_derived_probe_group::emit_module_exit (systemtap_session& s) struct kprobe_builder: public derived_probe_builder { - kprobe_builder() {} +private: + bool cache_initialized; + vector function_name_cache; + + void load_function_name_cache(systemtap_session & sess); + +public: + kprobe_builder(): cache_initialized(false) {} + + void build_no_more (systemtap_session &s) + { + if (! function_name_cache.empty()) + { + if (s.verbose > 3) + clog << _("kprobe_builder releasing cache") << endl; + function_name_cache.clear(); + } + } + virtual void build(systemtap_session & sess, probe * base, probe_point * location, @@ -8128,6 +8146,57 @@ struct kprobe_builder: public derived_probe_builder }; +void +kprobe_builder::load_function_name_cache(systemtap_session &sess) +{ + if (! cache_initialized) + { + cache_initialized = true; + string system_map_path = sess.kernel_build_tree + "/System.map"; + ifstream system_map; + + system_map.open(system_map_path.c_str(), ifstream::in); + if (! system_map.is_open()) + { + string system_map_path2 = "/boot/System.map-" + sess.kernel_release; + + system_map.clear(); + system_map.open(system_map_path2.c_str(), ifstream::in); + if (! system_map.is_open()) + { + if (sess.verbose > 3) + //TRANSLATORS: specific path cannot be opened + clog << system_map_path << _(" and ") + << system_map_path2 << _(" cannot be opened: ") + << strerror(errno) << endl; + return; + } + } + + string address, type, name; + do + { + system_map >> address >> type >> name; + + if (sess.verbose > 3) + clog << "'" << address << "' '" << type << "' '" << name + << "'" << endl; + + // 'T'/'t' are text code symbols + if (type != "t" && type != "T") + continue; + + // FIXME: better things to do here - look for _stext before + // remembering symbols. Also: + // - stop remembering names at ??? + // - what about __kprobes_text_start/__kprobes_text_end? + function_name_cache.push_back(name); + } + while (! system_map.eof()); + system_map.close(); + } +} + void kprobe_builder::build(systemtap_session & sess, probe * base, @@ -8165,19 +8234,39 @@ kprobe_builder::build(systemtap_session & sess, if (has_function_str) { - if (has_module_str) - function_string_val = module_string_val + ":" + function_string_val; + if (has_module_str) + { + function_string_val = module_string_val + ":" + function_string_val; + derived_probe *dp + = new kprobe_derived_probe (base, location, function_string_val, + 0, has_return, has_statement_num, + has_maxactive, has_path, has_library, + maxactive_val, path_tgt, library_tgt); + finished_results.push_back (dp); + } + else + { + load_function_name_cache(sess); - finished_results.push_back (new kprobe_derived_probe (base, - location, function_string_val, - 0, has_return, - has_statement_num, - has_maxactive, - has_path, - has_library, - maxactive_val, - path_tgt, - library_tgt)); + // Search function name list for matching names + for (vector::const_iterator it = function_name_cache.begin(); + it != function_name_cache.end(); it++) + { + // Below, "rc" has negative polarity: zero iff matching. + int rc = fnmatch(function_string_val.c_str(), (*it).c_str(), 0); + if (! rc) + { + derived_probe *dp + = new kprobe_derived_probe (base, location, *it, + 0, has_return, + has_statement_num, + has_maxactive, has_path, + has_library, maxactive_val, + path_tgt, library_tgt); + finished_results.push_back (dp); + } + } + } } else { -- 2.43.5