1.[root@localhost ~]# stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}' Pass 1: parsed user script and 85 library script(s) using 146900virt/23668res/3024shr/21332data kb, in 130usr/40sys/183real ms. Pass 2: analyzed script: 1 probe(s), 1 function(s), 3 embed(s), 0 global(s) using 257648virt/78000res/6100shr/71736data kb, in 510usr/870sys/2099real ms. Pass 3: using cached /root/.systemtap/cache/e2/stap_e2a36f2dcc498d9e1b0e44a8fa8004fa_1020.c Pass 4: using cached /root/.systemtap/cache/e2/stap_e2a36f2dcc498d9e1b0e44a8fa8004fa_1020.ko Pass 5: starting run. read performed Pass 5: run completed in 10usr/40sys/344real ms. 2.[root@localhost ~]# uname -m x86_64 3.[root@localhost ~]# uname -r 2.6.18-128.el5 4.[root@localhost ~]# uname -a Linux localhost.localdomain 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64 x86_64 x86_64 GNU/Linux 5.stap -r kernel_version script -m module_name stap -r 2.6.18-128.el5 -e 'probe vfs.read {exit()}' -m simple 生成simple.ko staprun simple.ko 6. [root@localhost ~]# echo "probe timer.s(10) {exit()}" | stap -v - 说明:To instruct stap to read a SystemTap script from standard input, use the - switch instead of the file name 7.stap -e 'probe module("ext3").function("*") {println(execname()," ",pid()) }' 8.stap -e 'probe timer.s(4) {println(execname()," ",pid()) }' 9.stap -e 'probe begin{printf ("hello world\n"); exit() }' 10.stap -e 'probe syscall.open { printf("%s(%d) open\n", execname(), pid()) }' 11.[root@localhost ~]# cat >thread_indent.stp probe kernel.function("*@net/socket.c").call { printf ("%s -> %s\n", thread_indent(1), probefunc()) } probe kernel.function("*@net/socket.c").return { printf ("%s <- %s\n", thread_indent(-1), probefunc()) } [root@localhost ~]# stap thread_indent.stp 0 pcscd(4230): -> sock_poll 13 pcscd(4230): <- sock_poll 0 pcscd(4230): -> sock_poll 6 pcscd(4230): <- sock_poll 12. [root@localhost ~]# cat 2.stp probe syscall.* { if(pid() == target()) printf("%s\n", name) } stap 2.stp -x 1 13.[root@localhost ~]# stap 2.stp -c "ls -a" 14.[root@localhost ~]# stap -L 'kernel.function("vfs_read")' kernel.function("vfs_read@fs/read_write.c:248") $file:struct file* $buf:char* $count:size_t $pos:loff_t* 15. 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(); }' 16.打印刷 函数的(vfs_read)四个参数 [root@localhost ~]# stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms); exit(); }' file=0xffff81005429d0c0 buf=0x7fff98a0c270 count=0x2004 pos=0xffff8100363d3f50 说明: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. 17.打印数据结构 stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms$); exit(); }' file={ .f_u={...}, .f_dentry=0xffff81003492c660, .f_vfsmnt=0xffff810047fb70c0, .f_op=0xffffffff886594a0, .f_count={...}, .f_flags=34818, .f_mode=15, .f_pos=0, .f_owner={...}, .f_uid=0, .f_gid=0, .f_ra={...}, .f_version=0, .f_security=0x0, .private_data=0x0, .f_ep_links={...}, .f_ep_lock={...}, .f_mapping=0xffff8100346125c0 } buf="" count=8196 pos=-139637099405488 18.打印更详细的数据结构 stap -e 'probe kernel.function("vfs_read") {printf("%s\n", $$parms$$); exit(); }' file={.f_u={.fu_list={.next=0xffff810057a3e0f8, .prev=0xffff8100440d70c0}, .fu_rcuhead={.next=0xffff810057a3e0f8, .func=0xffff8100440d70c0 } }, .f_dentry=0xffff810032dbb150, .f_vfsmnt=0xffff810047fb70c0, .f_op=0xffffffff8865b040, .f_count={.counter=2}, .f_flags=34818, .f_mode=15, .f_pos=0, .f_owner={.lock={.raw_lock={.lock=16777216}}, .pid=0, .uid=0, .euid=0, .security=0x0, .signum=0}, .f_uid=0, .f_gid=0, .f_ra={.start=0, .size=0, .flags=0, .cache_hit=0, .prev_page=18446744073709551615, .ahead_start=0, .ahea 说明: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 18.@cast:类型转换 function task_state:long (task:long) { return @cast(task, "task_struct", "kernel<linux/sched.h>")->state } The function returns the value of the state field from a task_struct pointed to by the long task. The first argument of the @cast operator, task, is the pointer to the object. The second argument is the type to cast the object to, task_struct. The third argument lists what file that the type definition information comes from and is optional. 19.命令行参数传递 Use $ if you are expecting the user to enter an integer as a command-line argument, and @ if you are expecting a string. cat >4.stp probe kenel.function(@1) { printfln( execname(),@1) } [root@localhost ~]# stap stap 4.stp vfs_read 20. foo["tom"] = 23 foo["dick"] = 24 foo["harry"] = 25 device[pid(),execname(),uid(),ppid(),"W"] = devname All associate arrays must be declared as global, regardless of whether the associate array is used in one or multiple probes 21. global reads probe vfs.read { reads[execname()] ++ } probe timer.s(3) { foreach (count in reads) printf("%s : %d \n", count, reads[count]) } 22. probe timer.s(3) { foreach (count in reads- limit 10) printf("%s : %d \n", count, reads[count]) } reads:数组 limit 10: The limit 10 option instructs the foreach to only process the first ten iterations (that is, print the first 10, starting with the highest value). -:in descending order cat >16.stp global reads probe vfs.read { reads[execname()] ++ } probe timer.s(3) { printf("=======\n") foreach (count in reads-) printf("%s : %d \n", count, reads[count]) if(["stapio"] in reads) { printf("stapio read detected, exiting\n") } 23. global reads probe vfs.read { reads[execname(),pid()] <<< 1 } probe timer.s(3) { foreach([var1,var2] in reads) printf("%s (%d) : %d \n", var1, var2, @count(reads[var1,var2])) } @count(reads[execname()]) will return how many values are stored in each unique key in array reads. @sum(reads[execname()]) will return the total of all values stored in each unique key in array reads. the operator <<< $count stores the amount returned by $count to the associated value of the corresponding execname() in the reads array