New @var language construct

Mark Wielaard mjw@redhat.com
Mon Mar 12 12:25:00 GMT 2012


Hi,

To fix PR13784 - Cannot find a defining variable location in different CU
I introduced a new language construct @var("varname[@src/file]") with
which you can select such a variable from a DWARF based probe handler.

Attached you will find the documentation for this new language construct
(we have way too many places to document new stuf...). Hopefully that is
precise enough to be helpful. If not, please yell and scream. Also please
review the implementation to see if it makes sense and matches what you
would expect. See below for the relevant commits.

Now that we do have @var we can use it to solve some other bugs/enhancement
requests. In particular PR11096 - Getting global module vars in functions
could be implemented by adding an extra argument to @var that describes
the module. So you can access DWARF target variables from any probe
context (including functions) as long as you explicitly describe CU and
module. And since @var takes the target variable name as string we can
allow "natural" C++ variable descriptions instead of names. This is
PR11008 - Support c++ namespace like syntax $foo::bar. I am not currently
planning to work on either of these, so please jump in if you want.

Cheers,

Mark

commit 179a00c3efb5ceac52a70debb17a91ee0c07722d
Author: Mark Wielaard <mjw@redhat.com>
Date:   Mon Mar 12 13:00:40 2012 +0100

    Document new @var construct in NEWS, langref, beginners and stapprobes.

commit acf4b3b10e9d70cbf8a0a681ae3c17c9681bdfbe
Author: Mark Wielaard <mjw@redhat.com>
Date:   Sat Mar 10 19:15:35 2012 +0100

    global_var_kernel.exp: tz_minuteswest can be negative.

commit 3965e105b73e196ec4f9b15c0b192c59bb14a2f8
Author: Mark Wielaard <mjw@redhat.com>
Date:   Fri Mar 9 15:57:31 2012 +0100

    Global vars don't need (cannot use) frame base in location descriptor.
    
    And so they also don't need cfa_ops (CFI) to calculate the frame base.

commit 3d9381fc814162b914288d45ff52017bf0a83fb4
Author: Mark Wielaard <mjw@redhat.com>
Date:   Fri Mar 9 15:19:12 2012 +0100

    Update verbose log and semantic exception messages for local vs global vars.
    
    Global @vars (with @cu/src_name.c) have a fixed scope/CU and don't depend
    on location/PC. Make that clean in verbose log and semantic error messages.

commit 8fa5f2719e4ec115486e69364e110a5048c7dfd7
Author: Mark Wielaard <mjw@redhat.com>
Date:   Fri Mar 9 00:10:52 2012 +0100

    Cannot use @var DWARF variables in tracepoints, warn, but don't crash.

commit 49131a6df3a031f0011256cfa33130afc63c001c
Author: Mark Wielaard <mjw@redhat.com>
Date:   Thu Mar 8 23:32:49 2012 +0100

    Make sure @var works for process.mark probes.

commit 54e9f0623713e7f32c9870baad5a5d5c06c2fd22
Author: Mark Wielaard <mjw@redhat.com>
Date:   Thu Mar 8 15:20:08 2012 +0100

    Select most specific CU srcfile that matches @var("var@src") specification.
    
    dwarf_var_expanding_visitor::getcuscope: If there is a perfect match
    select that CU, otherwise, select the CU srcfile that is most specific
    (matching path/src file lenght is shortest).

