Chapter 5. SystemTap—Filtering and Analyzing System Data

Contents

5.1. Conceptual Overview
5.2. Installation and Setup
5.3. Script Syntax
5.4. Example Script
5.5. For More Information

SystemTap provides a command line interface and a scripting language to examine the activities of a running Linux system, particularly the kernel, in fine detail. SystemTap scripts are written in the SystemTap scripting language, are then compiled to C-code kernel modules and inserted into the kernel. The scripts can be designed to extract, filter and summarize data, thus allowing the diagnosis of complex performance problems or functional problems. SystemTap provides information similar to the output of tools like netstat, ps, top, and iostat. However, more filtering and analysis options can be used for the collected information.

Basically, there are two different setups for using SystemTap:

Classic Setup and Initial Test

Have the SystemTap script compiled and the resulting kernel modules inserted on the same machine. This requires the machine to have the kernel debugging information installed.

Client-Server Setup

If the machine you want to probe does not have any development tools or kernel debugging information installed for any reason, you can make use of this setup. It allows you to compile a SystemTap module on a machine other than the one on which it will be run.

5.1. Conceptual Overview

Each time you run a SystemTap script, a SystemTap session is started. A number of passes are done on the script before it is allowed to run, at which point the script is compiled into a kernel module and loaded. In case the script has already been executed before and no changes regarding any components have occurred (for example, regarding compiler version, kernel version, library path, script contents), SystemTap does not compile the script again, but uses the *.c and *.ko data stored in the SystemTap cache (~/.systemtap). The module is unloaded when the tap has finished running. For an example, see the test run in Section 5.2.1, “Classic Setup and Initial Test” and the respective explanation.

5.1.1. SystemTap Scripts

SystemTap usage is based on SystemTap scripts (*.stp). They tell SystemTap which type of information to collect, and what to do once that information is collected. The scripts are written in the SystemTap scripting language that is similar to AWK and C. For the language definition, see http://sourceware.org/systemtap/langref/.

The essential idea behind a SystemTap script is to name events, and to give them handlers. When SystemTap runs the script, it monitors for certain events. When an event occurs, the Linux kernel runs the handler as a sub-routine, then resumes. Thus, events serve as the triggers for handlers to run. Handlers can record specified data and print it in a certain manner.

The SystemTap language only uses a few data types (integers, strings, and associative arrays of these), and full control structures (blocks, conditionals, loops, functions). It has a lightweight punctuation (semicolons are optional) and does not need detailed declarations (types are inferred and checked automatically).

For more information about SystemTap scripts and their syntax, refer to Section 5.3, “Script Syntax” and to the stapprobes and stapfuncs man pages, that are available with the systemtap-doc package.

5.1.2. Tapsets

Tapsets are a library of pre-written probes and functions that can be used in SystemTap scripts. When a user runs a SystemTap script, SystemTap checks the script's probe events and handlers against the tapset library. SystemTap then loads the corresponding probes and functions before translating the script to C. Like SystemTap scripts themselves, tapsets use the filename extension *.stp.

However, unlike SystemTap scripts, tapsets are not meant for direct execution—they constitute the library from which other scripts can pull definitions. Thus, the tapset library is an abstraction layer designed to make it easier for users to define events and functions. Tapsets provide useful aliases for functions that users may want to specify as an event (knowing the proper alias is mostly easier than remembering specific kernel functions that might vary between kernel versions).

5.1.3. Commands and Privileges

The main commands associated with SystemTap are stap and staprun. To execute them, you either need root privileges or must be a member of the stapdev or stapusr group.

stap

SystemTap front-end. Runs a SystemTap script (either from file, or from standard input). It translates the script into C code, compiles it, and loads the resulting kernel module into a running Linux kernel. Then, the requested system trace or probe functions are performed.

staprun

SystemTap back-end. Loads and unloads kernel modules produced by the SystemTap front-end.

For a list of options for each command, use --help. For details, refer to the stap and the staprun man pages.

