2011年9月9日金曜日

Eclipseでデバッグ

ブレークポイント
ブレークポイントは、実行時にその位置に来る(あるいは指定された状況が発生する)と実行が停止(中断)されるもの。
以下のような方法でブレークポイントを設定・削除できる。
* Javaソースの各行の左側をダブルクリックすると、ブレークポイントが設定される(ブレークポイントのマークをダブルクリックすると削除される)。
* Ctrl+Shift+Bで、現在のカーソルがある行にブレークポイントが設定される(ブレークポイントがあれば削除される)。
* メニューバーの「実行(R)」→「ブレークポイントの切り替え(K)」で、現在のカーソルがある行にブレークポイントが設定される(ブレークポイントがあれば削除される)。
現在どのようなブレークポイントが設定されているかは、ブレークポイントビューで確認できる。
* (「Java」パースペクティブ)メニューバーの「ウィンドウ(W)」→「ビューの表示(V)」→「その他(O)」⇒「デバッグ」→「ブレークポイント」
* (「デバッグ」パースペクティブ)メニューバーの「ウィンドウ(W)」→「ビューの表示(V)」→「ブレークポイント」
ブレークポイントビューに表示されている各ブレークポイントを右クリックしてプロパティーを表示することで、細かい設定をすることも出来る。

デバッグ実行(開始)
普通にmain()で始まるプログラム(直接Eclipseから実行できるプログラム)をデバッグする(ブレークポイントで止まるような実行をする)為には、デバッグモードで実行する必要がある。
* メニューバーの「実行(R)」→「デバッグ(G)」
* ツールバーの「デバッグ」ボタン

リモートデバッグ
Eclipse上から実行しないJavaプログラム(つまりバッチやシェル等から実行するJavaプログラム)もデバッグすることが出来る。
1. 実行時のjavaコマンドの引数にリモートデバッグ用のオプションを指定する。
2. Eclipseのリモートデバッグを実行する。
3. すると、Eclipse上で設定したブレークポイントに従ってデバッグできる。

javaコマンドのリモートデバッグ用オプション
JDK1.4
java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y 実行クラス
java -Xrunjdwp:help
JDK1.5以降
java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y 実行クラス
java -agentlib:jdwp=help

Eclipseで外部Javaアプリのデバッグをする(デバッグ情報を受け取る)には、以下のようにデバッグ実行する。
1. パッケージ・エクスプローラーで、デバッグしたいクラス(jarファイル)が含まれているプロジェクトを選択する。
2. メニューバーの「実行(R)」→「デバッグの構成(B)」で「デバッグ構成」ダイアログを開く。
3. 左ペインの「リモートJavaアプリケーション」を右クリックし、「新規」を選ぶ。
4. 「接続プロパティー(E)」の「ポート」に、JDWPのaddressで指定したポートを設定する。
5. 設定したリモートデバッグを実行する。

デバッグ操作
実行が停止(実行中断)されると、Eclipse上で色々操作することが出来る。

Shift + F5
ステップ・フィルターの有効・無効を切り替える。
ステップ・フィルターは、ステップ実行(?)で入る必要の無いクラスを指定するもの。java.*とかjavax.*等を想定しているらしい。
メニューバーの「ウィンドウ(W)」→「設定(P)」⇒「Java-デバッグ-ステップ・フィルター」でフィルターしたいクラスを指定する。
全てのインスタンス
 
ソース上でクラスを選択して右クリック→「すべてのインスタンス(T)」
Ctrl + Shift + N
指定されたクラスのインスタンスを全て表示する。
強制リターン
 
(ソース上で値を選択して)右クリック→「強制リターン(F)」
Alt + Shift + F
(Eclipse3.3からの新機能で、JDK1.6以降でしか使えないらしい)
現在のメソッドから即座にreturnする。
ソース上で選択していた箇所の値が戻り値となる。型が違っていたらエラーになってreturnできない。
戻り型がvoidのメソッドの場合は特に値を指定する必要は無い。
監視
 
ソース上で変数(や式)を選択して右クリック→「監視(T)」
 
選択した変数や計算式を「式」ビューに("監視式"として)追加する。
インスペクション
 
ソース上で変数や式を選択して右クリック→「インスペクション(E)」
Ctrl + Shift + I
選択した式の演算結果をポップアップで表示する。
ここでCtrl+Shift+Iを押すと、選択している式が「式」ビューに("インスペクション式"として)追加される。
※選択した式の中にメソッドがあれば、それも実行されるので注意
表示
 