commit bfa7e523ab8cd891a2a3f24c1540021665947b5d
Author: Mark Wielaard <mjw@redhat.com>
Date:   Wed Mar 7 19:58:12 2012 +0100

    PR13784 Allow defining a diffent CU source in @var.
    
    Add cu_name to struct target_symbol. Set it in parse_target_symbol
    to the string after @ in @var("somevar@some/src/file.c"). Make
    target_symbol::sym_name() aware of @cu_name postfix (don't return it).
    Add dwarf_var_expanding_visitor::getcuscope() which figures out the
    CU DIE to use as scope if target_symbol has cu_name part. Extend
    global_var.exp test to show new capability.

commit cc9001af0a5fa811ddf0e44439c7cddf465db945
Author: Mark Wielaard <mjw@redhat.com>
Date:   Tue Mar 6 17:34:36 2012 +0100

    Introduce @var("varname") as alternative syntax for $varname.
    
    Adds a field target_name and a method sym_name() to struct target_symbol
    to be used by the parser and tapsets translator so $name and @var("name")
    can be used interchanably. Adds a testcase at_var.exp to test this for
    various combinations of uprobes, kprobes, parameters, variables, arrays,
    fields access, pretty printing and taking addresses.

-------------- next part --------------
commit 179a00c3efb5ceac52a70debb17a91ee0c07722d
Author: Mark Wielaard <mjw@redhat.com>
Date:   Mon Mar 12 13:00:40 2012 +0100

    Document new @var construct in NEWS, langref, beginners and stapprobes.

diff --git a/NEWS b/NEWS
index 60060ed..16a422c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,16 @@
 * What's new in version 1.8
 
+- @var now an alternative language syntax for accessing DWARF variables
+  in uprobe and kprobe handlers (process, kernel, module). @var("somevar")
+  can be used where $somevar can be used. The @var syntax also makes it
+  possible to access non-local, global compile unit (CU) variables by
+  specifying the CU source file as follows @var("somevar@some/src/file.c").
+  This will provide the target variable value of global "somevar" as defined
+  in the source file "some/src/file.c". The @var syntax combines with all
+  normal features of DWARF target variables like @defined(), @entry(),
+  [N] array indexing, field access through ->, taking the address with
+  the & prefix and swallow or deep pretty printing with a $ or $$ suffix.
+
 - Stap now has resource limit options:
     --rlimit-as=NUM
     --rlimit-cpu=NUM
diff --git a/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml b/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml
index 9f6c669..155ab61 100644
--- a/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml
+++ b/doc/SystemTap_Beginners_Guide/en-US/ScriptConstructs.xml
@@ -164,6 +164,13 @@ target variables at the entry to the function.
 </para>
 
 <para>
+When a target variable is not local to the probe point, like a global
+external variable or a file local static variable defined in another file
+then it can be referenced through
+<quote><command>@var("<replaceable>varname</replaceable>@<replaceable>src/file.c</replaceable>")</command></quote>.
+</para>
+
+<para>
 SystemTap tracks the typing information of the target variable and can
 examine the fields of a structure with the <command>-></command> operator.
 The <command>-></command> operator can be chained to look at data structures
@@ -175,6 +182,27 @@ in a substructure or accessing another structure through a pointer.
 </para>
 
 <para>
+For example to access a field of the static files_stat target variable
+defined in fs/file_table.c (which holds some of the current file system
+sysctl tunables), one could write:
+</para>
+
+<screen>
+stap -e 'probe kernel.function("vfs_read") {
+           printf ("current files_stat max_files: %d\n",
+                   @var("files_stat@fs/file_table.c")->max_files);
+           exit(); }'
+</screen>
+
+<para>
+Which will yield something similar to the following:
+</para>
+
+<screen>
+current files_stat max_files: 386070
+</screen>
+
+<para>
 For pointers to base types such as integers and strings
 there are a number of functions listed below to access kernel-space data.
 The first argument for each functions is the pointer to the data item.
diff --git a/doc/langref.tex b/doc/langref.tex
index 5cee2ed..fb8ea19 100644
--- a/doc/langref.tex
+++ b/doc/langref.tex
@@ -52,7 +52,7 @@
 \newpage{}
 This document was derived from other documents contributed to the SystemTap project by employees of Red Hat, IBM and Intel.\newline
 
-Copyright \copyright\space  2007-2010 Red Hat Inc.\newline
+Copyright \copyright\space  2007-2012 Red Hat Inc.\newline
 Copyright \copyright\space  2007-2009 IBM Corp.\newline
 Copyright \copyright\space  2007 Intel Corporation.\newline
 
