OpenJDK+SystemTapでトラブル解析はここまでできる!Java on Linuxを鬼凄ネイティブデバッグ!(前篇)(3/3 ページ)

» 2011年09月22日 00時00分 公開
[末永恭正NTT OSSセンタ]
前のページへ 1|2|3       

OpenJDK+SystemTapを動かしてみよう

 ここまでOpenJDKとSystemTapの概要について説明しました。今回は「Hello World」的なサンプルとして、「java -version」コマンド実行時に、Javaランチャー(javaコマンド)が明示的にロードするクラスを列挙してみます。

Javaランチャーとは?

 「Javaランチャー」とは、JavaVMインスタンスを作成して、指定されたクラスのmainメソッドを呼び出すだけのJNIアプリケーションです。

 通常は引数に与えられたクラス名や、JARの「マニフェスト(Main-Class)」に書かれているクラスをFindClass()関数でロードし、GetStaticMethodID()関数でmainメソッドのメソッドIDを取得して、CallStaticVoidMethod()関数で呼び出します。通常のJNI関数からJavaの戻り値のないstaticメソッドを呼び出す手順と変わりありません。

動作を確認する環境

 今回は以下の環境で動作を確認しました。OpenJDKは2011年8月時点での最新版を使用しています。

  • OS:Red Hat Enterprise Linux Server 6.1(x86_64)
  • SystemTap:systemtap-1.4-6.el6.x86_64(※インストールメディア同梱)
  • OpenJDK:java-1.6.0-openjdk-1.6.0.0-1.39.1.9.8.el6_1.x86_64(※RHSA-2011:0856-1のエラータを適用)

 なお、OpenJDKとSystemTapを組み合わせて使用するには、最低でもOpenJDKの「debuginfo」パッケージが必要です。今回のOpenJDKに対応するdebuginfoパッケージは「java-1.6.0-openjdk-debuginfo-1.6.0.0-1.39.1.9.8.el6_1.x86_64」です。忘れずにインストールしてください。

実行してみる

 コンソールにrootユーザーで、以下のコマンドを入力します。使用するコマンドは「stap」という、SystemTapのコマンドです。

クリックで拡大します

 上記はJNI関数FindClass()の入りにプローブを掛け(【1】)、変数clazzの内容を出力する(【2】)スクリプトをワンライナーで書いています(「-e」オプション)。情報の出力に使用している「println()」関数はJavaのSystem.out.println()メソッドと同様、指定された引数の内容を出力後、改行します。

 最後に、このプローブ対象のコマンドとして「java -version」を渡しています(【3】:「-c」オプション)。

 実行結果は以下のようになります。-versionオプションを付加しただけでも、さまざまなJavaクラスが明示的にロードされていることが分かります。

クリックで拡大します

 -versionオプションを指定した場合、そこで表示されるバージョン情報は「sun.misc.Version.print()で」標準エラー出力に出力されます。そのため、FindClass()のプローブで「sun/misc/Version」が検知されました(※JNIなので、パッケージのデリミタはドットではなく、スラッシュになります)。

hotspot.jni.FindClassで取得できる項目

 今回サンプルで使用した、hotspot.jni.FindClassプローブで使用できる4つの変数の一覧を以下に示します。

  1. name
    固定値で「FindClass」が入っている
  2. env
    FindClass()の第1引数(env)の値。使用したJNIEnvへのポインタ
  3. clazz
    FindClass()の第2引数(name)の値。ロードする完全修飾クラス名
  4. probestr
    プローブ呼び出し時の概要の文字列表現

次回は、OpenJDK+SystemTapの5つの使用例

 今回は「OpenJDK+SystemTapの組み合わせで何ができるか?」を中心に説明しました。HotSpot VMに埋め込まれたプローブポイントを活用することで、ソースコードに手を加えずに、VMや(クラスライブラリを含む)JNI実装を深いレベルでデバッグ可能になります。

 プローブポイントはVM内で定義された個所だけでなく、libc内の任意の関数や(SystemTap本来の機能である)カーネル内関数など、さまざまな所に仕掛けられます。

 ぜひお手元のマシンで、Javaアプリケーションがネイティブレベルでどのように動作しているのか、確認してみてください。

 次回は、以下のようなOpenJDK+SystemTapの使用例を5つ紹介します。

  1. GC動作状況の取得
  2. 特定メソッドのプロファイリング
  3. 特定メソッド実行時のスタックトレース取得
  4. エンドポイントとのコネクション(ソケット)確認
  5. 競合するモニタオブジェクトの把握

前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。