(57)【要約】【課題】プログラム検証における処理負荷を抑制することを目的とする。【解決手段】プログラム検証支援システムは、第１情報処理装置と第２情報処理装置とを含む。第１情報処理装置は、検証対象プログラム内のコードに対応した履歴取得対象コードと、履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを検証対象プログラムに挿入して履歴取得プログラムを生成する第１生成部と、履歴取得プログラムを実行し、履歴情報を生成する第１実行部と、履歴情報を第２情報処理装置に送信する第１通信部と、を含む。第２情報処理装置は、履歴情報を受信する第２通信部と、検証対象プログラムに、履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する第２生成部と、履歴情報を用いて、再生プログラムを実行する第２実行部と、を含む。【選択図】図１
2018195299.tif 000002
【特許請求の範囲】
【請求項１】
第１情報処理装置と第２情報処理装置とを備えたプログラム検証支援システムであって、
前記第１情報処理装置は、
検証対象プログラム内のコードに対応した履歴取得対象コードと、前記履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを前記検証対象プログラムに挿入して履歴取得プログラムを生成する第１生成部と、
前記履歴取得プログラムを実行し、前記履歴情報を生成する第１実行部と、
前記履歴情報を前記第２情報処理装置に送信する第１通信部と、を含み、
前記第２情報処理装置は、
前記履歴情報を受信する第２通信部と、
前記検証対象プログラムに、前記履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する第２生成部と、
前記履歴情報を用いて、前記再生プログラムを実行する第２実行部と、を含む
ことを特徴とするプログラム検証支援システム。
【請求項２】
前記第１生成部は、前記履歴取得対象コードに含まれる変数の最新の値を記憶部に記憶するコードを前記検証対象プログラムに挿入し、
前記第１実行部は、前記記憶部から前記変数の最新の値を取得し、前記履歴情報に記録する
ことを特徴とする請求項１に記載のプログラム検証支援システム。
【請求項３】
前記第１生成部は、前記履歴取得プログラムを解析してプログラム解析情報を生成し、
前記第１通信部は、前記プログラム解析情報を前記第２情報処理装置に送信し、
前記第２通信部は、前記プログラム解析情報を受信し、
前記２実行部は、前記履歴情報および前記プログラム解析情報に基づいて、他のコードに移行する処理を実行するコードに対応する前記再生コードを特定し、特定した前記再生コードから前記他のコードに移行する処理を実行する
ことを特徴とする請求項１または２に記載のプログラム検証支援システム。
【請求項４】
前記第１生成部は、前記検証対象プログラムにおいて、前記他のコードに移行する処理を実行するコードの前に、所定の値を第１の変数に設定する前記履歴取得対象コードを挿入し、前記他のコードの後に前記第１の変数の値を第２の変数の値に設定する前記履歴取得対象コードを挿入し、前記所定の値および前記第２の変数を識別する識別情報がコードに対応づけられた前記プログラム解析情報を生成する
ことを特徴とする請求項３に記載のプログラム検証支援システム。
【請求項５】
前記他のコードに移行する処理を実行するコードは、例外を発生させるコードであり、
前記他のコードは、前記例外が発生した際に実行されるコードである
ことを特徴とする請求項３または４に記載のプログラム検証支援システム。
【請求項６】
前記検証対象プログラムは、複数のメソッドを含み、
前記第１生成部は、各メソッドに前記履歴取得対象コードを挿入する、
ことを特徴とする請求項１乃至５のうち何れか１項に記載のプログラム検証支援システム。
【請求項７】
前記第１情報処理装置は、
前記履歴取得プログラムに含まれる複数のコードのうち一部のコードが選択されて実行される場合、前記複数のコードの履歴情報に用いるメモリ領域を共通化する共通化部を含む
ことを特徴とする請求項１に記載のプログラム検証支援システム。
【請求項８】
前記第２情報処理装置は、
メモリ操作履歴を収集するためのコードを挿入してメモリ操作履歴出力用の再生プログラムを生成する第３生成部と、
前記操作履歴出力用の再生プログラムを再生して、メモリ操作履歴を収集する第３実行部と、
前記メモリ操作履歴を用いて、前記第２実行部が実行する再生プログラムの実行中に前記メモリに記憶された値に、前記値の過去および未来の操作を示す記号を付加したメモリ状態を表示させる表示制御部と、
を備えることを特徴とする請求項１に記載のプログラム検証支援システム。
【請求項９】
コンピュータに、
検証対象プログラム内のコードに対応した履歴取得対象コードと、前記履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを前記検証対象プログラムに挿入して生成された履歴取得プログラムが実行されて生成された前記履歴情報を受信し、
前記検証対象プログラムに、前記履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成し、
前記履歴情報を用いて、前記再生プログラムを実行する
処理を実行させるプログラム検証支援プログラム。
【請求項１０】
コンピュータが、
検証対象プログラム内のコードに対応した履歴取得対象コードと、前記履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを前記検証対象プログラムに挿入して生成された履歴取得プログラムが実行されて生成された前記履歴情報を受信し、
前記検証対象プログラムに、前記履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成し、
前記履歴情報を用いて、前記再生プログラムを実行する
処理を実行することを特徴とするプログラム検証支援方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラム検証支援システム、プログラム検証支援プログラム、およびプログラム検証支援方法に関する。
【背景技術】
【０００２】
複数の実行環境においてプログラムが動作した際の実行履歴を用いて、プログラムの動作の検証をするプログラム動作検証が行われている。
【０００３】
関連する技術として、トレース機能において、分岐命令前後のアドレスのみをトレースメモリへ格納することで、プログラムの実行履歴を再現する技術が提案されている（例えば、特許文献１を参照）。
【０００４】
関連する技術として、内部で大量の汎用レジスタを保持するマイクロプロセッサの応用プログラムをデバッグするためのトレース装置が提案されている（例えば、特許文献２を参照）。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２００１−０６０１６２号公報
【特許文献２】特開２０００−０５７０１２号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
プログラム検証を行う際に、検証対象プログラムを変換して、プログラムの実行履歴を取得するプログラムと、実行履歴の値を復元するプログラムとをそれぞれ生成し、異なる実行環境で実行することが考えられる。
【０００７】
しかし、例えば、検証対象プログラムにおいて、実行履歴の取得対象のコードが繰り返し実行される場合、取得対象コードの全ての実行履歴を取得すると、取得処理の負荷が大きいという課題がある。
【０００８】
１つの側面として、本発明は、プログラム検証における処理負荷を抑制することを目的とする。
【課題を解決するための手段】
【０００９】
１つの態様では、プログラム検証支援システムは、第１情報処理装置と第２情報処理装置とを備える。前記第１情報処理装置は、検証対象プログラム内のコードに対応した履歴取得対象コードと、前記履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを前記検証対象プログラムに挿入して履歴取得プログラムを生成する第１生成部と、前記履歴取得プログラムを実行し、前記履歴情報を生成する第１実行部と、前記履歴情報を前記第２情報処理装置に送信する第１通信部と、を含む。前記第２情報処理装置は、前記履歴情報を受信する第２通信部と、前記検証対象プログラムに、前記履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する第２生成部と、前記履歴情報を用いて、前記再生プログラムを実行する第２実行部と、を含む。
【発明の効果】
【００１０】
１つの側面によれば、プログラム検証における処理負荷を抑制することができる。
【図面の簡単な説明】
【００１１】
【図１】実施形態のプログラム検証支援システムの全体構成の一例を示す図である。
【図２】プログラム検証の第１の例を示す図である。
【図３】プログラム検証の第２の例を示す図である。
【図４】第１の実施形態における第１情報処理装置の一例を示す図である。
【図５】第１の実施形態における第２情報処理装置の一例を示す図である。
【図６】検証対象プログラムの第１の例を示す図である。
【図７】第１の実施形態における第１情報処理装置の処理の流れの一例を示すフローチャートである。
【図８】図７のステップＳ１０１の処理の流れの一例を示すフローチャート（その１）である。
【図９】図７のステップＳ１０１の処理の流れの一例を示すフローチャート（その２）である。
【図１０】履歴取得プログラムの第１の例を示す図である。
【図１１】プログラム解析情報の第１の例を示す図である。
【図１２】図７のステップＳ１０３の一例を示すフローチャートである。
【図１３】履歴情報の第１の例を示す図である。
【図１４】第１の実施形態における第２情報処理装置の処理の流れの一例を示すフローチャートである。
【図１５】図１４のステップＳ４０２の処理の流れの一例を示すフローチャートである。
【図１６】再生プログラムの第１の例を示す図である。
【図１７】図１４のＳ４０４の処理の流れの一例を示す図である。
【図１８】検証対象プログラムの第２の例を示す図である。
【図１９】履歴取得プログラムの第２の例を示す図である。
【図２０】プログラム解析情報の第２の例を示す図である。
【図２１】履歴情報の第２の例を示す図である。
【図２２】再生プログラムの第２の例を示す図である。
【図２３】メモリを共通化しないプログラムの再生例を示す図である。
【図２４】メモリを共通化しない場合の彩色後の干渉グラフの例を示す図である。
【図２５】第２の実施形態における第１情報処理装置の一例を示す図である。
【図２６】第２の実施形態における第２情報処理装置の一例を示す図である。
【図２７】制御フローグラフおよび干渉グラフの一例を示す図である。
【図２８】メモリを共通化したプログラムの再生例を示す図である。
【図２９】第２の実施形態における第１情報処理装置の処理の流れの一例を示すフローチャートである。
【図３０】図２９のステップＳ７０１の処理の流れの一例を示すフローチャート（その１）である。
【図３１】図２９のステップＳ７０１の処理の流れの一例を示すフローチャート（その２）である。
【図３２】検証対象プログラムおよび履歴対象プログラムの第３の例を示す図である。
【図３３】プログラム解析情報の第３の例を示す図である。
【図３４】図２９のステップＳ７０３の処理の流れの一例を示すフローチャートである。
【図３５】制御フローグラフおよび識別子の一例を示す図である。
【図３６】干渉グラフの彩色の一例を示す図である。
【図３７】変数の変換の一例を示す図である。
【図３８】共通化情報の一例を示す図である。
【図３９】履歴情報の第３の例を示す図である。
【図４０】第２の実施形態における第２情報処理装置の処理の流れの一例を示すフローチャートである。
【図４１】図４０のステップＳ１００３の処理の流れの一例を示すフローチャートである。
【図４２】再生プログラムの第３の例を示す図である。
【図４３】図４０のステップＳ１００５の処理の流れの一例を示す図である。
【図４４】インスペクションツールの第１の表示例を示す図である。
【図４５】インスペクションツールの第２の表示例を示す図である。
【図４６】第３の実施形態における第１情報処理装置の一例を示す図である。
【図４７】第３の実施形態における第２情報処理装置の一例を示す図である。
【図４８】検証対象プログラムの第４の例を示す図である。
【図４９】第３の実施形態における第１情報処理装置の処理の流れの一例を示すフローチャートである。
【図５０】図４９のステップＳ１３０１の処理の流れの一例を示すフローチャート（その１）である。
【図５１】図４９のステップＳ１３０１の処理の流れの一例を示すフローチャート（その２）である。
【図５２】履歴取得プログラムの第４の例を示す図である。
【図５３】プログラム解析情報の第４の例を示す図である。
【図５４】履歴情報の第４の例を示す図である。
【図５５】第３の実施形態における第２情報処理装置の処理の流れの一例を示すフローチャートである。
【図５６】図５２のステップＳ１５０２の処理の流れの一例を示すフローチャート（その１）である。
【図５７】図５２のステップＳ１５０２の処理の流れの一例を示すフローチャート（その２）である。
【図５８】メモリ操作履歴収集用の再生プログラムの例を示す図である。
【図５９】図５５のステップＳ１５０３の処理の流れの一例を示すフローチャート（その１）である。
【図６０】図５５のステップＳ１５０３の処理の流れの一例を示すフローチャート（その２）である。
【図６１】メモリ操作履歴の一例を示す図である。
【図６２】図５５のステップＳ１５０４の処理の流れの一例を示すフローチャートである。
【図６３】再生プログラムの第４の例を示す図である。
【図６４】図５５のステップＳ１５０６の処理の流れの一例を示すフローチャートである。
【図６５】文字列表現決定表の一例を示す図である。
【図６６】インスペクションツールの第３の表示例を示す図である。
【図６７】インスペクションツールの第４の表示例を示す図である。
【図６８】インスペクションツールの第５の表示例を示す図である。
【図６９】第１情報処理装置のハードウェア構成の一例を示す図である。
【図７０】第２情報処理装置のハードウェア構成の一例を示す図である。
【発明を実施するための形態】
【００１２】
（第１の実施形態）
＜実施形態のシステムの全体構成の一例＞
以下、図面を参照して、実施形態について説明する。図１は、実施形態のプログラム検証支援システムの全体構成の一例を示す図である。実施形態のプログラム検証支援システムは、第１情報処理装置１と第２情報処理装置２とを含む。第１情報処理装置１および第２情報処理装置２は、例えば、サーバ、パーソナルコンピュータ、またはタブレット端末等である。第２情報処理装置２は、コンピュータの一例である。
【００１３】
第１情報処理装置１は、検証対象プログラムに基づいて生成した履歴取得プログラムを実行し、履歴情報を生成する。
【００１４】
第２情報処理装置２は、実行履歴を取得し、実行履歴に基づいて、検証対象プログラムに基づいて生成した再生プログラムを再生する。
【００１５】
そして、第１情報処理装置１の実行結果と第２情報処理装置２の実行結果との比較により、異なる実行環境で同じ結果が得られるか検証が行われる。
【００１６】
＜プログラム検証の例＞
次にプログラムの動作を検証するプログラム検証の例について説明する。なお、本実施形態において、プログラミング言語としてＪａｖａ（登録商標）を用いた例を示すが、Ｊａｖａ以外のプログラミング言語が用いられてもよい。例えば、本実施形態において、オブジェクト指向ではない言語が用いられてもよい。例えば、Ｃ言語を適用した場合、本実施形態におけるメソッドは関数に相当する。また、以下の説明における「コード」はプログラムに含まれる各命令コードを示す。
【００１７】
図２は、プログラム検証の第１の例を示す図である。図２に示す例では、検証対象プログラムと、検証対象プログラムを２回実行して得られた実行履歴が示されている。
【００１８】
第１の例では、第１情報処理装置１は、検証対象プログラムに含まれるメソッドであるparent()とchild()とに含まれるコード"write($V)"による実行結果を実行履歴として取得し、第２情報処理装置２に送信する。図２の例に示すように、parent()は、while文に含まれており、繰り返し処理が行われるため、多数の実行履歴が出力される可能性がある。
【００１９】
図２の例に示すように、繰り返し処理が行われるプログラム内に実行履歴を出力するコードが含まれている場合、多数の実行履歴が出力される可能性がある。従って、プログラムを実行する第１情報処理装置１の負荷が大きい。
【００２０】
図３は、プログラム検証の第２の例を示す図である。図３における第２の例では、検証対象プログラムと、検証対象プログラムを２回実行して得られた実行履歴がと示されている。第２の例では、"text=“偶数”"または"text=“奇数”"が実行された際に、第１情報処理装置１は、メモリ内の$V[0]、$V[1]の値を実行履歴として取得したとする。
【００２１】
第２の例に示すプログラムは、parent()には、例外処理を行うtry節、catch節が含まれている。実行履歴（１回目）は、例外が検出されなかった例を示す。また、実行履歴（２回目）は、例外が検出された例を示す。
【００２２】
実行履歴（１回目）および実行履歴（２回目）では、child()の$V[0]の実行履歴が出力されるが、parent()内において、child()を呼び出すコードが２箇所存在するため、どちらのコードからchild()が呼び出されたかユーザが判断することが困難である。
【００２３】
実行履歴（２回目）では、"parent()の$V[1]は「Exception@999」"という実行履歴により、例外が検出されたことが示されている。しかし、どのコードを実行した際に例外が送出されたかユーザが判断することは困難である。
【００２４】
＜第１情報処理装置の一例＞
図４は、第１の実施形態における第１情報処理装置１の一例を示す図である。第１情報処理装置１は、第１通信部１１と、第１生成部１２と、第１実行部１３と、第１記憶部１４とを含む。
【００２５】
第１通信部１１は、後述する履歴情報と、プログラム解析情報とを第２情報処理装置２に送信する。
【００２６】
第１生成部１２は、検証対象プログラム内のコードに対応した履歴取得対象コードと、履歴取得対象コードの最後の動作（実行結果）を示す履歴情報を取得する履歴取得コードとを検証対象プログラムに挿入して履歴取得プログラムを生成する。また、第１生成部１２は、履歴取得プログラムを解析してプログラム解析情報を生成する。
【００２７】
第１実行部１３は、履歴取得プログラムを実行し、履歴情報を生成し、履歴情報を第１記憶部１４に記憶させる。第１実行部１３は、履歴情報を取得する際に、第１記憶部１４から履歴取得対象コードの最新の値を取得し、履歴情報に記録する。
【００２８】
第１記憶部１４には、検証対象プログラムと履歴取得プログラムとプログラム解析情報と履歴情報とが記憶される。検証対象プログラムは、予め第１記憶部１４に記憶される。履歴取得プログラムは、第１生成部１２が生成したプログラムである。プログラム解析情報は、第１生成部１２が生成した情報である。履歴情報は、第１実行部１３が取得した情報である。
【００２９】
＜第２情報処理装置の一例＞
図５は、第１の実施形態における第２情報処理装置２の一例を示す図である。第２情報処理装置２は、第２通信部２１と第２生成部２２と第２実行部２３と第２記憶部２４とを含む。
【００３０】
第２通信部２１は、第１情報処理装置１から、履歴情報とプログラム解析情報とを受信する。
【００３１】
第２生成部２２は、検証対象プログラムに、履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する。第２生成部２２は、生成された再生プログラムとプログラム解析情報とを対応づける。
【００３２】
第２実行部２３は、第１情報処理装置１から受信した履歴情報を用いて、再生プログラムを実行する。
【００３３】
第２記憶部２４には、検証対象プログラムとプログラム解析情報と履歴情報と再生プログラムとが記憶される。検証対象プログラムは、第１情報処理装置１の第１記憶部１４に記憶されているプログラムと同じである。プログラム解析情報および履歴情報は、第２通信部２１が第１情報処理装置１から受信した情報である。再生プログラムは、第２生成部２２が生成したプログラムである。
【００３４】
＜検証プログラムの一例＞
図６は、検証対象プログラムの第１の例を示す図である。図６に示すように、検証プログラムは、メソッドとして、parent()とchild()とを含む。parent()には、例外処理を行うtry節、catch節が含まれている。例えば、try節内の"int d =random();"において例外が発生した場合、処理はcatch節に移行する。また、child()内には、明示的な例外送出を行うコードとして" throw new Exception();"が記述されている。
【００３５】
＜実施形態の処理の流れの一例＞
図７は、第１の実施形態における第１情報処理装置１の処理の流れの一例を示すフローチャートである。第１生成部１２は、検証対象プログラム内のコードに対応した履歴取得対象コードと、履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを検証対象プログラムに挿入して履歴取得プログラムを生成する（ステップＳ１０１）。ステップＳ１０１の処理について、詳細は後述する。
【００３６】
第１生成部１２は、履歴取得プログラムを解析してプログラム解析情報を生成する（ステップＳ１０２）。
【００３７】
第１実行部１３は、履歴取得プログラムを実行し、履歴情報を生成し、履歴情報を第１記憶部１４に記憶させる（ステップＳ１０３）。
【００３８】
第１通信部１１は、第１実行部１３が取得した履歴情報と、第１生成部１２が生成したプログラム解析情報とを第２情報処理装置２に送信する（ステップＳ１０４）。
【００３９】
図８および図９は、図７のステップＳ１０１の処理の流れの一例を示すフローチャートである。
【００４０】
第１生成部１２は、履歴取得対象コードが未挿入のメソッドがあるか判定する（ステップＳ２０１）。本実施形態のプログラム検証では、第１情報処理装置１は、全てのメソッドの検証のために、１つのメソッド内に少なくとも１つの履歴取得対象コードを挿入する。
【００４１】
ステップＳ２０１でＹＥＳの場合、第１生成部１２は、コード番号CNに０を設定し、識別情報VSに０を設定する（ステップＳ２０２）。第１生成部１２は、履歴取得対象コードが未挿入のいずれかのメソッド内のコードを参照する（ステップＳ２０３）。
【００４２】
以下、コード番号CNを単にCNと記載することがある。CNは、所定の値の一例である。また、以下、識別情報VSを単にVSと記載することがある。
【００４３】
第１生成部１２は、一回目のステップＳ２０３の処理では、例えば、最初に実行されるメソッドの１行目のコードを参照する。ステップＳ２０３で参照したメソッドを、処理対象メソッドと称する。また、ステップＳ２０３で参照したコードを、処理対象コードと称する。
【００４４】
第１生成部１２は、処理対象コードが明示的な例外発生を行うコードか判定する（ステップＳ２０４）。明示的な例外発生を行うコードは、例えば、"throw new Exception();"である。
【００４５】
ステップＳ２０４でＹＥＳの場合、第１生成部１２は、処理対象コード直前に実行履歴取得を要求するコードを挿入する（ステップＳ２０５）。実行履歴取得を要求するコードは、例えば、$writeメソッドを呼び出す式（$write()）である。$write()は、履歴取得コードの一例である。ステップＳ２０５の処理後、処理は、「Ｂ」から図９のステップＳ２１７に移行する。
【００４６】
ステップＳ２０４でＮＯの場合、第１生成部１２は、処理対象コードが、戻り値があるメソッド呼び出しであるか判定する（ステップＳ２０６）。ステップＳ２０６でＹＥＳの場合、第１生成部１２は、処理対象コードを、変数$V[VS]に処理対象コードの戻り値を設定するコードで置換する（ステップＳ２０７）。第１生成部１２は、例えば、処理対象コードを、"$V[VS]=処理対象コード"というコードで置換する。
【００４７】
変数$V[VS]に設定される値は、メモリ（例えば、第１記憶部１４）に記憶される。変数$V[VS]の値が変更された場合、変更後の値がメモリに記憶される。すなわち、変数$V[VS]の最後の値がメモリに記憶される。
【００４８】
ステップＳ２０７の処理後、第１生成部１２は、VSにVS＋１を設定する（ステップＳ２０８）。そして、第１生成部１２は、処理対象コード直前に、コード番号値CNを変数$CNに設定するコードを挿入する（ステップＳ２０９）。ステップＳ２０９で挿入されるコードは、例えば、"$CN = CN"である。$CNは、第１の変数の一例である。
【００４９】
ステップＳ２０９の処理後、第１生成部１２は、CNにCN＋１を設定する（ステップＳ２１１）。そして、処理は、「Ｂ」からステップＳ２１７に移行する。
【００５０】
ステップＳ２０６でＮＯの場合、第１生成部１２は、処理対象コードが、戻り値がないメソッド呼び出しであるか判定する（ステップＳ２１０）。ステップＳ２１０でＹＥＳの場合、処理はステップＳ２０９に移行する。
【００５１】
try節内にある「戻り値があるメソッド呼び出し」および「戻り値がないメソッド呼び出し」は、他のコード（例えば、catch節内のコード）に移行する処理を実行するコードの一例である。ステップＳ２０６における「戻り値があるメソッド呼び出し」および「戻り値がないメソッド呼び出し」がtry節内にある場合、例外が発生するとcatch節に移動するためである。
【００５２】
ステップＳ２１０でＮＯの場合、処理は、「Ａ」からステップＳ２１２に移行する。第１生成部１２は、処理対象コードが例外検出を行うコードであるかを判定する（ステップＳ２１２）。例外処理を行うコードは、例えば、catch節の先頭に記述される"catch (Exception ex)"というコードである。例外検出を行うコードは、例外が発生した際に実行されるコードである。
【００５３】
ステップＳ２１２でＹＥＳの場合、第１生成部１２は、CNが設定された変数$CNの現在値を変数$V[VS]に設定するコードを挿入する（ステップＳ２１３）。ステップＳ２１３で挿入されるコードは、例えば、"$V[VS]=$CN"である。$V[VS]は、第２の変数の一例であり、履歴情報の記録対象である。第１生成部１２は、VSにVS+1を設定する（ステップＳ２１４）。
【００５４】
第１生成部１２は、変数$V[VS]に、処理対象コードが検出する例外オブジェクトを設定するコードを挿入する（ステップＳ２１５）。ステップＳ２１５で挿入されるコードは、例えば、"$V[VS] = ex;"である。第１生成部１２は、VSにVS+1を設定する（ステップＳ２１６）。
【００５５】
ステップＳ２１６の処理後、ステップＳ２１２でＮＯの場合、または処理が「Ｂ」に移行した場合、第１生成部１２は、処理対象メソッド内の全コードを参照したか判定する（ステップＳ２１７）。
【００５６】
ステップＳ２１７でＮＯの場合、第１生成部１２は、処理対象コードを処理対象メソッド内の次のコードに移動させる（ステップＳ２１８）。ステップＳ２１８の後、処理は、「Ｄ」から、図８のステップＳ２０３に移行する。
【００５７】
ステップＳ２１７でＹＥＳの場合、第１生成部１２は、処理対象メソッドの先頭に、CNを設定する変数を初期化するコードを挿入する（ステップＳ２１９）。ステップＳ２１９で挿入されるコードは、例えば、"int $CN = -1"である。この場合、変数$CNに初期値として"-1"が設定される。
【００５８】
第１生成部１２は、処理対象メソッドの先頭に、配列を初期化するコードを挿入する（ステップＳ２２０）。ステップＳ２２０で挿入されるコードは、例えば、"Object[] $V = new Object[VS]"である。なお、図８、図９に示す例では、ステップＳ２２０の処理の時点におけるVSが配列の最大値に相当する。ステップＳ２２０の処理後、処理は、「Ｃ」からステップＳ２０１に移行する。ステップＳ２０１でＮＯの場合、処理が終了する。
【００５９】
なお、図８、図９の処理において、Ｓ２０７、Ｓ２０９、Ｓ２１３およびＳ２１５で挿入されるコードは、履歴取得対象コードの例である。
【００６０】
第１情報処理装置１は、図８および図９の処理により、複数のメソッドを含む検証対象プログラムの各メソッドに履歴取得対象コードを挿入するため、複数のメソッドのそれぞれを検証することができる。
【００６１】
図１０は、履歴取得プログラムの第１の例を示す図である。図１０に示す履歴対象プログラムは、図６に示す検証対象プログラムに、図８および図９に示す処理が行われた結果、生成される。図１０において、下線部分が図８および図９に示す処理で挿入されたコードである。
【００６２】
図１１は、プログラム解析情報の第１の例を示す図である。プログラム解析情報は、識別情報（VS）と、コード番号（CN）と、メソッド定義と、コード種類と、例外の検出であるかを示す情報とを含む。
【００６３】
第１生成部１２は、図８および図９の処理中に、各コードを参照した際のVSおよびCNをプログラム解析情報に記録する。
【００６４】
第１生成部１２は、記録対象のコードのコード種類、該コードが含まれるメソッド（「メソッド定義」）をプログラム解析情報に記録する。第１生成部１２は、該コードが例外の検出を実行するコードであれば、プログラム解析情報の「例外の検出」列に「Ｙｅｓ」を記録する。
【００６５】
図１２は、図７のステップＳ１０３の一例を示すフローチャートである。第１実行部１３は、履歴取得プログラムのうち、呼び出し元のメソッドを実行する（ステップＳ３０１）。ステップＳ３０１の実行後、呼び出し元のメソッドが処理対象メソッドとなる。図１０に示す例では、"parent()"が呼び出し元のメソッドである。
【００６６】
第１実行部１３は、処理対象メソッド内のコードを参照する（ステップＳ３０２）。第１実行部１３は、ステップＳ３０２を１回目に実行する場合、処理対象メソッドの先頭コードを参照する。
【００６７】
第１実行部１３は、処理対象コードが実行履歴の取得を要求するコードか判定する（ステップＳ３０３）。実行履歴の取得を要求するコードは、例えば、"$write()"である。
【００６８】
ステップＳ３０３でＹＥＳの場合、第１実行部１３は、第１記憶部１４から、コールスタック中の各メソッドにおける変数$CNと変数$V[]の最新の値を履歴情報に記録する（ステップＳ３０４）。コールスタック中の各メソッドは、例えば、parent()およびchild()である。なお、同じ変数に異なる値が設定された場合、上書きされるため、第１記憶部１４に記憶された変数$CNと変数$V[]の値は、最新の値である。第１実行部１３は、履歴情報を第１記憶部１４に記憶させる。
【００６９】
ステップＳ３０３でＮＯの場合、第１実行部１３は、処理対象コードがメソッド呼び出し式かどうか判定する（ステップＳ３０５）。
【００７０】
処理対象コードがメソッド呼び出し式でない場合（ステップＳ３０５でＮＯ）、第１実行部１３は、処理対象コードを実行する（ステップＳ３０６）。処理対象コードがメソッド呼び出し式である場合（ステップＳ３０５でＹＥＳ）、第１実行部１３は、呼び出し先メソッドに移動する（ステップＳ３０７）。
【００７１】
第１実行部１３は、メソッド内の全コードを参照したか判定する（ステップＳ３０８）。ステップＳ３０８でＹＥＳの場合、処理が終了する。
【００７２】
ステップＳ３０８でＮＯの場合またはステップＳ３０４の処理後、第１実行部１３は、処理対象コードを次のコードに移動させる（ステップＳ３０９）。ステップＳ３０９の処理後、処理は、ステップＳ３０２に移動する。
【００７３】
以上のように、第１情報処理装置１は、ステップＳ３０４の処理において、各変数の最新の値を含む履歴情報を第１記憶部１４に記憶させるため、変数に設定された全ての値を記憶するより、第１情報処理装置１の履歴取得処理、および後述する第２情報処理装置２の再生処理の負荷を抑制することができる。
【００７４】
図１３は、履歴情報の第１の例を示す図である。図１３（ａ）は、第１記憶部１４に記憶される履歴情報の例を示す。図１３（ｂ）は、履歴情報の表示例を示す。
【００７５】
履歴情報は、履歴ＩＤと呼出深さと識別情報（VS）とメソッド定義と変数名と値とを含む。第１実行部１３は、図１２の処理を実行する際に、履歴情報を生成する。
【００７６】
「履歴ＩＤ」は、実行される履歴取得プログラムごとに付与される識別情報である。「呼び出し深さ」は、メソッド呼び出しの階層の深さを示している。図１３の例では、後に呼び出されるメソッドほど、小さい値が設定される。「識別情報（VS）」は、プログラム解析情報に基づいて設定される。
【００７７】
「メソッド定義」は、処理対象コードが存在するメソッド名である。「変数」は、履歴取得対象の変数名である。「値」は、履歴取得プログラムを実行した際に「変数」に設定される値である。
【００７８】
図１４は、第１の実施形態における第２情報処理装置２の処理の流れの一例を示すフローチャートである。
【００７９】
第２通信部２１は、第１情報処理装置１から履歴情報とプログラム解析情報とを受信する（ステップＳ４０１）。
【００８０】
第２生成部２２は、検証対象プログラムに、履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する（ステップＳ４０２）。ステップＳ４０２の処理について、詳細は後述する。
【００８１】
第２生成部２２は、生成された再生プログラムとプログラム解析情報とを対応づける（ステップＳ４０３）。
【００８２】
第２実行部２３は、第１情報処理装置１から受信した履歴情報を用いて、生成された再生プログラムを実行する（ステップＳ４０４）。ステップＳ４０４の処理について、詳細は後述する。
【００８３】
図１５は、図１４のステップＳ４０２の処理の流れの一例を示すフローチャートである。第２生成部２２は、再生コードが未挿入のメソッドがあるか判定する（ステップＳ５０１）。ステップＳ５０１でＹＥＳの場合、第２生成部２２は、CNに０を設定し、VSに０を設定する。
【００８４】
第２生成部２２は、再生プログラム内の処理対象メソッドのコードを参照する（ステップＳ５０３）。第２生成部２２は、再生コードが未挿入のメソッドのいずれかを処理対象メソッドとする。また、ステップＳ５０３で参照されたコードが、以降の処理における処理対象コードとなる。ステップＳ５０３の１回目の処理を行う場合、第２生成部２２は、例えば、処理対象メソッド内の先頭コードを参照する。
【００８５】
第２生成部２２は、処理対象コードがメソッド呼び出し式か判定する（ステップＳ５０４）。ステップＳ５０４でＮＯの場合、第２生成部２２は、処理対象コードが例外検出を行うコードであるか判定する（ステップＳ５０５）。例外検出を行うコードは、例えば、catch節の先頭に記述される"catch (Exception ex)"というコードである。ステップＳ５０５でＹＥＳの場合、第２生成部２２は、VSにVS＋２を設定する。
【００８６】
ステップＳ５０４でＹＥＳの場合、第２生成部２２は、処理対象コードが他のメソッドにステップインするコードか判定する（ステップＳ５０７）。他のメソッドにステップインするコードは、例えば、"child()"である。第２生成部２２は、例えば、CNが処理対象メソッドのCN値と一致し、かつ、処理対象メソッドが呼び出し元である場合、処理対象コードが他のメソッドにステップインするコードであると判定する。
【００８７】
ステップＳ５０７でＮＯの場合、処理対象コードを削除し、再生コードを挿入する（ステップＳ５０８）。すなわち、第２生成部２２は、処理対象コードを再生コードで置換する。再生コードは、履歴情報にもとづいて、検証対象プログラム内の履歴取得対象コードの最後の動作を再生するコードである。第２生成部２２は、再生コードとして、例えば、"emulate(CN)"を挿入する。
【００８８】
ステップＳ５０７でＮＯの場合、またはステップＳ５０８の処理後、第２生成部２２は、処理対象コードが、戻り値があるメソッド呼び出し式であるか判定する（ステップＳ５０９）。ステップＳ５０９でＹＥＳである場合、第２生成部２２は、VSにVS＋１を設定する（ステップＳ５１０）。
【００８９】
ステップＳ５０９でＮＯの場合、またはステップＳ５１０の処理後、第２生成部２２は、CNにCN＋１を設定する（ステップＳ５１１）。
【００９０】
ステップＳ５０５でＮＯの場合、ステップＳ５０６の処理後、またはステップＳ５１１の処理後、第２生成部２２は、処理対象メソッド内の全コードを参照したか判定する（ステップＳ５１２）。
【００９１】
ステップＳ５１２でＮＯの場合、第２生成部２２は、処理対象コードを次のコードに移動させる（ステップＳ５１３）。ステップＳ５１３の処理後、処理はステップＳ５０３に移動する。
【００９２】
ステップＳ５１２でＹＥＳの場合、処理は、ステップＳ５０１に戻る。ステップＳ５０１でＮＯの場合、処理が終了する。
【００９３】
図１６は、再生プログラムの第１の例を示す図である。図１６に示す再生プログラムのうち、下線部分が検証対象プログラムとの変更点である。すなわち、下線部分は、図１５に示す処理により、第２生成部２２が挿入したコードである。
【００９４】
第２生成部２２が挿入したコードのうち、"emulate(0)"および"emulate(1)"は、実行履歴の値を戻り値として返すメソッドである。
【００９５】
第２生成部２２は、図１６に示すように、再生プログラムにプログラム解析情報のVS値およびCN値を対応づける。再生プログラムに対応づけられたVS値およびCN値は、後述する第２実行部２３および第２実行部２３の処理に用いられる。
【００９６】
図１７は、図１４のＳ４０４の処理の流れの一例を示す図である。第２実行部２３は、第２生成部２２が生成した再生プログラム内の、呼出元のメソッドを実行する（ステップＳ６０１）。ステップＳ６０１の処理後、呼び出し元のメソッドが処理対象メソッドとなる。第２実行部２３は、処理対象メソッドのコードを参照する（ステップＳ６０２）。第２実行部２３は、ステップＳ６０２を１回目に実行する場合、処理対象メソッドの先頭コードを参照する。第２実行部２３は、ステップＳ６０２で参照したコードを処理対象コードとする。
【００９７】
第２実行部２３は、処理対象コードが再生コードであるか判定する（ステップＳ６０３）。再生コードは、第２生成部２２により検証対象プログラムに挿入されたコードである。図１６に示す例では、再生コードは、"emulate(CN)"（"emulate(0)"および"emulate(1)"）である。
【００９８】
第２実行部２３は、再生コードの引数（CN）値と、等しい実行履歴（$V[X]値）が存在するか判定する（ステップＳ６０４）。すなわち、第２実行部２３は、図９のＳ２１３でコードが挿入されたコードが存在するか判定する。
【００９９】
ステップＳ６０４でＹＥＳの場合、第２実行部２３は、X＋１＝VSとなるコードが例外検出を示すか判定する（ステップＳ６０５）。第２実行部２３は、例えば、図１１に示すプログラム解析情報に基づいて、X＋１＝VSとなるコードが例外検出を示すか判定する。例外を検出する節は、例えば、catch節である。Xは、図９の処理においてVSに対応する。すなわち、ステップＳ６０５では、X＋１＝VSとなるコードが図９のステップＳ２１５の処理により挿入されたか判定している。
【０１００】
ステップＳ６０５でＹＥＳとなる場合、取得対象コードのうち再生コードで置換されたコードが例外を発生し、catch節に移行したことを示す。すなわち、第２実行部２３は、ステップＳ６０４およびＳ６０５の処理により、他のコード（catch節内のコード）に移行する処理を実行するコード（例外を発生するコード）に対応する再生コード（emulate(0)）を特定することができる。
【０１０１】
なお、第１情報処理装置１が履歴取得プログラムを実行した際に、図１６の"int d = emulate(0)"で置換された図１０の"int d = ($V[0] = random());"が例外を発生させる。そして、catch節に移動し、" $V[1] = $CN; $V[2] = ex;"が実行される。
【０１０２】
ステップＳ６０５でＹＥＳの場合、第２実行部２３は、再生コードから、処理対象メソッドの$V[X+1]に対応する例外を発生する（ステップＳ６０６）。第２実行部２３は、ステップＳ６０６を実行することにより、特定した再生コードから他のコード（catch節）に実行処理を移行させる。
【０１０３】
ステップＳ６０４またはＳ６０５でＮＯの場合、第２実行部２３は、プログラム解析情報に、再生コードの引数（CN）値と対応するVS値がある場合、履歴情報における$V[VS]値を返す（ステップＳ６０７）。なお、第２実行部２３は、再生コードの引数（CN）値と対応するVS値が無ければ値を返さない。再生コードがvoid型である場合、引数（CN）値と対応するVS値が無いことが想定される。
【０１０４】
ステップＳ６０３でＮＯの場合、第２実行部２３は、処理対象コードがメソッド呼出式であるか判定する（ステップＳ６０８）。ステップＳ６０８でＹＥＳの場合、第２実行部２３は、呼び出し先のメソッドに移動し（ステップＳ６０９）、ステップＳ６０２に戻る。
【０１０５】
ステップＳ６０８でＮＯの場合、第２実行部２３は、処理対象コードを実行する（ステップＳ６１０）。
【０１０６】
ステップＳ６１０の処理後、またはステップＳ６０７の処理後、第２実行部２３は、メソッド内の全コードを参照したか判定する（ステップＳ６１１）。ステップＳ６１１でＹＥＳの場合、処理を終了する。
【０１０７】
ステップＳ６１１でＮＯの場合、第２実行部２３は、処理対象コードを次のコードに移行させ（ステップＳ６１２）、処理をステップＳ６０２に移行する。
【０１０８】
以上のように、検証対象プログラムに他のコードに移行する処理（例えば、例外発生）が含まれる場合であっても、第２実行部２３は、ステップＳ６０６の処理のように他のコードに移行させる処理を実行する。よって、第２実行部２３は、他のコードの後（例えば、catch節内）に実行履歴の取得対象メソッド（例えば、child()）が含まれている場合であっても、取得対象メソッドを再生することができる。従って、第２情報処理装置２は、検証対象プログラム内の広い範囲の検証を行うことができる。
【０１０９】
＜各種情報の他の例＞
図１８は、検証対象プログラムの第２の例を示す図である。図１８に示す検証対象プログラムは、parent()内にchild()が３つ含まれる点で、図６に示す第１の例と異なる。
【０１１０】
図１９は、履歴取得プログラムの第２の例を示す図である。図１９に示す履歴取得プログラムは、図１８に示す検証対象プログラムに基づいて第１生成部１２が生成したプログラムである。図１９に示す履歴取得プログラムは、parent()内の２つ目のchild()の前に、"$CN = 2;"が挿入され、catch節内のchild()の前に、"$CN = 3;"が挿入されている点で、図１０に示す第１の例と異なる。
【０１１１】
図２０は、プログラム解析情報の第２の例を示す図である。図２０に示すプログラム解析情報は、図１９に示す履歴取得プログラムに対応している。図２０に示すプログラム解析情報は、メソッドchildの呼び出しが増加しており、コード番号CNが増加している点で、図１１に示すプログラム解析情報の第１の例と異なる。
【０１１２】
図２１は、履歴情報の第２の例を示す図である。図２１に示す履歴情報は、図１９に示す履歴取得プログラムを第１実行部１３が実行した際に取得する情報である。図２１に示す履歴情報は、メソッド定義「parent」に対応する$CNの値が「３」である点で、図１３に示す履歴情報と異なる。
【０１１３】
図２２は、再生プログラムの第２の例を示す図である。図２２に示す再生プログラムは、図１８に示す検証対象プログラムに対応している。図２２に示す再生プログラムは、"emulate(2);"が挿入されている点、該挿入に伴い、CNの値が増加している点で図１６に示す再生プログラムと異なる。
【０１１４】
図２１に示すように、履歴情報のうち、$V[VS]の値は、図１３に示す第１の例と同じである。また、図２２に示すように、再生プログラムに対応づけられたVS値は、図１６に示すVS値と同じである。従って、第２実行部２３は、図１７のステップＳ６０４、Ｓ６０５の処理において、図１６に示す再生プログラムを用いた例と同様に、他のコードに移行する処理を実行する再生コードを特定することができる。
【０１１５】
（第２の実施形態）
以下、図面を参照して第２の実施形態について説明する。履歴取得対象コードの最後の動作を示す履歴情報を全て取得した場合、再生に使われない実行履歴を取得する可能性があり、確保するメモリ容量が増加する。よって、本実施形態のシステムは、複数のコードのうちいずれか一つが選択されて実行される場合、複数のコードのメモリを共通化し、実行されるコードの最後の動作を示す履歴情報のみ取得することにより、使用するメモリ容量を削減する。
【０１１６】
図２３は、メモリを共通化しないプログラムの再生例を示す図である。図２３に示す履歴取得プログラムは、所定の検証対象プログラムに対して、第１の実施形態に示した処理によって再生コードが挿入されたプログラムである。また、図２３に示すプログラムは、while文により繰り返し処理が実行される。"Path.getOne()"は、繰り返し毎に、データファイル内の１行分の文字列を返す。"getLen()"は、引数で与えられた文字列の長さを返す。"Path.getOne()"には、繰り返し処理の１回目に"bin/app"が設定され、２回目に"/user/local/bin/app"が設定されるとする。第１の実施形態に示したように、履歴情報には最後の動作が記録されるため、$V1には、"/user/local/bin/app"が記録される。また、繰り返し処理の１回目において、$V2に"8"が記録され、繰り返し処理の２回目において$V3に"18"が記録される。
【０１１７】
図２３に示す履歴情報を用いて、履歴取得プログラムに対応する再生プログラムが再生された場合、CN1のコードにおいて、$V1の値として"/user/local/bin/app"が用いられる。そして、CN2のコードは実行されず、CN3のコードにおいて、$V3の値として"18"が用いられる。この場合、$V2の履歴情報は使われない。
【０１１８】
図２４は、メモリを共通化しない場合の彩色後の干渉グラフの例を示す図である。図２４では、履歴取得プログラムにおける変数$V1,$V2,$V3の生存期間が表されている。また、各変数の生存期間に基づいて、彩色後の干渉グラフが示されている。なお、図面において、干渉グラフの色の違いをパターンの違いにより表現する。
【０１１９】
干渉グラフは、変数をノードで表し、生存期間の重複を実線のエッジで表した無向グラフである。また、エッジで結ばれた隣接ノードを異なる色で彩色されている。そして、同じ色のノードは１つのメモリ領域で管理されるとする。
【０１２０】
図２４に示す例では、全変数の生存期間が重複するため、全ノードがエッジで結ばれ、全ノードが異なる色で彩色されている。そのため、各変数には、それぞれ異なる記憶領域が用いられる。
【０１２１】
＜第１情報処理装置の一例＞
図２５は、第２の実施形態における第１情報処理装置３の一例を示す図である。第１情報処理装置３は、第１通信部３１と、第１生成部３２と、第１実行部３３と、共通化部３４と、第１記憶部３５とを含む。なお、第２の実施形態におけるプログラム検証支援システムは、図１に示す構成と同様であるとする。
【０１２２】
第１通信部３１は、後述する履歴情報と、プログラム解析情報と、共通化情報とを第２情報処理装置２に送信する。
【０１２３】
第１生成部３２は、検証対象プログラム内のコードに対応した履歴取得対象コードと、履歴取得対象コードの最後の動作（実行結果）を示す履歴情報を取得する履歴取得コードとを検証対象プログラムに挿入して履歴取得プログラムを生成する。また、第１生成部３２は、履歴取得プログラムを解析してプログラム解析情報を生成する。
【０１２４】
第１実行部３３は、履歴取得プログラムを実行し、履歴情報を生成し、履歴情報を第１記憶部３５に記憶させる。第１実行部３３は、履歴情報を取得する際に、第１記憶部３５から履歴取得対象コードの最新の値を取得し、履歴情報に記録する。
【０１２５】
共通化部２４は、履歴取得プログラムに含まれる複数のコードのうち一部のコードが選択されて実行される場合、複数のコードの履歴情報に用いるメモリを共通化する。また、共通化部２４は、メモリの共通化に関する共通化情報を生成し、第１記憶部３５に記憶させる。
【０１２６】
第１記憶部３５には、検証対象プログラムと履歴取得プログラムとプログラム解析情報と履歴情報と共通化情報とが記憶される。検証対象プログラムは、予め第１記憶部３５に記憶される。履歴取得プログラムは、第１生成部３２が生成したプログラムである。プログラム解析情報は、第１生成部３２が生成した情報である。履歴情報は、第１実行部３３が取得した情報である。図２５に示す第１記憶部３５は、共通化情報を含む点で、図４に示す第１記憶部１４とは異なる。
【０１２７】
＜第２情報処理装置の一例＞
図２６は、第２の実施形態における第２情報処理装置４の一例を示す図である。第２情報処理装置４は、第２通信部４１と第２生成部４２と第２実行部４３と共通化情報読み取り部４４と第２記憶部４５とを含む。
【０１２８】
第２通信部４１は、第１情報処理装置３から、履歴情報とプログラム解析情報と共通化情報とを受信する。
【０１２９】
第２生成部４２は、検証対象プログラムに、履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する。第２生成部４２は、生成された再生プログラムとプログラム解析情報とを対応づける。
【０１３０】
第２実行部４３は、第１情報処理装置３から受信した履歴情報を用いて、再生プログラムを実行する。
【０１３１】
第２記憶部４５には、検証対象プログラムとプログラム解析情報と履歴情報と再生プログラムと共通化情報とが記憶される。検証対象プログラムは、第１情報処理装置３の第１記憶部３５に記憶されているプログラムと同じである。プログラム解析情報、履歴情報および共通化情報は、第２通信部４１が第１情報処理装置３から受信した情報である。再生プログラムは、第２生成部４２が生成したプログラムである。図２６に示す第２記憶部４５は、共通化情報を含む点で図５に示す第２記憶部２４とは異なる。
【０１３２】
共通化情報読み取り部４４は、共通化情報を読み取り、共通化情報のコード番号を、検証対象プログラムのコードと対応付ける。
【０１３３】
図２７は、制御フローグラフおよび干渉グラフの一例を示す図である。共通化部３４は、図２３に示す履歴取得プログラムに基づいて、図２７に示す制御フローグラフを生成する。制御フローグラフにおいて、排他的な（辺疎な）ノード集合は、異なる枠で示されている。例えば、一点鎖線で囲まれたノード集合と、破線で囲まれたノード集合とは排他的なノード集合である。この例では、if文において条件を満たす場合に実行されるコードを示すノード集合と、条件を満たさない場合に実行されるコードを示すノード集合とが排他的であるとみなされる。
【０１３４】
また、共通化部３４は、削除ループ処理の戻り辺を削除する。図２７に示す例では、共通化部３４は、while文の末尾を示す"}"からwhile文の先頭である"while(;;){"に戻るルートを、削除する。すなわち、繰り返し処理が実行されないと仮定する。
【０１３５】
共通化部３４は、干渉グラフから、互いに排他的なノード集合に存在する変数間のエッジを除去する。共通化部３４は、図２７に示す例では、変数$V[2]と変数$V[3]との間のエッジを除去する。なお、図２７では、除去したエッジは破線で表されている。
【０１３６】
共通化部３４は、干渉グラフ上で、エッジで連結された２つのノードが異なる色になるように、エッジで連結されていない２つのノードを同色となるように彩色する。図３６の例では、変数$V[2]と変数$V[3]との間のエッジが除去されているため、共通化部３４は、変数$V[2]と変数$V[3]とを同じ色に彩色する。
【０１３７】
図２８は、メモリを共通化したプログラムの再生例を示す図である。図２８に示す履歴取得プログラムは、図２７に示す干渉グラフに基づいて、図２３に示す履歴取得プログラム内の変数を変換した例である。図２８に示すプログラムは、図２３に示すコードの$V2と$V3が共通化されて、$V2_3という変数に変換されている。
【０１３８】
図２８に示すプログラムは、while文により繰り返し処理が実行される。"Path.getOne()"には、繰り返し処理の１回目に"bin/app"が設定され、２回目に"/user/local/bin/app"が設定されるとする。第１の実施形態に示したように、履歴情報には最後の動作が記録されるため、$V1には、"/user/local/bin/app"が記録される。また、繰り返し処理の１回目において、$V2_3に"8"が記録され、繰り返し処理の２回目において$V2_3に"18"が記録される。第１実行部３３は、履歴情報には、$V2_3の最後の動作を示す"18"のみ記録する。
【０１３９】
以上のように、第１情報処理装置３は、複数のコードのうち一部のコードが選択されて実行される場合、複数のコードの履歴情報に用いるメモリを共通化するので、履歴採取処理の負荷を低減し、メモリの使用容量および履歴情報のサイズを削減することができる。
【０１４０】
＜実施形態の処理の流れの一例＞
図２９は、第２の実施形態における第１情報処理装置３の処理の流れの一例を示すフローチャートである。第１生成部３２は、検証対象プログラム内のコードに対応した履歴取得対象コードと、履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを検証対象プログラムに挿入して履歴取得プログラムを生成する（ステップＳ７０１）。ステップＳ７０１の処理について、詳細は後述する。
【０１４１】
第１生成部３２は、履歴取得プログラムを解析してプログラム解析情報を生成する（ステップＳ７０２）。
【０１４２】
共通化部３４は、履歴取得プログラムに含まれる複数のコードのうちいずれか一つのコードが選択されて実行される場合、複数のコードの履歴情報に用いるメモリ領域を共通化し、共通化に関する共通化情報を生成する（ステップＳ７０３）。
【０１４３】
第１実行部３３は、履歴取得プログラムを実行し、履歴情報を生成し、履歴情報を第１記憶部３５に記憶させる（ステップＳ７０４）。ステップＳ７０４の処理は、図１２（図７のステップＳ１０３）と同様であるため、説明を省略する。なお、本実施形態では、第１実行部３３は、$V[CN]の最新値を履歴情報に記録する。
【０１４４】
第１通信部３１は、第１実行部３３が取得した履歴情報と、第１生成部３２が生成したプログラム解析情報と、共通化部３４が生成した共通化情報を第２情報処理装置２に送信する（ステップＳ７０５）。
【０１４５】
図３０および図３１は、図２９のステップＳ７０１の処理の流れの一例を示すフローチャートである。
【０１４６】
第１生成部３２は、履歴取得対象コードが未挿入のメソッドがあるか判定する（ステップＳ８０１）。本実施形態のプログラム検証では、第１情報処理装置３は、全てのメソッドの検証のために、１つのメソッド内に少なくとも１つの履歴取得対象コードを挿入する。
【０１４７】
ステップＳ８０１でＹＥＳの場合、第１生成部３２は、CNに０を設定する（ステップＳ８０２）。第１生成部３２は、履歴取得対象コードが未挿入のいずれかのメソッド内のコードを参照する（ステップＳ８０３）。
【０１４８】
第１生成部３２は、一回目のステップＳ８０３の処理では、例えば、最初に実行されるメソッドの１行目のコードを参照する。ステップＳ８０３で参照したメソッドを、処理対象メソッドと称する。また、ステップＳ８０３で参照したコードを、処理対象コードと称する。
【０１４９】
第１生成部３２は、処理対象コードが明示的な例外発生を行うコードか判定する（ステップＳ８０４）。明示的な例外発生を行うコードは、例えば、"throw new Error();"である。
【０１５０】
ステップＳ８０４でＹＥＳの場合、第１生成部３２は、処理対象コード直前に実行履歴取得を要求するコードを挿入する（ステップＳ８０５）。実行履歴取得を要求するコードは、例えば、$writeErrorメソッドを呼び出す式（$writeError()）である。$writeError()は、履歴取得コードの一例である。ステップＳ８０５の処理後、処理は、「Ａ」から図３１のステップＳ８１１に移行する。
【０１５１】
ステップＳ８０４でＮＯの場合、第１生成部３２は、処理対象コードが、非決定的な戻り値があるメソッド呼び出しであるか判定する（ステップＳ８０６）。ステップＳ８０６でＹＥＳの場合、第１生成部３２は、処理対象コードを、変数$V[CN]に処理対象コードの戻り値を設定するコードで置換する（ステップＳ８０７）。第１生成部３２は、例えば、処理対象コードを、"$V[CN]=処理対象コード"というコードで置換する。
【０１５２】
変数$V[CN]に設定される値は、メモリ（例えば、第１記憶部３５）に記憶される。変数$V[CN]の値が変更された場合、変更後の値がメモリに記憶される。すなわち、変数$V[CN]の最後の値がメモリに記憶される。
【０１５３】
ステップＳ８０６でＮＯの場合、第１生成部３２は、処理対象コードが、オブジェクト生成式であるか判定する（ステップＳ８０８）。ステップＳ８０８でＹＥＳの場合、第１生成部３２は、処理対象コードを、変数$V[CN]に処理対象コードが生成したオブジェクトを設定するコードで置換する（ステップＳ８０９）。第１生成部３２は、例えば、処理対象コードを、"$V[CN]=処理対象コード"に置換する。なお、Ｓ８０７及びＳ８０９で挿入されるコードは、履歴取得対象コードの例である。
【０１５４】
ステップＳ８０７またはＳ８０９の処理後、第１生成部３２は、CNにCN＋１を設定する（ステップＳ８１０）。そして、ステップＳ８０８でＮＯの場合、またはステップＳ８１０の処理後、「Ａ」からステップＳ８１１に移行する。
【０１５５】
第１生成部３２は、処理対象メソッド内の全コードを参照したか判定する（ステップＳ８１１）。ステップＳ８１１でＮＯの場合、第１生成部３２は、処理対象コードを処理対象メソッド内の次のコードに移動させる（ステップＳ８１２）。ステップＳ８１２の後、処理は、「Ｃ」から、図３０のステップＳ８０３に移行する。
【０１５６】
ステップＳ８１１でＹＥＳの場合、第１生成部３２は、処理対象メソッドの先頭に、配列を初期化するコードを挿入する（ステップＳ８１３）。ステップＳ８１３で挿入されるコードは、例えば、"Object[] $V = new Object[CN]"である。すなわち、CNの現在値が、配列の最大値として設定される。ステップＳ８１３の処理後、処理は、「Ｂ」からステップＳ８０１に移行する。ステップＳ８０１でＮＯの場合、処理が終了する。
【０１５７】
図３２は、検証対象プログラムおよび履歴対象プログラムの第３の例を示す図である。図３２の検証対象プログラムに図３０、図３１の処理を適用すると、図３２の履歴取得プログラムが生成される。履歴取得プログラムにおける下線部が、図３０、図３１の処理で変更された部分である。
【０１５８】
図３３は、プログラム解析情報の第３の例を示す図である。プログラム解析情報は、コード番号（CN）と、メソッド定義と、コード種類とを含む。第１生成部３２は、図３０および図３１の処理中に、各コードを参照した際のCNをプログラム解析情報に記録する。また、第１生成部３２は、記録対象のコードのコード種類、該コードが含まれるメソッド（「メソッド定義」）をCNに対応付けてプログラム解析情報に記録する。
【０１５９】
図３４は、図２９のステップＳ７０３の処理の流れの一例を示すフローチャートである。共通化部３４は、検証対象プログラム内の各コードをノードとする制御フローグラフを生成する（ステップＳ９０１）。共通化部３４は、制御フローグラフから、ループ処理の戻り辺を除去する（ステップＳ９０２）。ループ処理の戻り辺は、例えば、while文の末尾を示す"}"からwhile文の先頭である"while(;;){"に戻るルートである。
【０１６０】
共通化部３４は、制御フローグラフで互いに排他的なノード集合を分類する（ステップＳ９０３）。例えば、複数のコード集合のうち一部のコード集合が選択されて実行される場合、その複数のコードを示すノードの集合を排他的なノード集合であるとする。
【０１６１】
共通化部３４は、排他的なノード集合でのみ使われる変数に同一の識別子を付与する（ステップＳ９０４）。共通化部３４は、変数の生存期間に基づいて干渉グラフを生成する（ステップＳ９０５）。
【０１６２】
共通化部３４は、干渉グラフから、同一の識別子が付与された変数間のエッジを除去する（ステップＳ９０６）。上述のように、干渉グラフにおいて生存期間の重複がエッジで表される。すなわち、共通化部３４は、同一の識別子が付与された変数同士は生存期間の重複がないとみなして干渉グラフを修正する。
【０１６３】
共通化部３４は、干渉グラフ上で、エッジで連結された２つのノードが異なる色になるように彩色する（ステップＳ９０７）。共通化部３４は、履歴取得プログラムにおいて、干渉グラフ上で同じ色に彩色されたノードに対応する変数を同一の変数に変換することにより、メモリ領域を共通化する（ステップＳ９０８）。共通化部３４は、ステップＳ９０８の変換前の変数と変換後の変数との対応関係を示す共通化情報を生成する（ステップＳ９０９）。
【０１６４】
図３５は、制御フローグラフおよび識別子の一例を示す図である。図３５に示す制御フローグラフおよび識別子は、図３４に示す処理で生成される。制御フローグラフにおいて、排他的なノード集合は、異なる枠で示されている。例えば、一点鎖線で囲まれたノード集合と、破線で囲まれたノード集合とは排他的なノード集合である。この例では、if文において条件を満たす場合に実行されるコードを示すノード集合と、条件を満たさない場合に実行されるコードを示すノード集合とが排他的であるとみなされる。
【０１６５】
また、削除ループ処理の戻り辺は削除されるため、図３５におけるwhile文の末尾を示す"}"からwhile文の先頭である"while(;;){"に戻るルートは、削除される。すなわち、繰り返し処理が実行されないと仮定する。
【０１６６】
図３５に示す例では、共通化部３４は、排他的なノード集合のうち一方の集合で用いられる変数$V[1]と他方の集合で用いられる変数$V[2]に同一の識別子１を付与する。共通化部３４は、同様に、変数$V[1]と変数$V[3]に同一の識別子２を付与する。すなわち、共通化部３４は、同時に使用されない変数に同一の識別子を付与する。
【０１６７】
図３６は、干渉グラフの彩色の一例を示す図である。共通化部３４は、履歴取得プログラムと、変数に付与された識別子に基づいて、干渉グラフを生成し、彩色する。共通化部３４は、干渉グラフから、同一の識別子が付与された変数間のエッジを除去する。共通化部３４は、図３６に示す例では、変数$V[1]と変数$V[2]との間のエッジ、および変数$V[1]と変数$V[3]との間のエッジを除去する。破線のエッジは、除去されたことを示す。
【０１６８】
共通化部３４は、干渉グラフ上で、エッジで連結された２つのノードが異なる色になるように彩色する。図３６の例では、変数$V[1]と変数$V[3]との間のエッジが除去されているため、共通化部３４は、変数$V[1]と変数$V[3]とを同じ色に彩色する。また、共通化部３４は、変数$V[2]を変数$V[1]および変数$V[3]と異なる色に彩色する。共通化部３４は、変数$V[1]と変数$V[2]とを同じ色に彩色し、変数$V[3]を変数$V[1]および変数$V[3]と異なる色に彩色してもよい。
【０１６９】
図３７は、変数の変換の一例を示す図である。共通化部３４は、履歴取得プログラムにおいて、干渉グラフ上で同じ色に彩色されたノードに対応する変数を同一の変数に変換することにより、メモリ領域を共通化する。
【０１７０】
図３６に示すように、干渉グラフ上で変数$V[1]と変数$V[3]とが同じ色に彩色されている。よって、共通化部３４は、変数$V[3]を変数$V[1]に変換することにより、メモリ領域を共通化する。
【０１７１】
図３８は、共通化情報の一例を示す図である。CNは、図３０のステップＳ８０７、Ｓ８０９に示すように、配列$V[]の要素番号に用いられている。図３７に示したように、共通化部３４は、変数$V[3]を変数$V[1]に変換したため、共通化前コード番号（ＣＮ）「３」と共通化後コード番号（ＣＮ）「１」とを対応付けて記録する。他の変数は変換されていないため、共通化部３４は、共通化前コード番号（ＣＮ）と共通化後コード番号に同じ数字を記録する。
【０１７２】
図３９は、履歴情報の第３の例を示す図である。第１実行部３３は、図３７に示した変換後の履歴取得プログラムを実行して、履歴情報を生成する。図３７に示したように変数$V[3]は変数$V[1]に変換されているため、変数$V[3]の履歴は記録されない。そして、変換後のプログラムには、変数$V[1]は２つ存在するが、最後の動作を示す履歴情報が記録されるため、"throw $V[1]"で出力されるエラーメッセージが記録される。
【０１７３】
以上のように、本実施形態の第１情報処理装置３は、複数のコードのうち一部のコードが選択されて実行される場合、複数のコードの履歴情報に用いるメモリを共通化するため、履歴の採取負荷を低減し、メモリ使用量を削減することができる。
【０１７４】
図４０は、第２の実施形態における第２情報処理装置４の処理の流れの一例を示すフローチャートである。
【０１７５】
第２通信部４１は、第１情報処理装置３から履歴情報、プログラム解析情報、および共通化情報を受信する（ステップＳ１００１）。
【０１７６】
共通化情報読み取り部４４は、共通化情報を読み取り、共通化情報のコード番号を、検証対象プログラムのコードと対応付ける（ステップＳ１００２）。
【０１７７】
第２生成部４２は、検証対象プログラムに、履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する（ステップＳ１００３）。ステップＳ１００３の処理について、詳細は後述する。
【０１７８】
第２生成部４２は、生成された再生プログラムとプログラム解析情報とを対応づける（ステップＳ１００４）。
【０１７９】
第２実行部４３は、第１情報処理装置３から受信した履歴情報を用いて、生成された再生プログラムを実行する（ステップＳ１００５）。ステップＳ１００５の処理について、詳細は後述する。
【０１８０】
図４１は、図４０のステップＳ１００３の処理の流れの一例を示すフローチャートである。第２生成部４２は、再生コードが未挿入のメソッドがあるか判定する（ステップＳ１１０１）。ステップＳ１１０１でＹＥＳの場合、第２生成部４２は、再生プログラム内の処理対象メソッドのコードを参照する（ステップＳ１１０２）。第２生成部４２は、再生コードが未挿入のメソッドのいずれかを処理対象メソッドとする。また、ステップＳ１１０２で参照されたコードが、以降の処理における処理対象コードとなる。ステップＳ１１０２の１回目の処理を行う場合、第２生成部４２は、例えば、処理対象メソッド内の先頭コードを参照する。
【０１８１】
第２生成部４２は、処理対象コードがプログラム解析情報に含まれるか判定する（ステップＳ１１０３）。ステップＳ１１０３でＹＥＳの場合、第２生成部４２は、共通化情報から、処理対象コードに対応する共通化後コード番号（CN’）を取得する（ステップＳ１１０４）。第２生成部４２は、例えば、プログラム解析情報中で処理対象コードに付与されたコード番号（CN）と同じ値を共通化情報内の共通化前コード番号（CN）から検索する。そして、第２生成部４２は、その共通化前コード番号（CN）に対応する共通化後コード番号（CN’）を共通化情報から取得する。
【０１８２】
第２生成部４２は、ステップＳ１１０４で取得した共通化後コード番号（CN’）を用いて、処理対象コードを、実行履歴中の値を返すコード（emulate(CN’)）に置換する（ステップＳ１１０５）。
【０１８３】
ステップＳ１１０３でＮＯの場合、またはステップＳ１１０５の処理後、第２生成部４２は、処理対象メソッド内の全コードを参照したか判定する（ステップＳ１１０６）。
【０１８４】
ステップＳ１１０６でＮＯの場合、第２生成部４２は、処理対象コードを次のコードに移動させる（ステップＳ１１０７）。ステップＳ１１０７の処理後、処理はステップＳ１１０２に移動する。ステップＳ１１０６でＹＥＳの場合、処理は、ステップＳ１１０１に戻る。ステップＳ１１０１でＮＯの場合、処理が終了する。
【０１８５】
図４２は、再生プログラムの第３の例を示す図である。図４２に示す再生プログラムは、図４１の処理により生成されたプログラムである。図４１に示したように、第２生成部４２は、共通化後コード番号（CN’）を用いて、処理対象コードを、実行履歴中の値を返すコード（emulate(CN’)）に置換する。図４２に示す例では、第２生成部４２は、処理対象コードをemulate(0)、emulate(1)、emulate(2)、emulate(1)に置換して、再生プログラムを生成している。
【０１８６】
図４３は、図４０のステップＳ１００５の処理の流れの一例を示す図である。第２実行部４３は、第２生成部４２が生成した再生プログラム内の、呼出元のメソッドを実行する（ステップＳ１２０１）。ステップＳ１２０１の処理後、呼び出し元のメソッドが処理対象メソッドとなる。第２実行部４３は、処理対象メソッドのコードを参照する（ステップＳ１２０２）。第２実行部４３は、ステップＳ１２０２を１回目に実行する場合、処理対象メソッドの先頭コードを参照する。第２実行部４３は、ステップＳ１２０２で参照したコードを処理対象コードとする。
【０１８７】
第２実行部４３は、処理対象コードが再生コードであるか判定する（ステップＳ１２０３）。再生コードは、第２生成部４２により検証対象プログラムに挿入されたコードである。図４２に示す例では、再生コードは、"emulate(CN’)"（emulate(0)、emulate(1)およびemulate(2)）である。
【０１８８】
ステップＳ１２０３でＹＥＳの場合、第２実行部４３は、再生コードの引数（CN’）値と対応する$V[CN’]値を履歴情報から取得し、再生コードの戻り値に設定する（ステップＳ１２０４）。例えば、図３９に示すように、emulate(0)に対応する$V[0]の値は、"/usr/local/bin/app"であるため、第２実行部４３は、"/usr/local/bin/app"を、emulate(0)の戻り値に設定する。また、emulate(1)に対応する$V[1]の値は、"Error@999"であるため、第２実行部４３は、"Error@999"を、emulate(1)の戻り値に設定する。また、emulate(2)に対応する$V[2]の値は、"8"であるため、第２実行部４３は、"8"を、emulate(2)の戻り値に設定する。
【０１８９】
ステップＳ１２０３でＮＯの場合、第２実行部４３は、処理対象コードがメソッド呼出式であるか判定する（ステップＳ１２０５）。ステップＳ１２０５でＹＥＳの場合、第２実行部４３は、呼び出し先のメソッドに移動し（ステップＳ１２０６）、ステップＳ１２０２に戻る。ステップＳ１２０５でＮＯの場合、第２実行部４３は、処理対象コードを実行する（ステップＳ１２０７）。
【０１９０】
ステップＳ１２０４またはＳ１２０７の処理後、第２実行部４３は、処理対象メソッド内の全コードを参照したか判定する（ステップＳ１２０８）。ステップＳ１２０８でＹＥＳの場合、第２実行部４３は、処理を終了する。ステップＳ１２０８でＮＯの場合、第２実行部４３は、処理対象コードを次のコードに移行させ（ステップＳ１２０９）、ステップＳ１２０２に戻る。
【０１９１】
（第３の実施形態）
以下、図面を参照して第３の実施形態について説明する。本実施形態では、再生中のプログラム内の変数等の値が記憶されたメモリの状態を可視化するインスペクションツールを適用した例について説明する。
【０１９２】
上述のように、第１情報処理装置１または第１情報処理装置３は、履歴取得対象コードの最後の動作を示す履歴情報を取得する。そして、第２情報処理装置２または第２情報処理装置４は、履歴情報を用いて、再生プログラムを実行する。第２情報処理装置２または第２情報処理装置４がインスペクションツールを適用した場合、例えば、再生されていない値のメモリ状態が明示されない。
【０１９３】
図４４は、インスペクションツールの第１の表示例を示す図である。図４４に示すように、履歴情報（実行履歴）を用いて再生プログラムを実行した場合、インスペクションツールを用いると、所定タイミングの各値のメモリ状態が可視化される。図４４に示す例では、CN2のコード実行直後におけるインスペクションツールの表示例を示す。
【０１９４】
例えば"mm.msg"および"mm.time"の値は、CN2のコード実行時点では、使用されない。よって、図４４に示す例では、"mm.msg"および"mm.time"の値の初期値である空文字列が表示されている。すなわち、インスペクションツールの表示タイミングにおいて使用されていない値は、不明となる。
【０１９５】
図４５は、インスペクションツールの第２の表示例を示す図である。図４５では、例えば、スナップショットポイントを用いて、事前に再生プログラムを再生させた際に、各コードの実行直後のメモリ状態を可視化し、再生前後の値をマージして可視化した例である。図４５は、図４４に示す再生プログラムを実行し、CN3のコード実行直後のメモリ状態と、CN5のコード実行直後のメモリ状態とをマージして、CN4のコード実行直後のメモリ状態を表現した例を示している。
【０１９６】
図４５に示すように、"mm.msg"および"mm.time"の値は、CN3のコード実行直後とCN5のコード実行直後とで異なるため、CN4のコード実行直後のメモリ状態は、"・・・"or"・・・"という形式で表示されている。しかし、この表示方法では、値の適切さや不定性を読み取ることが困難である。また、表示項目が増加するため、表示を実行するためのメモリ使用量が増加する。
【０１９７】
＜第１情報処理装置の一例＞
図４６は、第３の実施形態における第１情報処理装置５の一例を示す図である。第１情報処理装置５は、第１通信部５１と、第１生成部５２と、第１実行部５３と、第１記憶部５４とを含む。なお、第３の実施形態におけるプログラム検証支援システムの全体構成は、図１に示す構成と同様であるとする。
【０１９８】
第１通信部５１は、後述する履歴情報と、プログラム解析情報とを第２情報処理装置６に送信する。
【０１９９】
第１生成部５２は、検証対象プログラム内のコードに対応した履歴取得対象コードと、履歴取得対象コードの最後の動作（実行結果）を示す履歴情報を取得する履歴取得コードとを検証対象プログラムに挿入して履歴取得プログラムを生成する。また、第１生成部５２は、履歴取得プログラムを解析してプログラム解析情報を生成する。
【０２００】
第１実行部５３は、履歴取得プログラムを実行し、履歴情報を生成し、履歴情報を第１記憶部５４に記憶させる。第１実行部５３は、履歴情報を取得する際に、第１記憶部５４から履歴取得対象コードの最新の値を取得し、履歴情報に記録する。
【０２０１】
第１記憶部５４には、検証対象プログラムと履歴取得プログラムとプログラム解析情報と履歴情報とが記憶される。検証対象プログラムは、予め第１記憶部５４に記憶される。履歴取得プログラムは、第１生成部５２が生成したプログラムである。プログラム解析情報は、第１生成部５２が生成した情報である。履歴情報は、第１実行部５３が取得した情報である。
【０２０２】
＜第２情報処理装置の一例＞
図４７は、第３の実施形態における第２情報処理装置６の一例を示す図である。第２情報処理装置６は、第２通信部６１と第２生成部６２と第２実行部６３と第３生成部６４と第３実行部６５と表示制御部６６と第２記憶部６７とを含む。第２情報処理装置６は、表示装置７と接続される。
【０２０３】
第２通信部６１は、第１情報処理装置１から、履歴情報とプログラム解析情報とを受信する。
【０２０４】
第２生成部６２は、検証対象プログラムに、履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラムを生成する。第２生成部６２は、生成された再生プログラムとプログラム解析情報とを対応づける。
【０２０５】
第２実行部６３は、第１情報処理装置１から受信した履歴情報を用いて、再生プログラムを実行する。第２実行部６３は、再生プログラム中に表示制御部６６を呼び出す。
【０２０６】
第３生成部６４は、メモリ操作履歴を収集するためのコードを挿入してメモリ操作履歴出力用の再生プログラムを生成する。
【０２０７】
第３実行部６５は、第３生成部６４が生成した操作履歴出力用の再生プログラムを再生して、メモリ操作履歴を収集する。
【０２０８】
表示制御部６６は、メモリ操作履歴を用いて、第２実行部６３が実行する再生プログラムの実行中にメモリに記憶された値に、値の過去および未来の操作を示す記号を付加したメモリ状態を表示させる。表示制御部６６は、例えば、第２情報処理装置６に接続された表示装置７に、上記メモリ状態を表示させる。
【０２０９】
第２記憶部６７には、検証対象プログラムとプログラム解析情報と履歴情報と再生プログラムと操作履歴とが記憶される。検証対象プログラムは、第１情報処理装置５の第１記憶部５４に記憶されているプログラムと同じである。プログラム解析情報および履歴情報は、第２通信部６１が第１情報処理装置５から受信した情報である。再生プログラムは、第２生成部６２が生成したプログラムである。操作履歴は、第３実行部６５が収集したメモリ状態を示す履歴である。
【０２１０】
図４８は、検証対象プログラムの第４の例を示す図である。図４８に示す検証対象プログラムは、以下に説明する本実施形態の処理において使用される。
【０２１１】
＜実施形態の処理の流れの一例＞
図４９は、第３の実施形態における第１情報処理装置５の処理の流れの一例を示すフローチャートである。第１生成部５２は、検証対象プログラム内のコードに対応した履歴取得対象コードと、履歴取得対象コードの最後の動作を示す履歴情報を取得する履歴取得コードとを検証対象プログラムに挿入して履歴取得プログラムを生成する（ステップＳ１３０１）。ステップＳ１３０１の処理について、詳細は後述する。
【０２１２】
第１生成部５２は、履歴取得プログラムを解析してプログラム解析情報を生成する（ステップＳ１３０２）。
【０２１３】
第１実行部５３は、履歴取得プログラムを実行し、履歴情報を生成し、履歴情報を第１記憶部５４に記憶させる（ステップＳ１３０３）。ステップＳ１３０３の処理は、図７のステップＳ１０３、および図１２に示す処理と同様であるため詳細な説明を省略する。
【０２１４】
第１通信部５１は、第１実行部５３が取得した履歴情報と、第１生成部５２が生成したプログラム解析情報とを第２情報処理装置６に送信する（ステップＳ１３０４）。
【０２１５】
図５０および図５１は、図４９のステップＳ１３０１の処理の流れの一例を示すフローチャートである。第１生成部５２は、履歴取得対象コードが未挿入のメソッドがあるか判定する（ステップＳ１４０１）。
【０２１６】
ステップＳ１４０１でＹＥＳの場合、第１生成部５２は、識別情報VSに０を設定する（ステップＳ１４０２）。そして、第１生成部５２は、履歴取得対象コードを未挿入であるメソッドの引数があるか判定する（ステップＳ１４０３）。ステップＳ１４０３でＹＥＳの場合、第１生成部５２は、実行結果を記憶するローカル変数にメソッドの引数を設定するコードを挿入する（ステップＳ１４０５）。ステップＳ１４０５で挿入されるコードは、例えば、"$V[VS]=引数A"という形式である。そして、第１生成部５２は、VSにVS+1を設定し（ステップＳ１４０６）、ステップＳ１４０３に戻る。
【０２１７】
ステップＳ１４０３でＮＯの場合、第１生成部５２は、履歴取得対象コードが未挿入のいずれかのメソッド内のコードを参照する（ステップＳ１４０７）。第１生成部５２は、一回目のステップＳ１４０７の処理では、例えば、最初に実行されるメソッドの１行目のコードを参照する。ステップＳ１４０７で参照したコードを含むメソッドを、処理対象メソッドと称する。また、ステップＳ１４０７で参照したコードを、処理対象コードと称する。
【０２１８】
第１生成部５２は、処理対象コードが復帰（return文）であるか判定する（ステップＳ１４０８）。ステップＳ１４０８でＹＥＳの場合、第１生成部５２は、処理対象コード直前に実行履歴取得を要求するコードを挿入する（ステップＳ１４０９）。実行履歴取得を要求するコードは、例えば、$writeメソッドを呼び出す式（$write()）である。$write()は、履歴取得コードの一例である。ステップＳ１４０９の処理後、処理は、図５１のステップＳ１４１４に移行する。
【０２１９】
ステップＳ１４０８でＮＯの場合、処理は、「Ａ」から図５１のステップＳ１４１０に移行する。第１生成部５２は、処理対象コードが、フィールド（属性）読込式であるか判定する（ステップＳ１４１０）。ステップＳ１４１０でＹＥＳの場合、第１生成部５２は、処理対象コードを、変数$V[VS]に処理対象コードの読込値を設定するコードで置換する（ステップＳ１４１１）。第１生成部５２は、例えば、処理対象コードを、"$V[VS]=処理対象コード"というコードで置換する。
【０２２０】
変数$V[VS]に設定される値は、メモリ（例えば、第１記憶部５４）に記憶される。変数$V[VS]の値が変更された場合、変更後の値がメモリに記憶される。すなわち、変数$V[VS]の最後の値がメモリに記憶される。
【０２２１】
第１生成部５２は、処理対象コードがフィールド（属性）書込式、ローカル変数読込式、またはローカル変数書込式のいずれかであるか判定する（ステップＳ１４１３）。
【０２２２】
ステップＳ１４１１の処理後またはステップＳ１４１３でＹＥＳの場合、第１生成部５２は、VSにVS＋１を設定する（ステップＳ１４１２）。ステップＳ１４１２の処理後またはステップＳ１４１３でＮＯの場合、第１生成部５２は、処理対象メソッドの全コードを参照したか判定する（ステップＳ１４１４）。ステップＳ１４１４でＮＯの場合、第１生成部５２は、処理対象コードを処理対象メソッド内の次のコードに移動させる（ステップＳ１４１５）。ステップＳ１４１５の処理後、処理は、図５０のステップＳ１４０７に移行する。
【０２２３】
ステップＳ１４１４でＹＥＳの場合、第１生成部５２は、処理対象メソッドの先頭に、配列を初期化するコードを挿入する（ステップＳ１４１６）。ステップＳ１４１６で挿入されるコードは、例えば、"Object[]$V=new Object[VS]"である。なお、図５０、５１に示す例では、ステップＳ１４１６の処理の時点におけるVSが配列の最大値に相当する。ステップＳ１４１６の処理後、処理は、図５０のステップＳ１４０１に移行する。ステップＳ１４０１でＮＯの場合、処理が終了する。
【０２２４】
なお、図５０、５１の処理において、Ｓ１４０５およびＳ１４１１で挿入されるコードは、履歴取得対象コードの例である。
【０２２５】
図５２は、履歴取得プログラムの第４の例を示す図である。第１生成部５２は、図４８に示す検証対象プログラムに対して、図５０、５１の処理を実行した結果、図５２に示す履歴取得プログラムを生成する。なお、図５２のプログラム内の下線部分は、図５０、５１の処理で追加または変更された部分である。
【０２２６】
図５３は、プログラム解析情報の第４の例を示す図である。第１生成部５２は、図５２に示す履歴取得プログラムを解析して、図５３に示すプログラム解析情報を生成する。図５３に示すように本実施形態におけるプログラム解析情報は、VS、行番号、オブジェクトの型、属性／変数の名前、および操作を含む。
【０２２７】
図５４は、履歴情報の第４の例を示す図である。第１実行部５３は、図５２に示す履歴取得プログラムを実行して、図５４に示す履歴情報（実行履歴）を生成し、履歴情報を第１記憶部５４に記憶させる。図５４に示すように、第１実行部５３は、履歴取得プログラムで挿入されたコードにより、$V[0],$V[2],$V[6]の値を履歴情報として記録する。
【０２２８】
図５５は、第３の実施形態における第２情報処理装置６の処理の流れの一例を示すフローチャートである。
【０２２９】
第２通信部６１は、第１情報処理装置５から履歴情報とプログラム解析情報とを受信する（ステップＳ１５０１）。
【０２３０】
第３生成部６４は、メモリ操作履歴を収集するためのコードを挿入してメモリ操作履歴出力用の再生プログラム（第１再生プログラム）を生成する（ステップＳ１５０２）。
【０２３１】
第３実行部６５は、操作履歴出力用の再生プログラムを再生して、メモリ操作履歴を収集する（ステップＳ１５０３）。
【０２３２】
第２生成部６２は、検証対象プログラムに、履歴取得対象コードの動作を再生する再生コードを挿入して再生プログラム（第２再生プログラム）を生成する（ステップＳ１５０４）。
【０２３３】
第２生成部６２は、生成された再生プログラムとプログラム解析情報とを対応づける（ステップＳ１５０５）。
【０２３４】
第２実行部６３は、第１情報処理装置５から受信した履歴情報を用いて、第２生成部６２により生成された再生プログラムを実行する（ステップＳ１５０６）。表示制御部６６は、ステップＳ１５０６の処理中に、メモリ操作履歴を用いて、メモリに記憶された値に、値の過去および未来の操作を示す記号を付加したメモリ状態を表示させる。
【０２３５】
ステップＳ１５０２、Ｓ１５０３、Ｓ１５０５およびＳ１５０６の処理について、詳細は後述する。
【０２３６】
図５６および図５７は、図５２のステップＳ１５０２の処理の流れの一例を示すフローチャートである。第３生成部６４は、メモリ操作履歴を収集するためのコード（収集コード）が未挿入のメソッドがあるか判定する（ステップＳ１６０１）。ステップＳ１６０１でＹＥＳの場合、第３生成部６４は、識別情報VSに０を設定する（ステップＳ１６０２）。そして、第３生成部６４は、収集コードを未挿入であるメソッドの引数があるか判定する（ステップＳ１６０３）。ステップＳ１６０３でＹＥＳの場合、第３生成部６４は、メモリ操作履歴「VS、変数、読込値,“読込”」を収集するコードを挿入する（ステップＳ１６０４）。ステップＳ１６０４で挿入されるコードは、例えば、"trace(VS)"という形式である。そして、第３生成部６４は、ステップＳ１６０３に戻る。
【０２３７】
ステップＳ１６０３でＮＯの場合、第３生成部６４は、収集コードが未挿入のいずれかのメソッド内のコードを参照する（ステップＳ１６０５）。
【０２３８】
第３生成部６４は、一回目のステップＳ１６０５の処理では、例えば、最初に実行されるメソッドの１行目のコードを参照する。ステップＳ１６０５で参照したコードを含むメソッドを、処理対象メソッドと称する。また、ステップＳ１６０５で参照したコードを、処理対象コードと称する。
【０２３９】
処理は、ステップＳ１６０５から、図５７のステップＳ１６０６に移行する。第３生成部６４は、処理対象コードがフィールド（属性）読込式であるか判定する（ステップＳ１６０６）。ステップＳ１６０６でＹＥＳの場合、第３生成部６４は、処理対象コードを、メモリ操作履歴「VS、参照、属性、読込値、“読込”」を収集するコードで置換する（ステップＳ１６０７）。ステップＳ１６０７でメモリ操作履歴を収集するコードは、例えば、"trace(VS)"という形式である。
【０２４０】
第３生成部６４は、処理対象コードがフィールド書込式であるか判定する（ステップＳ１６０８）。ステップＳ１６０８でＹＥＳの場合、第３生成部６４は、処理対象コードを、メモリ操作履歴「VS、参照、属性、書込値、“書込”」を収集するコードで置換する（ステップＳ１６０９）。ステップＳ１６０９でメモリ操作履歴を収集するコードは、例えば、"trace(VS)，書込値"という形式である。
【０２４１】
第３生成部６４は、処理対象コードがローカル変数読込式であるか判定する（ステップＳ１６１０）。ステップＳ１６１０でＹＥＳの場合、第３生成部６４は、処理対象コードを、メモリ操作履歴「VS、変数、読込値、“読込”」を収集するコードで置換する（ステップＳ１６１１）。ステップＳ１６１１でメモリ操作履歴を収集するコードは、例えば、"trace(VS)"という形式である。
【０２４２】
第３生成部６４は、処理対象コードがローカル変数書込式であるか判定する（ステップＳ１６１２）。ステップＳ１６１２でＹＥＳの場合、第３生成部６４は、処理対象コードを、メモリ操作履歴「VS、変数、書込値、“書込”」を収集するコードで置換する（ステップＳ１６１３）。ステップＳ１６１３でメモリ操作履歴を収集するコードは、例えば、"trace(VS)，書込値"という形式である。
【０２４３】
ステップＳ１６０７、Ｓ１６０９、Ｓ１６１１、およびＳ１６１３の処理後、第３生成部６４は、VSにVS＋１を設定する（ステップＳ１６１４）。ステップＳ１６１４の処理後またはステップＳ１６１２でＮＯの場合、第３生成部６４は、処理対象メソッドの全コードを参照したか判定する（ステップＳ１６１５）。ステップＳ１６１５でＮＯの場合、第３生成部６４は、処理対象コードを処理対象メソッド内の次のコードに移動させ（ステップＳ１６１６）、図５６のステップＳ１６０５に移行する。
【０２４４】
ステップＳ１６１５でＹＥＳの場合、処理は、図５６のステップＳ１６０１に移行する。ステップＳ１６０１でＮＯの場合、処理が終了する。
【０２４５】
図５８は、メモリ操作履歴収集用の再生プログラムの例を示す図である。図５８に示すメモリ操作履歴収集用の再生プログラム（第１再生プログラム）は、図４８に示す検証対象プログラムに対して図５６および図５７に示す処理を実行して生成されたプログラムである。
【０２４６】
図５９および図６０は、図５５のステップＳ１５０３の処理の流れの一例を示すフローチャートである。第３実行部６５は、第３生成部６４が生成した再生プログラム内の、呼出元のメソッドを実行する（ステップＳ１７０１）。ステップＳ１７０１の処理後、呼び出し元のメソッドが処理対象メソッドとなる。第３実行部６５は、処理対象メソッドのコードを参照する（ステップＳ１７０２）。第３実行部６５は、ステップＳ１７０２を１回目に実行する場合、処理対象メソッドの先頭コードを参照する。以下、ステップＳ１７０２で参照したコードを処理対象コードとする。
【０２４７】
第３実行部６５は、処理対象コードが読込式に対する収集コードであるか判定する（ステップＳ１７０３）。読込式に対する収集コードは、第３実行部６５により検証対象プログラムに挿入された読込式のメモリ操作履歴を収集するコード（trace(VS, …, “読込”）である。ステップＳ１７０３でＹＥＳの場合、第３実行部６５は、メモリ操作履歴に「VS、参照、属性、読込値、“読込”」を記録する。そして、第３実行部６５は、処理対象コードがフィールド読込式の収集コードであるか判定する（ステップＳ１７０５）。
【０２４８】
ステップＳ１７０５でＹＥＳの場合、第３実行部６５は、収集コードの引数（VS）値と対応する値（$V[VS]）を返す（ステップＳ１７０６）。ステップＳ１７０５でＮＯの場合、第３実行部６５は、収集コードの引数（読込値）を返す（ステップＳ１７０７）。ステップＳ１７０６またはステップＳ１７０７の処理後、処理は、図６０のステップＳ１７１２に移行する。
【０２４９】
ステップＳ１７０３でＮＯの場合、第３実行部６５は、処理対象コードが書込式に対する収集コードであるか判定する（ステップＳ１７０８）。ステップＳ１７０８でＹＥＳの場合、第３実行部６５は、メモリ操作履歴に「VS、参照、属性、書込値、“書込”」を記録する（ステップＳ１７０９）。また、第３実行部６５は、収集コードの引数（書込値）を返す（ステップＳ１７１０）。
【０２５０】
ステップＳ１７０８でＮＯの場合、第３実行部６５は、処理対象コードを実行する（ステップＳ１７１１）。ステップＳ１７１０またはステップＳ１７１１の処理後、処理は、図６０のステップＳ１７１２に移行する。
【０２５１】
第３実行部６５は、メソッド内の全コードを参照したか判定する（ステップＳ１７１２）。ステップＳ１７１２でＹＥＳの場合、処理を終了する。
【０２５２】
ステップＳ１７１２でＮＯの場合、第３実行部６５は、処理対象コードを次のコードに移行させ（ステップＳ１７１３）、処理は、図５９のステップＳ１７０２に移行する。
【０２５３】
図６１は、メモリ操作履歴の一例を示す図である。図６１に示すようにメモリ操作履歴は、VS、参照、属性名／変数名、読込値／書込値、操作を含む。「参照」は、オブジェクトの識別子であり、例えば、異なるオブジェクト間で重複する可能性が低いハッシュ値が適用される。図６１に示すメモリ操作履歴は、図５９および図６０の処理により生成される。
【０２５４】
図６２は、図５５のステップＳ１５０４の処理の流れの一例を示すフローチャートである。第２生成部６２は、再生コードが未挿入のメソッドがあるか判定する（ステップＳ１８０１）。ステップＳ１８０１でＹＥＳの場合、第２生成部６２は、VSに０を設定する。
【０２５５】
第２生成部６２は、再生コードを未挿入であるメソッドの引数があるか判定する（ステップＳ１８０３）。ステップＳ１８０３でＹＥＳの場合、第２生成部６２は、再生コードを挿入する（ステップＳ１８０４）。再生コードは、実行履歴中の値を返すコードであり、履歴情報にもとづいて、検証対象プログラム内の履歴取得対象コードの最後の動作を再生するコードである。再生コードの形式は、例えば、"emulate(VS)"という形式である。
【０２５６】
そして、第２生成部６２は、VSにVS+1を設定する（ステップＳ１８０５）。ステップＳ１８０５の処理後、ステップＳ１８０３に戻る。ステップＳ１８０３でＮＯの場合、第２生成部６２は、再生プログラム内の処理対象メソッドのコードを参照する（ステップＳ１８０６）。ステップＳ１８０６で参照したコードを処理対象コードと称する。また、処理対象コードが含まれるメソッドを処理対象メソッドと称する。
【０２５７】
第２生成部６２は、処理対象コードがフィールド読込式であるか判定する（ステップＳ１８０７）。ステップＳ１８０７でＹＥＳの場合、第２生成部６２は、処理対象コードを再生コードで置換する（ステップＳ１８０８）。
【０２５８】
ステップＳ１８０７でＮＯの場合、第２生成部６２は、処理対象コードがフィールド書込式、ローカル変数読込式、またはローカル変数書込式のいずれかであるか判定する（ステップＳ１８０９）。ステップＳ１８０９でＹＥＳの場合、またはステップＳ１８０８の処理後、第２生成部６２は、VSにVS+1を設定する（ステップＳ１８１０）。
【０２５９】
ステップＳ１８０９でＮＯの場合、第２生成部６２は、処理対象メソッド内の全コードを参照したか判定する（ステップＳ１８１１）。
【０２６０】
ステップＳ１８１１でＮＯの場合、第２生成部６２は、処理対象コードを次のコードに移動させる（ステップＳ１８１２）。ステップＳ１８１２の処理後、処理はステップＳ１８０６に移動する。
【０２６１】
ステップＳ１８１１でＹＥＳの場合、処理は、ステップＳ１８０１に戻る。ステップＳ１８０１でＮＯの場合、処理は終了する。
【０２６２】
図６３は、再生プログラムの第４の例を示す図である。図６３に示す再生プログラムは、図４８の検証対象プログラムに基づいて、図６２の処理により第２生成部６２が生成したプログラム（第２再生プログラム）である。図６３の再生プログラムのうち、下線部は、図６２の処理により挿入または置換されたコードである。
【０２６３】
図６４は、図５５のステップＳ１５０６の処理の流れの一例を示すフローチャートである。第２実行部６３は、第２生成部６２が生成したプログラムの、呼出元のメソッドを実行する（ステップＳ１９０１）。ステップＳ１９０１の処理後、呼び出し元のメソッドが処理対象メソッドとなる。
【０２６４】
表示制御部６６は、メモリ操作履歴と文字列表現決定表に基づいて、メモリ状態を表示させる（ステップＳ１９０２）。メモリ状態の表示方法について、詳細は後述する。第２実行部６３は、処理対象メソッドのコードを参照する（ステップＳ１９０３）。第２実行部６３は、ステップＳ１９０３を１回目に実行する場合、処理対象メソッドの先頭コードを参照する。以下、ステップＳ１９０３で参照したコードを処理対象コードとする。
【０２６５】
第２実行部６３は、処理対象コードが再生コードであるか判定する（ステップＳ１９０４）。再生コードは、第２生成部６２により検証対象プログラムに挿入されたコードである。ステップＳ１９０４でＹＥＳの場合、第２実行部６３は、再生コードの引数（VS）値と対応する値（$V[VS]）を返す（ステップＳ１９０５）。
【０２６６】
ステップＳ１９０４でＮＯの場合、第２実行部６３は、処理対象コードを実行する（ステップＳ１９０６）。ステップＳ１９０５またはステップＳ１９０６の処理後、表示制御部６６は、メモリ操作履歴と文字列表現決定表に基づいて、現在のメモリ状態を表示させる（ステップＳ１９０７）。なお、表示制御部６６は、まだ表示していないローカル変数、またはオブジェクトの属性のメモリ状態がある場合に、そのメモリ状態を表示する。
【０２６７】
第２実行部６３は、メソッド内の全コードを参照したか判定する（ステップＳ１９０８）。ステップＳ１９０８でＹＥＳの場合、処理を終了する。
【０２６８】
ステップＳ１９０８でＮＯの場合、第２実行部６３は、処理対象コードを次のコードに移行させ（ステップＳ１９０９）、処理をステップＳ１９０３に移行する。
【０２６９】
図６５は、文字列表現決定表の一例を示す図である。文字列表現決定表は、例えば、第２記憶部６７に予め記憶されている。表示制御部６６は、図６５に示す文字列表現決定表に基づいて、現在のメモリ状態を表示させる。表示制御部６６は、メモリ操作履歴と文字列表現決定表とに基づいて、メモリに記憶された変数値または属性値に、値に対する過去および未来の操作を示す記号を付加したメモリ状態を表示させる。記号は、例えば、"→"、"←"、または"＊"である。
【０２７０】
図６６は、インスペクションツールの第３の表示例を示す図である。図６６に示すインスペクションツールの表示例は、図６１のメモリ操作履歴のVS=2に対応するコードの実行直後におけるメモリの状態を図６４の処理により表示制御部６６が可視化した例である。
【０２７１】
例えば、VS=2に対応するコードは、属性userへの読込操作であり、処理対象コードの実行から、変数への書込み操作までの間に、読込操作（boss）があるので、図６５のcase1に該当し、表示制御部６６は、変数userの値を"boss"→と表示する。また、VS=1に対応するコードは、変数mmへの読込操作であり、処理対象コードの実行から、変数への書込み操作までの間に、読込操作（Memo@111）があるので、図６５のcase1に該当し、表示制御部６６は、変数mmの値を"Memo@111"→と表示する。また、VS=2に対応するコード実行時においてもその表示は維持される。
【０２７２】
また、属性mm.msgに関して、処理対象のコードの実行から、属性への書込操作までの間に読込操作（working）があるので、case6に該当し、表示制御部６６は、→"Working"と表示する。また、属性mm.timeに関して、図６５のいずれの条件についてもNOとなるため、case5に該当し、表示制御部６６は、"＊"と表示する。
【０２７３】
図６７は、インスペクションツールの第４の表示例を示す図である。表示制御部６６は、図６７に示す操作履歴と図６５に示す文字列表現決定表に基づいて、インスペクションツールの表示方法を決定する。
【０２７４】
属性mm.msgに関して、VS=8のコードの実行直後では、図６５のcase6に該当するため、表示制御部６６は、→"Breaking"と表示する。また、属性mm.msgに関して、VS=10のコードの実行直後では、図６５のcase3に該当するため、表示制御部６６は、←"Breaking"と表示する。また、属性mm.msgに関して、VS=2のコードの実行直後では、図６５のcase6に該当するため、表示制御部６６は、→"Working"と表示する。
【０２７５】
また、属性mm.msgに関して、VS=6のコードの実行直後では、図６５のcase2に該当するため、表示制御部６６は、"Working"と表示する。また、属性mm.msgに関して、VS=6のコードの実行直後では、図６５のcase2に該当するため、表示制御部６６は、"Working"と表示する。また、属性mm.timeに関して、VS=8のコードの実行直後では、図６５のcase5に該当するため、表示制御部６６は、"＊"と表示する。
【０２７６】
図６８は、インスペクションツールの第５の表示例を示す図である。図６８に示すメモリ操作履歴は、図６７に示すメモリ操作履歴を説明のために変形した例である。表示制御部６６は、図６８に示す操作履歴と図６５に示す文字列表現決定表に基づいて、インスペクションツールの表示方法を決定する。
【０２７７】
VS＝２のコード実行直後において、処理対象コードは変数userの読込操作(boss)であり、処理対象コードの実行から，変数userへの書込操作までの間に、読込操作(boss)がある。よって、図６５のcase4に該当するため、表示制御部６６は、→"boss"→と表示する。
【０２７８】
以上のように、第２情報処理装置６は、メモリに記憶された値に、値の過去および未来の操作を示す記号を付加したメモリ状態を表示させるので、まだ再生されていない値、過去に記憶されていた値等を考慮したメモリ状態の表示を行うことができる。よって、少ない表示内容で、過去および未来の操作を含むメモリ状態をユーザに示すことができる。
【０２７９】
＜第１情報処理装置１，３，５のハードウェア構成の一例＞
次に、図６９の例を参照して、第１情報処理装置１，３，５のハードウェア構成の一例を説明する。図６９の例に示すように、バス１００に対して、プロセッサ１１１とRandom Access Memory(RAM)１１２とRead Only Memory(ROM)１１３とが接続される。また、該バス１００に対して、補助記憶装置１１４と媒体接続部１１５と通信インタフェース１１６とが接続される。
【０２８０】
プロセッサ１１１はＲＡＭ１１２に展開されたプログラムを実行する。プロセッサ１１１は、例えば、第１プロセッサである。実行されるプログラムとしては、実施形態における処理を行うプログラム検証支援プログラムが適用されてもよい。
【０２８１】
ＲＯＭ１１３はＲＡＭ１１２に展開されるプログラムを記憶する不揮発性の記憶装置である。補助記憶装置１１４は、種々の情報を記憶する記憶装置であり、例えばハードディスクドライブや半導体メモリ等を補助記憶装置１１４に適用してもよい。補助記憶装置１１４に実施形態の処理を行うプログラム検証支援プログラムが記録されていてもよい。
【０２８２】
媒体接続部１１５は、可搬型記録媒体１１８と接続可能に設けられている。可搬型記録媒体１１８としては、可搬型のメモリや光学式ディスク（例えば、Compact Disc(CD)やDigital Versatile Disc(DVD))、半導体メモリ等を適用してもよい。可搬型記録媒体１１８に実施形態の処理を行うプログラム検証支援プログラムが記録されていてもよい。
【０２８３】
図４に示す第１記憶部１４、図２５に示す第１記憶部３５、および図４６に示す第１記憶部５４は、ＲＡＭ１１２や補助記憶装置１１４等により実現されてもよい。図４に示す第１通信部１１、図２５に示す第１通信部３１、図４６に示す第１通信部５１は、通信インタフェース１１６により実現されてもよい。図４に示す第１生成部１２、第１実行部１３、図２５に示す第１生成部３２、第１実行部３３、共通化部３４、および図４６に示す第１生成部５２、第１実行部５５は、与えられたプログラム検証支援プログラムをプロセッサ１１１が実行することにより実現されてもよい。
【０２８４】
ＲＡＭ１１２、ＲＯＭ１１３、補助記憶装置１１４および可搬型記録媒体１１８は、何れもコンピュータ読み取り可能な有形の記憶媒体の一例である。これらの有形な記憶媒体は、信号搬送波のような一時的な媒体ではない。
【０２８５】
＜第２情報処理装置２，４，６のハードウェア構成の一例＞
次に、図７０の例を参照して、第２情報処理装置２のハードウェア構成の一例を説明する。図７０の例に示すように、バス２００に対して、プロセッサ２１１とRandom Access Memory(RAM)２１２とRead Only Memory(ROM)２１３とが接続される。また、該バス２００に対して、補助記憶装置２１４と媒体接続部２１５と通信インタフェース２１６とが接続される。
【０２８６】
プロセッサ２１１はＲＡＭ２１２に展開されたプログラムを実行する。プロセッサ２１１は、例えば、第２プロセッサである。実行されるプログラムとしては、実施形態における処理を行うプログラム検証支援プログラムが適用されてもよい。
【０２８７】
ＲＯＭ２１３はＲＡＭ２１２に展開されるプログラムを記憶する不揮発性の記憶装置である。補助記憶装置２１４は、種々の情報を記憶する記憶装置であり、例えばハードディスクドライブや半導体メモリ等を補助記憶装置２１４に適用してもよい。補助記憶装置２１４に実施形態の処理を行うプログラム検証支援プログラムが記録されていてもよい。
【０２８８】
媒体接続部１１５は、可搬型記録媒体１１８と接続可能に設けられている。可搬型記録媒体１１８としては、可搬型のメモリや光学式ディスク（例えば、Compact Disc(CD)やDigital Versatile Disc(DVD))、半導体メモリ等を適用してもよい。可搬型記録媒体１１８に実施形態の処理を行うプログラム検証支援プログラムが記録されていてもよい。
【０２８９】
図５に示す第２記憶部２４、図２６に示す第２記憶部４５、および図４７に示す第２記憶部６７は、ＲＡＭ２１２や補助記憶装置２１４等により実現されてもよい。図５に示す第２通信部２１、図２６に示す第２通信部４１、および図４７に示す第２通信部６１は、通信インタフェース２１６により実現されてもよい。図５に示す第２生成部２２、第２実行部２３、図２６に示す第２生成部４２、第２実行部４３、共通化情報読み取り部４４、および図４７に示す第２生成部６２、第２実行部６３、第３生成部６４、第３実行部６５、表示制御部６６は、与えられたプログラム検証支援プログラムをプロセッサ２１１が実行することにより実現されてもよい。
【０２９０】
ＲＡＭ２１２、ＲＯＭ２１３、補助記憶装置２１４および可搬型記録媒体２１８は、何れもコンピュータ読み取り可能な有形の記憶媒体の一例である。これらの有形な記憶媒体は、信号搬送波のような一時的な媒体ではない。
【０２９１】
＜その他＞
本実施形態は、以上に述べた実施の形態に限定されるものではなく、本実施形態の要旨を逸脱しない範囲内で種々の構成または実施形態を取ることができる。
【符号の説明】
【０２９２】
１，３，５    第１情報処理装置
２，４，６    第２情報処理装置
１１，３１，５１    第１通信部
１２，３２，５２    第１生成部
１３，３３，５３    第１実行部
１４，３５，５４    第１記憶部
２１，４１，６１    第２通信部
２２，４２，６２    第２生成部
２３，４３，６３    第２実行部
２４，４５，６７    第２記憶部
３４    共通化部
４４    共通化情報読み取り部
６４    第３生成部
６５    第３実行部
６６    表示制御部
１００，２００    バス
１１１，２１１    プロセッサ
１１２，２１２    ＲＡＭ
１１３，２１３    ＲＯＭ
１１４，２１４    補助記憶装置
１１５，２１５    媒体接続部
１１６，２１６    通信インタフェース
１１８，２１８    可搬型記録媒体
【図１】
2018195299.tif 000003
【図２】
2018195299.tif 000004
【図３】
2018195299.tif 000005
【図４】
2018195299.tif 000006
【図５】
2018195299.tif 000007
【図６】
2018195299.tif 000008
【図７】
2018195299.tif 000009
【図８】
2018195299.tif 000010
【図９】
2018195299.tif 000011
【図１０】
2018195299.tif 000012
【図１１】
2018195299.tif 000013
【図１２】
2018195299.tif 000014
【図１３】
2018195299.tif 000015
【図１４】
2018195299.tif 000016
【図１５】
2018195299.tif 000017
【図１６】
2018195299.tif 000018
【図１７】
2018195299.tif 000019
【図１８】
2018195299.tif 000020
【図１９】
2018195299.tif 000021
【図２０】
2018195299.tif 000022
【図２１】
2018195299.tif 000023
【図２２】
2018195299.tif 000024
【図２３】
2018195299.tif 000025
【図２４】
2018195299.tif 000026
【図２５】
2018195299.tif 000027
【図２６】
2018195299.tif 000028
【図２７】
2018195299.tif 000029
【図２８】
2018195299.tif 000030
【図２９】
2018195299.tif 000031
【図３０】
2018195299.tif 000032
【図３１】
2018195299.tif 000033
【図３２】
2018195299.tif 000034
【図３３】
2018195299.tif 000035
【図３４】
2018195299.tif 000036
【図３５】
2018195299.tif 000037
【図３６】
2018195299.tif 000038
【図３７】
2018195299.tif 000039
【図３８】
2018195299.tif 000040
【図３９】
2018195299.tif 000041
【図４０】
2018195299.tif 000042
【図４１】
2018195299.tif 000043
【図４２】
2018195299.tif 000044
【図４３】
2018195299.tif 000045
【図４４】
2018195299.tif 000046
【図４５】
2018195299.tif 000047
【図４６】
2018195299.tif 000048
【図４７】
2018195299.tif 000049
【図４８】
2018195299.tif 000050
【図４９】
2018195299.tif 000051
【図５０】
2018195299.tif 000052
【図５１】
2018195299.tif 000053
【図５２】
2018195299.tif 000054
【図５３】
2018195299.tif 000055
【図５４】
2018195299.tif 000056
【図５５】
2018195299.tif 000057
【図５６】
2018195299.tif 000058
【図５７】
2018195299.tif 000059
【図５８】
2018195299.tif 000060
【図５９】
2018195299.tif 000061
【図６０】
2018195299.tif 000062
【図６１】
2018195299.tif 000063
【図６２】
2018195299.tif 000064
【図６３】
2018195299.tif 000065
【図６４】
2018195299.tif 000066
【図６５】
2018195299.tif 000067
【図６６】
2018195299.tif 000068
【図６７】
2018195299.tif 000069
【図６８】
2018195299.tif 000070
【図６９】
2018195299.tif 000071
【図７０】
2018195299.tif 000072