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

## 説明

トレースデバッガでは, 実行時のプログラム内部の情報を記録したファイルであるトレースファイルを読み込み, その読み込んだトレースを元にデバッグ実行を行うことができます.
逆方向バージョンは, 先ほど操作していただいた順方向のトレースデバッガに, さらに以下の機能を追加したものです.

- ステップ系の実行(ステップオーバー、ステップイン、ステップリターン)を逆方向に行うステップバック系の機能
- 現在の実行時点を登録し, 任意のタイミングで登録した実行時点に移ることができる機能
- フィールドが現在参照しているオブジェクトや, コレクションから取得してきたオブジェクトに対して, そのオブジェクトが実際に代入または追加された時点まで遡る機能
- プログラム実行時のある時点でオブジェクトaとオブジェクトbが関連付けられたときに, それらのオブジェクトが別々の場所から接近してきて関連付けられるまでの過程を抽出する機能

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

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

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

順方向トレースデバッガのときと同様に, トレースファイル(C:\Users\userXX\runtime-EclipseApplication\TraceDebuggerTest\test.trace)を読み込んで,
ブレークポイント(D.java の6行目と, E.java の7行目)をEclipseから取り入れてください.
そのあと, デバッグアイコンをクリックしてデバッグ実行し, 再開ボタンを1回押して E.java の7行目で一時停止している状態にしてください.
このデバッガには, 「再開」を逆向きに行う機能があります.
ブレークポイントビューの「逆向きに再開」アイコンをクリックすると, 有効なブレークポイントが入っている行のうち,
現在の実行時点から実行を巻き戻して最初に遭遇する行まで実行が進み, そこで実行が再び一時停止します.
もし, 該当するブレークポイントがなかった場合は, そのままデバッグ実行が終了します.
ここでは, E.java の7行目で一時停止している状態から「逆向きに再開」アイコンをクリックしてください．
そうすると, D.java の6行目にまで実行が巻き戻されて再び一時停止します.

いったんステップオーバーを1回押して, D.java の7行目で実行が一時停止している状態にしてください.
このデバッガには, 「ステップオーバー」を逆向きに行う機能があります.
ブレークポイントビューの「ステップバックオーバー」アイコンをクリックすると, 実行を行単位で巻き戻します.
ここでは, ステップバックオーバーによって, D クラスの passB(B) メソッドの7行目から6行目へと実行を巻き戻します.

いったんステップオーバーを2回押して, D.java の8行目で実行が一時停止している状態にしてください.
このデバッガには, 「ステップイン」を逆向きに行う機能があります.
ブレークポイントビューの「ステップイン」アイコンをクリックすると, 実行をステートメント単位で巻き戻し,
呼び出し先のメソッドがある場合はその呼び出し先のメソッドに後ろから入ります.
ここでは, ステップバックインによって, ひとつ前の呼び出し先である E クラスの setC() メソッドへ入っていきます.
なお, 逆方向に戻っていく関係上, 呼び出し先メソッドの開始時点ではなく終了時点に現在の実行が移る点に注意してください.

このデバッガには, 「ステップリターン」を逆向きに行う機能があります.
ブレークポイントビューの「ステップバックリターン」アイコンをクリックすると, 呼び出し元からそのメソッドに入る直前まで実行を巻き戻します.
ここでは, ステップバックリターンによって, この E クラスの setC(C) メソッドが呼び出される直前の時点,
すなわち, 呼び出し元である D クラスの passB(B) メソッドの7行目まで実行を巻き戻します.

いったん, ステップバックインを1回押して, B.java の6行目で実行が一時停止している状態にしてください.
実行時点の登録ビューでは, 任意のタイミングで現在の実行時点を登録することができます.
ここでは, 現在の実行時点を登録するに, ビュー上にある追加ボタンをクリックしてください.
登録された実行時点はビュー上に一覧で表示されます.

また, 登録した実行時点へはいつでもジャンプすることができます
ビュー上に登録されている実行時点をクリックすると, その登録した場所に対応するソースコードがエディタ上で開きます.
また, ダブルクリックで選択するか, 選択した状態でジャンプボタンをクリックすると, 選んだ実行時点へと現在の実行時点が移ります.
ここでは, まずステップリターンを2回押して A.java の10行目で実行が一時停止している状態にしてください.
そのあと, ビュー上に登録されている実行時点をダブルクリックで選択するか, 選択した状態でジャンプボタンをクリックして,
実際に先ほど登録した B クラスの getC() メソッドの6行目に実際にジャンプすることを確認してください.

いったんステップオーバーを2回押して, D.java の8行目で実行が一時停止している状態にしてください.
変数ビューで this などを開き, フィールドを選択した状態で右クリックすると, ポップアップメニューが表示され,
「値の代入時点に飛ぶ」を選択すると, このフィールドで参照されているオブジェクトが実際に代入される直前の時点まで実行を遡ることができます.
ここでは, this を開いたあとにそのフィールド e をさらに開き, 表示されたフィールド c を右クリックして「値の代入時点に飛ぶ」を選択してください.
すると, このフィールド c に値が代入された時点である E クラスの setC(C) メソッドの6行目にまで実行が巻き戻されます.

変数ビュー上で「フィールド代入前」などを開き, その中にある参照先などを右クリックすると, ポップアップメニューが表示されます.
ここで, 「オブジェクトの接近過程抽出」を選択すると, 参照元となるオブジェクトと参照先となるオブジェクトがどのようにして接近してきたのかの過程を抽出することができます.

「オブジェクト接近過程」ビュー上の「開始時点」をクリックすると, 参照先側のオブジェクトがどのように接近してきたのかの過程について,
その開始時点となるメソッド実行に飛ぶことができます.

「オブジェクト接近過程」ビュー上の「参照先側」をクリックすると, 参照先側のオブジェクトがどのように接近してきたのかの過程について各時点に飛んで見ていくことができます.

「オブジェクト接近過程」ビュー上の「参照元側」をクリックすると, 参照元側のオブジェクトがどのように接近してきたのかの過程について各時点に飛んで見ていくことができます.

「オブジェクト接近過程」ビュー上の「参照時点」をクリックすると, 参照元側のオブジェクトが参照先側のオブジェクトを参照するようになる時点に飛ぶことができます.

実験開始の説明へ進む