]> sourceware.org Git - systemtap.git/commitdiff
2005-07-05 Graydon Hoare <graydon@redhat.com>
authorgraydon <graydon>
Wed, 6 Jul 2005 01:32:09 +0000 (01:32 +0000)
committergraydon <graydon>
Wed, 6 Jul 2005 01:32:09 +0000 (01:32 +0000)
* elaborate.{h,cxx}: Revert previous changes.
* tapsets.{h,cxx}: Adapt to verbose as a member of session.
* elaborate.cxx (alias_expansion_builder::build): Avoid copying
locals between alias definition and use.
* testsuite/semok/{twelve,thirteen,fourteen}.stp: New tests.
* staptree.cxx (probe_alias::printsig): Print equals sign.

ChangeLog
elaborate.cxx
elaborate.h
staptree.cxx
tapsets.cxx
testsuite/semok/fourteen.stp [new file with mode: 0755]
testsuite/semok/thirteen.stp [new file with mode: 0755]
testsuite/semok/twelve.stp [new file with mode: 0755]

index 916ac1e86f20b3e898384eb05c94b49db4ffca93..88cb0ca13a187e21c5a05e5b4d272142f1ea67c4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-05  Graydon Hoare  <graydon@redhat.com>
+
+       * elaborate.{h,cxx}: Revert previous changes.
+       * tapsets.{h,cxx}: Adapt to verbose as a member of session.
+       * elaborate.cxx (alias_expansion_builder::build): Avoid copying
+       locals between alias definition and use.
+       * testsuite/semok/{twelve,thirteen,fourteen}.stp: New tests.
+       * staptree.cxx (probe_alias::printsig): Print equals sign.
+
 2005-07-05  Frank Ch. Eigler  <fche@redhat.com>
 
        * elaborate.h (systemtap_session): Add more command-line arguments.
index 890d6f4ac4c0f3b3db22430169917514645a3de3..37d43ee162dffda65a786f5db3c9967791edcf51 100644 (file)
@@ -234,7 +234,8 @@ alias_expansion_builder
     : alias(a)
   {}
 