Apart from the commands above which are used in a setup where you build the kernel modules on the same machine that you want to probe, there is also a specific set of commands for a client-server setup: systemtap-client and systemtap-server, the latter containing a number of subcommands. This set of commands allows you to compile a SystemTap module on a machine other than the one on which it will be run. For more information about this specific setup and the commands involved, refer to Section 5.2, “Installation and Setup” and to the stap-server and stap-client man pages.

To avoid giving root access to users just for running SystemTap, you can make use of the following SystemTap groups. They are not available by default on SUSE Linux Enterprise, but you can create the groups and modify the access rights accordingly.

stapdev

Members of this group can run SystemTap scripts with stap, or run SystemTap instrumentation modules with staprun. As running stap involves compiling scripts into kernel modules and loading them into the kernel, members of this group still have effective root access.

stapusr

Members of this group are only allowed to run SystemTap instrumentation modules with staprun. In addition, they can only run those modules from /lib/modules/kernel_version/systemtap/. This directory must be owned by root and must only be writable for the root user.

5.1.4. Important Files and Directories

The following list gives an overview of the SystemTap main files and directories.

/lib/modules/kernel_version/systemtap/

Holds the SystemTap instrumentation modules.

/usr/share/systemtap/tapset/

Holds the standard library of tapsets.

/usr/share/doc/packages/systemtap/examples

Holds a number of example SystemTap scripts for various purposes. Only available if the systemtap-doc package is installed.

~/.systemtap/cache

Data directory for cached SystemTap files.

/tmp/stap*

Temporary directory for SystemTap files, including translated C code and kernel object.

If you use the SystemTap client-server setup, the following directories are also important:

/etc/systemtap/ssl/server

Public SystemTap server certificate and key database. Used if the SystemTap server is set up under root's account.

/etc/systemtap/ssl/client

SystemTap client-side certificate database. Only located in this directory if a SystemTap server is authorized as trusted for all SystemTap clients running on this machine.

~/.systemtap/ssl/server

Private SystemTap server certificate and key database. Used if the SystemTap server is not running under a root account, but under a regular user's account. Usually, a dedicated user named stap-server is created for that purpose.

~/.systemtap/ssl/client

Client-side certificate database, located in a regular user's home directory. Only located in this directory if a SystemTap server has been authorized as trusted for SystemTap clients run by this specific user.

/var/log/stap-server.log

Default SystemTap server log file.

5.2. Installation and Setup

Depending on your preferred setup, check the sections below for an overview of the packages you need. As SystemTap needs information about the kernel, some kernel-related packages must be installed in addition to the SystemTap packages. For each kernel you want to probe with SystemTap, you need to install a set of the following packages that exactly matches the kernel version and flavor (indicated by * in the tables below).

[Important]Repository for Packages with Debugging Information

If you subscribed your system for online updates, you can find debuginfo packages in the *-Debuginfo-Updates online installation repository relevant for openSUSE 11.4. Use YaST to enable the repository.

To get access to the man pages and to a helpful collection of example SystemTap scripts for various purposes, additionally install the systemtap-doc package.

5.2.1. Classic Setup and Initial Test

For this setup, install the following packages (using either YaST or zypper).

  • systemtap

  • systemtap-client

  • systemtap-server

  • systemtap-doc (optional)

  • kernel-*-base

  • kernel-*-debuginfo

  • kernel-*-devel

  • kernel-source-*

  • gcc

To check if all packages are correctly installed on the machine and if SystemTap is ready to use, execute the following command as root.

stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}'

It probes the currently used kernel by running a script and returning an output. If the output is similar to the following, SystemTap is successfully deployed and ready to use:


Pass 1: parsed user script and 59 library script(s) in 80usr/0sys/214real ms.
Pass 2: analyzed script: 1 probe(s), 11 function(s), 2 embed(s), 1 global(s) in 
 140usr/20sys/412real ms. 
Pass 3: translated to C into
 "/tmp/stapDwEk76/stap_1856e21ea1c246da85ad8c66b4338349_4970.c" in 160usr/0sys/408real ms. 
Pass 4: compiled C into "stap_1856e21ea1c246da85ad8c66b4338349_4970.ko" in 
 2030usr/360sys/10182real ms. 
