トレースデバッガでは, 実行時のプログラム内部の情報を時系列に記録したファイルであるトレースファイルを読み込み, その読み込んだトレースを元にデバッグ実行を再現することができます.
通常のデバッガと比較するとトレースデバッガには以下のような特徴があります.
以降の操作はEC2インスタンスにログインし, Eclipseを起動した上で行ってください. EC2インスタンスへのログイン方法についてはこちらです.
まずは, ワークスペース上の TraceDebuggerTest プロジェクトを開き, D.java の6行目と E.java の7行目にブレークポイントを入れてください.
メニューバーの ウィンドウ → パースペクティブ → パースペクティブを開く → その他... → トレースデバッガ(順方向) でトレースデバッガのパースペクティブを開いてください.
実際に「トレースデバッガ(順方向)」のパースペクティブを開くと下図のような状態になります.
このパースペクティブは4つのビューで構成されており, 左上が呼び出しスタックビュー, 右上が変数ビュー, 左下がエディタ, 右下がブレークポイントビューになっています.
このデバッガは, プログラムを実際に実行した際に収集したトレースファイルを読み込むことで, トレース上でデバッグ実行を再現できるものです.
まずは, こちら側で事前に用意しておいたトレースファイルを読み込んでいただきます.
右下にあるブレークポイントビューのフォルダアイコンをクリックすると, ファイル選択のダイアログが開くので,
トレースファイル(C:\Users\userXX\runtime-EclipseApplication\TraceDebuggerTest\test.trace)を選択すると読み込むことができます.
トレースファイルを読み込んだら, 次はこのデバッガ上でデバッグ実行するために必要なブレークポイントを設定します.
D.java の6行目と E.java の7行目にブレークポイントが入ってることを確認したら,
ブレークポイントを右下にあるブレークポイントビューの「ブレークポイントをEclipseから取り入れる」アイコンをクリックします.
すると, ブレークポイントビュー上に, トレースデバッガ専用のブレークポイントが生成されます.
ただし, 読み込んだトレースファイル上に記録されていない行のブレークポイントは取り込まれません.
ブレークポイントを生成したら, 右下のブレークポイントビューの「デバッグ」アイコンをクリックすると, トレースデバッガのデバッグ実行が開始されます.
最初は, 有効なブレークポイントが入っている行のうち, トレースの時系列上で最初に遭遇する行まで実行が進み, そこで実行が一時停止します.
ここでは, D クラスの passB(B) メソッドの6行目が該当しているため, そこまで実行が進んだ状態で一時停止しています.
デバッグ実行中の状態で, 右下のブレークポイントビューの「終了」アイコンをクリックすると, デバッグ実行が停止します.
再びデバッグアイコンをクリックしてデバッグ実行し, D.java の6行目で一時停止している状態にしてください.
一時停止の状態で, 右下のブレークポイントビューの「再開」アイコンをクリックすると, 有効なブレークポイントが入っている行のうち,
現在の実行時点以降で最初に遭遇する行にまで実行が進み, そこで実行が再び一時停止します.
もし, 該当するブレークポイントがなかった場合は, そのままデバッグ実行が終了します.
ここでは, E クラスの setC(C) メソッドの7行目が該当しているため, そこまで実行が進んだ状態で一時停止します.
いったん終了アイコンを押してデバッグ実行を終了したあと, 再びデバッグアイコンをクリックしてデバッグ実行し, D.java の6行目で一時停止している状態にしてください.
左上の呼び出しスタックビューには, 現在一時停止しているメソッドをトップとしたメソッド呼び出し列のスタックが表示されています.
表示されているメソッドシグ二チャをクリックすることで, 呼び出し元のスタックフレームや呼び出し先のスタックフレームを見ることができ, エディタに表示されているソースコードも連動して切り替わります.
もう一度, 呼び出しスタックビュー上のスタックトップにある「D.passB(B) 行: 6」を選択し, エディタ上で D.java が開いている状態にしてください.
トレースデバッガでは, トレースファイルにステートメント単位で記録された実行時情報を元に, 実行を少しずつ進めていくことができます.
ここで, ステートメントは行よりも細かい単位であることに注意してください.
右下のブレークポイントビューの「ステップオーバー」アイコンをクリックすると, 実行を行単位で進めます.
なお, 呼び出し先のメソッドがあったとしても, その呼び出し先のメソッドに入ることはありません.
ここでは, ステップオーバーによって, D クラスの passB(B) メソッドの6行目から7行目へと実行を進めます.
右下のブレークポイントビューの「ステップイン」アイコンをクリックすると, 実行をステートメント単位で進め,
呼び出し先のメソッドがある場合はその呼び出し先のメソッドに入ります.
ここでは, ステップインによって, 呼び出し先である B クラスの getC() メソッドへ入っていきます.
右下のブレークポイントビューの「ステップリターン」アイコンをクリックすると, 呼び出し元のメソッドに復帰するまで実行を進めたうえで,
その呼び出し元のメソッド内で次のステートメントにまで進めます.
ここでは, ステップリターンによって, 呼び出し元のメソッドである D クラスの passB(B) メソッドに復帰し,
呼び出し元では B.getC() の次のメソッド呼び出しステートメントである E.setC(C) の直前にまで実行を進めます.
いったん終了アイコンをクリックしてデバッグ実行を終了したあと, 再びデバッグアイコンをクリックしてデバッグ実行し, D.java の6行目で一時停止している状態にしてください.
そのあと, ステップオーバーを1回押して7行目にまで進んだ状態にしてください.
右下のブレークポイントビューの「ステップネクスト」アイコンをクリックすると, 実行をステートメント単位で進めます.
「ステップイン」とは違い, こちらは呼び出し先のメソッドがあったとしても, その呼び出し先のメソッドには入ることはありません.
「ステップオーバー」では行単位で実行が進んでしまいますが, 「ステップネクスト」ではより細かいステートメント単位で同一メソッド実行内を進むことができます.
ここでは, ステップネクストによって, 現在のメソッド呼び出しステートメントである B.getC() の呼び出し先には入らずに,
そのまま次のメソッド呼び出しステートメントである E.setC(C) の直前にまで実行を進めます.
いったん終了アイコンをクリックしてデバッグ実行を終了したあと, 再びデバッグアイコンをクリックしてデバッグ実行し, D.java の6行目で一時停止している状態にしてください.
右上の変数ビューでは, 現在のスタックフレームから見える仮引数やthisの値(値がオブジェクトへの参照である場合はそのクラス名とID)を確認できます.
値がオブジェクトへの参照である場合は, 参照先オブジェクト内部のフィールドの値も開いて確認することができます.
ここでは, thisの内部を見てみましょう.
なお, ローカル変数名とその値は, トレースファイルに記録されていないため表示されないことに注意してください.
また, 右上の変数ビューでは, 通常のデバッガとは異なり, 以下の特殊なケースの場合にも関連するオブジェクトが表示され, そのクラス名とIDが確認できます.
これで, 順方向トレースデバッガの説明は終了です.
終了アイコンをクリックしてデバッグ実行を終了した状態にしてください.
デバッグ実行が終了していることを確認したら, 右上にあるパースペクティブを右クリックし, 「トレースデバッガ(順方向)」のパースペクティブを閉じてください.