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 }
这个是脚本badname.stp中的内容。。。。
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.