[Java] JVMTIを使ってJVMエージェントを作ってみる その4

エージェント側のスレッド起動

JVMTIを使ってJVMエージェントを作ってみる その1
JVMTIを使ってJVMエージェントを作ってみる その2
JVMTIを使ってJVMエージェントを作ってみる その3
とは少し趣向を変えて、エージェント側のスレッドを起動してみよう。

スレッドの起動自体はRunAgentThreadを使って起動するんだけど、これはJavaのスレッドとして起動するため、Agent_OnLoad時ではなく、JVMが起動してから呼び出す必要がある。
このため、VMInitのイベントハンドラを登録して、そこからRunAgentThreadを呼び出す形になる。

[Java] JVMTIを使ってJVMエージェントを作ってみる その3

ブレークポイントを設定する

JVMTIを使ってJVMエージェントを作ってみる その1JVMTIを使ってJVMエージェントを作ってみる その2に引き続き、今度はmainメソッドの先頭にブレークポイントを設定して、その時点のスレッドを表示してみよう。

ポイントはClassPrepareの中でSetBreakpointを使って、Breakpoint関数をmainメソッドの先頭(インデックス:0)のイベントハンドラとして登録しているところ。

[Java] JVMTIを使ってJVMエージェントを作ってみる その2

バイトコード表示

JVMTIを使ってJVMエージェントを作ってみる その1ではClassPrepareイベントハンドラを登録するところまでだったけど、今回はmainメソッドのバイトコードを表示するところまでやってみよう。

バイトコード表示にはバイトコードを取得する許可を与える必要があるため、AddCapabilitiesを使って、許可を与える。
    jvmtiCapabilities capabilities = { 0 };
    capabilities.can_get_bytecodes = 1;
    (*jvmti)->AddCapabilities(jvmti, &capabilities);

[Java] JVMTIを使ってJVMエージェントを作ってみる その1

JVMTI

Javaのコードを書き換えることなく、実行中にスレッドやヒープの情報を取得するツールはいろいろと存在する。
これらのツールのようにJavaの実行環境情報を実行中に取得するにはどうしたらいいんだろう。

JNIでクラス検索するときのパッケージ名ではJNIを使って、CからJVMを起動したけど、今度はJVMTIを使って、JVMから呼び出されるCのコードを作ってみよう。

JVITI(JVM Tool Interface)
https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html

※今回試した実行環境はJDK8, openSUSE 42.2