Pass 5: starting run. 
 read performed
Pass 5: run completed in 10usr/20sys/257real ms. 

1

Checks the script against the existing tapset library in /usr/share/ systemtap/tapset/ for any tapsets used. Tapsets are scripts that form a library of pre-written probes and functions that can be used in SystemTap scripts.

2

Examines the script for its components.

3

Translates the script to C. Runs the system C compiler to create a kernel module from it. Both the resulting C code (*.c) and the kernel module (*.ko) are stored in the SystemTap cache, ~/.systemtap.

4

Loads the module and enables all the probes (events and handlers) in the script by hooking into the kernel. The event being probed is a Virtual File System (VFS) read. As the event occurs on any processor, a valid handler is executed (prints the text read performed) and closed with no errors.

5

After the SystemTap session is terminated, the probes are disabled, and the kernel module is unloaded.

In case any error messages appear during the test, check the output for hints about any missing packages and make sure they are installed correctly. Rebooting and loading the appropriate kernel may also be needed.

5.2.2. Client-Server Setup

A SystemTap compile server listens for connections from SystemTap clients on a secure SSL network port and accepts requests to run the SystemTap front-end. The server advertises its presence and configuration on the local network using avahi (a free Zeroconf implementation that allows programs to publish and discover services and hosts in a local network without any specific configuration). The compile server broadcasts its IP address, port, and details about the Linux kernel it runs. Thus, the SystemTap client can automatically detect a compile server on the network that is compatible to the client's kernel version.

As SystemTap exposes kernel internal data structures and potentially private user information, it provides several layers of security:

  • A separate front-end (stap) and back-end (staprun), with only the front-end requiring access to kernel information packages for compiling the SystemTap script into C code and for creating a kernel module. For more information, refer to Section 5.1.3, “Commands and Privileges”.

  • An encrypted network connection between SystemTap client and server via SSL. The SSL connection is based on certificates and key pairs consisting of public and private keys.

  • Users or system administrators can authorize SystemTap servers on the network as trusted.

  • Use of SystemTap groups with different privileges. For more information, refer to Section 5.1.3, “Commands and Privileges”.

5.2.2.1. Installing SystemTap

For this setup, install the following packages (using YaST or zypper):

Client
  • systemtap

  • systemtap-client

  • systemtap-doc (optional)

Server
  • systemtap

  • systemtap-server

  • kernel-*-debuginfo

  • kernel-*-devel

  • kernel-source-*

  • gcc

5.2.2.2. Setting Up the Server

You have two choices for setting up the SystemTap compile server: you can run it as root or as non-root user. This has implications on the certificate management on server- and client-side and on the process of establishing a given compile server as trusted by a given client. For the SSL connection between the compile server and the SystemTap client, you need to create a certificate for authentication. Depending on how the SystemTap compile server is set up (as root or as non-root), the location of the server certificate differs. When set up as root user, the certificate is stored in a database at /etc/systemtap/ssl/server. However, when the compile server is set up as non-root (usually by the user stap-server), the server certificate is stored in a database in the systemtap-server user's home directory: ~/.systemtap/ssl/server.

Procedure 5.1. Running the Compile Server as Non-root User

