]> sourceware.org Git - systemtap.git/commitdiff
2005-09-05 Frank Ch. Eigler <fche@elastic.org>
authorfche <fche>
Mon, 5 Sep 2005 22:00:43 +0000 (22:00 +0000)
committerfche <fche>
Mon, 5 Sep 2005 22:00:43 +0000 (22:00 +0000)
PR 1172.
* staptree.h, staptree.cxx: Make all ::print*(), operator<<
functions take const staptree objects.
(literal_string::print): \-prefix double-quotes.
* translate.cxx (emit_common_header): Add context probe_point field.
Switch to atomic_t busy flags.
(emit_module_exit): Use atomic operations for busy flag.
(visit_*): Use lex_cast_qstring for last_stmt strings.
* tapsets.cxx (lex_cast_quoted): \-prefix double-quotes too.
(*::emit_probe_entries): Populate probe_point.  Use atomic operations
for busy flag.
* tapset/context.stp (pp): New function.
* stapfuncs.5.in: Document it.
* testsuite/buildok/context_test.stp: Test it.

ChangeLog
stapfuncs.5.in
staptree.cxx
staptree.h
tapset/context.stp
tapsets.cxx
testsuite/buildok/context_test.stp
translate.cxx

index 2a59812b3468a9a527da146d5b441cfee6c7671e..71bf11ea7bcdf4db960a89b913566143d6f815a3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-09-05  Frank Ch. Eigler  <fche@elastic.org>
+
+       PR 1172.
+       * staptree.h, staptree.cxx: Make all ::print*(), operator<<
+       functions take const staptree objects.
+       (literal_string::print): \-prefix double-quotes.
+       * translate.cxx (emit_common_header): Add context probe_point field.
+       Switch to atomic_t busy flags.
+       (emit_module_exit): Use atomic operations for busy flag.
+       (visit_*): Use lex_cast_qstring for last_stmt strings.
+       * tapsets.cxx (lex_cast_quoted): \-prefix double-quotes too.
+       (*::emit_probe_entries): Populate probe_point.  Use atomic operations
+       for busy flag.
+       * tapset/context.stp (pp): New function.
+       * stapfuncs.5.in: Document it.
+       * testsuite/buildok/context_test.stp: Test it.
+
 2005-09-04  Frank Ch. Eigler  <fche@elastic.org>
 
        * translate.cxx (visit_literal_string): \-prefix double-quotes.
index 212e5193509a9f2c0885ffcac9858f3d56862114..dbecf0d3a8fa36cf7dfde1844dcec09bfc2cf817 100644 (file)
@@ -15,13 +15,13 @@ Examples:
 
 .TP
 example1:long (v:string, k:long)
-Function "example1" does something with the given string and integer.
-It returns some integer.
+In function "example1", do something with the given string and integer.
+Return some integer.
 
 .TP
 example2:unknown ()
-Function "example2" does something.  There is no explicit return value
-and it takes no parameters.
+In function "example2", do something.  There is no explicit return value
+and take no parameters.
 
 .SS LOGGING
 
@@ -98,52 +98,57 @@ Return the number of seconds since the UNIX epoch.
 
 .TP
 execname:string ()
-Returns the name of the current process.
+Return the name of the current process.
 
 .TP
 pexecname:string()
-Returns the name of the parent process.
+Return the name of the parent process.
 
 .TP
 pid:long ()
-Returns the current pid. 
+Return the current pid. 
 
 .TP
 ppid:long ()
-Returns the current pid.
+Return the current pid.
 
 .TP
 uid:long ()
-Returns the uid of the current process.
+Return the uid of the current process.
 
 .TP
 euid:long ()
-Returns the effective uid of the current process.
+Return the effective uid of the current process.
 
 .TP
 gid:long ()
-Returns the gid of the current process.
+Return the gid of the current process.
 
 .TP
 egid:long ()
-Returns the effective gid of the current process.
+Return the effective gid of the current process.
 
 .TP
 print_regs:unknown ()
-Prints a register dump.
+Print a register dump.
 
 .TP
 print_backtrace:unknown ()
-Prints a symbolic backtrace.  Use with care. May be timeconsuming.
+Print a symbolic backtrace.  Use with care.  May be timeconsuming.
 
 .TP
 backtrace:string ()
-Returns a string of hex addresses that are a backtrace of the stack.
+Return a string of hex addresses that are a backtrace of the stack.
 May be truncated due to maximum string length.
 
 .TP
