#1 はじめに
systemtapの使い方の続編です。
インストール方法やその他の使い方は、下記を参照ください。
SystemTapの使い方
SystemTapの使い方(グルモード編)
SystemTapの使い方(User-Space Probing)
SystemTapの使い方(tapset編)
本記事の説明は、説明を簡単にするため、すべてbegin
プローブ内でスクリプトを実行しました。
本記事の説明は、begin
以外のend
プローブ内や本体の部分でも実行できます。
#2 環境
VMware Workstation 14 Playerで作成した仮想マシンを使用しました。
仮想マシンのOS版数は以下のとりです。
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@server ~]# uname -r
3.10.0-957.el7.x86_64
#3 連想配列(Associative arrays)の使い方
連想配列とは、添え字にスカラー数値以外のデータ型(文字列型等)も使用できる配列のことです。
SystemTapの連想配列の構文は、配列名[インデックス]
になります。
さらに、インデックスはカンマ区切りで最大9個までの値を指定できます。
たとえば、test["Hello"]
やfoo[1,2,3,4,5,6,7,8,9]
のような配列を定義することができます。
##3.1 連想配列への値の代入方法、参照方法
配列testに10、配列fooに20を代入します。
そして、代入した値を表示してみます。
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
global foo
probe begin
{
test["Hello"] = 10
foo[1,2,3,4,5,6,7,8,9] = 20
printf("test=%d,foo=%d\n",test["Hello"], foo[1,2,3,4,5,6,7,8,9])
delete test
exit()
}
[root@server ~]# stap tp.stp
test=10,foo=20
##3.2 連想値(associated value)のインクリメント、デクリメント
配列testに10、配列fooに20を代入します。
次に、testは1インクリメント、fooは1デクリメントします。
そして、連想値を表示してみます。
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
global foo
probe begin
{
test["Hello"] = 10
foo[1,2,3,4,5,6,7,8,9] = 20
printf("test=%d,foo=%d\n",test["Hello"], foo[1,2,3,4,5,6,7,8,9])
test["Hello"] ++
foo[1,2,3,4,5,6,7,8,9] --
printf("test=%d,foo=%d\n",test["Hello"], foo[1,2,3,4,5,6,7,8,9])
delete test
exit()
}
[root@server ~]# stap tp.stp
test=10,foo=20
test=11,foo=19
##3.3 繰り返しの使い方(foreach)
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test[1, "Hello"] = 30
test[2, "Hello"] = 10
test[3, "Hello"] = 20
foreach ([a,b] in test) {
printf("a=%d,b=%s,test=%d\n",a,b,test[a,b])
}
delete test
exit()
}
[root@server ~]# stap tp.stp
a=1,b=Hello,test=30
a=2,b=Hello,test=10
a=3,b=Hello,test=20
##3.4 繰り返しの使い方(降順に表示する方法)
配列testの第1インデックスをキーに降順に連想値を表示してみます。
降順に表示するため、[a,b]
を[a-,b]
に変更します。
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test[1, "Hello"] = 30
test[2, "Hello"] = 10
test[3, "Hello"] = 20
foreach ([a-,b] in test) {
printf("a=%d,b=%s,test=%d\n",a,b,test[a,b])
}
delete test
exit()
}
[root@server ~]# stap tp.stp
a=3,b=Hello,test=20
a=2,b=Hello,test=10
a=1,b=Hello,test=30
今度は、配列testの連想値をキーに降順に連想値を表示してみます。
降順に表示するため、test
をtest-
に変更します。
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test[1, "Hello"] = 30
test[2, "Hello"] = 10
test[3, "Hello"] = 20
foreach ([a,b] in test-) {
printf("a=%d,b=%s,test=%d\n",a,b,test[a,b])
}
delete test
exit()
}
[root@server ~]# stap tp.stp
a=1,b=Hello,test=30
a=3,b=Hello,test=20
a=2,b=Hello,test=10
##3.5 連想配列がキーを持つかどうかを判定する方法
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test[1, "Hello"] = 30
test[2, "Hello"] = 10
test[3, "Hello"] = 20
if([1,"Hello"] in test)
printf("1000\n")
if([2,"Hello"] in test)
printf("2000\n")
if([3,"Hello"] in test)
printf("3000\n")
delete test
exit()
}
[root@server ~]# stap tp.stp
1000
2000
3000
#4 統計集計 (Statistical Aggregates) の使い方
統計集計に値を追加するには、演算子<<<
を使用します。
##4.1 個数を求める方法(@count
)
配列testに10を代入してみます。
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test[100] <<< 10
printf("count=%d\n", @count(test[100]))
delete test
exit()
}
[root@server ~]# stap tp.stp
count=1
配列testに10と20を代入してみます。
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test[100] <<< 10
test[100] <<< 20
printf("count=%d\n", @count(test[100]))
delete test
exit()
}
[root@server ~]# stap tp.stp
count=2
##4.2 最小(@min
)、最大(@max
)、平均(@avg
)、合計(@sum
)、を求める方法
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test["hello"] <<< 10
test["hello"] <<< 20
test["hello"] <<< 30
printf("count=%d,min=%d,max=%d,avg=%d,sum=%d\n",
@count(test["hello"]),
@min(test["hello"]),
@max(test["hello"]),
@avg(test["hello"]),
@sum(test["hello"])
)
delete test
exit()
}
[root@server ~]# stap tp.stp
count=3,min=10,max=30,avg=20,sum=60
#5 ヒストグラフの描き方( Histogram extractors)
ヒストグラムの書き方を以下に示します。
##5.1 hist_linearの使い方(@hist_linear
)
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test <<< 100
test <<< 110
test <<< 700
print(@hist_linear(test, 0, 1000, 50))
delete test
exit()
}
[root@server ~]# stap tp.stp
value |-------------------------------------------------- count
0 | 0
50 | 0
100 |@@ 2
150 | 0
200 | 0
~
600 | 0
650 | 0
700 |@ 1
750 | 0
800 | 0
##5.2 hist_logの使い方(@hist_log
)
[root@server ~]# cat tp.stp
#!/usr/bin/stap
global test
probe begin
{
test <<< 100
test <<< 110
test <<< 700
print(@hist_log(test))
delete test
exit()
}
[root@server ~]# stap tp.stp
value |-------------------------------------------------- count
16 | 0
32 | 0
64 |@@ 2
128 | 0
256 | 0
512 |@ 1
1024 | 0
2048 | 0
#Z 参考情報
3.5. SYSTEMTAP でのアレイ演算
SystemTap Language Reference
mmitouの日記
SystemTap 3.2 SystemTap Beginners Guide