貰った Java プログラムが不可解な動きをするので、それを追うために jdb を使うことにした。
幸いにも今までそのレベルの問題に遭遇したことが無かったため、 jdb の使い方自体知らない。
勉強したのでその内容を記す。
環境
- OS: Windows 10 Pro
- Java: java version "1.8.0_201"
Java プログラム
テスト用にこんなプログラムを用意。
/**
* Main
*/
public class Main {
public static void main(String[] args) {
String message = getMessage();
System.out.printf("Hello, %s!\n", message);
}
private static String getMessage() {
return "mikoto2000";
}
}
コンパイル
-g
オプションを付けてコンパイル。
javac -g .\Main.java
Main.class
が生成される。
デバッグ
jdb
から対象プログラムを直接実行する方法と、 jdb
接続まちしているプログラムに jdb
で接続する方法(リモートデバッグ)がある。
jdb
から直接実行
jdb
の引数にクラスパスとクラス名を渡して実行。
> jdb -classpath . Main
jdbの初期化中...
> stop in Main.main
遅延したブレークポイントMain.main。
クラスがロードされた後に設定されます。
> run
Mainの実行
捕捉されないjava.lang.Throwableの設定
遅延した捕捉されないjava.lang.Throwableの設定
>
VMが開始されました: 遅延したブレークポイントMain.mainの設定
ヒットしたブレークポイント: "スレッド=main", Main.main()、行=6 bci=0
6 String message = getMessage();
main[1] next
>
ステップが完了しました: "スレッド=main", Main.main()、行=7 bci=4
7 System.out.printf("Hello, %s!\n", message);
main[1] cont
> Hello, mikoto2000!
アプリケーションが終了しました
リモートデバッグ
「TCP ポート 1234 で jdb
を待ち受けて、 jdb
が接続されるまでプログラムをスタートしない」 としようとする場合、次のような手順を実施。
デバッグ対象プログラム実行
以下コマンドでデバッグ対象プログラムを実行する。
java -cp . -agentlib:jdwp=transport=dt_socket,server=y,address=1234 Main
agentlib:jdwp
: Java Debug Wire Protocol を使用してデバッグしますよと宣言transport=dt_socket
: トランスポートに使うライブラリの指定server=y
: サーバーを起動して待ち受けますよという宣言address=1234
: 1234 番ポートで待ち受けますよと宣言
デバッガ実行
以下コマンドでデバッガを実行する。
jdb -attach 1234
Windows の場合は、 SocketAttach コネクタで接続する必要がある。
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=1234
あとは、直接プログラムを起動するのと同じですね。
以上。
細かい使い方は参考資料を参照のこと。
0 件のコメント:
コメントを投稿