/** @mainpage SystemTap Runtime @section intro_sec Introduction This document describes the implementation of the SystemTap Runtime. It is intended for developers of the SystemTap Language translator, TapSet authors or kprobes programmers. These functions are not directly available from the SystemTap Language. The SystemTap Runtime Library consists of all functions and code fragments needed by the compiler/translator to include in building a kernel module using kprobes. It also includes I/O code to transmit its output from the kernel to userspace. In addition to the library, the runtime includes a SystemTap user-space daemon (staprun). Staprun grabs data sent from the I/O code in the runtime and displays it and/or saves it to files. Staprun will handle other issues like inserting and removing modules. Staprun and the I/O code makes use of /proc (and optionally relayfs) for communications. For kernels without relayfs builtin, it is provided as a standalone module under the runtime directory. @ref start_page @ref maps @ref lists @ref string @ref counter @ref stat @ref io_page SystemTap Project Page */ /** @page start_page Getting Started The library is written in C and is really not a library but a collection of code that can be conditionally included in a modules. This allows for a high degree of customization and efficiency. To get started, first compile everything. @verbatim >cd stp/src/runtime > make make -w -C relayfs make[1]: Entering directory `/home/hunt/stp/src/runtime/relayfs' make -C /lib/modules/2.6.11-1.27_FC3.huntsmp/build SUBDIRS=/home/hunt/stp/src/runtime/relayfs modules make[2]: Entering directory `/lib/modules/2.6.11-1.27_FC3.huntsmp/build' Building modules, stage 2. MODPOST make[2]: Leaving directory `/lib/modules/2.6.11-1.27_FC3.huntsmp/build' make[1]: Leaving directory `/home/hunt/stp/src/runtime/relayfs' make -w -C transport make[1]: Entering directory `/home/hunt/stp/src/runtime/transport' make -C /lib/modules/2.6.11-1.27_FC3.huntsmp/build include SUBDIRS=/home/hunt/stp/src/runtime/transport modules make[2]: Entering directory `/lib/modules/2.6.11-1.27_FC3.huntsmp/build' make[2]: Nothing to be done for `include'. Building modules, stage 2. MODPOST make[2]: Leaving directory `/lib/modules/2.6.11-1.27_FC3.huntsmp/build' make[1]: Leaving directory `/home/hunt/stp/src/runtime/transport' make -w -C stpd make[1]: Entering directory `/home/hunt/stp/src/runtime/stpd' make[1]: Nothing to be done for `all'. make[1]: Leaving directory `/home/hunt/stp/src/runtime/stpd' cd probes; ./build Building shellsnoop Building test4 Building where_func Building scf @endverbatim You might want to test things out. To do this: @verbatim > cd probes/shellsnoop > su > ./stp shellsnoop.ko @endverbatim Now from another shell, type some commands. You should see information about the command displayed in the shellsnoop window. Hit ^C to exit from a probe. To write your own probe, look through the example probes. You can start writing your own by editing this one or one of the examples. @include template.c */ /** @page io_page I/O Generally things are written to a "print buffer" using the internal functions _stp_print_xxx(). @code _stp_print ("Output is: "); _stp_printf ("pid is %d ", current->pid); _stp_printf ("name is %s", current->comm); @endcode before the probe returns it must call _stp_print_flush(). (This behaviour is expected to change soon!) This timestamps the accumulated print buffer and sends it to relayfs. When relayfs fills an internal buffer, the user-space daemon is notified data is ready and reads a big per-cpu chunk. The user-daemon (staprun) saves this data to a file named something like "stpd_cpu2". When the user hits ^c, a timer expires, or the probe module notifies staprun that it wants to terminate, staprun does "system(rmmod)" then collects the last output before exiting. As an option, if we want high-speed bulk per-cpu data, we can put \code #define STP_RELAYFS \endcode at the top of the module and all output will go over relayfs. In the SystemTap language, we will provide some simple functions to control the buffering policy, which will control the parameters to relayfs and staprun. */ /** @addtogroup string One of the biggest restrictions the library has is that it cannot put large things like strings on the stack. And allocating memory from within a probe is a very bad idea. It is also not a good idea to dynamically allocate space for strings with kmalloc(). That leaves us with statically allocated space for strings. This is what is implemented in the String module. Strings use preallocated per-cpu buffers and are safe to use (unlike C strings) because operations which manipulate them all check to prevent overflowing their allocated space. Every probe function that uses a string needs to call _stp_string_init() with a unique number. For example, here is a bit of code that grabs a string, puts a stack trace into it and then uses that for a map key. @code String str = _stp_string_init (0); _stp_stack_sprint (str, regs); _stp_map_key_str(map1, _stp_string_ptr(str)); @endcode If the same probe needs a another String, you would create it with @code String str = _stp_string_init (1); @endcode Be sure to declare how many strings you need the top of your sources, before including "runtime.h". @code #define STP_NUM_STRINGS 2 @endcode Note that STP_NUM_STRINGS should be set to the maximum number of strings a probe needs. Probes are per-cpu so many different probes can all call _stp_string_init(0) without fear that of collisions. Each CPU that could be in a probe will get a different buffer for String 0. */ /** @addtogroup lists A list is a special map which has internally ascending int64 keys. Adding a value to a list does not require setting a key first. Create a list with _stp_list_new(). Add to it with _stp_list_add_str() or _stp_list_add_int64(). You can read the list by calling _stp_list_size() and then using _stp_map_key_int64() with keys from 0 to the size. Or better yet, use foreach(). For example, if you have a list of strings called "mylist" @code struct map_node *ptr; foreach (mylist, ptr) _stp_print(_stp_get_str(ptr)); @endcode Clear it with _stp_list_clear(). */