-  virtual void build(probe * use, 
+  virtual void build(systemtap_session & sess,
+                    probe * use, 
                     probe_point * location,
                     std::map<std::string, literal *> const & parameters,
                     vector<probe *> & results_to_expand_further,
@@ -253,10 +254,14 @@ alias_expansion_builder
     // the token location of the use,
     n->tok = use->tok;
 
-    // and a set of locals and statements representing the 
-    // concatenation of the alias' body with the use's.
-    copy(alias->locals.begin(), alias->locals.end(), back_inserter(n->locals));
-    copy(use->locals.begin(), use->locals.end(), back_inserter(n->locals));
+    // and statements representing the concatenation of the alias'
+    // body with the use's. 
+    //
+    // NB: locals are *not* copied forward, from either alias or
+    // use. The expansion should have its locals re-inferred since
+    // there's concatenated code here and we only want one vardecl per
+    // resulting variable.
+
     copy(alias->body->statements.begin(), 
         alias->body->statements.end(),
         back_inserter(n->body->statements));
@@ -317,11 +322,32 @@ systemtap_session::register_library_aliases()
 }
 
 
+static unsigned max_recursion = 100;
+
+struct 
+recursion_guard
+{
+  unsigned & i;
+  recursion_guard(unsigned & i) : i(i)
+    {
+      if (i > max_recursion)
+       throw semantic_error("recursion limit reached");
+      ++i;
+    }
+  ~recursion_guard() 
+    {
+      --i;
+    }
+};
+
 // The match-and-expand loop.
 void
 symresolution_info::derive_probes (match_node * root, 
                                   probe *p, vector<derived_probe*>& dps)
 {
+  static unsigned depth=0;
+  recursion_guard guard(depth);
+
   for (unsigned i = 0; i < p->locations.size(); ++i)
     {
       probe_point *loc = p->locations[i];
@@ -337,7 +363,7 @@ symresolution_info::derive_probes (match_node * root,
 
       param_vec_to_map(param_vec, param_map);
 
-      builder->build(p, loc, param_map, re_expand, dps);
+      builder->build(session, p, loc, param_map, re_expand, dps);
       
       // Recursively expand any further-expanding results
       if (!re_expand.empty())
@@ -393,7 +419,6 @@ semantic_pass_symbols (systemtap_session& s)
             {
               sym.current_function = fd;
               sym.current_probe = 0;
-              sym.current_derived_probe = 0;
               fd->body->visit (& sym);
             }
           catch (const semantic_error& e)
@@ -402,36 +427,8 @@ semantic_pass_symbols (systemtap_session& s)
             }
         }
 
-      // Pass 3: resolve symbols in probes (pre-derivation).  Symbols
-      // used in a probe are bound to vardecls in the probe's "locals"
-      // vector.
-
-      for (unsigned i=0; i<dome->probes.size(); i++)
-       {
-         probe *p = dome->probes[i];
-         sym.current_function = 0;
-         sym.current_probe = p;
-         sym.current_derived_probe = 0;
-         p->body->visit (& sym);
-       }
-
-      // Pass 4: resolve symbols in aliases (pre-expansion).  Symbols
-      // used in an alias probe are bound to vardecls in the alias'
-      // "locals" vector.
-
-      for (unsigned i=0; i<dome->aliases.size(); i++)
-       {
-         probe *p = dome->aliases[i];
-         sym.current_function = 0;
-         sym.current_probe = p;
-         sym.current_derived_probe = 0;
-         p->body->visit (& sym);
-       }
-
-      // Pass 5: derive probes and resolve any further symbols in the
-      // derived results. Symbols used in a derived probe (but not
-      // already bound to the base probe) are bound to vardecls in the
-      // derived probe's "locals" vector.
+      // Pass 3: derive probes and resolve any further symbols in the
+      // derived results. 
 
       for (unsigned i=0; i<dome->probes.size(); i++)
         {
@@ -458,8 +455,7 @@ semantic_pass_symbols (systemtap_session& s)
               try 
                 {
                   sym.current_function = 0;
-                  sym.current_probe = 0;
-                 sym.current_derived_probe = dp;
+                  sym.current_probe = dp;
                   dp->body->visit (& sym);
                 }
               catch (const semantic_error& e)
@@ -514,8 +510,7 @@ systemtap_session::print_error (const semantic_error& e)
 
 
 symresolution_info::symresolution_info (systemtap_session& s):
-  session (s), current_function (0), 
-  current_probe (0), current_derived_probe(0)
+  session (s), current_function (0), current_probe (0)
 {
 }
 
@@ -575,8 +570,6 @@ symresolution_info::visit_symbol (symbol* e)
         current_function->locals.push_back (v);
       else if (current_probe)
         current_probe->locals.push_back (v);
-      else if (current_derived_probe)
-        current_derived_probe->locals.push_back (v);
       else
         // must not happen
         throw semantic_error ("no current probe/function", e->tok);
@@ -625,9 +618,7 @@ symresolution_info::find_scalar (const string& name)
   // search locals
   vector<vardecl*>& locals = (current_function ? 
                               current_function->locals :
-                             (current_probe ? 
-                              current_probe->locals :
-                              current_derived_probe->locals));    
+                             current_probe->locals);
 
   for (unsigned i=0; i<locals.size(); i++)
     if (locals[i]->name == name)
index e61796fa522ff2759260961d38ca724dd8d0e1cf..f25ee5e78043b7c1cd7c5e53ec83372b5ce78ce4 100644 (file)
@@ -30,8 +30,7 @@ protected:
 
 public:
   functiondecl* current_function;
-  probe* current_probe;
-  derived_probe* current_derived_probe;
+  derived_probe* current_probe;
   symresolution_info (systemtap_session& s);
 
   // XXX: instead in systemtap_session?
@@ -140,7 +139,8 @@ struct derived_probe: public probe
 struct
 derived_probe_builder
 {
-  virtual void build(probe * base, 
+  virtual void build(systemtap_session & sess,
+                    probe * base, 
                     probe_point * location,
                     std::map<std::string, literal *> const & parameters,
                     std::vector<probe *> & results_to_expand_further,
index 1243df985e28b8170656f160fbcd9ae62c9f9d98..e64c3710bd47a14c68fce7f4c711ccd6dfe6cf38 100644 (file)
@@ -435,6 +435,7 @@ void probe_alias::printsig (ostream& o)
       o << (i>0 ? " = " : "");
       alias_names[i]->print (o);
     }
+  o << " = ";
   for (unsigned i=0; i<locations.size(); i++)
     {
       o << (i>0 ? ", " : "");
index 160cb2fe14e72c8dcf3c80c09ccbc811679be001..3dbbfa81523ceb8bc45910e92d5956c04703c292 100644 (file)
@@ -52,7 +52,8 @@ be_builder
 {
   bool begin;
   be_builder(bool b) : begin(b) {}
-  virtual void build(probe * base, 
+  virtual void build(systemtap_session & sess,
+                    probe * base, 
                     probe_point * location,
                     std::map<std::string, literal *> const & parameters,
                     vector<probe *> & results_to_expand_further,
@@ -126,7 +127,7 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
 struct
 dwflpp
 {
-
+  systemtap_session & sess;
   Dwfl * dwfl;
 
   // These are "current" values we focus on.
@@ -145,22 +146,28 @@ dwflpp
   {
     if (in) 
       return in;
-    if (verbose)
+    if (sess.verbose)
       clog << "WARNING: no name found for " << type << endl;
     return string("default_anonymous_" ) + type;
   }
 
+  void get_module_dwarf()
+  {
+    if (!module_dwarf)
+      module_dwarf = dwfl_module_getdwarf(module, &module_bias);
+  }
+
   void focus_on_module(Dwfl_Module * m)
   {
     assert(m);
     module = m;
-    module_dwarf = dwfl_module_getdwarf(module, &module_bias);
+    module_dwarf = NULL;
     module_name = default_name(dwfl_module_info(module, NULL, 
                                                NULL, NULL,
                                                NULL, NULL,
                                                NULL, NULL),
                               "module");
-    if (verbose)
+    if (sess.verbose)
       clog << "focused on module " << module_name << endl;
   }
 
@@ -169,7 +176,7 @@ dwflpp
     assert(c);
     cu = c;
     cu_name = default_name(dwarf_diename(c), "cu");
-    if (verbose)
+    if (sess.verbose)
       clog << "focused on CU " << cu_name 
           << ", in module " << module_name << endl;
   }
@@ -180,7 +187,7 @@ dwflpp
     function = f;
     function_name = default_name(dwarf_func_name(function), 
                                 "function");
-    if (verbose)
+    if (sess.verbose)
       clog << "focused on function " << function_name 
           << ", in CU " << cu_name 
           << ", module " << module_name << endl;
@@ -189,7 +196,7 @@ dwflpp
   void focus_on_module_containing_global_address(Dwarf_Addr a)
   {
     assert(dwfl);
-    if (verbose)
+    if (sess.verbose)
       clog << "focusing on module containing global addr " << a << endl;
     focus_on_module(dwfl_addrmodule(dwfl, a));
   }
@@ -199,7 +206,8 @@ dwflpp
     assert(dwfl);
     assert(module);
     Dwarf_Addr bias;
-    if (verbose)
+    get_module_dwarf();
+    if (sess.verbose)
       clog << "focusing on cu containing module addr " << a << endl;
     focus_on_cu(dwfl_module_addrdie(module, a, &bias));
     assert(bias == module_bias);
@@ -208,7 +216,8 @@ dwflpp
   void focus_on_cu_containing_global_address(Dwarf_Addr a)
   {
     assert(dwfl);
-    if (verbose)
+    get_module_dwarf();
+    if (sess.verbose)
       clog << "focusing on cu containing global addr " << a << endl;
     focus_on_module_containing_global_address(a);
     assert(a > module_bias);
@@ -219,7 +228,8 @@ dwflpp
   Dwarf_Addr module_address_to_global(Dwarf_Addr a)
   {
     assert(module);
-    if (verbose)
+    get_module_dwarf();
+    if (sess.verbose)
       clog << "module addr " << a 
           << " + bias " << module_bias 
           << " -> global addr " << a + module_bias << endl;
@@ -229,7 +239,8 @@ dwflpp
   Dwarf_Addr global_address_to_module(Dwarf_Addr a)
   {
     assert(module);
-    if (verbose)
+    get_module_dwarf();
+    if (sess.verbose)
       clog << "global addr " << a 
           << " - bias " << module_bias 
           << " -> module addr " << a - module_bias << endl;
@@ -240,8 +251,9 @@ dwflpp
   bool module_name_matches(string pattern)
   {
     assert(module);
+    get_module_dwarf();
     bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
-    if (verbose)
+    if (sess.verbose)
       clog << "pattern '" << pattern << "' "
           << (t ? "matches " : "does not match ") 
           << "module '" << module_name << "'" << endl;
@@ -252,7 +264,7 @@ dwflpp
   {
     assert(function);
     bool t = (fnmatch(pattern.c_str(), function_name.c_str(), 0) == 0);
-    if (verbose)
+    if (sess.verbose)
       clog << "pattern '" << pattern << "' "
           << (t ? "matches " : "does not match ") 
           << "function '" << function_name << "'" << endl;
@@ -263,7 +275,7 @@ dwflpp
   {
     assert(cu);
     bool t = (fnmatch(pattern.c_str(), cu_name.c_str(), 0) == 0);
-    if (verbose)
+    if (sess.verbose)
       clog << "pattern '" << pattern << "' "
           << (t ? "matches " : "does not match ") 
           << "CU '" << cu_name << "'" << endl;
@@ -276,8 +288,9 @@ dwflpp
       throw semantic_error(string("dwfl failure: ") + dwfl_errmsg(rc));
   }
 
-  dwflpp()
+  dwflpp(systemtap_session & sess)
     :
+    sess(sess),
     dwfl(NULL),
     module(NULL),
     module_dwarf(NULL),
@@ -330,7 +343,7 @@ dwflpp
                                             Dwarf *, Dwarf_Addr, void *),
                            void * data)
   {
-    if (verbose)
+    if (sess.verbose)
       clog << "iterating over modules" << endl;
     ptrdiff_t off = 0;
     do
@@ -338,7 +351,7 @@ dwflpp
        off = dwfl_getdwarf(dwfl, callback, data, off);
       }
     while (off > 0);
-    if (verbose)
+    if (sess.verbose)
       clog << "finished iterating over modules" << endl;
     dwflpp_assert(off);
   }
@@ -346,13 +359,15 @@ dwflpp
   void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg), 
                         void * data)
   {
+    get_module_dwarf();
+
     if (!module_dwarf)
       {
        cerr << "WARNING: no dwarf info found for module " << module_name << endl;
        return;
       }
 
-    if (verbose)
+    if (sess.verbose)
       clog << "iterating over CUs in module " << module_name << endl;
 
     Dwarf *dw = module_dwarf;
@@ -375,7 +390,7 @@ dwflpp
   {
     assert(module);
     assert(cu);
-    if (verbose)
+    if (sess.verbose)
       clog << "iterating over functions in CU " << cu_name << endl;
     dwarf_getfuncs(cu, callback, data, 0);
   }
@@ -393,20 +408,20 @@ dwflpp
     Dwarf_Addr lo, hi;
     if (dwarf_func_lowpc(function, &lo) != 0)
       {
-       if (verbose)
+       if (sess.verbose)
          clog << "WARNING: cannot find low PC value for function " << function_name << endl;
        return false;
       }
     
     if (dwarf_func_highpc(function, &hi) != 0)
     {
-      if (verbose)
+      if (sess.verbose)
        clog << "WARNING: cannot find high PC value for function " << function_name << endl;
       return false;
     }
     
     bool t = lo <= addr && addr <= hi;
-    if (verbose)
+    if (sess.verbose)
       clog << "function " << function_name << " = [" << lo << "," << hi << "] "
           << (t ? "contains " : "does not contain ") 
           << " global addr " << addr << endl;
@@ -430,7 +445,7 @@ dwflpp
     dwflpp_assert(dwarf_getsrclines(cu, &lines, &nlines));
     linep = dwarf_onesrcline(lines, line);
     dwflpp_assert(dwarf_lineaddr(linep, &addr));
-    if (verbose)
+    if (sess.verbose)
       clog << "line " << line 
           << " of cu " << cu_name 
           << " has module address " << addr 
@@ -508,12 +523,15 @@ struct dwarf_derived_probe : public derived_probe
 struct 
 dwarf_query
 {
-  dwarf_query(probe * base_probe,
+  dwarf_query(systemtap_session & sess,
+             probe * base_probe,
              probe_point * base_loc,
              dwflpp & dw,
              map<string, literal *> const & params,
              vector<derived_probe *> & results);
 
+  systemtap_session & sess;
+
   // Parameter extractors.
   static bool has_null_param(map<string, literal *> const & params, 
                             string const & k);
@@ -570,7 +588,8 @@ dwarf_builder
   : public derived_probe_builder
 {
   dwarf_builder() {}
-  virtual void build(probe * base, 
+  virtual void build(systemtap_session & sess,
+                    probe * base, 
                     probe_point * location,
                     std::map<std::string, literal *> const & parameters,
                     vector<probe *> & results_to_expand_further,
@@ -636,12 +655,14 @@ dwarf_query::add_module_probe(string const & module,
 }
 
 
-dwarf_query::dwarf_query(probe * base_probe,
+dwarf_query::dwarf_query(systemtap_session & sess,
+                        probe * base_probe,
                         probe_point * base_loc,
                         dwflpp & dw,
                         map<string, literal *> const & params,
                         vector<derived_probe *> & results)
-  : results(results),
+  : sess(sess),
+    results(results),
     base_probe(base_probe), 
     base_loc(base_loc),
     dw(dw)
@@ -704,7 +725,7 @@ dwarf_query::parse_function_spec(string & spec)
 
   if (i == e)
     {
-      if (verbose)
+      if (sess.verbose)
        clog << "parsed '" << spec 
             << "' -> func '" << function 
             << "'" << endl;
@@ -719,7 +740,7 @@ dwarf_query::parse_function_spec(string & spec)
   
   if (i == e)
     {
-      if (verbose)
+      if (sess.verbose)
        clog << "parsed '" << spec 
             << "' -> func '"<< function 
             << "', file '" << file 
@@ -733,7 +754,7 @@ dwarf_query::parse_function_spec(string & spec)
   try
     {
       line = lex_cast<int>(string(i, e));
-      if (verbose)
+      if (sess.verbose)
        clog << "parsed '" << spec 
             << "' -> func '"<< function 
             << "', file '" << file 
@@ -791,7 +812,7 @@ query_function(Dwarf_Func * func, void * arg)
   Dwarf_Addr addr;
   if (!q->dw.function_entrypc(&addr))
     {
-      if (verbose)
+      if (q->sess.verbose)
        clog << "WARNING: cannot find entry PC for function " 
             << q->dw.function_name << endl;
       return DWARF_CB_OK;
@@ -877,7 +898,11 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)),
 
   // If we have enough information in the pattern to skip a module and
   // the module does not match that information, return early.
-  if (!q->dw.module_name_matches(q->module_val))
+
+  if (q->has_kernel && !q->dw.module_name_matches("kernel"))
+    return DWARF_CB_OK;
+
+  if (q->has_module && !q->dw.module_name_matches(q->module_val))
     return DWARF_CB_OK;
 
   if (q->has_function_num || q->has_statement_num)
@@ -904,6 +929,13 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)),
       q->dw.iterate_over_cus(&query_cu, q);
     }
 
+  // If we just processed the module "kernel", and the user asked for
+  // the kernel patterh, there's no need to iterate over any further
+  // modules
+
+  if (q->has_kernel && q->dw.module_name_matches("kernel"))
+    return DWARF_CB_ABORT;
+
   return DWARF_CB_OK;
 }
 
@@ -1092,15 +1124,16 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum
 
 
 void
-dwarf_builder::build(probe * base, 
+dwarf_builder::build(systemtap_session & sess,
+                    probe * base, 
                     probe_point * location,
                     std::map<std::string, literal *> const & parameters,
                     vector<probe *> & results_to_expand_further,
                     vector<derived_probe *> & finished_results)
 {
 
-  dwflpp dw;
-  dwarf_query q(base, location, dw, parameters, finished_results);
+  dwflpp dw(sess);
+  dwarf_query q(sess, base, location, dw, parameters, finished_results);
 
   dw.setup(q.has_kernel || q.has_module);
 
diff --git a/testsuite/semok/fourteen.stp b/testsuite/semok/fourteen.stp
new file mode 100755 (executable)
index 0000000..9326ebe
--- /dev/null
@@ -0,0 +1,30 @@
+#! stap -p2
+
+function trace (s) { return 0 }
+
+# recursive alias expansion
+
+probe foo = begin
+{
+       trace("hello")
+}
+
+probe bar = foo 
+{
+       x=1
+}
+
+probe baz = bar
+{
+       y=2
+}
+
+probe quux = baz
+{
+       z = x + y
+}
+
+probe quux, end
+{
+       trace("goodbye")
+}
diff --git a/testsuite/semok/thirteen.stp b/testsuite/semok/thirteen.stp
new file mode 100755 (executable)
index 0000000..91d767f
--- /dev/null
@@ -0,0 +1,27 @@
+#! stap -p2
+
+function trace (s) { return 0 }
+
+# define some aliases which resolve to kernel functions
+
+probe pipe_read = kernel.function("pipe_read")
+{
+       fname = "pipe_read"
+       reading_from_pipe = 1
+}
+
+probe pipe_write = kernel.function("pipe_write")
+{
+       fname = "pipe_write"
+       reading_from_pipe = 0
+}
+
+# use the aliases, including variables defined in them
+
+probe pipe_read, pipe_write
+{
+       if (reading_from_pipe)
+               trace("reading from pipe in " . fname)
+       else
+               trace("writing to pipe in " . fname)
+}
diff --git a/testsuite/semok/twelve.stp b/testsuite/semok/twelve.stp
new file mode 100755 (executable)
index 0000000..8eccd46
--- /dev/null
@@ -0,0 +1,17 @@
+#! stap -p2
+
+function trace (s) { return 0 }
+
+# resolve to a set of kernel functions
+
+probe kernel.function("pipe_*")
+{
+       trace("doing something with a pipe")
+}
+
+# resolve to a set of module functions
+
+probe module("jbd").function("journal_get_*_access@*/transaction.c")
+{
+       trace("inside journal_get_*_access, in transaction.c")
+}
This page took 0.062516 seconds and 5 git commands to generate.