<!DOCTYPE HTML> <html lang = "ja"> <head> <title>トレースデバッガ (順方向)</title> <meta charset = "UTF-8"> <link rel = "stylesheet" type = "text/css" href = "../../prettify.css"> <script type="text/javascript"> function init(param) { var course = "A"; if (param) { var c = getParam('course', param); if (c) course = c; } var next = document.getElementById("next"); next.href = "../Reverse/TraceDebugger_Reverse.html?course=" + course; } function getParam(name, url) { name = name.replace(/[\[\]]/g, "\\$&"); var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, " ")); } </script> </head> <body onLoad="init(location.search)"> <h1>トレースデバッガ (順方向)</h1> <hr> <h2>説明</h2> <p> このデバッガでは, プログラムの実行時情報が記録されたファイルであるトレースファイルを読み込み, その読み込んだトレースを元にデバッグ実行を行うことができます.<br> 通常のデバッガと比較した際のこのデバッガの特徴を下記に示します.<br> <ul> <li>トレースを読み込むので, 何度でも同じ実行を再現できる.</li> <li>操作の情報や画面の情報は残っていないので, その実行でユーザーがアプリケーションに対してどのように操作してアプリケーションでどんな画面が表示されたかはわからない.</li> <li>IDがトレースに記録されているため, 何回実行してもIDは毎回同じものになる.</li> <li>全ての行を記録しているわけではないので, ステップ実行の際に途中の行を飛ばすことがある.</li> <li>部分的に一行よりも細かい単位で記録しているので, 一行よりも細かい単位でのステップ実行も可能である.</li> <li>ローカル変数の値はトレースに記録されていないため表示されない.</li> </ul> </p> <p> <p class = "explanation"> メニューバーの Window → Perspective → Open Perspective → Other... → トレースデバッガ(順方向) でトレースデバッガのパースペクティブを開いてください.<br> <div class = "image"><img src = "./images/OpenPerspective.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/OpenPerspective_Forward_1.png" class = "halfSize"></div> </p> <p class = "explanation"> 実際に「トレースデバッガ(順方向)」のパースペクティブを開くと下図のような状態になります.<br> このパースペクティブは4つのビューで構成されており, 左上が呼び出しスタックビュー, 右上が変数ビュー, 左下がエディタ, 右下がブレークポイントビューになっています.<br> <div class = "image"><img src = "./images/OpenPerspective_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> このデバッガは, プログラムを実際に実行した際の情報を収集したトレースファイルを読み込むことで, トレース上でデバッグ実行を再現できるものです.<br> まずは, トレースファイルを読み込みます.<br> 右下にあるブレークポイントビューのフォルダアイコンをクリックすると, ファイル選択のダイアログが開くので, トレースファイルを選択すると読み込むことができます.<br> <div class = "image"><img src = "./images/OpenTraceFile_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/OpenTraceFile_Forward_2.png" class = "halfSize"></div> </p> <p class = "explanation"> トレースファイルを読み込んだら, 次はこのデバッガ上でデバッグ実行するために必要なブレークポイントを設定します.<br> まずは, デバッグ実行を一時停止したい行に対して, 普通のデバッガを利用する際と同様の手順で Eclipse 標準のブレークポイントを入れていきます.<br> それらのブレークポイントを入れ終わったら, 右下にあるブレークポイントビューの「ブレークポイントをEclipseから取り入れる」アイコンをクリックします.<br> すると, ブレークポイントビュー上に, このデバッガ専用のブレークポイントが生成されます.<br> ただし, 実際に読み込んだトレースファイルに記録されていない行については, このブレークポイントは生成されません.<br> <div class = "image"><img src = "./images/ImportBreakpoint_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/ImportBreakpoint_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> ブレークポイントを生成したら, 右下のブレークポイントビューの「デバッグ」アイコンをクリックすると, 実際にデバッグ実行が開始されます.<br> 最初は, 有効なブレークポイントが入っている行のうち, 時系列上で最初に実行された行にまで実行が進み, そこで実行が一時停止します.<br> この画像の場合では, D クラスの passB(B) メソッドの6行目が該当しているため, そこまで実行が進んだ状態で一時停止しています.<br> <div class = "image"><img src = "./images/Debug_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/Debug_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> デバッグ実行中の状態で, 右下のブレークポイントビューの「終了」アイコンをクリックすると, デバッグ実行が停止します.<br> <div class = "image"><img src = "./images/Terminate_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/Terminate_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> デバッグ実行中の状態で, 右下のブレークポイントビューの「再開」アイコンをクリックすると, 有効なブレークポイントが入っている行のうち,<br> 現在の実行時点よりも後の実行で最も近い行にまで実行が進み, そこで実行が再び一時停止します.<br> もし, 該当する行がなかった場合は, そのままデバッグ実行が終了します.<br> この画像の場合では, E クラスの setC(C) メソッドの7行目が該当しているため, そこまで実行が進んだ状態で一時停止します.<br> <div class = "image"><img src = "./images/Resume_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/Resume_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 左上の呼び出しスタックビューには, 現在一時停止している行をトップとしたメソッド呼び出しのスタックが表示されています.<br> 表示されているメソッドシグ二チャをクリックすることで, 呼び出し元のメソッドや呼び出し先のメソッドを見ることができます.<br> <div class = "image"><img src = "./images/CallStack_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/CallStack_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> このデバッガでは, トレースファイルに記録されたステートメント単位の実行時情報を元に, 実行を少しずつ進めていくことができます.<br> ここで, このステートメント単位は行単位よりも細かい粒度になっていることに注意してください.<br> 右下のブレークポイントビューの「ステップオーバー」アイコンをクリックすると, 実行を行単位で進めます.<br> なお, 呼び出し先のメソッドがあったとしても, その呼び出し先のメソッドに入ることはありません.<br> この画像の場合では, ステップオーバーによって, D クラスの passB(B) メソッドの6行目から7行目へと実行が進んでいます.<br> <div class = "image"><img src = "./images/StepOver_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/StepOver_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 右下のブレークポイントビューの「ステップイン」アイコンをクリックすると, 実行をステートメント単位で進め,<br> 呼び出し先のメソッドがある場合はその呼び出し先のメソッドに入ります.<br> この画像の場合では, ステップインによって, 呼び出し先である B クラスの getC() メソッドへ入っています.<br> <div class = "image"><img src = "./images/StepInto_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/StepInto_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 右下のブレークポイントビューの「ステップリターン」アイコンをクリックすると, 呼び出し元のメソッドに復帰するまで実行を進めたうえで,<br> その呼び出し元のメソッド内で次のステートメントにまで進めます.<br> この画像の場合では, ステップリターンによって, 呼び出し元のメソッドである D クラスの passB(B) メソッドに復帰し,<br> 呼び出し元では B.getC() の次のメソッド呼び出しステートメントである E.setC(C) の直前にまで実行が進んでいます.<br> <div class = "image"><img src = "./images/StepReturn_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/StepReturn_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 右下のブレークポイントビューの「ステップネクスト」アイコンをクリックすると, 実行をステートメント単位で進めます.<br> 「ステップイン」とは違い, こちらは呼び出し先のメソッドがあったとしても, その呼び出し先のメソッドには入ることはありません.<br> 「ステップオーバー」では行単位で実行が進んでしまいますが, 「ステップネクスト」ではより細かいステートメント単位で同一メソッド実行内を進むことができます.<br> この画像の場合では, 現在のメソッド呼び出しステートメントである B.getC() の呼び出し先には入らずに, <br> そのまま次のメソッド呼び出しステートメントである E.setC(C) の直前にまで実行が進んでいます.<br> <div class = "image"><img src = "./images/StepNext_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/StepNext_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> 右上の変数ビューでは, 現在見ているメソッド実行内から見える各オブジェクトのクラス名とIDが確認できます.<br> また, あるオブジェクトがフィールドとして別のオブジェクトを参照している場合は, そのオブジェクトの部分を開くことで,<br> フィールドと参照先のオブジェクトの関係を確認することもできます.<br> なお, ローカル変数が参照しているオブジェクトの情報については, 仮引数を除いてトレースファイルに記録されていないため表示されないことに注意してください.<br> <div class = "image"><img src = "./images/Variable_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/Variable_Forward_2.png" class = "threeQuartersSize"></div> </p> <p class = "explanation"> また, 右上の変数ビューでは, 通常のデバッガとは異なり, 以下の特殊なケースの場合にも関連するオブジェクトが表示され, そのクラス名とIDが確認できます.<br> <ul> <li>フィールド代入の直前 (参照元オブジェクトと参照先オブジェクトが確認できる)</li> <li>フィールド参照の直後 (参照元オブジェクトと参照先オブジェクトが確認できる)</li> <li>メソッド呼び出しの直前 (当該メソッドのレシーバのオブジェクトと引数のオブジェクトが確認できる)</li> <li>メソッド呼び出しの直後 (当該メソッドのレシーバのオブジェクトと戻り値のオブジェクトが確認できる)</li> </ul> <div class = "image"><img src = "./images/Variable_SP_Forward_1.png" class = "threeQuartersSize"></div> <div class = "image"><img src = "./images/Variable_SP_Forward_2.png" class = "threeQuartersSize"></div> </p> </p> <a id="next" href="../Reverse/TraceDebugger_Reverse.html">逆方向トレースデバッガの説明へ進む</a> </body> </html>