]> sourceware.org Git - systemtap.git/commitdiff
Allow more than one java probe point per script
authorLukas Berk <lberk@redhat.com>
Wed, 3 Apr 2013 21:26:40 +0000 (17:26 -0400)
committerLukas Berk <lberk@redhat.com>
Wed, 1 May 2013 15:11:26 +0000 (11:11 -0400)
*tapset-method.cxx: add filter to match probe against the class
    and method, if it doesn't match, then skip
    the probe point
*session.cxx: change how rules are uninstalled

session.cxx
session.h
tapset-method.cxx

index 5be5f41888966cd40d0c16de27250169cc1a2383..05c167fdc2244a1e6c6d5c91a0e77ed700ce7e5b 100644 (file)
@@ -161,12 +161,10 @@ systemtap_session::systemtap_session ():
   sysroot = "";
   update_release_sysroot = false;
   suppress_time_limits = false;
-  java_pid = 0;
-  java_proc_class = "";
 #ifdef HAVE_HELPER
   bminstall_path = "";
   bmsubmit_path = "";
-  byteman_script_path = "";
+  run_once = false;
   byteman_log = "";
 #endif //HAVE_HELPER
 
@@ -345,6 +343,7 @@ systemtap_session::systemtap_session (const systemtap_session& other,
 
 
 #ifdef HAVE_HELPER
+  run_once = other.run_once;
   java_pid = other.java_pid;
   java_proc_class = other.java_proc_class;
   bminstall_path = other.bminstall_path;
@@ -389,7 +388,7 @@ systemtap_session::~systemtap_session ()
 {
 #ifdef HAVE_HELPER
 
-  if(java_pid != 0 || !java_proc_class.empty())
+  //  if(!java_pid.empty() || !java_proc_class.empty())
     java_detach();
 #endif //HAVE_HELPER
   remove_tmp_dir();
@@ -2015,16 +2014,19 @@ translator_output* systemtap_session::op_create_auxiliary()
 void
 systemtap_session::java_detach()
 {
-  vector<string> bmcommand;
-  bmcommand.push_back(bmsubmit_path);
-  bmcommand.push_back(" -o");
-  bmcommand.push_back(byteman_log);
-  bmcommand.push_back(" -u");
-  bmcommand.push_back(byteman_script_path);
-  (void) stap_system(verbose, bmcommand);
-  if (verbose>1)
-    clog << _F("Removed byteman rule: \"%s\"", byteman_script_path.c_str()) << endl;
 
+  for(vector<string>::const_iterator it = byteman_script_path.begin(); it != byteman_script_path.end(); ++it)
+    {
+      vector<string> bmcommand;
+      bmcommand.push_back(bmsubmit_path);
+      bmcommand.push_back(" -o");
+      bmcommand.push_back(byteman_log);
+      bmcommand.push_back(" -u");
+      bmcommand.push_back(*it);
+      (void) stap_system(verbose, bmcommand);
+  if (verbose>1)
+    clog << _F("Removed byteman rule: \"%s\"", (*it).c_str()) << endl;
+    }
 }
 #endif
 
index a7b8494e33f15db47d011324ba2a0c8d84008722..5a836adac386eb99a2f18aa255091b3106f0ac28 100644 (file)
--- a/session.h
+++ b/session.h
@@ -202,11 +202,12 @@ public:
   bool suppress_time_limits;
 
   void java_detach();
-  int java_pid;
-  std::string java_proc_class;
+  bool run_once;
+  std::vector<int> java_pid;
+  std::vector<std::string> java_proc_class;
+  std::vector<std::string> byteman_script_path;
   std::string bminstall_path;
   std::string bmsubmit_path;
-  std::string byteman_script_path;
   std::string byteman_log;
 
   enum { kernel_runtime, dyninst_runtime } runtime_mode;
index bcf54cdaf52dfb1ea8af8bc35d11b2109fe67114..68ab5cdd17dd29810144a5cd425cc68254e2027d 100644 (file)
@@ -44,7 +44,6 @@ private:
   typedef pair<java_cache_const_iterator_t, java_cache_const_iterator_t>
     java_cache_const_iterator_pair_t;
   java_cache_t java_cache;
-  //  string helper_path;
 
 public:
   java_builder (): cache_initialized (false) {}
@@ -99,7 +98,7 @@ java_builder::build (systemtap_session & sess,
   bool has_method_str = get_param (parameters, TOK_METHOD, method_str_val);
   int short_method_pos = method_str_val.find ('(');
   //only if it exists, run check
-  bool one_arg = false;
+  bool one_arg = false; // used to check if there is an argument in the method
   if (short_method_pos)
     {
       int second_method_pos = 0;
@@ -107,12 +106,45 @@ java_builder::build (systemtap_session & sess,
       if ((second_method_pos - short_method_pos) >= 1)
        one_arg = true;
     }
+  vector<int>::iterator it;
+  vector<string>::iterator is;
+  int _java_pid = 0;
+  string _java_proc_class = "";
   string short_method_str = method_str_val.substr (0, short_method_pos);
   string class_str_val; // fully qualified class string
   bool has_class_str = get_param (parameters, TOK_CLASS, class_str_val);
-  bool has_pid_int = get_number_param (parameters, TOK_JAVA, sess.java_pid);
-  bool has_pid_str = get_param (parameters, TOK_JAVA, sess.java_proc_class);
+  bool has_pid_int = get_number_param (parameters, TOK_JAVA, _java_pid);
+  bool has_pid_str = get_param (parameters, TOK_JAVA, _java_proc_class);
 
+  if (has_pid_int)
+    {
+      for (it = sess.java_pid.begin(); it != sess.java_pid.end(); ++it)
+       {
+         if(*it == _java_pid) //if we work our way though it all and still doesn't 
+           {
+             break;                    // match then we push back on the vector
+           }
+         else if ((*it != _java_pid) && ++it == sess.java_pid.end())
+           {
+             sess.java_pid.push_back(_java_pid);
+           }
+       }
+
+    }
+  else
+    {
+      for (is = sess.java_proc_class.begin(); is != sess.java_proc_class.end(); ++is)
+       {
+         if(*is == _java_proc_class)
+           {
+             break;
+           }
+         else if ((*is != _java_proc_class) && (++is == sess.java_proc_class.end()))
+           {
+             sess.java_proc_class.push_back(_java_proc_class);
+           }
+       }
+    }
   //need to count the number of parameters, exit if more than 10
   int method_params_counter = 1;
   int method_params_count = count (method_str_val.begin (), method_str_val.end (), ',');
@@ -128,24 +160,33 @@ java_builder::build (systemtap_session & sess,
   (void) has_method_str;
   assert (has_class_str);
   (void) has_class_str;
-
+  string _tmp = "";
   if (! cache_initialized)
     {
 
-      cache_initialized = true;
-      sess.byteman_script_path = sess.tmpdir + "/stap-byteman.btm";
+      //      cache_initialized = true;
+      if(has_pid_int)
+       {
+         _tmp = static_cast <ostringstream*> ( & (ostringstream ()
+                                                        << (_java_pid)))->str ();
+
+         sess.byteman_script_path.push_back(sess.tmpdir + "/stap-byteman-" + _tmp + ".btm");
+       }
+      else
+       sess.byteman_script_path.push_back(sess.tmpdir + "/stap-byteman-" + _java_proc_class + ".btm");
+
       if (sess.verbose > 3)
        {
-         clog << "byteman script path: " << sess.byteman_script_path
+         clog << "byteman script path: " << sess.byteman_script_path.at(*it)
               << endl;
        }
       ofstream byteman_script;
-      byteman_script.open (sess.byteman_script_path.c_str(), ifstream::out);
+      byteman_script.open ((sess.byteman_script_path.back()).c_str(), ifstream::app); //| ifstream::out);
       if (! byteman_script)
        {
          if (sess.verbose > 3)
            //TRANSLATORS: Specific path cannot be opened
-           clog << sess.byteman_script_path << _(" cannot be opened: ")
+           clog << sess.byteman_script_path.at(*it) << _(" cannot be opened: ")
                 << strerror (errno) << endl;
          return;
        }
@@ -153,7 +194,7 @@ java_builder::build (systemtap_session & sess,
       if (sess.verbose > 2)
        clog << "Writting byteman script" << endl;
       // none of this should be translated, byteman syntax is specific
-      byteman_script << "RULE Stap " << sess.base_hash << endl;
+      byteman_script << "RULE Stap " << sess.base_hash << method_str_val << endl;
       // we'll need detection here for second type of syntax
       // XXX change the method name being passed
       byteman_script << "CLASS " << class_str_val << endl
@@ -162,8 +203,9 @@ java_builder::build (systemtap_session & sess,
                     << "AT ENTRY" << endl
                     << "IF TRUE" << endl
                     << "DO METHOD_STAP_PROBE" << method_params_count
-                    << "(\"stap-" << sess.base_hash << "\", \""
-                    << short_method_str << "\", ";
+                    << "(\"" << class_str_val <<  "\", \""
+       //                   << short_method_str << "\", ";
+                    << method_str_val << "\", ";
       // we need increment the var number, while decrementing the count
       for (method_params_counter = 1;
           method_params_counter <= method_params_count;
@@ -192,14 +234,15 @@ java_builder::build (systemtap_session & sess,
   if (! (has_pid_int || has_pid_str) )
     exit (1); //XXX proper exit with warning message
 
-  string arg = static_cast <ostringstream*> ( & (ostringstream ()
-                                                << sess.java_pid) )->str ();
+  const char* java_pid_str;
+  if (has_pid_int)
+    java_pid_str = _tmp.c_str();
+  else
+    java_pid_str = _java_proc_class.c_str();
   
-  const char* java_pid_str = arg.c_str ();
-
   sess.bminstall_path = (find_executable ("bminstall.sh"));
 
-  if (sess.verbose > 3)
+  if (sess.verbose > 2)
     clog << "Reported bminstall.sh path: " << sess.bminstall_path << endl;
   // XXX check both scripts here, exit if not available
 
@@ -208,10 +251,16 @@ java_builder::build (systemtap_session & sess,
   if(!has_pid_str)
     bminstall_cmd.push_back(java_pid_str);
   else
-    bminstall_cmd.push_back(sess.java_proc_class);
-
-  (void) stap_system(sess.verbose, bminstall_cmd);
-
+    bminstall_cmd.push_back(_java_proc_class);
+  //need to properly check this
+  int ret = stap_system(sess.verbose, bminstall_cmd);
+  if (sess.verbose > 2)
+    {
+      if (ret)
+       clog << "WARNING: stap_system for bminstall.sh returned error: " << ret << endl;
+      else
+       clog << "stap_system for bminstall.sh returned: " << ret << endl;
+    }
   vector<string> bmsubmit_cmd;
   sess.bmsubmit_path = (find_executable ("bmsubmit.sh"));
   sess.byteman_log = sess.tmpdir + "/byteman.log";
@@ -219,7 +268,11 @@ java_builder::build (systemtap_session & sess,
   bmsubmit_cmd.push_back(" -o");
   bmsubmit_cmd.push_back(sess.byteman_log);
   bmsubmit_cmd.push_back(" -l");
-  bmsubmit_cmd.push_back(sess.byteman_script_path);
+
+  if(has_pid_int)
+    bmsubmit_cmd.push_back(sess.byteman_script_path.back());
+  else
+    bmsubmit_cmd.push_back(sess.byteman_script_path.back());
   (void) stap_system(sess.verbose, bmsubmit_cmd);
   if (sess.verbose > 3)
     clog << "Reported bmsubmit.sh path: " << sess.bmsubmit_path << endl;
@@ -230,16 +283,81 @@ java_builder::build (systemtap_session & sess,
    * using a vector, iterate though, changing as needed
    * redefine functor values with new literal_string("foo")
    */
-  probe_point* new_loc = new probe_point (*loc);
-  vector<probe_point::component*> java_marker;
-  java_marker.push_back( new probe_point::component 
-                        (TOK_PROCESS, new literal_string ("/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/jre/lib/amd64/libHelperSDT.so")));
-  java_marker.push_back( new probe_point::component 
-                        (TOK_MARK, new literal_string ("*")));
-  probe_point * derived_loc = new probe_point (*new_loc);
-  derived_loc->components = java_marker;
-  probe *new_mark_probe = base->create_alias (derived_loc, new_loc);
-  derive_probes (sess, new_mark_probe, finished_results);
+      //XXX can this be moved into its own function, or after root->bind'ing takes place
+      probe_point* new_loc = new probe_point (*loc);
+      vector<probe_point::component*> java_marker;
+      java_marker.push_back( new probe_point::component 
+       (TOK_PROCESS, new literal_string (HAVE_HELPER)));
+      java_marker.push_back( new probe_point::component 
+       (TOK_MARK, new literal_string ("*")));
+      probe_point * derived_loc = new probe_point (*new_loc);
+
+      block *b = new block;
+      b->tok = base->body->tok;
+
+      // first half of argument
+      target_symbol *cc = new target_symbol;
+      cc->tok = b->tok;
+      cc->name = "$provider";
+
+      functioncall *ccus = new functioncall;
+      ccus->function = "user_string";
+      ccus->type = pe_string;
+      ccus->tok = b->tok;
+      ccus->args.push_back(cc);
+      
+      // second half of argument
+      target_symbol *mc = new target_symbol;
+      mc->tok = b->tok;
+      mc->name = "$name";
+
+
+      functioncall *mcus = new functioncall;
+      mcus->function = "user_string";
+      mcus->type = pe_string;
+      mcus->tok = b->tok;
+      mcus->args.push_back(mc);
+      
+      //build if statement
+      if_statement *ifs = new if_statement;
+      ifs->thenblock = new next_statement;
+      ifs->elseblock = NULL;
+      ifs->tok = b->tok;
+      ifs->thenblock->tok = b->tok;
+
+      //class comparison
+      comparison *ce = new comparison;
+      ce->op = "!=";
+      ce->tok = b->tok;
+      ce->left = ccus;
+      ce->right = new literal_string(class_str_val);
+      ce->right->tok = b->tok;
+      ifs->condition = ce;
+      b->statements.push_back(ifs);
+
+      //method comparision
+      comparison *me = new comparison;
+      me->op = "!=";
+      me->tok = b->tok;
+      me->left = mcus;
+      me->right = new literal_string(method_str_val);
+      me->right->tok = b->tok;
+
+      logical_or_expr *le = new logical_or_expr;
+      le->op = "||";
+      le->tok = b->tok;
+      le->left = ce;
+      le->right = me;
+      ifs->condition = le;
+      b->statements.push_back(ifs);
+
+      b->statements.push_back(base->body);
+      base->body = b;
+
+      derived_loc->components = java_marker;
+      probe *new_mark_probe = base->create_alias (derived_loc, new_loc);
+      derive_probes (sess, new_mark_probe, finished_results);
+   
 #else
   cerr << _("Cannot probe java method, configure --with-helper=") << endl;
 #endif
This page took 0.041541 seconds and 5 git commands to generate.