Attachment 'ScriptFestHandout.txt'

Download

   1 OLS SystemTap ScriptFest Handout
   2 --------------------------------
   3 
   4 What is SystemTap?
   5 
   6 SystemTap provides a simple scripting interface to poke into, gather,
   7 visualize, analyze and rectify systemic problems on Linux. It provides a
   8 safe and flexible mechanism to dynamically instrument a Linux system
   9 without modifying source code, recompiling or rebooting.
  10 
  11 SystemTap includes a rich set of predefined probes (tapsets) for key
  12 areas of the Linux OS.  Additional probes can be easily defined as
  13 needed. Customized tapsets can help in understanding, debugging,
  14 monitoring, and tuning of applications and subsystems.
  15 
  16 SystemTap QuickLinks:
  17 ---------------------
  18 Homepage           :: http://sourceware.org/systemtap/ 
  19 Wiki               :: http://sourceware.org/systemtap/wiki
  20 Tutorial           :: http://sourceware.org/systemtap/tutorial/
  21 Language Reference :: http://sourceware.org/systemtap/langref/
  22 Using Markers      :: http://sourceware.org/systemtap/wiki/UsingMarkers
  23 FAQ                :: http://sourceware.org/systemtap/wiki/SystemTapFAQ
  24 Report Bugs        :: http://sourceware.org/systemtap/wiki/HowToReportBugs
  25 OLS2008 Handout    :: http://sourceware.org/systemtap/wiki/ScriptFest
  26 
  27 How to Set Up SystemTap on Fedora
  28 ---------------------------------
  29 
  30 yum install systemtap kernel-devel
  31 yum --enablerepo=fedora-debuginfo --enablerepo=updates-debuginfo install
  32 							kernel-debuginfo
  33 
  34 Instructions for installing SystemTap on other distros are available on
  35 the SystemTap wiki.
  36 Refer http://sourceware.org/systemtap/wiki/SystemtapOnUbuntu to find
  37 instructions for installing SystemTap on Ubuntu.
  38 
  39 Building SystemTap from the Latest Sources
  40 ------------------------------------------
  41 a. Download SystemTap 
  42   git clone git://sources.redhat.com/git/systemtap.git systemtap
  43  	OR
  44   git clone http://sources.redhat.com/git/systemtap.git systemtap
  45  	OR
  46   wget ftp://sources.redhat.com/pub/systemtap/snapshots/latest.tar.bz2 
  47   tar jxf latest.tar.bz2 -C systemtap
  48 
  49 b. Download elfutils
  50  wget ftp://sources.redhat.com/pub/systemtap/elfutils/elfutils-<nnn>.tar.gz
  51  wget ftp://sources.redhat.com/pub/systemtap/elfutils/elfutils-portability.patch
  52  tar xzf elfutils-<nnn>.tar.gz
  53  cd elfutils-<nnn>
  54  patch -p1 < ../elfutils-portability.patch
  55  ELFUTILS_DIR=`pwd`
  56 
  57 c. Build and install 
  58 <Navigate to systemtap source directory.>
  59   ./configure --with-elfutils=$ELFUTILS_DIR
  60   make all check
  61 <This builds SystemTap and runs the testsuite. This takes several minutes.>
  62   make install (as root)
  63 
  64 Verifying SystemTap Installation
  65 ----------------------------------
  66 Run the following command as root:
  67   # stap -ve 'probe begin, kernel.function("do_fork") {log("Success!") exit()}'
  68 <stap should report 5 passes and print "Success!">
  69 
  70 Basics
  71 
  72 SystemTap scripts are written in an awk-like language.  Several sample
  73 scripts are shown later in this document.  A script specifies one or
  74 more events (probepoints) and the instrumentation code (handler) to be
  75 run when that event occurs.  SystemTap parses the script, pulls in
  76 referenced code from the various tapsets (script libraries), and
  77 consults debuginfo from the probed kernel and/or applications to
  78 generate a loadable kernel module.  SystemTap loads the module, which
  79 runs the designated handler each time an event of interest occurs.
  80 Output is directed to stdout of the stap command.  At session close,
  81 SystemTap unloads the module.
  82 
  83 SystemTap has built-in safety features.  Handler routines cannot run for
  84 too long, cannot allocate memory, and cannot perform unsafe operations.
  85 Locking is employed to ensure correctness. Resource limits can be
  86 adjusted using stap -D flags.  Guru mode trades off some safety features
  87 for more power. Scripts run in Guru mode can modify kernel data.
  88 
  89 Refer to the SystemTap Tutorial and the Language Reference guide for
  90 more details.
  91 
  92 Probes associate abstract events with statement blocks (handlers).
  93 Here are some commonly used types of probes.
  94 
  95 probe kernel.function("funcname")
  96 probe kernel.function("funcname").return
  97 probe module("modname").function("funcname")
  98 probe module("modname").function("funcname").return
  99 probe kernel.statement("funcname@pathname:lineno")
 100 probe kernel.statement(0xc0443322).absolute
 101 probe begin
 102 probe end
 103 probe timer.ms(500)
 104 [probe time.ms(5000) would be more clearly expressed as timer.sec(5)]
 105 probe timer.jiffies(N).randomize(M)
 106 
 107 Names of functions, modules, and files can contain wildcard characters
 108 to specify sets of related probepoints.
 109 
 110 Tapsets define auxiliary functions and probe "aliases."  An alias
 111 defines a probepoint and a set of values (e.g., function argument
 112 values) available to any script that uses that alias.  For example,
 113 syscall.read is an alias for kernel.function("sys_read"), and provides
 114 values such as fd and count.
 115 
 116 Variables can be integers, strings, associative arrays, or aggregates
 117 (explained below).  Each variable's type is inferred from its use.
 118 
 119 Comments can be shell-style, C++-style, or C-style.
 120 
 121 Operators use the same general syntax, semantics and precedence as in C
 122 and awk.
 123 
 124 SystemTap supports control-flow statements such as if-else, for, do,
 125 while, break, continue, foreach, next, and return.
 126 
 127 Arrays are implemented as fixed-size hash tables. Arrays are always
 128 global.
 129 
 130 Aggregates are used to collect statistics on numerical values.  Values
 131 are added to aggregates using the <<< operator.  Functions like @count,
 132 @sum, and @max can be used to report statistics from aggregate
 133 variables.
 134 
 135 Refer to the SystemTap Language Reference guide for more details.
 136 
 137 Help via Email/IRC
 138 ------------------
 139 For help with problems in SystemTap, you can send us an email at
 140 systemtap@sources.redhat.com, or join the Systemtap discussion
 141 at #systemtap on irc.freenode.net.
 142 
 143 Sample Scripts
 144 ------------------------------------------------------
 145 #! /usr/bin/env stap
 146 #
 147 # Trace entry and exit of all functions defined in kernel/sched.c.
 148 #
 149 probe begin {
 150   printf ("Collecting data... Type Ctrl-C to exit\n")
 151 }
 152 
 153 probe kernel.function("*@kernel/sched.c") {
 154   printf ("%s -> %s\n", thread_indent(1), probefunc())
 155 }
 156 probe kernel.function("*@kernel/sched.c").return {
 157   printf ("%s <- %s\n", thread_indent(-1), probefunc())
 158 }
 159 -------------------------------------------------------
 160 
 161 
 162 ---------------------------------------------------------
 163 #! /usr/bin/env stap
 164 
 165 # Using statistics and maps to examine kernel memory allocations
 166 
 167 global kmalloc
 168 
 169 probe kernel.function("__kmalloc") {
 170         kmalloc[execname()] <<< $size
 171 }
 172 
 173 # Exit after 10 seconds
 174 probe timer.ms(10000) { exit () }
 175 
 176 probe end {
 177         foreach (name in kmalloc) {
 178                 printf("Allocations for %s\n", name)
 179                 printf("Count:   %d allocations\n", @count(kmalloc[name]))
 180                 printf("Sum:     %d Kbytes\n", @sum(kmalloc[name])/1000)
 181                 printf("Average: %d bytes\n", @avg(kmalloc[name]))
 182                 printf("Min:     %d bytes\n", @min(kmalloc[name]))
 183                 printf("Max:     %d bytes\n", @max(kmalloc[name]))
 184                 print("\nAllocations by size in bytes\n")
 185                 print(@hist_log(kmalloc[name]))
 186                 printf("-------------------------------------------------------\n\n");
 187         }
 188 }
 189 ---------------------------------------------------------
 190 
 191 
 192 ---------------------------------------------------------
 193 #!/usr/bin/env stap
 194 
 195 # This is an example of profiling a specific command or pid.
 196 # It works by recording the time when a system call is entered
 197 # exited. 
 198 
 199 # Usage: prof.stp -c "top -n5"
 200 # Will start up "top" and after 5 iterations, will exit.
 201 #
 202 # Usage: prof.stp -x 3323
 203 # Will profile pid 3323 until it ^c is hit.
 204 #
 205 
 206 probe kernel.function("sys_*").call {
 207         if (target() == tid())
 208                 calltime[tid()] = gettimeofday_us()
 209 }
 210 
 211 probe kernel.function("sys_*").return {
 212         if (target() != tid())  next
 213         now = gettimeofday_us()  
 214         c = calltime[tid()]
 215         if (!c) next
 216         ttime[probefunc()] <<< now - c
 217         delete calltime[tid()]
 218 }
 219 
 220 probe end {
 221         printf("\n")
 222         foreach (x in ttime)
 223                 printf("%-20s\tcalls:%6d\tavg time (us):%5d\ttotal(us):%7d\n", 
 224                         x, @count(ttime[x]), @avg(ttime[x]), @sum(ttime[x]))
 225 }
 226 
 227 global calltime, ttime
 228 ---------------------------------------------------------
 229 
 230 ---------------------------------------------------------
 231 
 232 #! /usr/bin/env stap
 233 # rwtiming.stp
 234 #
 235 # This is a simple example to track the amount of time
 236 # spent doing reads and writes for the various programs running on the
 237 # system.
 238 
 239 probe begin { log("starting probe") }
 240 # Exit after 10 seconds
 241 probe timer.ms(10000) { exit () }
 242 
 243 global names, opens, reads, writes
 244 global entry_opens, entry_reads, entry_writes
 245 global time_opens, time_reads, time_writes
 246 
 247 probe kernel.function("sys_open") {
 248   t=gettimeofday_us(); p=pid(); e=execname();
 249   names[e]=1
 250   opens[e] ++ # plain integer
 251   entry_opens[p] = t;
 252 }
 253 
 254 probe kernel.function("sys_open").return {
 255   t=gettimeofday_us(); p=pid(); e=execname();
 256   time_opens[e] <<< t - entry_opens[p];
 257 }
 258 
 259 probe kernel.function("sys_read") {
 260   t= gettimeofday_us(); p =pid(); e=execname();
 261   names[e]=1
 262   reads[e] <<< $count # statistics
 263   entry_reads[p] = t;
 264 }
 265 
 266 probe kernel.function("sys_read").return {
 267   t=gettimeofday_us(); p=pid(); e=execname();
 268   time_reads[e] <<< t - entry_reads[p];
 269 }
 270 
 271 probe kernel.function("sys_write") {
 272   t=gettimeofday_us(); p=pid(); e=execname();
 273   names[e]=1
 274   writes[e] <<< $count # statistics
 275   entry_writes[p] = t;
 276 }
 277 
 278 probe kernel.function("sys_write").return {
 279   t = gettimeofday_us(); p = pid(); e=execname();
 280   time_writes[e] <<< t - entry_writes[p];
 281 }
 282 
 283 probe end {
 284   foreach(name+ in names) { # sort by names
 285     printf ("process: %s\n", name)
 286     if (opens[name]) {
 287       printf ("opens n=%d\n", opens[name])
 288       print (@hist_log(time_opens[name]))
 289     }
 290     if (@count(reads[name])) {
 291       printf ("reads n=%d, sum=%d, avg=%d\n",
 292          @count(reads[name]), # extracting stat results
 293          @sum(reads[name]),
 294          @avg(reads[name]))
 295       print ("read timing distribution\n")
 296       print (@hist_log(time_reads[name]))
 297     }
 298     if (@count(writes[name])) {
 299       printf ("writes n=%d, sum=%d, avg=%d\n",
 300          @count(writes[name]), # extracting stat results
 301          @sum(writes[name]),
 302          @avg(writes[name]))
 303       print ("write timing distribution\n")
 304       print (@hist_log(time_writes[name]))
 305     }
 306   }
 307 }
 308 ---------------------------------------------------------
 309 ---------------------------------------------------------
 310 #! /usr/bin/env stap
 311 # This is a simple example to demonstrate using markers thro SystemTap. 
 312 # Assuming a marker of the form "trace_mark(Marker1, "count %d", count);"
 313 # is placed in kernel code.
 314 
 315 probe begin { log("starting probe") }
 316 probe kernel.mark("Marker1") {print("Marker1 hit: %d\n", $arg1) }
 317 
 318 ---------------------------------------------------------
 319 
 320 ---------------------------------------------------------
 321 #! /usr/bin/env stap
 322 # Example to demonstrate handling markers that have the same name but
 323 # different format strings thro SystemTap. 
 324 # Assuming a marker of the form 
 325 # "trace_mark(Marker2, "count %d", count);"
 326 # "trace_mark(Marker2, "mesg %s", mesg);"
 327 # is placed in kernel code.
 328 
 329 probe begin { log("starting probe") }
 330 probe kernel.mark("Marker2").format(int) {print("Marker2 taking int hit: %d\n", $arg1) }
 331 probe kernel.mark("Marker2").format(char *) {print("Marker2 taking mesg hit: %s\n", $arg1) }
 332 ---------------------------------------------------------
 333 ---------------------------------------------------------
 334 #! /usr/bin/env stap
 335 #
 336 # Probe a process with pid $1 at its vaddr $2.
 337 #
 338 probe begin {
 339         log("Probing...")
 340 }
 341 probe process($1).statement($2).absolute.return,
 342         process($1).statement($2).absolute
 343 {
 344         log (pp())
 345 }
 346 
 347 ---------------------------------------------------------
 348 ---------------------------------------------------------
 349 #! /usr/bin/env stap
 350 #
 351 # Probe syscalls made by /bin/ls.
 352 #
 353 probe begin {
 354         log("Probing...")
 355 }
 356 probe process("/bin/ls").syscall { printf("|%d", $syscall) }
 357 ---------------------------------------------------------
 358 
 359 
 360 For more examples see testsuite/systemtap.examples directory 

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.