-print_stack(bt:string)
-Does a symbolic lookup of the addresses in bt and prints one per line.
+print_stack (bt:string)
+Perform a symbolic lookup of the addresses in bt and prints one per line.
+
+.TP
+pp:string ()
+Return the probe point associated with the currently running probe handler,
+including alias and wildcard expansion effects.
 
 .SH FILES
 .nh
index 8af920d69a932061f502c6141504bd69a3aff26d..47a5cd0cae8567588563eedbc90aaf8beb1a1b25 100644 (file)
@@ -168,27 +168,32 @@ operator << (ostream& o, const exp_type& e)
 // ------------------------------------------------------------------------
 // parse tree printing
 
-ostream& operator << (ostream& o, expression& k)
+ostream& operator << (ostream& o, const expression& k)
 {
   k.print (o);
   return o;
 }
 
 
-void literal_string::print (ostream& o)
+void literal_string::print (ostream& o) const
 {
-  // XXX: quote special chars
-  o << '"' << value << '"';
+  o << '"';
+  for (unsigned i=0; i<value.size(); i++)
+    if (value[i] == '"') // or other escapeworthy characters?
+      o << '\\' << '"';
+    else
+      o << value[i];
+  o << '"';
 }
 
 
-void literal_number::print (ostream& o)
+void literal_number::print (ostream& o) const
 {
   o << value;
 }
 
 
-void binary_expression::print (ostream& o)
+void binary_expression::print (ostream& o) const
 {
   o << '(' << *left << ")" 
     << op 
@@ -196,12 +201,12 @@ void binary_expression::print (ostream& o)
 }
 
 
-void unary_expression::print (ostream& o)
+void unary_expression::print (ostream& o) const
 {
   o << op << '(' << *operand << ")"; 
 }
 
-void array_in::print (ostream& o)
+void array_in::print (ostream& o) const
 {
   o << "[";
   for (unsigned i=0; i<operand->indexes.size(); i++)
@@ -212,13 +217,13 @@ void array_in::print (ostream& o)
   o << "] in " << operand->base;
 }
 
-void post_crement::print (ostream& o)
+void post_crement::print (ostream& o) const
 {
   o << '(' << *operand << ")" << op; 
 }
 
 
-void ternary_expression::print (ostream& o)
+void ternary_expression::print (ostream& o) const
 {
   o << "(" << *cond << ")?("
     << *truevalue << "):("
@@ -226,13 +231,13 @@ void ternary_expression::print (ostream& o)
 }
 
 
-void symbol::print (ostream& o)
+void symbol::print (ostream& o) const
 {
   o << name;
 }
 
 
-void target_symbol::print (std::ostream& o)
+void target_symbol::print (std::ostream& o) const
 {
   o << base_name;
   for (unsigned i = 0; i < components.size(); ++i)
@@ -250,7 +255,7 @@ void target_symbol::print (std::ostream& o)
 }
 
 
-void vardecl::print (ostream& o)
+void vardecl::print (ostream& o) const
 {
   o << name;
   if (arity > 0 || index_types.size() > 0)
@@ -258,7 +263,7 @@ void vardecl::print (ostream& o)
 }
 
 
-void vardecl::printsig (ostream& o)
+void vardecl::printsig (ostream& o) const
 {
   o << name << ":" << type;
   if (index_types.size() > 0)
@@ -271,7 +276,7 @@ void vardecl::printsig (ostream& o)
 }
 
 
-void functiondecl::print (ostream& o)
+void functiondecl::print (ostream& o) const
 {
   o << "function " << name << " (";
   for (unsigned i=0; i<formal_args.size(); i++)
@@ -281,7 +286,7 @@ void functiondecl::print (ostream& o)
 }
 
 
-void functiondecl::printsig (ostream& o)
+void functiondecl::printsig (ostream& o) const
 {
   o << name << ":" << type << " (";
   for (unsigned i=0; i<formal_args.size(); i++)
@@ -293,7 +298,7 @@ void functiondecl::printsig (ostream& o)
 }
 
 
-void arrayindex::print (ostream& o)
+void arrayindex::print (ostream& o) const
 {
   o << base << "[";
   for (unsigned i=0; i<indexes.size(); i++)
@@ -302,7 +307,7 @@ void arrayindex::print (ostream& o)
 }
 
 
-void functioncall::print (ostream& o)
+void functioncall::print (ostream& o) const
 {
   o << function << "(";
   for (unsigned i=0; i<args.size(); i++)
@@ -311,21 +316,21 @@ void functioncall::print (ostream& o)
 }  
 
 
