Javaアプリケーションがソケットやファイル入出力を行う際の、システムコール呼び出しをstraceでトレースしてみたメモです。
検証環境:
$ cat /etc/centos-release
CentOS Linux release 7.2.1511 (Core)
$ strace -V
strace -- version 4.8
$ java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)
straceしてみるJavaサンプル
- アプリケーション自体はスレッドを3つ使う。
- /dev/zero, /dev/urandom から 1秒間隔で32バイト読み込むのが2スレッド。
- mainスレッドではHOME環境変数のディレクトリ一覧を1秒間隔で読み込む。
StraceDemo.java
import java.io.*;
public class StraceDemo extends Thread {
final String file;
public StraceDemo(String file) {
this.file = file;
}
public void run() {
byte[] dummy = new byte[32];
try (InputStream is = new FileInputStream(file)) {
int c = 0;
while (true) {
int b = is.read(dummy);
System.out.println(this.file + ":" + c + ":" + b);
Thread.sleep(1000);
}
} catch (Exception ignore) {
}
}
public static void main(String[] args) throws Exception {
(new StraceDemo("/dev/zero")).start();
(new StraceDemo("/dev/urandom")).start();
File homedir = new File(System.getenv("HOME"));
while (true) {
File[] files = homedir.listFiles();
System.out.println("HOME : " + files.length + " entries.");
Thread.sleep(1000);
}
}
}
straceでJavaアプリをトレース
straceの説明と使い方は man 1 strace
参照。今回使うのは以下のオプション。
-f : fork(2)/vfork(2)/clone(2) で作られた子プロセスもトレースする。
-t : タイムスタンプをトレースに出力
-x : 非ASCII文字を16進数で表示
-e expr : トレースしたいシステムコールをフィルタ
-o filename : トレース結果をファイルに出力
-p pid : トレースしたいプロセスID
-P path : 指定したファイルパスについてのシステムコールのみトレース
-s len : 文字列表示の最大サイズ
複数スレッドのシステムコールをトレース
mainスレッドから作ったスレッドのシステムコールをトレースするため -f
オプションを指定する。
$ strace -f -t -x -s 1024 -o strace_demo1.log java StraceDemo
ファイル関連のシステムコールだけトレースしたい
-e trace=file
だけだとread(2)やwrite(2)、その他ファイルディスクリプタ関連のシステムコールをトレースできないので、追加で指定する。
$ strace -f -t -x -s 1024 -o strace_demo2.log -e trace=file,read,write,desc java StraceDemo
起動済みのマルチスレッドJavaアプリをトレース
-f
+ -p PID
で、そのプロセスIDだけでなく、PIDが等しいスレッドもまとめてトレースしてくれる。
$ strace -f -t -x -s 1024 -p (PID of target java) -o strace_demo3.log
あるファイルパスについてのシステムコールのみトレース
$ strace -f -t -x -s 1024 -o strace_demo4.log -e trace=file,read,write,desc -P /dev/zero java StraceDemo
参考URL
- strace コマンドの使い方をまとめてみた - sonots:blog
- 7 Strace Examples to Debug the Execution of a Program in Linux
- Using strace to attach to a multi-threaded process (like a JVM/Java) – ITSA Consulting, LLC