- Prev
- SystemTap Beginners Guide
- Next

### ⁠3.3.2. Target Variables

The probe events that map to actual locations in the code (for example `kernel.function("function")` and `kernel.statement("statement")`) allow the use of target variables to obtain the value of variables visible at that location in the code. You can use the `-L` option to list the target variable available at a probe point. If the debug information is installed for the running kernel, you can run the following command to find out what target variables are available for the `vfs_read` function:

    stap -L 'kernel.function("vfs_read")'

This will yield something similar to the following:

    kernel.function("vfs_read@fs/read_write.c:277") $file:struct file* $buf:char* $count:size_t $pos:loff_t*

Each target variable is proceeded by a “`$`” and the type of the target variable follows the “`:`”. The kernel's `vfs_read` function has `$file` (pointer to structure describing the file), `$buf` (pointer to the user-space memory to store the read data), `$count` (number of bytes to read), and `$pos` (position to start reading from in the file) target variables at the entry to the function.
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 “`@var("varname@src/file.c")`”.
It is also supported to specify an executable or library file path as the second argument, as in “`@var("varname", "/path/to/exe/or/lib")`”
SystemTap tracks the typing information of the target variable and can examine the fields of a structure with the `->` operator. The `->` operator can be chained to look at data structures contained within data structures and follow pointers to other data structures. The `->` operator will obtain the value in the field of the structure. The `->` operator is used regardless whether accessing a field in a substructure or accessing another structure through a pointer.
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:

    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(); }'

Which will yield something similar to the following:

    current files_stat max_files: 386070

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. Similar functions are described in Section 4.2, “Accessing User-Space Target Variables” for accessing target variables in user-space code.

kernel_char(address)
  Obtain the character at address from kernel memory.
kernel_short(address)
  Obtain the short at address from kernel memory.
kernel_int(address)
  Obtain the int at address from kernel memory.
kernel_long(address)
  Obtain the long at address from kernel memory
kernel_string(address)
  Obtain the string at address from kernel memory.
kernel_string_n(address, n)
  Obtain the string at address from the kernel memory and limits the string to n bytes.

#### ⁠3.3.2.1. Pretty Printing Target Variables

SystemTap scripts are often used to observe what is happening within the code. In many cases just printing the values of the various context variables is sufficient. SystemTap makes a number operations available that can generate printable strings for target variables:

$$vars
  Expands to a character string that is equivalent to `sprintf("parm1=%x ... parmN=%x var1=%x ... varN=%x", parm1, ..., parmN, var1, ..., varN)` for each variable in scope at the probe point. Some values may be printed as “`=?`” if their run-time location cannot be found.
$$locals
  Expands to a subset of `$$vars` containing only the local variables.
$$parms
  Expands to a subset of `$$vars` containing only the function parameters.
$$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.

Below is a command-line script that prints the values of the parameters passed into the function `vfs_read`:

    stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms); exit(); }'

There are four parameters passed into `vfs_read`: `file`, `buf`, `count`, and `pos`. The `$$parms` generates a string for the parameters passed into the function. In this case all but the `count` parameter are pointers. The following is an example of the output from the previous command-line script:

    file=0xffff8800b40d4c80 buf=0x7fff634403e0 count=0x2004 pos=0xffff8800af96df48

Having the address a pointer points to may not be useful. Instead the fields of the data structure the pointer points to may be of more use. Use the “`$`” suffix to pretty print the data structure. The following command-line example uses the pretty printing suffix to print more details about the data structures passed into the function `vfs_read`:

    stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms$); exit(); }'

The previous command line will generate something similar to the following with the fields of the data structure included in the output:

    file={.f_u={...}, .f_path={...}, .f_op=0xffffffffa06e1d80, .f_lock={...}, .f_count={...}, .f_flags=34818, .f_mode=31, .f_pos=0, .f_owner={...}, .f_cred=0xffff88013148fc80, .f_ra={...}, .f_version=0, .f_security=0xffff8800b8dce560, .private_data=0x0, .f_ep_links={...}, .f_mapping=0xffff880037f8fdf8} buf="" count=8196 pos=-131938753921208

With the “`$`” suffix fields that are composed of data structures are not expanded. The “`$$`” suffix will print the values contained within the nested data structures. Below is an example using the “`$$`” suffix:

    stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms$$); exit(); }'

The “`$$`” suffix, like all strings, is limited to the maximum string size. Below is a representative output from the previous command-line script, which is truncated because of the string size limit:

    file={.f_u={.fu_list={.next=0xffff8801336ca0e8, .prev=0xffff88012ded0840}, .fu_rcuhead={.next=0xffff8801336ca0e8, .func=0xffff88012ded0840}}, .f_path={.mnt=0xffff880132fc97c0, .dentry=0xffff88001a889cc0}, .f_op=0xffffffffa06f64c0, .f_lock={.raw_lock={.slock=196611}}, .f_count={.counter=2}, .f_flags=34818, .f_mode=31, .f_pos=0, .f_owner={.lock={.raw_lock={.lock=16777216}}, .pid=0x0, .pid_type=0, .uid=0, .euid=0, .signum=0}, .f_cred=0xffff880130129a80, .f_ra={.start=0, .size=0, .async_size=0, .ra_pages=32, .

- Prev3.3. Basic SystemTap Handler Constructs
- Up
- Home
- Next3.3.2.2. Typecasting