-ostream& operator << (ostream& o, statement& k)
+ostream& operator << (ostream& o, const statement& k)
 {
   k.print (o);
   return o;
 }
 
 
-void embeddedcode::print (ostream &o)
+void embeddedcode::print (ostream &o) const
 {
   o << "%{";
   o << code;
   o << "%}";
 }
 
-void block::print (ostream& o)
+void block::print (ostream& o) const
 {
   o << "{" << endl;
   for (unsigned i=0; i<statements.size(); i++)
@@ -334,7 +339,7 @@ void block::print (ostream& o)
 }
 
 
-void for_loop::print (ostream& o)
+void for_loop::print (ostream& o) const
 {
   o << "for (";
   init->print (o);
@@ -347,7 +352,7 @@ void for_loop::print (ostream& o)
 }
 
 
-void foreach_loop::print (ostream& o)
+void foreach_loop::print (ostream& o) const
 {
   o << "foreach ([";
   for (unsigned i=0; i<indexes.size(); i++)
@@ -360,45 +365,45 @@ void foreach_loop::print (ostream& o)
 }
 
 
-void null_statement::print (ostream& o)
+void null_statement::print (ostream& o) const
 {
   o << ";"; 
 }
 
 
-void expr_statement::print (ostream& o)
+void expr_statement::print (ostream& o) const
 {
   o << *value;
 }
 
 
-void return_statement::print (ostream& o)
+void return_statement::print (ostream& o) const
 {
   o << "return " << *value;
 }
 
 
-void delete_statement::print (ostream& o)
+void delete_statement::print (ostream& o) const
 {
   o << "delete " << *value;
 }
 
-void next_statement::print (ostream& o)
+void next_statement::print (ostream& o) const
 {
   o << "next";
 }
 
-void break_statement::print (ostream& o)
+void break_statement::print (ostream& o) const
 {
   o << "break";
 }
 
-void continue_statement::print (ostream& o)
+void continue_statement::print (ostream& o) const
 {
   o << "continue";
 }
 
-void if_statement::print (ostream& o)
+void if_statement::print (ostream& o) const
 {
   o << "if (" << *condition << ") "
     << *thenblock << endl;
@@ -407,7 +412,7 @@ void if_statement::print (ostream& o)
 }
 
 
-void stapfile::print (ostream& o)
+void stapfile::print (ostream& o) const
 {
   o << "# file " << name << endl;
 
@@ -441,7 +446,7 @@ void stapfile::print (ostream& o)
 }
 
 
-void probe::print (ostream& o)
+void probe::print (ostream& o) const
 {
   o << "probe ";
   printsig (o);
@@ -449,7 +454,7 @@ void probe::print (ostream& o)
 }
 
 