For this setup, it is advisable to create a dedicated system group and user for the compile server.

  1. Log in as root.

  2. Create a home directory for the compile server user, for example:

    mkdir /var/lib/stapserver
  3. Add a system group for the operation of the compile server. In the following example, the group is named stap-server and the group ID (GID) is 155, but you can also specify a different group name or GID:

    groupadd -g 155 -r stap-server
  4. Add a user belonging to the group you created before and specify the user's home directory:

    useradd -c "SystemTap Compile Server" -u 155 -g stap-server -d \ /var/lib/stapserver -m -r -s /sbin/nologin stap-server

    The command above will create a user named stap-server with the user ID 155. The user's finger information is specified with -c and the options -g and -d specify the user's main group (stap-server) and his home directory you created in Step 2, respectively. The user account will be a system account (specified with -r) and the user will not be able to log in, as his login shell is set to /sbin/nologin with the -s option.

  5. Change the owner and the group for the home directory to use:

    chown -R stap-server.stap-server /var/lib/stapserver/
  6. Run a shell as user stap-server and pass the stap-gen-cert command to generate a SystemTap certificate:

    su -s /bin/sh - stap-server -c  /usr/bin/stap-gen-cert

    You are prompted to set a password for the SystemTap server certificate and key database.

  7. Enter a password for the SystemTap server certificate and confirm it.

    This generates a certificate (stap.cert) that is stored in the systemtap-server user's home directory—in this case: /var/lib/stapserver/.systemtap/ssl/server.

  8. Start the compile server with:

    su -s /bin/sh - stap-server -c /usr/bin/stap-start-server

    Upon first start of the compile server, this creates a client-side certificate database in the systemtap-server user's home directory (~/.systemtap/ssl/client) to which the server's certificate has now automatically been added. Thus, a server started by the user stap-server is automatically trusted by clients run by that user.

Procedure 5.2. Running the Compile Server as root User

Compared to Procedure 5.1, “Running the Compile Server as Non-root User”, this setup is much simpler but it has security implications.

[Warning]Security Risk

In the following setup, the compile server certificate is stored in /etc/systemtap/ssl/server, together with the client-side database located at /etc/systemtap/ssl/client. As these files are accessible for anyone, anyone can run the stap-client command, thus potentially exposing kernel internal data structures and private user information.

  1. Log in as root.

  2. Create a SystemTap certificate by executing the following command:

    /usr/bin/stap-gen-cert

    You are prompted to set a password for the SystemTap server certificate and key database.

  3. Enter a password and confirm it.

    The certificate (stap.cert) is generated. In contrast to the setup as non-root, it is stored in a database located at /etc/systemtap/ssl/server.

  4. Start a SystemTap server on the local host by using the following command:

    /usr/bin/stap-start-server

    At the same time, a client-side certificate database is created at /etc/systemtap/ssl/client. The server certificate is automatically added to the client-side certificate database.

The client-side certificate database created for root is also the global client-side database for all clients on the host. Thus, a server started by root is automatically trusted by clients run by any user on that host: Any user can now compile kernel modules on the compile server using the stap-client command. For more information about the security implications, see the Safety and Security section of the stap-server man page.

5.2.2.3. Setting Up the Client

To be able to invoke stap-client from another host, you need to copy the certificate that has been created on the server to the client and to authorize the compile server as trusted for the client. The location of the original server certificate to copy depends on how the SystemTap compile server has been set up. For the authorization process you can choose to either authorize the compile server as trusted for all SystemTap clients running on that machine or only for clients that are run by a specific user.

  1. Log in to the client machine.

  2. If you have set up the compile server as non-root, copy the server certificate to the client machine as follows:

    scp root@servername:~stap-server/.systemtap/ssl/server/stap.cert \ /tmp/stap.cert
  3. If you have set up the compile server as root, copy the server certificate to the client machine as follows:

    scp root@servername:/etc/systemtap/ssl/server/stap.cert /tmp/stap.cert
  4. If you want to authorize the compile server as trusted for all SystemTap clients running on that machine (no matter by which user), execute the following command as root:

    /usr/bin/stap-authorize-server-cert /tmp/stap.cert

    In this case, the server certificate will be added to the client-side certificate database (/etc/systemtap/ssl/client).

  5. If you want to authorize the compile server only as trusted for SystemTap clients on that machine that are run by a specific user, execute the following command as regular user:

    /usr/bin/stap-authorize-server-cert /tmp/stap.cert

    In that case, the server certificate will be added to the client-side certificate database for that user ( ~/.systemtap/ssl/client).

  6. Remove the copied certificate from the /tmp directory:

     rm /tmp/stap.cert

5.2.2.4. Using the Client

