]> sourceware.org Git - systemtap.git/commitdiff
Fixed PR11424 by using System.map data to validate dwarfless kprobe probes.
authorDavid Smith <dsmith@redhat.com>
Wed, 18 Jul 2012 18:30:59 +0000 (13:30 -0500)
committerDavid Smith <dsmith@redhat.com>
Wed, 18 Jul 2012 18:30:59 +0000 (13:30 -0500)
* 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

index 354b40d1d7f151581f1d189a3c89c5adc4403c43..9280032cf0253dd2e7de4c935c9a51b3582f0920 100644 (file)
@@ -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<string> 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<string>::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
     {
This page took 0.037539 seconds and 5 git commands to generate.