Fedora17でsystemtapを実行する

Fedora17でsystemtapを実行出来るようにするまでの手順のメモ

環境は以下の通り。

$uname -rs
Linux 3.4.0-1.fc17.x86_64
$cat /etc/redhat-release 
Fedora release 17 (Beefy Miracle)
$stap -V
Systemtap translator/driver (version 1.7/0.153 non-git sources)
Copyright (C) 2005-2012 Red Hat, Inc. and others
This is free software; see the source for copying conditions.
enabled features: AVAHI LIBRPM LIBSQLITE3 NSS BOOST_SHARED_PTR TR1_UNORDERED_MAP NLS

1. debuginfoのインストール

debuginfoはリポジトリが別。
debuginfo用リポジトリを--enablerepoで有効にする。

$sudo yum install --enablerepo=fedora-debuginfo --enablerepo=updates-debuginfo kernel-debuginfo 

2. カーネルソースのインストール

ソースコードのダウンロードにはyumdownloaderを使う。ダウンロードしたソースは、rpmコマンドでインストールする。

$yumdownloader --source kernel
$sudo rpm -Uvh kernel-3.4.0-1.fc17.src.rpm

systemtap1.8になら、ここまでで動作するはず。
Fedora17のsystemtapは1.8になったので、次のパッチを当てる作業は無用になった。

3. パッチを当てる

systemtap1.7で実行すると、「エラー: ‘cpu_possible_map’ が宣言されていません (この関数内での最初の使用)」と言われる。
以下が実行時の様子。

# cat test.stp 
#!/usr/bin/stap

probe syscall.ioctl.return {
  exit();
}

# stap -v test.stp
Pass 1: parsed user script and 88 library script(s) using 205096virt/26816res/2984shr kb, in 140usr/10sys/155real ms.
Pass 2: analyzed script: 2 probe(s), 1 function(s), 2 embed(s), 0 global(s) using 375484virt/147872res/91620shr kb, in 530usr/40sys/567real ms.
Pass 3: translated to C into "/tmp/stap67oA7n/stap_b059bc31fd31b49db2a70e90d36fe453_6367_src.c" using 375484virt/147980res/91728shr kb, in 10usr/0sys/4real ms.
In file included from /tmp/stap67oA7n/stap_b059bc31fd31b49db2a70e90d36fe453_6367_src.c:21:0:
/usr/share/systemtap/runtime/stat.c: 関数 ‘_stp_stat_get’ 内:
/usr/share/systemtap/runtime/stat.c:214:2: エラー: ‘cpu_possible_map’ が宣言されていません (この関数内での最初の使用)
/usr/share/systemtap/runtime/stat.c:214:2: 備考: 未宣言の識別子は出現した各関数内で一回のみ報告されます
/usr/share/systemtap/runtime/stat.c: 関数 ‘_stp_stat_clear’ 内:
/usr/share/systemtap/runtime/stat.c:249:2: エラー: ‘cpu_possible_map’ が宣言されていません (この関数内での最初の使用)
make[1]: *** [/tmp/stap67oA7n/stap_b059bc31fd31b49db2a70e90d36fe453_6367_src.o] エラー 1
make: *** [_module_/tmp/stap67oA7n] エラー 2
WARNING: make exited with status: 2
Pass 4: compiled C into "stap_b059bc31fd31b49db2a70e90d36fe453_6367.ko" in 4760usr/910sys/5830real ms.
Pass 4: compilation failed.  Try again with another '--vp 0001' option.

このままでは実行出来ない。
http://sourceware.org/git/gitweb.cgi?p=systemtap.git;a=commit;h=e14ac0e274c6de3fee1f74cd190ec6248f28e559からpatchを落として、適用する。

#cp systemtap.git-e14ac0e274c6de3fee1f74cd190ec6248f28e559.patch /usr/share/systemtap
#cd /usr/share/systemtap
#patch -p1 < systemtap.git-e14ac0e274c6de3fee1f74cd190ec6248f28e559.patch

patching file runtime/map-stat.c
patching file runtime/map.c
patching file runtime/perf.c
patching file runtime/pmap-gen.c
patching file runtime/runtime.h
Hunk #1 succeeded at 47 (offset -10 lines).
patching file runtime/stat.c
patching file runtime/transport/procfs.c
can't find file to patch at input line 251
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/translate.cxx b/translate.cxx
|index fc4fb6e..ecc9931 100644
|--- a/translate.cxx
|+++ b/translate.cxx
--------------------------
File to patch: 
Skip this patch? [y] y
Skipping patch.
1 out of 1 hunk ignored

translate.cxxというファイルが元々/usr/share/systemtap/runtimeにないので、それだけスキップした。

メモのメモ
patchコマンドのp1オプションは、patchファイルに書かれているファイルパスのディレクトリを一階層分無視する。
例えば、パッチファイルにa/runtime/map-stat.cと書かれていれば、runtime/map-stat.cとのようにパスを扱う。

これでsystemtapが実行出来るようになった。

# stap -v test.stp 
Pass 1: parsed user script and 88 library script(s) using 205096virt/26816res/2984shr kb, in 160usr/20sys/183real ms.
Pass 2: analyzed script: 2 probe(s), 1 function(s), 2 embed(s), 0 global(s) using 375484virt/147872res/91620shr kb, in 530usr/30sys/565real ms.
Pass 3: using cached /root/.systemtap/cache/bc/stap_bc303dc0cbde60c4c04c0f7a2f5ed867_6367.c
Pass 4: using cached /root/.systemtap/cache/bc/stap_bc303dc0cbde60c4c04c0f7a2f5ed867_6367.ko
Pass 5: starting run.
Pass 5: run completed in 0usr/10sys/316real ms.