After you have set up the SystemTap compile server and client as described in the previous sections, you can make use of the stap-client program. It is analogous to the stap front-end, except that it tries to find a compatible SystemTap compile server on the local network. It then uses this server for compiling the SystemTap script into a module, loading the kernel module and enabling the probes (passes 1-4 of a SystemTap session). If requested, pass 5 actions are performed on the localhost using staprun. For more information about a SystemTap session and the individual passes, see Section 5.2.1, “Classic Setup and Initial Test”.

[Note]Executing stap-client

You can run stap-client either as root or as non-root. If run as non-root, the underlying staprun command needs to be suid and the user executing stap-client must be a member of the stapdev group. For more information, refer to Section 5.1.3, “Commands and Privileges”.

Usually, a running SystemTap compile server on the local network advertises its presence using avahi and is automatically detected by the SystemTap client. The following procedure illustrates how to make use of the SystemTap client-server setup and covers the most common commands and options needed for that.

  1. To make sure that a compatible SystemTap server is running on your local network, execute the following command on the SystemTap client:

    stap-find-servers

    This invokes avahi-browse to find servers. The details of any servers found are echoed to standard output. If this command does not return anything, no compatible SystemTap server can be found on your network.

  2. In this case, log in to the compile server and run

    stap-start-server

    This starts avahi-publish-service in the background. The server listens for connections on a random port and advertises its presence on the local network using the avahi daemon. If the server is started successfully, the process ID of the server is echoed to standard output.

    Note that stap-start-server does not work for the initial setup as described in Procedure 5.2, “Running the Compile Server as root User”, where /usr/bin/stap-serverd is used instead. stap-start-server puts the server in the background—thus, you would not see the prompt asking for the server certificate password.

    ps -ef | grep avahi

    should now return an output similar to the following:

    
    avahi 3300     1  0 15:14 ?      00:00:00 avahi-daemon: running [linux-48zp.local]
    root  4687  4655  0 18:03 ttyS0  00:00:00 avahi-publish-service Systemtap Compile Se
    root  4700  4160  0 18:05 ttyS0  00:00:00 grep avahi
  3. To run a simple test, execute the following command on the SystemTap client:

    stap-client -e 'probe begin { printf("Hello"); exit(); }'

    This compiles and executes a simple example on any compatible SystemTap server found on the local network. If the test is successful, it prints Hello to standard output.

Instead of using any compatible server found on the network, you can also determine which SystemTap server to contact and use. To do so, run the stap-client command with the --server option. It lets you specify the hostname or IP address of the SystemTap server, optionally also a port (which is useful fore connecting to non-local servers). For more information and details about the other available commands and options, refer to the stap-server and stap-client man pages.

5.2.2.5. Troubleshooting

There are several things that can go wrong when using the SystemTap client-server setup. If you have difficulties establishing a connection between SystemTap client and server or running stap-client, proceed according to the following list.

Compatible SystemTap Compile Server Available?

If stap-client reports that it is unable to find a server, check if a compatible SystemTap compile server is available:

stap-find-servers

If this command does not return anything, no compatible SystemTap server can be found on your network.

SystemTap Compile Server Running?

To make sure that the SystemTap compile server is running, log in to the server and run

stap-server-start

If the server is started successfully, the process ID of the server is echoed to standard output.

Avahi Installed?

The SystemTap client-server setup depends on avahi for automatically announcing the presence and configuration of any SystemTap servers in the network and on client-side for automatically detecting a compatible server. As a consequence, the following packages are usually automatically installed together with the systemtap-server and systemtap-client packages:

  • avahi

  • avahi-utils

Check if the packages are installed with

rpm -qa | grep avahi

If not, install them with YaST or zypper.

Avahi Daemon Running?

Check if the avahi daemon is running:

/etc/init.d/avahi-daemon status

If not, start it with

/etc/init.d/avahi-daemon start

Also check if the avahi daemon was configured to be started automatically at runlevels 3 and 5:

chkconfig -l avahi-daemon

This should return the following output:

avahi-daemon              0:off  1:off  2:off  3:on   4:off  5:on   6:off

If not, configure this option with

chkconfig avahi-daemon 35

Virtual Machine: Bridged Network?