-void probe::printsig (ostream& o)
+void probe::printsig (ostream& o) const
 {
   for (unsigned i=0; i<locations.size(); i++)
     {
@@ -459,7 +464,7 @@ void probe::printsig (ostream& o)
 }
 
 
-void probe_point::print (ostream& o)
+void probe_point::print (ostream& o) const
 {
   for (unsigned i=0; i<components.size(); i++)
     {
@@ -471,12 +476,13 @@ void probe_point::print (ostream& o)
     }
 }
 
+
 probe_alias::probe_alias(std::vector<probe_point*> const & aliases):
   probe (), alias_names (aliases)
 {
 }
 
-void probe_alias::printsig (ostream& o)
+void probe_alias::printsig (ostream& o) const
 {
   for (unsigned i=0; i<alias_names.size(); i++)
     {
@@ -492,14 +498,14 @@ void probe_alias::printsig (ostream& o)
 }
 
 
-ostream& operator << (ostream& o, probe_point& k)
+ostream& operator << (ostream& o, const probe_point& k)
 {
   k.print (o);
   return o;
 }
 
 
-ostream& operator << (ostream& o, symboldecl& k)
+ostream& operator << (ostream& o, const symboldecl& k)
 {
   k.print (o);
   return o;
index 8e4ae9bb9bd8272e2c435020c0ef07bc1ae16d8d..fd19bd99cc93743c1ec170baa41ad968fd99c493 100644 (file)
@@ -56,11 +56,11 @@ struct expression
   const token* tok;
   expression ();
   virtual ~expression ();
-  virtual void print (std::ostream& o) = 0;
+  virtual void print (std::ostream& o) const = 0;
   virtual void visit (visitor* u) = 0;
 };
 
-std::ostream& operator << (std::ostream& o, expression& k);
+std::ostream& operator << (std::ostream& o, const expression& k);
 
 
 struct literal: public expression
@@ -72,7 +72,7 @@ struct literal_string: public literal
 {
   std::string value;
   literal_string (const std::string& v);
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -81,7 +81,7 @@ struct literal_number: public literal
 {
   int64_t value;
   literal_number (int64_t v);
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -91,7 +91,7 @@ struct binary_expression: public expression
   expression* left;
   std::string op;
   expression* right;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -100,7 +100,7 @@ struct unary_expression: public expression
 {
   std::string op;
   expression* operand;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -113,7 +113,7 @@ struct pre_crement: public unary_expression
 
 struct post_crement: public unary_expression
 {
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -134,7 +134,7 @@ struct arrayindex;
 struct array_in: public expression
 {
   arrayindex* operand;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -156,7 +156,7 @@ struct ternary_expression: public expression
   expression* cond;
   expression* truevalue;
   expression* falsevalue;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -173,7 +173,7 @@ struct symbol: public expression
   std::string name;
   vardecl *referent;
   symbol ();
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -187,7 +187,7 @@ struct target_symbol : public expression
     };
   std::string base_name;
   std::vector<std::pair<component_type, std::string> > components;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);  
 };
 
@@ -198,7 +198,7 @@ struct arrayindex: public expression
   std::vector<expression*> indexes;
   vardecl *referent;
   arrayindex ();
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -210,7 +210,7 @@ struct functioncall: public expression
   std::vector<expression*> args;
   functiondecl *referent;
   functioncall ();
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -226,18 +226,18 @@ struct symboldecl // unique object per (possibly implicit)
   exp_type type;
   symboldecl ();
   virtual ~symboldecl ();
-  virtual void print (std::ostream &o) = 0;
-  virtual void printsig (std::ostream &o) = 0;
+  virtual void print (std::ostream &o) const = 0;
+  virtual void printsig (std::ostream &o) const = 0;
 };
 
 
-std::ostream& operator << (std::ostream& o, symboldecl& k);
+std::ostream& operator << (std::ostream& o, const symboldecl& k);
 
 
 struct vardecl: public symboldecl
 {
-  void print (std::ostream& o);
-  void printsig (std::ostream& o);
+  void print (std::ostream& o) const;
+  void printsig (std::ostream& o) const;
   vardecl ();
   void set_arity (int arity);
   bool compatible_arity (int a);
@@ -258,8 +258,8 @@ struct functiondecl: public symboldecl
   std::vector<vardecl*> locals;
   statement* body;
   functiondecl ();
-  void print (std::ostream& o);
-  void printsig (std::ostream& o);
+  void print (std::ostream& o) const;
+  void printsig (std::ostream& o) const;
 };
 
 
@@ -268,20 +268,20 @@ struct functiondecl: public symboldecl
 
 struct statement
 {
-  virtual void print (std::ostream& o) = 0;
+  virtual void print (std::ostream& o) const = 0;
   virtual void visit (visitor* u) = 0;
   const token* tok;
   statement ();
   virtual ~statement ();
 };
 
-std::ostream& operator << (std::ostream& o, statement& k);
+std::ostream& operator << (std::ostream& o, const statement& k);
 
 
 struct embeddedcode: public statement
 {
   std::string code;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -289,7 +289,7 @@ struct embeddedcode: public statement
 struct block: public statement
 {
   std::vector<statement*> statements;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -301,7 +301,7 @@ struct for_loop: public statement
   expression* cond;
   expr_statement* incr;
   statement* block;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -314,14 +314,14 @@ struct foreach_loop: public statement
   vardecl* base_referent;
 
   statement* block;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
 
 struct null_statement: public statement
 {
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -329,7 +329,7 @@ struct null_statement: public statement
 struct expr_statement: public statement
 {
   expression* value;  // executed for side-effects
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -339,42 +339,42 @@ struct if_statement: public statement
   expression* condition;
   statement* thenblock;
   statement* elseblock;
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
 
 struct return_statement: public expr_statement
 {
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
 
 struct delete_statement: public expr_statement
 {
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
 
 struct break_statement: public statement
 {
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
 
 struct continue_statement: public statement
 {
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
 
 struct next_statement: public statement
 {
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   void visit (visitor* u);
 };
 
@@ -392,7 +392,7 @@ struct stapfile
   std::vector<embeddedcode*> embeds;
   bool privileged;
   stapfile (): privileged (false) {}
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
 };
 
 
@@ -409,12 +409,12 @@ struct probe_point
   };
   std::vector<component*> components;
   const token* tok; // points to first component's functor
-  void print (std::ostream& o);
+  void print (std::ostream& o) const;
   probe_point ();
   probe_point(std::vector<component*> const & comps,const token * t); 
 };
 
-std::ostream& operator << (std::ostream& o, probe_point& k);
+std::ostream& operator << (std::ostream& o, const probe_point& k);
 
 
 struct probe
@@ -424,8 +424,8 @@ struct probe
   const token* tok;
   std::vector<vardecl*> locals;
   probe ();
-  void print (std::ostream& o);
-  virtual void printsig (std::ostream &o);
+  void print (std::ostream& o) const;
+  virtual void printsig (std::ostream &o) const;
   virtual ~probe() {}
 };
 
@@ -433,7 +433,7 @@ struct probe_alias: public probe
 {
   probe_alias(std::vector<probe_point*> const & aliases);
   std::vector<probe_point*> alias_names;  
-  virtual void printsig (std::ostream &o);
+  virtual void printsig (std::ostream &o) const;
 };
 
 
index 4d80195611f1adc47d9852fa92821cb718a78949..3e776547293beb2949c54c5a651f1c9e0657ffcb 100644 (file)
@@ -88,3 +88,7 @@ function print_stack(stk:string) %{
                tok = strsep(&ptr, " ");
        }
 %}
+
+function pp:string () %{
+       strlcpy (THIS->__retvalue, CONTEXT->probe_point, MAXSTRINGLEN);
+%}
index 14031308137864da38b6244e225d7cab582e3eea..de80d3a24613f446ddff8b0f345a7f6a311a12dd 100644 (file)
@@ -38,6 +38,51 @@ extern "C" {
 
 using namespace std;
 
+
+// XXX: should standardize to these functions throughout translator
+
+template <typename OUT, typename IN> inline OUT
+lex_cast(IN const & in)
+{
+  stringstream ss;
+  OUT out;
+  if (!(ss << in && ss >> out))
+    throw runtime_error("bad lexical cast");
+  return out;
+}
+
+template <typename OUT, typename IN> inline OUT
+lex_cast_hex(IN const & in)
+{
+  stringstream ss;
+  OUT out;
+  if (!(ss << hex << showbase << in && ss >> out))
+    throw runtime_error("bad lexical cast");
+  return out;
+}
+
+
+// return as quoted string, with at least '"' backslash-escaped
+template <typename IN> inline string
+lex_cast_qstring(IN const & in)
+{
+  stringstream ss;
+  string out, out2;
+  if (!(ss << in && ss >> out))
+    throw runtime_error("bad lexical cast");
+
+  out2 += '"';
+  for (unsigned i=0; i<out.length(); i++)
+    {
+      if (out[i] == '"') // XXX others?
+       out2 += '\\';
+      out2 += out[i];
+    }
+  out2 += '"';
+  return out2;
+}
+
+
 // ------------------------------------------------------------------------
 // begin/end probes are run right during registration / deregistration
 // ------------------------------------------------------------------------
@@ -102,6 +147,8 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
       // While begin/end probes are executed single-threaded, we
       // still code defensively and use a per-cpu context.
       o->newline(1) << "struct context* c = & contexts [smp_processor_id()];";
+      o->newline() << "const char* probe_point = "
+                  << lex_cast_qstring(*l) << ";";
 
       // A precondition for running a probe handler is that we're in STARTING
       // or STOPPING state (not ERROR), and that no one else is already using
@@ -110,16 +157,15 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
       if (begin) o->line() << "STAP_SESSION_STARTING)";
       else o->line() << "STAP_SESSION_STOPPING)";
       o->newline(1) << "return;";
-      o->newline(-1) << "if (c->busy) {";
-      o->newline(1) << "printk (KERN_ERR \"probe reentrancy\");";
+      o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
+      o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\", "
+                   << "c->probe_point, probe_point);";
       o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
       o->newline() << "return;";
       o->newline(-1) << "}";
       o->newline();
-
-      o->newline() << "c->busy ++;";
-      o->newline() << "mb ();"; // for smp
       o->newline() << "c->last_error = 0;";
+      o->newline() << "c->probe_point = probe_point;";
       o->newline() << "c->nesting = 0;";
       o->newline() << "c->regs = 0;";
       o->newline() << "c->actioncount = 0;";
@@ -132,8 +178,7 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
       o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
       o->newline(-1) << "}";
 
-      o->newline() << "c->busy --;";
-      o->newline() << "mb ();";
+      o->newline() << "atomic_dec (&c->busy);";
       o->newline(-1) << "}" << endl;
     }
 }
@@ -156,27 +201,7 @@ static string TOK_LABEL("label");
 static string TOK_RELATIVE("relative");
 
 
-// XXX: should standardize to these functions throughout translator
 
-template <typename OUT, typename IN> inline OUT
-lex_cast(IN const & in)
-{
-  stringstream ss;
-  OUT out;
-  if (!(ss << in && ss >> out))
-    throw runtime_error("bad lexical cast");
-  return out;
-}
-
-template <typename OUT, typename IN> inline OUT
-lex_cast_hex(IN const & in)
-{
-  stringstream ss;
-  OUT out;
-  if (!(ss << hex << showbase << in && ss >> out))
-    throw runtime_error("bad lexical cast");
-  return out;
-}
 
 struct 
 func_info
@@ -1973,7 +1998,6 @@ dwarf_derived_probe::emit_deregistrations (translator_output* o, unsigned proben
 void
 dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum)
 {
-
   // Construct a single entry function, and a struct kprobe pointing into
   // the entry function. The entry function will call the probe function.
   o->newline();
@@ -1985,22 +2009,23 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum
     o->line() << "struct kprobe *_ignored";
   o->line() << ", struct pt_regs *regs) {";
   o->newline(1) << "struct context *c = & contexts [smp_processor_id()];";
-  o->newline();
+  o->newline() << "const char* probe_point = "
+              << lex_cast_qstring(*locations[0]) << ";";
 
   // A precondition for running a probe handler is that we're in RUNNING
   // state (not ERROR), and that no one else is already using this context.
   o->newline() << "if (atomic_read (&session_state) != STAP_SESSION_RUNNING)";
   o->newline(1) << "return 0;";
-  o->newline(-1) << "if (c->busy) {";
-  o->newline(1) << "printk (KERN_ERR \"probe reentrancy\");";
+  o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
+  o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\", "
+                   << "c->probe_point, probe_point);";
   o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
   o->newline() << "return 0;";
   o->newline(-1) << "}";
   o->newline();
 
-  o->newline() << "c->busy ++;";
-  o->newline() << "mb ();"; // for smp
   o->newline() << "c->last_error = 0;";
+  o->newline() << "c->probe_point = probe_point;";
   o->newline() << "c->nesting = 0;";
   o->newline() << "c->regs = regs;";
   o->newline() << "c->actioncount = 0;";
@@ -2013,9 +2038,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o, unsigned probenum
   o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
   o->newline(-1) << "}";
   
-  o->newline() << "c->busy --;";
-  o->newline() << "mb ();";
-
+  o->newline() << "atomic_dec (& c->busy);";
   o->newline() << "return 0;";
   o->newline(-1) << "}" << endl;
 
@@ -2140,7 +2163,8 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
 
   o->newline() << "void enter_" << j << " (unsigned long val) {";
   o->newline(1) << "struct context* c = & contexts [smp_processor_id()];";
-  
+  o->newline() << "const char* probe_point = "
+              << lex_cast_qstring(*locations[0]) << ";";
   o->newline() << "(void) val;";
 
   // A precondition for running a probe handler is that we're in
@@ -2149,8 +2173,9 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
   o->newline() << "if (atomic_read (&session_state) != STAP_SESSION_RUNNING)";
   o->newline(1) << "return;";
 
-  o->newline(-1) << "if (c->busy) {";
-  o->newline(1) << "printk (KERN_ERR \"probe reentrancy\");";
+  o->newline(-1) << "if (atomic_inc_return (&c->busy) != 1) {";
+  o->newline(1) << "printk (KERN_ERR \"probe reentrancy (%s vs %s)\", "
+               << "c->probe_point, probe_point);";
   o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
   o->newline() << "return;";
   o->newline(-1) << "}";
@@ -2162,11 +2187,10 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
     o->line() << " + _stp_random_pm(" << randomize << ")";
   o->line() << ");";
   
-  o->newline() << "c->busy ++;";
-  o->newline() << "mb ();"; // for smp
+  o->newline() << "c->probe_point = probe_point;";
   o->newline() << "c->last_error = 0;";
   o->newline() << "c->nesting = 0;";
-  o->newline() << "if (in_interrupt())";
+  o->newline() << "if (in_interrupt())";
   o->newline(1) << "c->regs = 0;";
   o->newline(-1) << "else";
   o->newline(1) << "c->regs = task_pt_regs (current);";
@@ -2181,8 +2205,7 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
   o->newline() << "atomic_set (& session_state, STAP_SESSION_ERROR);";
   o->newline(-1) << "}";
   
-  o->newline() << "c->busy --;";
-  o->newline() << "mb ();";
+  o->newline() << "atomic_dec (&c->busy);";
   o->newline(-1) << "}" << endl;
 }
 
index 9059c04ce56e62b604392c995878cf25ab8e16cf..c85bce67d52eb096148d616ed4c3e75f1317f1f3 100755 (executable)
@@ -1,7 +1,6 @@
 #! stap -p4
 
-probe kernel.function("uptime_read_proc") {
-       print("NOW IN UPTIME\n")
+function print_stuff () {
        print_regs()
        print_backtrace()
        bt = backtrace()
@@ -9,33 +8,26 @@ probe kernel.function("uptime_read_proc") {
        print("\n\n")
        print_stack(bt)
        print("\n\n")
-       log("name is " . execname())
+       log("execname is \"" . execname() . "\"")
        log("pid is " . string(pid()))
-       log("parentname is " . pexecname())
+       log("pexecname is \"" . pexecname() . "\"")
        log("ppid is " . string(ppid()))
        log("uid is " . string(uid()))
        log("euid is " . string(euid()))
        log("gid is " . string(gid()))
        log("egid is " . string(egid()))
+       log("pp is '" . pp() . "'")
+}
+
+probe kernel.function("uptime_read_proc") {
+       print("NOW IN UPTIME\n")
+       print_stuff ()
 }
 
 probe kernel.function("uptime_read_proc").return {
        print("DONE WITH UPTIME\n")
-       print_regs()
-       print_backtrace()
-       bt = backtrace()
-       print("the stack is " . bt)
-       print("\n\n")
-       print_stack(bt)
-       print("\n\n")
-       log("name is " . execname())
-       log("pid is " . string(pid()))
-       log("parentname is " . pexecname())
-       log("ppid is " . string(ppid()))
-       log("uid is " . string(uid()))
-       log("euid is " . string(euid()))
-       log("gid is " . string(gid()))
-       log("egid is " . string(egid()))
+       print_stuff ()
+       exit ()
 }
 
 probe begin {
index c3412cda86e641c49385556334c616d6026b7011..b71ef3794a8af2e37b0f3e12d10f9fa53c0feba8 100644 (file)
@@ -30,6 +30,27 @@ stringify(T t)
   return s.str ();
 }
 
+// return as quoted string, with at least '"' backslash-escaped
+template <typename IN> inline string
+lex_cast_qstring(IN const & in)
+{
+  stringstream ss;
+  string out, out2;
+  if (!(ss << in && ss >> out))
+    throw runtime_error("bad lexical cast");
+
+  out2 += '"';
+  for (unsigned i=0; i<out.length(); i++)
+    {
+      if (out[i] == '"') // XXX others?
+       out2 += '\\';
+      out2 += out[i];
+    }
+  out2 += '"';
+  return out2;
+}
+
+
 struct var;
 struct tmpvar;
 struct mapvar;
@@ -575,7 +596,8 @@ c_unparser::emit_common_header ()
   o->newline() << "atomic_t session_state = ATOMIC_INIT (STAP_SESSION_STARTING);";
   o->newline();
   o->newline() << "struct context {";
-  o->newline(1) << "unsigned busy;"; // XXX: should be atomic_t ?
+  o->newline(1) << "atomic_t busy;";
+  o->newline() << "const char *probe_point;";
   o->newline() << "unsigned actioncount;";
   o->newline() << "unsigned nesting;";
   o->newline() << "const char *last_error;";
@@ -779,14 +801,13 @@ c_unparser::emit_module_exit ()
   o->newline() << "do {";
   o->newline(1) << "int i;";
   o->newline() << "holdon = 0;";
-  o->newline() << "mb ();";
   o->newline() << "for (i=0; i<NR_CPUS; i++)";
-  o->newline(1) << "if (contexts[i].busy) holdon = 1;";
+  o->newline(1) << "if (atomic_read (&contexts[i].busy)) holdon = 1;";
   // o->newline(-1) << "if (holdon) msleep (5);";
   o->newline(-1) << "} while (holdon);";
   o->newline(-1);
   // XXX: might like to have an escape hatch, in case some probe is
-  // genuinely stuck
+  // genuinely stuck somehow
 
   for (int i=session->probes.size()-1; i>=0; i--)
     session->probes[i]->emit_deregistrations (o, i);
@@ -797,7 +818,6 @@ c_unparser::emit_module_exit ()
       if (v->index_types.size() > 0)
        o->newline() << getmap (v).fini();
     }
-  // XXX: if anyrc, log badness
   o->newline(-1) << "}" << endl;
 }
 
@@ -1335,7 +1355,7 @@ c_unparser::visit_statement (statement *s, unsigned actions)
 
   o->newline() << "if (unlikely (c->last_error)) goto " << outlabel << ";";
   assert (s->tok);
-  o->newline() << "c->last_stmt = \"" << *s->tok << "\";";
+  o->newline() << "c->last_stmt = " << lex_cast_qstring(*s->tok) << ";";
   if (actions > 0)
     {
       o->newline() << "c->actioncount += " << actions << ";";
@@ -1709,9 +1729,7 @@ c_unparser::visit_binary_expression (binary_expression* e)
       tmpvar right = gensym (pe_long);
 
       o->line() << "({";
-
-      o->newline() << "c->last_stmt = \"" << *e->tok << "\";";
-
+      o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
       o->newline(1) << left << " = ";
       e->left->visit (this);
       o->line() << ";";
@@ -1800,7 +1818,7 @@ c_unparser::visit_array_in (array_in* e)
 
   vector<tmpvar> idx;
   load_map_indices (e->operand, idx);
-  o->newline() << "c->last_stmt = \"" << *e->tok << "\";";
+  o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
 
   tmpvar res = gensym (pe_long);
 
@@ -1878,7 +1896,7 @@ c_unparser::visit_concatenation (concatenation* e)
   
   o->line() << "({ ";
   o->indent(1);
-  o->newline() << "c->last_stmt = \"" << *e->tok << "\";";
+  o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
   c_assign (t.qname(), e->left, "assignment");
   c_strcat (t.qname(), e->right);
   o->newline() << t << ";";
@@ -2045,7 +2063,7 @@ c_unparser_assignment::visit_symbol (symbol *e)
   if (e->referent->index_types.size() != 0)
     throw semantic_error ("unexpected reference to array", e->tok);
 
-  parent->o->newline() << "c->last_stmt = \"" << *e->tok << "\";";
+  parent->o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
   tmpvar rval = parent->gensym (e->type);
   tmpvar res = parent->gensym (e->type);
 
@@ -2105,7 +2123,8 @@ c_unparser::load_map_indices(arrayindex *e,
        throw semantic_error ("array index type mismatch", e->indexes[i]->tok);
       
       tmpvar ix = gensym (r->index_types[i]);
-      o->newline() << "c->last_stmt = \"" << *e->indexes[i]->tok << "\";";
+      o->newline() << "c->last_stmt = "
+                  << lex_cast_qstring(*e->indexes[i]->tok) << ";";
       c_assign (ix.qname(), e->indexes[i], "array index copy");
       idx.push_back (ix);
     }
@@ -2141,7 +2160,7 @@ c_unparser::visit_arrayindex (arrayindex* e)
   { // block used to control varlock_r lifespan
     mapvar mvar = getmap (e->referent, e->tok);
     // XXX: should be varlock_r, but runtime arrays reads mutate
-    o->newline() << "c->last_stmt = \"" << *e->tok << "\";";
+    o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
     varlock_w guard (*this, mvar);
     o->newline() << mvar.seek (idx) << ";";
     c_assign (res, mvar.get(), e->tok);
@@ -2218,7 +2237,7 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e)
   
   { // block used to control varlock_w lifespan
     mapvar mvar = parent->getmap (e->referent, e->tok);
-    o->newline() << "c->last_stmt = \"" << *e->tok << "\";";
+    o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
     varlock_w guard (*parent, mvar);
     o->newline() << mvar.seek (idx) << ";";
     if (op != "=") // don't bother fetch slot if we will just overwrite it
@@ -2273,14 +2292,15 @@ c_unparser::visit_functioncall (functioncall* e)
        throw semantic_error ("function argument type mismatch",
                              e->args[i]->tok, "vs", r->formal_args[i]->tok);
 
-      o->newline() << "c->last_stmt = \"" << *e->args[i]->tok << "\";";
+      o->newline() << "c->last_stmt = "
+                  << lex_cast_qstring(*e->args[i]->tok) << ";";
       c_assign (t.qname(), e->args[i], "function actual argument evaluation");
     }
 
   o->newline();
   o->newline() << "if (unlikely (c->nesting+2 >= MAXNESTING)) {";
   o->newline(1) << "c->last_error = \"MAXNESTING exceeded\";";
-  o->newline() << "c->last_stmt = \"" << *e->tok << "\";";
+  o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
   o->newline(-1) << "} else if (likely (! c->last_error)) {";
   o->indent(1);
 
This page took 0.079006 seconds and 5 git commands to generate.