ソース上で変数や式を選択して右クリック→「表示(Y)」
Ctrl + Shift + D
選択した式の演算結果をポップアップで表示する。
ここでCtrl+Shift+Dを押すと、選択している式と演算結果が「表示」ビューに表示される。
※選択した式の中にメソッドがあれば、それも実行されるので注意
実行
 
ソース上で式や文を選択して右クリック→「実行(X)」
Ctrl + U
選択した式や文を実行する。
(メソッドを呼び出したり変数に値をセットしたり出来る)
(ただし、return文を実行してもメソッドから抜けるわけではない)
指定行まで実行
 
ソース上の行を右クリック→「指定行まで実行(L)」
Ctrl + R
実行を再開し、ソース上のカーソルがある行(=指定行)まで来たら停止する。
(途中で他のブレークポイントにより停止することもある)
(if文等による分岐で指定行を通らない場合は、そのまま処理が続行されてゆく…)
ステップ実行中にfor文等のループに来て、そこを抜けたい場合に便利。
インスペクションと表示は機能が似ているので、使い分けがいまいち分からないが…。

「変数」ビュー
現在のメソッドから参照できる変数(ローカル変数・フィールド等)全ての値を一覧表示するビュー。
デバッグパースペクティブではデフォルトで表示される(と思う)が、メニューバーの「ウィンドウ(W)」→「ビューの表示(V)」→「変数」で表示することが出来る。
変数名に対しその値が表示される。プリミティブ型やStringの場合は、中身がそのまま表示される。
それ以外の参照型の場合はクラス名が表示される。この場合、変数名の欄が折りたたみになってフィールドが表示できるようになっているので、それを追っていけば中を確認することが出来る。
また、下部のペインに(たぶんtoString()を呼んだ結果の)値が表示される。
また、右クリック→「監視式の作成(T)」で「式」ビューに監視式として追加することも出来る。
「変数」ビューでは、プリミティブ型やStringの場合、値欄をクリックすれば値を変更することが出来る。
それ以外の参照型の場合でも、右クリック→「値の変更(C)」で値を変更することが出来る。
例えばString配列なら「new String[]{ "abc", "def" }」といった具合。

「式」ビュー
監視式やインスペクション式を表示するビュー。
メニューバーの「ウィンドウ(W)」→「ビューの表示(V)」→「式」で表示することが出来る。
変数や式を「式」ビューに追加しておくと、それらが一覧表示される。
個々の式を選択すると、右側にその値が表示される。参照型の場合、たぶんtoString()を呼んだ結果が返る。
監視式の追加は、右クリック→「監視式を追加(A)」や、インスペクション操作から行う。
インスペクション式の場合、右クリック→「監視式に変換(W)」で監視式に変更できる。
式には「変数のみ」だけでなく、演算やメソッド呼び出し、果ては文を書くことも出来る。
例えばMapの変数mapに対し、以下のような監視式が定義できる。
map
map.size()
new java.util.TreeMap(map)
StringBuilder sb = new StringBuilder();
for (Object key : map.keySet()) {
if (sb.length() > 0) sb.append(", ");
sb.append(key);
sb.append("=\"");
sb.append(map.get(key));
sb.append("\"");
}
return sb;
なお、変数は、現在表示中のメソッドのスコープから見られる変数が使われる。
(つまり、同名の変数であっても、デバッグ中のメソッドによってはローカル変数だったり親クラスのフィールドだったりする)
監視式の削除はDeleteキーまたは右クリック→「除去(O)」で行える。

「表示」ビュー
変数の内容や式の演算結果を一時的に表示するビュー。
表示する操作を行えば自動的に出てくるが、メニューバーの「ウィンドウ(W)」→「ビューの表示(V)」→「 表示」で表示することも出来る。
表示ビューの中は自由に編集する(Javaソースを書く)ことが出来る。
そして、ここで書いたソースも(選択して右クリックからメニューを開くことにより)インスペクション・表示・実行・監視・強制リターンに使うことが出来る!
変数の値を変更する例
n = 1
↑表示ビューに上記の内容を書いて全選択(Ctrl+A)して実行(Ctrl+U)すると、変数に値をセットすることが出来る。
新しいオブジェクトを作って強制リターンする例
Map m = new HashMap();
m.put("ZZZ", "zzz");
returm m;
↑Mapを返すメソッドの中で停止させ、表示ビューに上記の内容を書いて全選択(Ctrl+A)して強制リターンさせると、このマップを返した状態になる。
例外を発生させる例
throw new RuntimeException("zzz");
↑全選択(Ctrl+A)して実行(Ctrl+U)すると、例外を発生させることが出来る。
 その際の(スタックトレースの)例外発生箇所は、デバッグで停止していた行になる。

0 件のコメント:

コメントを投稿