# トレースデバッガ (順方向)

## 説明

トレースデバッガでは, 実行時のプログラム内部の情報を記録したファイルであるトレースファイルを読み込み, その読み込んだトレースを元にデバッグ実行を行うことができます.
通常のデバッガと比較するとトレースデバッガには以下のような特徴があります.

- トレースを読み込むので, 何度でも同じ実行を再現できる.
- 操作の情報や画面の情報は残っていないので, その実行でユーザーがアプリケーションをどのように操作し, アプリケーションでどんな画面が表示されたかはわからない.
- オブジェクトIDがトレースに記録されているため, 何回実行しても同じオブジェクトのIDは変わらない.
- 全ての行をトレースに記録しているわけではないので, ステップ実行の際に途中の行を飛ばすことがある.
- 部分的に一行よりも細かい単位で記録しているので, 一行よりも細かい単位でのステップ実行も可能である.
- ローカル変数の値はトレースに記録されていないため表示されない.

以降の操作はEC2インスタンスにログインし, Eclipseを起動した上で行ってください. EC2インスタンスへのログイン方法についてはこちらです.

メニューバーの ウィンドウ → パースペクティブ → パースペクティブを開く → その他... → トレースデバッガ(順方向) でトレースデバッガのパースペクティブを開いてください.

実際に「トレースデバッガ(順方向)」のパースペクティブを開くと下図のような状態になります.
このパースペクティブは4つのビューで構成されており, 左上が呼び出しスタックビュー, 右上が変数ビュー, 左下がエディタ, 右下がブレークポイントビューになっています.

このデバッガは, プログラムを実際に実行した際に収集したトレースファイルを読み込むことで, トレース上でデバッグ実行を再現できるものです.
まずは, こちら側で事前に用意しておいたトレースファイルを読み込んでいただきます.
右下にあるブレークポイントビューのフォルダアイコンをクリックすると, ファイル選択のダイアログが開くので, トレースファイル(C:\Users\userXX\runtime-EclipseApplication\TraceDebuggerTest\test.trace)を選択すると読み込むことができます.

トレースファイルを読み込んだら, 次はこのデバッガ上でデバッグ実行するために必要なブレークポイントを設定します.
まずは, デバッグ実行を一時停止したい行に対して, 普通のデバッガを利用する際と同様の手順で Eclipse 標準のブレークポイントを入れていきます.
ここでは, TraceDebuggerTest プロジェクトの中の 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行目で一時停止している状態にしてください.
右上の変数ビューでは, 現在のスタックフレームから見える仮引数やフィールドの値(値がオブジェクトへの参照である場合はそのクラス名とID)を確認できます.
なお, ローカル変数名とその値は, トレースファイルに記録されていないため表示されないことに注意してください.

また, 右上の変数ビューでは, 通常のデバッガとは異なり, 以下の特殊なケースの場合にも関連するオブジェクトが表示され, そのクラス名とIDが確認できます.

- フィールド代入の直前 (参照元オブジェクトと参照先オブジェクトが確認できる)
- フィールド参照の直後 (参照元オブジェクトと参照先オブジェクトが確認できる)
- メソッド呼び出しの直前 (当該メソッドのレシーバのオブジェクトと引数のオブジェクトが確認できる)
- メソッド呼び出しの直後 (当該メソッドのレシーバのオブジェクトと戻り値のオブジェクトが確認できる)

ここでは, いったんステップオーバーを1回押して, D.java の7行目で一時停止している状態にしたあと,
変数ビュー上の「フィールド参照後」や「呼び出し前」を開き, それぞれに関連するオブジェクトが表示されていることを確認してください.
逆方向トレースデバッガの説明へ進む