@@ -799,19 +799,47 @@ module address or an absolute kernel address.
 Some of the source-level variables, such as function parameters, locals,
 or globals visible in the compilation unit, are visible to probe handlers.
 Refer to these variables by prefixing their name with a dollar sign within
-the scripts. In addition, a special syntax allows limited traversal of structures,
-pointers, and arrays.
+the scripts. In addition, a special syntax allows limited traversal of
+structures, pointers, arrays, taking the address of a variable or pretty
+printing a whole structure.
 
 \texttt{\$var} refers to an in-scope variable var. If it is a type similar
 to an integer, it will be cast to a 64-bit integer for script use. Pointers
 similar to a string (char {*}) are copied to SystemTap string values by the
 \texttt{kernel\_string()} or \texttt{user\_string()} functions.
 
-\texttt{\$var->field} traverses a structure's field. The indirection operator
-may be repeated to follow additional levels of pointers.
-
-\texttt{\$var{[}N]} indexes into an array. The index is given with a literal
-number.
+\texttt{@var("varname")} is an alternative syntax for \texttt{\$varname}.
+It can also be used to access global variables in a particular compile
+unit (CU).  \texttt{@var("varname@src/file.c")} refers to the global
+(either file local or external) variable varname defined when the file
+src/file.c was compiled. The CU in which the variable is resolved is
+the first CU in the module of the probe point which matches the given
+file name at the end and has the shortest file name path (e.g. given
+\texttt{@var("foo@bar/baz.c")} and CUs with file name paths
+\texttt{src/sub/module/bar/baz.c} and \texttt{src/bar/baz.c} the second
+CU will be chosen to resolve \texttt{foo}).
+
+\texttt{\$var->field} or \texttt{@var("var@file.c")->field} traverses a
+structure's field. The indirection operator may be repeated to follow
+additional levels of pointers.
+
+\texttt{\$var{[}N]} or \texttt{@var("var@file.c"){[}N]} indexes into an
+array. The index is given with a literal number.
+
+\texttt{\&\$var} or \texttt{\&@var("var@file.c")} provides the address of
+a variable as a long. It can also be used in combination with field access
+or array indexing to provide the address of a particular field or an
+element in an array with \texttt{\&var->field},
+\texttt{\&@var("var@file.c"){[}N]} or a combination of those accessors.
+
+Using a single \texttt{\$} or a double \texttt{\$\$} suffix provides a
+swallow or deep string representation of the variable data type. Using
+a single \texttt{\$}, as in \texttt{\$var\$}, will provide a string that
+only includes the values of all basic type values of fields of the variable
+structure type but not any nested complex type values (which will be
+represented with \texttt{\{...\}}). Using a double \texttt{\$\$},
+as in \texttt{@var("var")\$\$} will provide a string that also includes
+all values of nested data types.
 
 \texttt{\$\$vars} expands to a character string that is equivalent to
 \texttt{sprintf("parm1=\%x ... parmN=\%x var1=\%x ... varN=\%x", \$parm1, ..., \$parmN,
diff --git a/stapprobes.3stap b/stapprobes.3stap
index 48c8602..14c426b 100644
--- a/stapprobes.3stap
+++ b/stapprobes.3stap
@@ -410,6 +410,28 @@ pointers (char *) may be copied to systemtap string values using the
 .IR kernel_string " or " user_string
 functions.
 .TP
+@var("varname")
+an alternative syntax for
+.IR $varname
+.
+.TP
+@var("varname@src/file.c")
+refers to the global (either file local or external) variable
+.IR varname
+defined when the file
+.IR src/file.c
+was compiled. The CU in which the variable is resolved is the first CU
+in the module of the probe point which matches the given file name at
+the end and has the shortest file name path (e.g. given
+.IR @var("foo@bar/baz.c")
+and CUs with file name paths
+.IR src/sub/module/bar/baz.c
+and
+.IR src/bar/baz.c
+the second CU will be chosen to resolve the (file) global variable
+.IR foo
+.
+.TP
 $var\->field traversal via a structure's or a pointer's field.  This
 generalized indirection operator may be repeated to follow more
 levels.  Note that the


More information about the Systemtap mailing list