ksino's diary

覚えたことを忘れないように、小さなことでも書いていく。

Bytemanを使ってみる

Bytemanを使って、実行中のアプリの情報を取得してみます。

入手と導入

ここからダウンロードできます。
http://www.jboss.org/byteman/downloads.html
適当なディレクトリに展開し、展開先ディレクトリを環境変数BYTEMAN_HOMEとして設定しました。ついでに、環境変数PATHに「%BYTEMAN_HOME%\bin」とか通しておけば便利ですかね。

情報取得対象のアプリ

しょーもないアプリです。

public class Plus {
    private static int plus(int a, int b) {
        return a + b;
    }
    
    public static void main(String[] args) {
        for (int i = 0; i < 5000; i++) {
            System.out.println(plus(i, i));
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }
        }
    }
}

Bytemanのルールを作成

こんな感じでルールを書きます。ファイルはtest.btmという名前で保存しました。

RULE entry
CLASS Plus
METHOD plus
AT ENTRY
IF TRUE
DO traceln("###---- plus begin [" + $1 + ", " + $2 + "]")
ENDRULE

RULE return
CLASS Plus
METHOD plus
AT RETURN
IF TRUE
DO traceln("### return=[" + $! + "]")
ENDRULE

RULE exit
CLASS Plus
METHOD plus
AT EXIT
IF TRUE
DO traceln("###---- plus end")
ENDRULE

意味は、、何となく分かるか。メソッド開始時に引数を出力、return時に戻り値を出力、メソッド終了時に目印を出力といったところですね。

アプリの起動とBytemanの適用

コマンドプロンプトを開き、アプリは普通に起動します。

> java Plus
0
2
4
6
8
 :

コマンドプロンプトをもう一つ開き、jpsコマンドでアプリのプロセスIDを調べます。

> jps
12764 Plus
13204 Jps

12764ですね。これに対して、bminstall.batを実行します。

> bminstall.bat 12764

とくに何も表示されず、終了しました。
続いてbmsubmit.batを実行します。

> bmsubmit.bat -l test.btm
install rule entry
install rule return
install rule exit

entry, return, exitの3ルールをインストールしたよーと表示されました。
インストール後、Plusアプリを実行していたコマンドプロンプトを見ると…

 :
###---- plus begin [124, 124]
### return=[248]
###---- plus end
248
###---- plus begin [125, 125]
### return=[250]
###---- plus end
250
 :

出てますね。
ルールの適用を止めるには、以下のようにします。

>bmsubmit.bat -u test.btm
uninstall RULE entry
uninstall RULE return
uninstall RULE exit

Plusアプリを実行していたコマンドプロンプトを見ると…

 :
256
258
260
262
 :

止まってました。

ちなみに、以下のように実行するとアプリ開始時にルールを適用できます。

java -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=script:test.btm Plus

Bytemanをうまく使えば、実行中のシステムのバグをこっそり修正とか、極悪なこともできそうですね。。