If you are running SystemTap in a virtual machine setup, make sure the network has been bridged, otherwise broadcasting via avahi will not work.

Certificate Not Found?

If running an stap-client command fails because the certificate database was not found, check if you have set up the SystemTap client correctly. For details, refer to Section 5.2.2.3, “Setting Up the Client”.

5.3. Script Syntax

SystemTap scripts consist of the following two components:

SystemTap Events (Probe Points)

Name the kernel events at the associated handler should be executed. Examples for events are entering or exiting a certain function, a timer expiring, or starting or terminating a session.

SystemTap Handlers (Probe Body)

Series of script language statements that specify the work to be done whenever a certain event occurs. This normally includes extracting data from the event context, storing them into internal variables, or printing results.

An event and its corresponding handler is collectively called a probe. SystemTap events are also called probe points. A probe's handler is also referred to as probe body.

Comments can be inserted anywhere in the SystemTap script in various styles: using either #, /* */, or // as marker.

5.3.1. Probe Format

A SystemTap script can have multiple probes. They must be written in the following format:

probe event {statements}

Each probe has a corresponding statement block. This statement block must be enclosed in { } and contains the statements to be executed per event.

Example 5.1. Simple SystemTap Script

The following example shows a simple SystemTap script.

probe1 begin2
{3
   printf4 ("hello world\n")5
   exit ()6
}7

1

Start of the probe.

2

Event begin (the start of the SystemTap session).

3

Start of the handler definition, indicated by {.

4

First function defined in the handler: the printf function.

5

String to be printed by the printf function, followed by a line break (/n).

6

Second function defined in the handler: the exit() function. Note that the SystemTap script will continue to run until the exit() function executes. If you want to stop the execution of the script before, stop it manually by pressing +C.

7

End of the handler definition, indicated by }.

The event begin 2 (the start of the SystemTap session) triggers the handler enclosed in { }, in this case the printf function 4 which prints hello world followed by a new line 5, then exits.


If your statement block holds several statements, SystemTap executes these statements in sequence—you do not need to insert special separators or terminators between multiple statements. A statement block can also be nested within another statement blocks. Generally, statement blocks in SystemTap scripts use the same syntax and semantics as in the C programming language.

5.3.2. SystemTap Events (Probe Points)

SystemTap supports a number of built-in events.

The general event syntax is a dotted-symbol sequence. This allows a breakdown of the event namespace into parts. Each component identifier may be parametrized by a string or number literal, with a syntax like a function call. A component may include a * character, to expand to other matching probe points. A probe point may be followed by a ? character, to indicate that it is optional, and that no error should result if it fails to expand. Alternately, a probe point may be followed by a ! character to indicate that it is both optional and sufficient.

SystemTap supports multiple events per probe—they need to be separated by a comma (,). If multiple events are specified in a single probe, SystemTap will execute the handler when any of the specified events occur.

