2007年4月18日水曜日

EclipseでJNIをデバッグする

前回、EclipseでJNIの開発について書いたが、その後デバッグをするにはどうするのかというのをゴリゴリとやっていたが、例のごとくはまってしまってので、忘れないように書いておくことにする。 まずは、JNIモジュールのデバッグは次のような基本手順を踏むということする。

  1. JNIのソースにブレイクポイントを設定
  2. 呼び出すJavaソースにブレイクポイントを設定
  3. Javaをデバッグ実行
  4. JNIモジュールをデバッガでアタッチ

まずはJavaのブレイクポイントは、System.LoadLibrary();を呼び出した後でかつJNIのブレイクポイントが呼び出される前に設定する。Javaのデバッグ実行でこの設定したブレイクポイントで止まった状態で、JNIモジュールをアタッチする。

JNIモジュールのデバッグ設定は、Eclipseの「構成およびデバッグ」のダイアログで、「ローカルアプリケーションへの接続」という構成で設定できる。このとき、アタッチの対象となるモジュール(ここではWin32なのでDLL)を「メイン」のC/C++アプリケーションというところに書くのだが、ここにはビルドしたモジュールを設定する(デフォルトだと「デバッグ/<DLLのファイル名>」)。

あと、「デバッガー」の項目のところは、「gdb/mi」を選択して、gdbのコマンドのところは、実行できる適切なパスが設定されていればよい。あと、このときに「詳細コンソールモード」というチェックをONにしておくと、デバッガーが何をしているのかわかるので最初のうちはONにしておいたほうがよいだろう。

この設定で指定したモジュール(DLL)がJavaから呼び出されないとアタッチできないので、Javaのデバッグ構成の管理で、引数のところでプログラムの引数かVMの引数のところで、「-Djava.library.path=<デバッグするモジュールのパス>」を設定をする。

これでEclipseからの操作でデバッグができる。DLLのデバッグで、gdbのアタッチ後に中断状態になるが、そのまま再開すればモジュールは実行される。

あとは、MinGWの固有だと思われるが、gdbのバージョンが古いとEclipseから投げるMIのコマンドの不一致か、ブレイクポイントがうまく設定されないようだった。そのため、MinGWからgdb6.xをダウンロードしてインストールすればよいようだ。

もうひとつ、これはうちの固有の問題かもしれないが、gdbでデバッグしようとすると「LdrAccessResource」のところでセグメンテイションエラーが発生して、gdbが落ちてしまう。これについては、いろいろ調べているものの解決方法がわからず、現状デバッグ不能である。どうやら、ntdllとgdbの相性の問題のようで詳細はわかりませんでした。

0 件のコメント: