]> sourceware.org Git - systemtap.git/commitdiff
PR6836: $$vars extensions, $$return
authorFrank Ch. Eigler <fche@elastic.org>
Fri, 15 Aug 2008 16:21:22 +0000 (12:21 -0400)
committerFrank Ch. Eigler <fche@elastic.org>
Fri, 15 Aug 2008 16:21:22 +0000 (12:21 -0400)
ChangeLog
NEWS
stapprobes.5.in
tapsets.cxx
testsuite/semok/thirtytwo.stp [new file with mode: 0755]

index 397308a75a1dc04c54f3fd6c53162040e9e576b0..ac800e8c4335445aed46393c8fff1f0b1cb4b922 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-08-15  Frank Ch. Eigler  <fche@elastic.org>
+
+       PR 6836.
+       * tapsets.cxx (dwarf_var...visit_target_symbol): Show
+       "var=?" for unlocatable variables.  Support $$return.
+       Make sure $$parms/etc. work in .return probes too.
+       * testsuite/semok/thirtytwo.stp: New test.
+       * NEWS, stapprobes.5.in: Document them.
+
 2008-08-15  Michael Meeks  <michael.meeks@novell.com>
 
        * configure.ac: suggest (SUSE) package name for dwfl.
diff --git a/NEWS b/NEWS
index 0cdc2aa3d0ce8daba41e0d411fed67d3c6893d52..d6d220a0e2d46998e95f0f9224de189be41c1bc9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,10 @@
 
 - A formatted string representation of the variables, parameters, or local
   variables at a probe point is now supported via the special $$vars,
-  $$parms, and $$locals context variables.
+  $$parms, and $$locals context variables, which expand to a string
+  containing a list "var1=0xdead var2=0xbeef var3=?".  (Here, var3 exists
+  but is for some reason unavailable.)  In return probes only, $$return
+  expands to an empty string for a void function, or "$return=0xf00".
 
 * What's new in version 0.7
 
index c71f79d3e7ff9bfe5cb7f53cdaed83fed657c0bb..f1626166e2c409cac21819816d2c2fd0f691cfc9 100644 (file)
@@ -334,6 +334,11 @@ $var\->field
 traversal to a structure's field.  The indirection operator
 may be repeated to follow more levels of pointers.
 .TP
+$return
+is available in return probes only for functions that are declared
+with a return value.
+.TP
+.TP
 $var[N]
 indexes into an array.  The index is given with a
 literal number.
@@ -344,12 +349,15 @@ sprintf("parm1=%x ... parmN=%x var1=%x ... varN=%x", parm1, ..., parmN,
 var1, ..., varN)
 .TP
 $$locals
-expands to a character string that is equivalent to
-sprintf("var1=%x ... varN=%x", var1, ..., varN)
+expands to a subset of $$vars for only local variables.
 .TP
 $$parms
-expands to a character string that is equivalent to
-sprintf("parm1=%x ... parmN=%x", parm1, ..., parmN)
+expands to a subset of $$vars for only function parameters.
+.TP
+$$return
+is available in return probes only.  It expands to a string that
+is equivalent to sprintf("$return=%x", $return)
+if the probed function has a return value, or else an empty string.
 .PP
 For ".return" probes, context variables other than the "$return"
 value itself are only available for the function call parameters.
index 664dfb1f986348ddc7a84fccd2072aec6f7843ce..1f7d2555b3a8995301c9bba406dcf1cc547058d9 100644 (file)
@@ -4002,7 +4002,11 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
   if (lvalue && !q.sess.guru_mode)
     throw semantic_error("write to target variable not permitted", e->tok);
 