In general, events can be classified into the following categories:

  • Synchronous events: Occur when any process executes an instruction at a particular location in kernel code. This gives other events a reference point (instruction address) from which more contextual data may be available.

    An example for a synchronous event is vfs.file_operation: The entry to the file_operation event for Virtual File System (VFS). For example, in Section 5.2.1, “Classic Setup and Initial Test”, read is the file_operation event used for VFS.

  • Asynchronous events: Not tied to a particular instruction or location in code. This family of probe points consists mainly of counters, timers, and similar constructs.

    Examples for asynchronous events are: begin (start of a SystemTap session—as soon as a SystemTap script is run, end (end of a SystemTap session), or timer events. Timer events specify a handler to be executed periodically, like example timer.s(seconds), or timer.ms(milliseconds).

    When used in conjunction with other probes that collect information, timer events allow you to print out periodic updates and see how that information changes over time.

Example 5.2. Probe with Timer Event

For example, the following probe would print the text hello world every 4 seconds:

probe timer.s(4)
{
   printf("hello world\n")
}

For detailed information about supported events, refer to the stapprobes man page. The See Also section of the man page also contains links to other man pages that discuss supported events for specific subsystems and components.

5.3.3. SystemTap Handlers (Probe Body)

Each SystemTap event is accompanied by a corresponding handler defined for that event, consisting of a statement block.

5.3.3.1. Functions

If you need the same set of statements in multiple probes, you can place them in a function for easy reuse. Functions are defined by the keyword function followed by a name. They take any number of string or numeric arguments (by value) and may return a single string or number.

function function_name(arguments) {statements}
probe event {function_name(arguments)}

The statements in function_name are executed when the probe for event executes. The arguments are optional values passed into the function.

Functions can be defined anywhere in the script. They may take any

One of the functions needed very often was already introduced in Example 5.1, “Simple SystemTap Script”: the printf function for printing data in a formatted way. When using the printf function, you can specify how arguments should be printed by using a format string. The format string is included in quotation marks and can contain further format specifiers, introduced by a % character.

Which format strings to use depends on your list of arguments. Format strings can have multiple format specifiers—each matching a corresponding argument. Multiple arguments can be separated by a comma.

Example 5.3. printf Function with Format Specifiers

printf ("1%s2(%d3) open\n4", execname(), pid())

1

Start of the format string, indicated by ".

2

String format specifier.

3

Integer format specifier.

4

End of the format string, indicated by ".


The example above would print the current executable name (execname()) as string and the process ID (pid()) as integer in brackets, followed by a space, then the word open and a line break:

[...]
vmware-guestd(2206) open
hald(2360) open
[...]
   

Apart from the two functions execname()and pid()) used in Example 5.3, “printf Function with Format Specifiers”, a variety of other functions can be used as printf arguments.

Among the most commonly used SystemTap functions are the following:

tid()

ID of the current thread.

pid()

Process ID of the current thread.

uid()

ID of the current user.

cpu()

Current CPU number.

execname()

Name of the current process.

gettimeofday_s()

Number of seconds since UNIX epoch (January 1, 1970).

ctime()

Convert time into a string.

pp()

String describing the probe point currently being handled.

thread_indent()

Useful function for organizing print results. It (internally) stores an indentation counter for each thread (tid()). The function takes one argument, an indentation delta, indicating how many spaces to add or remove from the thread's indentation counter. It returns a string with some generic trace data along with an appropriate number of indentation spaces. The generic data returned includes a timestamp (number of microseconds since the initial indentation for the thread), a process name, and the thread ID itself. This allows you to identify what functions were called, who called them, and how long they took.

Call entries and exits often do not immediately precede each other (otherwise it would be easy to match them). In between a first call entry and its exit, usually a number of other call entries and exits are made. The indentation counter helps you match an entry with its corresponding exit as it indents the next function call in case it is not the exit of the previous one. For an example SystemTap script using thread_indent() and the respective output, refer to the SystemTap Tutorial: http://sourceware.org/systemtap/tutorial/Tracing.html#fig:socket-trace.

For more information about supported SystemTap functions, refer to the stapfuncs man page.

5.3.3.2. Other Basic Constructs

