LoginSignup
7
6

More than 5 years have passed since last update.

参考メモ/Javaのシステムコール呼び出しをstraceで確認するメモ

Posted at

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

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6