-  if (q.has_return && e->base_name != "$return")
+  // See if we need to generate a new probe to save/access function
+  // parameters from a return probe.  PR 1382.
+  if (q.has_return
+      && e->base_name != "$return" // not the special return-value variable handled below
+      && e->base_name != "$$return") // nor the other special variable handled below
     {
       if (lvalue)
        throw semantic_error("write to target variable not permitted in .return probes", e->tok);
@@ -4287,7 +4291,8 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
 
   if (e->base_name == "$$vars"
       || e->base_name == "$$parms"
-      || e->base_name == "$$locals")
+      || e->base_name == "$$locals"
+      || (q.has_return && (e->base_name == "$$return")))
     {
       Dwarf_Die *scopes;
       if (dwarf_getscopes_die (scope_die, &scopes) == 0)
@@ -4298,55 +4303,85 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
 
       // Convert $$parms to sprintf of a list of parms and active local vars
       // which we recursively evaluate
-      token* tmp_tok = new token;
-      tmp_tok->type = tok_identifier;
-      tmp_tok->content = "sprintf";
-      pf->tok = tmp_tok;
+
+      // NB: we synthesize a new token here rather than reusing
+      // e->tok, because print_format::print likes to use
+      // its tok->content.
+      token* pf_tok = new token;
+      pf_tok->location = e->tok->location;
+      pf_tok->type = tok_identifier;
+      pf_tok->content = "sprint";
+
+      pf->tok = pf_tok;
       pf->print_to_stream = false;
       pf->print_with_format = true;
       pf->print_with_delim = false;
       pf->print_with_newline = false;
       pf->print_char = false;
 
-      Dwarf_Die result;
-      if (dwarf_child (&scopes[0], &result) == 0)
-       do
-         {
-           switch (dwarf_tag (&result))
-             {
-             case DW_TAG_variable:
-               if (e->base_name == "$$parms")
-                 continue;
-               break;
-             case DW_TAG_formal_parameter:
-               if (e->base_name == "$$locals")
-                 continue;
-               break;
-
-             default:
-               continue;
-             }
+      if (q.has_return && (e->base_name == "$$return"))
+        {
+          tsym->tok = e->tok;
+          tsym->base_name = "$return";
+          
+          // Ignore any variable that isn't accessible.
+          tsym->saved_conversion_error = 0;
+          this->visit_target_symbol(tsym); // NB: throws nothing ...
+          if (tsym->saved_conversion_error) // ... but this is how we know it happened.
+            {
 
-           const char *diename = dwarf_diename (&result);
-           token* sym_tok = new token;
-           sym_tok->location = e->get_tok()->location;
-           sym_tok->type = tok_identifier;
-           sym_tok->content = diename;
-           tsym->tok = sym_tok;
-           tsym->base_name = "$";
-           tsym->base_name += diename;
-
-           // Ignore any variable that isn't accessible.
-            tsym->saved_conversion_error = 0;
-            this->visit_target_symbol(tsym); // NB: throws nothing ...
-            if (! tsym->saved_conversion_error) // ... but this is how we know it happened.
+            }
+          else
+            {
+              pf->raw_components += "$return";
+              pf->raw_components += "=%#x ";
+              pf->args.push_back(*(expression**)this->targets.top());
+            }
+        }
+      else
+        {
+          // non-.return probe: support $$parms, $$vars, $$locals
+          Dwarf_Die result;
+          if (dwarf_child (&scopes[0], &result) == 0)
+            do
               {
-                pf->raw_components += diename;
-                pf->raw_components += "=%#x ";
-                pf->args.push_back(*(expression**)this->targets.top());
+                switch (dwarf_tag (&result))
+                  {
+                  case DW_TAG_variable:
+                    if (e->base_name == "$$parms")
+                      continue;
+                    break;
+                  case DW_TAG_formal_parameter:
+                    if (e->base_name == "$$locals")
+                      continue;
+                    break;
+                    
+                  default:
+                    continue;
+                  }
+                
+                const char *diename = dwarf_diename (&result);
+                tsym->tok = e->tok;
+                tsym->base_name = "$";
+                tsym->base_name += diename;
+                
+                // Ignore any variable that isn't accessible.
+                tsym->saved_conversion_error = 0;
+                this->visit_target_symbol(tsym); // NB: throws nothing ...
+                if (tsym->saved_conversion_error) // ... but this is how we know it happened.
+                  {
+                    pf->raw_components += diename;
+                    pf->raw_components += "=? ";
+                  }
+                else
+                  {
+                    pf->raw_components += diename;
+                    pf->raw_components += "=%#x ";
+                    pf->args.push_back(*(expression**)this->targets.top());
+                  }
               }
-         }
-       while (dwarf_siblingof (&result, &result) == 0);
+            while (dwarf_siblingof (&result, &result) == 0);
+        }
 
       pf->components = print_format::string_to_components(pf->raw_components);
       provide <print_format*> (this, pf);
@@ -4366,7 +4401,7 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
 
   try
     {
-      if (q.has_return && e->base_name == "$return")
+      if (q.has_return && (e->base_name == "$return"))
         {
          ec->code = q.dw.literal_stmt_for_return (scope_die,
                                                   addr,
diff --git a/testsuite/semok/thirtytwo.stp b/testsuite/semok/thirtytwo.stp
new file mode 100755 (executable)
index 0000000..2a69b8c
--- /dev/null
@@ -0,0 +1,5 @@
+#! stap -p2
+
+# PR 6836
+
+probe kernel.function("sys_open").return { log($$return . $$parms) }
This page took 0.052068 seconds and 5 git commands to generate.