Apart from functions, you can use several other common constructs in SystemTap handlers, including variables, conditional statements (like if/else, while loops, for loops, arrays or command line arguments.

5.3.3.2.1. Variables

Variables may be defined anywhere in the script. To define one, simply choose a name and assign a value from a function or expression to it:

foo = gettimeofday( )

Then you can use the variable in an expression. From the type of values assigned to the variable, SystemTap automatically infers the type of each identifier (string or number). Any inconsistencies will be reported as errors. In the example above, foo would automatically be classified as a number and could be printed via printf() with the integer format specifier (%d).

However, by default, variables are local to the probe they are used in: They are initialized, used and disposed of at each handler evocation. To share variables between probes, declare them global anywhere in the script. To do so, use the global keyword outside of the probes:

Example 5.4. Using Global Variables

global count_jiffies, count_ms
probe timer.jiffies(100) { count_jiffies ++ }
probe timer.ms(100) { count_ms ++ }
probe timer.ms(12345)
{
  hz=(1000*count_jiffies) / count_ms
  printf ("jiffies:ms ratio %d:%d => CONFIG_HZ=%d\n",
    count_jiffies, count_ms, hz)
  exit ()
  }

This example script computes the CONFIG_HZ setting of the kernel by using timers that count jiffies and milliseconds, then computing accordingly. (A jiffy is the duration of one tick of the system timer interrupt. It is not an absolute time interval unit, since its duration depends on the clock interrupt frequency of the particular hardware platform). With the global statement it is possible to use the variables count_jiffies and count_ms also in the probe timer.ms(12345). With ++ the value of a variable is incremented by 1.


5.3.3.2.2. Conditional Statements

There are a number of conditional statements that you can use in SystemTap scripts. The following are probably most common:

If/Else Statements

They are expressed in the following format:

if (condition)1
  statement12
else3
  statement24

The if statement compares an integer-valued expression to zero. If the condition expression 1 is non-zero, the first statement 2 is executed. If the condition expression is zero, the second statement 4 is executed. The else clause (3 and 4) is optional. Both 2 and 4 can also be statement blocks.

While Loops

They are expressed in the following format:

while (condition)1 
  statement2

As long as condition is non-zero, the statement 2 is executed. 2 can also be a statement block. It must change a value so condition will eventually be zero.

For Loops

They are basically a shortcut for while loops and are expressed in the following format:

for (initialization1; conditional2; increment3) statement

The expression specified in 1 is used to initialize a counter for the number of loop iterations and is executed before execution of the loop starts. The execution of the loop continues until the loop condition 2 is false. (This expression is checked at the beginning of each loop iteration). The expression specified in 3 is used to increment the loop counter. It is executed at the end of each loop iteration.

Conditional Operators

The following operators can be used in conditional statements:

==:  Is equal to

!=:  Is not equal to

>=:  Is greater than or equal to

<=:  Is less than or equal to

5.4. Example Script

If you have installed the systemtap-doc package, you can find a number of useful SystemTap example scripts in /usr/share/doc/packages/systemtap/examples.

This section describes a rather simple example script in more detail: /usr/share/doc/packages/systemtap/examples/network/tcp_connections.stp.

Example 5.5. Monitoring Incoming TCP Connections with tcp_connections.stp

#! /usr/bin/env stap
    
probe begin {
  printf("%6s %16s %6s %6s %16s\n",
         "UID", "CMD", "PID", "PORT", "IP_SOURCE")
}
    
probe kernel.function("tcp_accept").return?,
      kernel.function("inet_csk_accept").return? {
  sock = $return
  if (sock != 0)
    printf("%6d %16s %6d %6d %16s\n", uid(), execname(), pid(),
           inet_get_local_port(sock), inet_get_ip_source(sock))
}

This SystemTap script monitors the incoming TCP connections and helps to identify unauthorized or unwanted network access requests in real time. It shows the following information for each new incoming TCP connection accepted by the computer:

  • User ID (UID)

  • Command accepting the connection (CMD)

  • Process ID of the command (PID)

  • Port used by the connection (PORT)

  • IP address from which the TCP connection originated (IP_SOUCE)

To run the script, execute

stap /usr/share/doc/packages/systemtap/examples/network/tcp_connections.stp

and follow the output on the screen. To manually stop the script, press +C.

5.5. For More Information

This chapter only provides a short SystemTap overview. Refer to the following links for more information about SystemTap:

http://sourceware.org/systemtap/

SystemTap project home page.

http://sourceware.org/systemtap/wiki/

Huge collection of useful information about SystemTap, ranging from detailed user and developer documentation to reviews and comparisons with other tools, or Frequently Asked Questions and tips. Also contains collections of SystemTap scripts, examples and usage stories and lists recent talks and papers about SystemTap.

http://sourceware.org/systemtap/documentation.html

Features a SystemTap Tutorial, a SystemTap Beginner's Guide, a Tapset Developer's Guide, and a SystemTap Language Reference in PDF and HTML format. Also lists the relevant man pages.

You can also find the SystemTap language reference and SystemTap tutorial in your installed system under /usr/share/doc/packages/systemtap. Example SystemTap scripts are available from the example subdirectory.