1.如何在命令行传递给脚本参数?
在testsuit的例子里,eventcount.stp脚本给出了一种很好的方式:
#!/usr/bin/stap global c probe %($# == 0 || $# > 32 %? begin %: never %) { printf("Please specify between 1 and 32 events to count.\n") exit() } //paramaterize up to 32 arguments probe %($# >= 1 %? $1 %: never %), %($# >= 2 %? $2 %: never %), %($# >= 3 %? $3 %: never %), %($# >= 4 %? $4 %: never %), %($# >= 5 %? $5 %: never %), %($# >= 6 %? $6 %: never %), %($# >= 7 %? $7 %: never %), %($# >= 8 %? $8 %: never %), %($# >= 9 %? $9 %: never %), %($# >= 10 %? $10 %: never %), %($# >= 11 %? $11 %: never %), %($# >= 12 %? $12 %: never %), %($# >= 13 %? $13 %: never %), %($# >= 14 %? $14 %: never %), %($# >= 15 %? $15 %: never %), %($# >= 16 %? $16 %: never %), %($# >= 17 %? $17 %: never %), %($# >= 18 %? $18 %: never %), %($# >= 19 %? $19 %: never %), %($# >= 20 %? $20 %: never %), %($# >= 21 %? $21 %: never %), %($# >= 22 %? $22 %: never %), %($# >= 23 %? $23 %: never %), %($# >= 24 %? $24 %: never %), %($# >= 25 %? $25 %: never %), %($# >= 26 %? $26 %: never %), %($# >= 27 %? $27 %: never %), %($# >= 28 %? $28 %: never %), %($# >= 29 %? $29 %: never %), %($# >= 30 %? $30 %: never %), %($# >= 31 %? $32 %: never %), %($# >= 32 %? $32 %: never %) { totalc <<< 1 if (target() && ! target_set_pid(pid())) next filteredc <<< 1 c[sprintf("%s(%d)",execname(),tid()), pn()]<<<1 } global totalc, filteredc probe begin { start_ms = gettimeofday_ms() if (target()) msg = sprintf ("pid %d + children", target()) else msg = "unfiltered"; printf("Starting event counting at %s, %s\n", tz_ctime(gettimeofday_s()), msg) } global start_ms probe end { printf("Finished event counting at %s.\n", tz_ctime(gettimeofday_s())) elapsed_ms = gettimeofday_ms() - start_ms if (elapsed_ms < 0) elapsed_ms=1 printf("Total time elapsed: %d ms, %d events total, %d filtered.\n", elapsed_ms, @count(totalc), @count(filteredc)) printf("%-25s %-30s %s\n", "TID", "EVENT", "COUNT (RATE Hz)") printf("%-25s %-30s %s\n", "---", "-----", "---------------") foreach([tid+, name] in c) printf("%-25s %-30s %d (%d.%02d)\n", tid, name, @count(c[tid, name]), (@count(c[tid,name])*100000/elapsed_ms)/100, (@count(c[tid,name])*100000/elapsed_ms)%100) }
你可以在命令行中输入:
sudo stap eventcount.stp syscall.open syscall.close syscall.read syscall.write
2.疑问????
21 probe kernel.function("inode_permission@fs/namei.c").return !, //感叹号是什么意思? 22 kernel.function("permission@fs/namei.c").return 23 { 24 if (!$return && squash_inode_permission[tid()]) //这个return 应该是那个probe的return 25 $return = -13 # -EACCES (Permission denied) 26 delete squash_inode_permission[tid()] 27 }
3.脚本中的不同的probe的执行次序问题:
# Array to hold the list of drop points we find global locations # Note when we turn the monitor on and off probe begin { printf("Monitoring for dropped packets\n") } probe end { printf("Stopping dropped packet monitor\n") } # increment a drop counter for every location we drop at probe kernel.trace("kfree_skb") { locations[$location] <<< 1 } # Every 5 seconds report our drop locations probe timer.sec(5) { printf("\n") foreach (l in locations-) { printf("%d packets dropped at %s\n", @count(locations[l]), symname(l)) } delete locations }
上面这个脚本中,可以看到probe end是第二个probe,是不是意味着下面的probe不会被执行呢?
当然不是,probe end只有在遇到Ctrl+C或者exit()时才会执行,而且,每个probe相当于一个监视模块,因此彼此之间相对比较独立,跟各个probe的顺序的关系不是很大。
4. 在testsuit中有para-callgraph.stp脚本,疑点如下:
%( $# > 1 %? if (tid() in trace) %)
$#是什么意思?(表示的是命令行中给出的参数的个数)
如果$#>1, 紧接着判断if(tid() in trace)...
5.
stap 命令行传递过来的字面值
字符值要么是由引号包含的字符串,要么是整数。关于整数的信息,请参阅 5.2.2 节,而字符
串的信息,请参阅 5.2.3 节。
命令行后面的脚本参数被扩展为字面值,可将它用于所有接受字面值的上下文中,但引用不存
在的参数编号将引致错误。
5.7.1 $1 ... $<NN> 将参数转换成整数
使用$1 ... $<NN> 将命令行参数转换成整数字面值。
@1 ... @<NN> 将参数转换成字符串
@1 ... @<NN> 将命令行参数转换成字符串字面值。
以下述为例,假定该脚本的名字为 example.stp
probe begin { printf("%d, %s/n", $1, @2) }
运行如下:
# stap example.stp 10 mystring
那么,$1 会被替换成 10 ,而@2 会被替换成"mystring" ,结果输出:
10, mystring
6.
打印目标变量
在.return中打印return值
printf("return = %d", $$return);注意,这个只能在.return中使用
syscall.fork中打印传递进来的参数的值:
printf("%s\n", $$parms);
但是如何打印函数中指定的变量的值?
printf("trace = %d\n", $trace);
As code evolves the target variables available may change. The @defined makes it easier to handle
those variations in the available target variables. The @defined provides a test to see if a particular
target variable is available. The result of this test can be used to select the appropriate expression
但是,有的时候会出现找不到指定变量的情况,这个是systemtap的原因。。。
printf("%s", $$locals);这个会将函数中所有的变量的值打印,注意这个是运行到该行时探寻到的变量的值。
如何插桩到函数的指定行?
probe kernel.statement("do_fork@kernel/fork.c+30");这样就在do_fork+30行处插入了一个桩
7.
/**
* sfunction kernel_string - Retrieves string from kernel memory
* @addr: The kernel address to retrieve the string from
*
* Description: This function returns the null terminated C string
* from a given kernel memory address. Reports an error on string
* copy fault.
*/
@hist_log可以打印你存储在static aggregate类型中数据(参见脚本deviceseeks.stp)
9.
在blk_stat.stp脚本中用到了@entry()操作:
A new operator, @entry, is available for automatically saving an expression at entry time for use in a .return probe.