(57)【要約】  プログラムデバッグ装置１は、セグメントが割り当てられるアドレスのみを変更してセグメントの配置を変更するアドレス割当部１２と、セグメントの配置を変更されたプログラムを実行するとともにプログラムの実行に伴ってなされるメモリアクセスをトレースして、メモリアクセスにより参照された参照先アドレスを得るとともに、プログラムの実行結果、メモリアクセスのアクセス回数またはプログラムの実行順序の少なくとも一つを得るメモリアクセストレース部１１−１〜１１−Ｔと、プログラムを複数回実行して、得られた複数の実行結果、アクセス回数または実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析部１３１と、等しいと判定されたとき、解析対象のメモリアクセスの参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析部１３２と、を備える。
2009075116.tif 000002
【特許請求の範囲】
【請求項１】
プログラムの実行時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスをデバッグするプログラムデバッグ方法であって、
前記記憶領域のアドレスのうち前記セグメントが割り当てられるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当ステップと、
前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行ステップと、
前記アドレス割当ステップと前記プログラム実行ステップとを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析ステップと、
前記実行結果解析ステップにて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析ステップと、
を備えることを特徴とするプログラムデバッグ方法。
【請求項２】
前記プログラムは、ポインタ変数を用いる各種の言語で記述されるソースファイル、前記ソースファイルを実行形式にした実行形式ファイルおよび前記ソースファイルをコンパイルした結果得られるオブジェクトファイルのいずれかであることを特徴とする請求項１に記載のプログラムデバッグ方法。
【請求項３】
前記メモリアクセス解析ステップは、前記解析対象メモリアクセスの参照先アドレスに基づいて前記解析対象メモリアクセスにおけるアドレス指定の基点である基点セグメントを特定する基点セグメント特定ステップを含み、
前記基点セグメント特定ステップが前記基点セグメントを特定できないとき、前記解析対象メモリアクセスが適正ではないと判定することを特徴とする請求項１または２に記載のプログラムデバッグ方法。
【請求項４】
前記メモリアクセス解析ステップは、前記基点セグメント特定ステップにより特定された前記基点セグメントに前記解析対象メモリアクセスの参照先アドレスが含まれるか否か判定する境界検査ステップを含み、
前記境界検査ステップが、前記解析対象メモリアクセスにおける参照先アドレスが前記セグメントに含まれると判定するとき、前記解析対象メモリアクセスが適正と判定し、前記解析対象メモリアクセスにおける参照先アドレスが前記セグメントに含まれないと判定するとき、前記解析対象メモリアクセスが適正ではないと判定することを特徴とする請求項３に記載のプログラムデバッグ方法。
【請求項５】
前記基点セグメント特定ステップは、前記解析対象メモリアクセスの参照先アドレスのうち第１の回において参照された第１参照先アドレスと第２の回において参照された第２参照先アドレスの差分が、同一の識別番号が割り当てられたセグメントに対して前記第１の回にて割り当てられた第１先頭アドレスと前記第２の回にて割り当てられた第２先頭アドレスの差分と一致したとき、当該セグメントを前記基点セグメントとして特定することを特徴とする請求項４に記載のプログラムデバッグ方法。
【請求項６】
前記アドレス割当ステップは、前記セグメントの配置を変更するとき、前記セグメントの変更前の先頭アドレスと前記セグメントの変更後の先頭アドレスの差分を、前記セグメントの中で一意な値で与えることを特徴とする請求項５に記載のプログラムデバッグ方法。
【請求項７】
前記アドレス割当ステップは、前記セグメントの配置を変更するとき、前記セグメントのうち第１セグメントと第２セグメントとの変更後の先頭アドレスの差分を変更前の先頭アドレスの差分の整数倍とすることを特徴とする請求項５に記載のプログラムデバッグ方法。
【請求項８】
前記アドレス割当ステップは、前記セグメントの配置を変更するとき、隣接する前記セグメントの間に置かれた空白域の大きさを変更前より変更後の方が一意の値だけ大きくなるように変更することを特徴とする請求項５に記載のプログラムデバッグ方法。
【請求項９】
前記アドレス割当ステップは、前記セグメントの配置を変更するとき、前記セグメントの変更前の先頭アドレスと前記セグメントの変更後の先頭アドレスの大小関係が逆順になるようにすることを特徴とする請求項５に記載のプログラムデバッグ方法。
【請求項１０】
前記境界検査ステップは、前記解析対象メモリアクセスの参照先アドレスから前記基点セグメントの先頭アドレスを減算して得られるオフセットを求め、前記オフセットが前記基点セグメントのサイズから当該参照先アドレスが指定するアドレスの数を減算した値以下であるとき、当該参照先アドレスが前記セグメントに含まれると判定することを特徴とする請求項５乃至９のいずれかに記載のプログラムデバッグ方法。
【請求項１１】
前記プログラムのセグメントは、ヒープ上に動的に確保されるセグメントであることを特徴とする請求項１乃至１０のいずれかに記載のプログラムデバッグ方法。
【請求項１２】
前記プログラムのセグメントは、前記プログラムの実行時に静的に配置されるセグメントであることを特徴とする請求項１乃至１０のいずれかに記載のプログラムデバッグ方法。
【請求項１３】
前記プログラムのセグメントは、スタック上に配置されるセグメントであることを特徴とする請求項１乃至１０のいずれかに記載のプログラムデバッグ方法。
【請求項１４】
前記プログラムのセグメントは、関数もしくはその関数から呼び出される子関数を含む関数群に対して、一つの関数または関数群内で、スタックポインタを基点とする相対アドレス参照が許可される連続メモリ領域として定義され、
前記プログラムの実行中に、関数の呼出が発生した時点で、当該関数に対応するセグメントをスタックポインタと共に異なるアドレスに移動させ、当該関数から呼出元に戻る時点で当該セグメントをスタックポインタと共に元のアドレスに移動させることを特徴とする請求項１３に記載のプログラムデバッグ方法。
【請求項１５】
第１の関数または関数群の実行指令の中で、第２の関数または関数群が呼び出された状態では、第１の関数または関数群に対して定義された前記連続メモリ領域から、第２の関数または関数群に対して定義された前記連続メモリ領域と重複する領域を除去した領域を、第１の関数または関数群に対して定義されたセグメントとすることを特徴とする請求項１４に記載のプログラムデバッグ方法。
【請求項１６】
前記プログラム実行ステップは、前記プログラム実行ステップが使用するレジスタとメモリとに複数の格納値を記憶させられる仮想実行環境を生成し、前記レジスタと前記メモリとに、前記アドレス割当ステップにて変更された前記セグメントの配置に基づいて前記プログラムを実行した場合に得られる複数の格納値を記憶させることで前記プログラムを実行して参照先アドレスを求めること、
または、前記仮想実行環境を用いて前記プログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得ることを特徴とする請求項１に記載のプログラムデバッグ方法。
【請求項１７】
前記プログラム実行ステップは、前記プログラムで使用される変数に、複数の格納値を記憶させられる仮想実行環境を生成し、各々の変数に、前記アドレス割当ステップにて変更された前記セグメントの配置に基づいて前記プログラムを実行した場合に得られる複数の格納値を記憶させることで、前記プログラムを実行して参照先アドレスを求めること、
もしくは、前記仮想実行環境を用いて前記プログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得ることを特徴とする請求項１に記載のプログラムデバッグ方法。
【請求項１８】
第１の情報処理装置がプログラムを実行する時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスの検査処理を第２の情報処理装置に行わせるデバッグ用プログラムを、前記プログラムを変換して生成するプログラム変換方法であって、
前記デバッグ用プログラムは、
前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当処理と、
前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、
前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、
前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、
を前記第２の情報処理装置に行わせることを特徴とするプログラム変換方法。
【請求項１９】
プログラムの実行時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスをデバッグするプログラムデバッグ装置であって、
前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当手段と、
前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行手段と、
前記アドレス割当手段と前記プログラム実行手段とにより前記プログラムを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析手段と、
前記実行結果解析手段にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析手段と、
を備えることを特徴とするプログラムデバッグ装置。
【請求項２０】
前記プログラムは、ポインタ変数を用いる各種の言語で記述されるソースファイル、前記ソースファイルを実行形式にした実行形式ファイルおよび前記ソースファイルをコンパイルした結果得られるオブジェクトファイルのいずれかであることを特徴とする請求項１９に記載のプログラムデバッグ装置。
【請求項２１】
前記メモリアクセス解析手段は、前記解析対象メモリアクセスの参照先アドレスに基づいて前記解析対象メモリアクセスにおけるアドレス指定の基点である基点セグメントを特定する基点セグメント特定手段を含み、
前記基点セグメント特定手段が前記基点セグメントを特定できないとき、前記解析対象メモリアクセスが適正ではないと判定することを特徴とする請求項１９または２０に記載のプログラムデバッグ装置。
【請求項２２】
前記メモリアクセス解析手段は、前記基点セグメント特定手段により特定された基点セグメントに前記解析対象メモリアクセスの参照先アドレスが含まれるか否か判定する境界検査手段を含み、
前記境界検査手段が、前記解析対象メモリアクセスにおける参照先アドレスが前記セグメントに含まれると判定するとき、前記解析対象メモリアクセスが適正と判定し、前記解析対象メモリアクセスにおける参照先アドレスが前記セグメントに含まれないと判定するとき、前記解析対象メモリアクセスが適正ではないと判定することを特徴とする請求項２１に記載のプログラムデバッグ装置。
【請求項２３】
前記基点セグメント特定手段は、前記解析対象メモリアクセスの参照先アドレスのうち第１の回において参照された第１参照先アドレスと第２の回において参照された第２参照先アドレスの差分が、同一の識別番号が割り当てられたセグメントに対して前記第１の回にて割り当てられた第１先頭アドレスと前記第２の回にて割り当てられた第２先頭アドレスの差分と一致したとき、当該セグメントを前記基点セグメントとして特定することを特徴とする請求項２２に記載のプログラムデバッグ装置。
【請求項２４】
前記アドレス割当手段は、前記セグメントの配置を変更するとき、前記セグメントの変更前の先頭アドレスと前記セグメントの変更後の先頭アドレスの差分を、前記セグメントの中で一意な値で与えることを特徴とする請求項２３に記載のプログラムデバッグ装置。
【請求項２５】
前記アドレス割当手段は、前記セグメントの配置を変更するとき、前記セグメントのうち第１セグメントと第２セグメントとの変更後の先頭アドレスの差分を変更前の先頭アドレスの差分の整数倍とすることを特徴とする請求項２３に記載のプログラムデバッグ装置。
【請求項２６】
前記アドレス割当手段は、前記セグメントの配置を変更するとき、隣接する前記セグメントの間に置かれた空白域の大きさを変更前より変更後の方が一意の値だけ大きくなるように変更することを特徴とする請求項２３に記載のプログラムデバッグ装置。
【請求項２７】
前記アドレス割当手段は、前記セグメントの配置を変更するとき、前記セグメントの変更前の先頭アドレスと前記セグメントの変更後の先頭アドレスの大小関係が逆順になるようにすることを特徴とする請求項２３に記載のプログラムデバッグ装置。
【請求項２８】
前記境界検査手段は、前記解析対象メモリアクセスの参照先アドレスから前記基点セグメントの先頭アドレスを減算して得られるオフセットを求め、前記オフセットが前記基点セグメントのサイズから当該参照先アドレスが指定するアドレスの数を減算した値以下であるとき、当該参照先アドレスが前記セグメントに含まれると判定することを特徴とする請求項２３乃至２７のいずれかに記載のプログラムデバッグ装置。
【請求項２９】
前記プログラムのセグメントは、ヒープ上に動的に確保されるセグメントであることを特徴とする請求項１９乃至２８のいずれかに記載のプログラムデバッグ装置。
【請求項３０】
前記プログラムのセグメントは、前記プログラムの実行時に静的に配置されるセグメントであることを特徴とする請求項１９乃至２８のいずれかに記載のプログラムデバッグ装置。
【請求項３１】
前記プログラムのセグメントは、スタック上に配置されるセグメントであることを特徴とする請求項１９乃至２８のいずれかに記載のプログラムデバッグ装置。
【請求項３２】
前記プログラムのセグメントは、関数もしくはその関数から呼び出される子関数を含む関数群に対して、一つの関数または関数群内で、スタックポインタを基点とする相対アドレス参照が許可される連続メモリ領域として定義され、
前記プログラムの実行中に、関数の呼出が発生した時点で、当該関数に対応するセグメントをスタックポインタと共に異なるアドレスに移動させ、当該関数から呼出元に戻る時点で当該セグメントをスタックポインタと共に元のアドレスに移動させることを特徴とする請求項３１に記載のプログラムデバッグ装置。
【請求項３３】
第１の関数または関数群の実行指令の中で、第２の関数または関数群が呼び出された状態では、第１の関数または関数群に対して定義された前記連続メモリ領域から、第２の関数または関数群に対して定義された前記連続メモリ領域と重複する領域を除去した領域を、第１の関数または関数群に対して定義されたセグメントとすることを特徴とする請求項３２に記載のプログラムデバッグ装置。
【請求項３４】
前記プログラム実行手段は、前記プログラム実行手段が使用するレジスタとメモリとに複数の格納値を記憶させられる仮想実行環境を生成し、前記レジスタと前記メモリとに、前記アドレス割当手段にて変更された前記セグメントの配置に基づいて前記プログラムを実行した場合に得られる複数の格納値を記憶させることで前記プログラムを実行して参照先アドレスを求めること、
または、前記仮想実行環境を用いて前記プログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得ることを特徴とする請求項１９に記載のプログラムデバッグ装置。
【請求項３５】
前記プログラム実行手段は、前記プログラムで使用される変数に、複数の格納値を記憶させられる仮想実行環境を生成し、各々の変数に、前記アドレス割当手段にて変更された前記セグメントの配置に基づいて前記プログラムを実行した場合に得られる複数の格納値を記憶させることで、前記プログラムを実行して参照先アドレスを求めること、
もしくは、前記仮想実行環境を用いて前記プログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得ることを特徴とする請求項１９に記載のプログラムデバッグ装置。
【請求項３６】
第１の情報処理装置がプログラムを実行する時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスの検査処理を第２の情報処理装置に行わせるデバッグ用プログラムを、前記プログラムを変換して生成するプログラム変換装置であって、
前記デバッグ用プログラムは、
前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当処理と、
前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、
前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、
前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、
を前記第２の情報処理装置に行わせることを特徴とするプログラム変換装置。
【請求項３７】
プログラムの実行時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスをデバッグするデバッグ用プログラムを格納する、コンピュータ読み出し可能な記憶媒体であって、
前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当処理と、
前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、
前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、
前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、
をコンピュータに実行させるデバッグ用プログラムを格納することを特徴とする記憶媒体。
【請求項３８】
前記メモリアクセス解析処理は、前記解析対象メモリアクセスの参照先アドレスに基づいて前記解析対象メモリアクセスにおけるアドレス指定の基点である基点セグメントを特定する基点セグメント特定処理を含み、
前記基点セグメント特定処理が前記基点セグメントを特定できないとき、前記解析対象メモリアクセスが適正ではないと判定するデバッグ用プログラムを格納することを特徴とする請求項３７に記載の記憶媒体。
【請求項３９】
前記メモリアクセス解析処理は、前記基点セグメント特定処理により特定された前記基点セグメントに前記解析対象メモリアクセスの参照先アドレスが含まれるか否か判定する境界検査処理を含み、
前記境界検査処理が、前記解析対象メモリアクセスにおける参照先アドレスが前記セグメントに含まれると判定するとき、前記解析対象メモリアクセスが適正と判定し、前記解析対象メモリアクセスにおける参照先アドレスが前記セグメントに含まれないと判定するとき、前記解析対象メモリアクセスが適正ではないと判定するデバッグ用プログラムを格納することを特徴とする請求項３８に記載の記憶媒体。
【請求項４０】
前記基点セグメント特定処理は、前記解析対象メモリアクセスの参照先アドレスのうち第１の回において参照された第１参照先アドレスと第２の回において参照された第２参照先アドレスの差分が、同一の識別番号が割り当てられたセグメントに対して前記第１の回にて割り当てられた第１先頭アドレスと前記第２の回にて割り当てられた第２先頭アドレスの差分と一致したとき、当該セグメントを前記基点セグメントとして特定するデバッグ用プログラムを格納することを特徴とする請求項３９に記載の記憶媒体。
【請求項４１】
前記アドレス割当処理は、前記セグメントの配置を変更するとき、前記セグメントの変更前の先頭アドレスと前記セグメントの変更後の先頭アドレスの差分を、前記セグメントを一意の値で与えるデバッグ用プログラムを格納することを特徴とする請求項４０に記載の記憶媒体。
【請求項４２】
前記アドレス割当処理は、前記セグメントの配置を変更するとき、前記セグメントのうち第１セグメントと第２セグメントとの変更後の先頭アドレスの差分を変更前の先頭アドレスの差分の整数倍とするデバッグ用プログラムを格納することを特徴とする請求項４０に記載の記憶媒体。
【請求項４３】
前記アドレス割当処理は、前記セグメントの配置を変更するとき、隣接する前記セグメントの間に置かれた空白域の大きさを変更前より変更後の方が一意の値だけ大きくなるように変更するデバッグ用プログラムを格納することを特徴とする請求項４０に記載の記憶媒体。
【請求項４４】
前記アドレス割当処理は、前記セグメントの配置を変更するとき、前記セグメントの変更前の先頭アドレスと前記セグメントの変更後の先頭アドレスの大小関係が逆順になるようにするデバッグ用プログラムを格納することを特徴とする請求項４０に記載の記憶媒体。
【請求項４５】
前記境界検査処理は、前記解析対象メモリアクセスの参照先アドレスから前記基点セグメントの先頭アドレスを減算して得られるオフセットを求め、前記オフセットが前記基点セグメントのサイズから当該参照先アドレスが指定するアドレスの数を減算した値以下であるとき、当該参照先アドレスが前記セグメントに含まれると判定するデバッグ用プログラムを格納することを特徴とする請求項４０乃至４５に記載の記憶媒体。
【請求項４６】
前記プログラム実行処理は、前記プログラム実行処理が使用するレジスタとメモリとに複数の格納値を記憶させられる仮想実行環境を生成し、前記レジスタと前記メモリとに、前記アドレス割当処理にて変更された前記セグメントの配置に基づいて前記プログラムを実行した場合に得られる複数の格納値を記憶させることで前記プログラムを実行して参照先アドレスを求めること、
または、前記仮想実行環境を用いて前記プログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得るデバッグ用プログラムを格納することを特徴とする請求項３７に記載の記憶媒体。
【請求項４７】
前記プログラム実行処理は、前記プログラムで使用される変数に、複数の格納値を記憶させられる仮想実行環境を生成し、各々の変数に、前記アドレス割当処理にて変更された前記セグメントの配置に基づいて前記プログラムを実行した場合に得られる複数の格納値を記憶させることで、前記プログラムを実行して参照先アドレスを求めること、
もしくは、前記仮想実行環境を用いて前記プログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得るデバッグ用プログラムを格納することを特徴とする請求項３７に記載の記憶媒体。
【請求項４８】
第１の情報処理装置がプログラムを実行する時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスの検査処理を第２の情報処理装置に行わせるデバッグ用プログラムを格納する記憶媒体であって、
前記記憶領域のアドレスのうち前記セグメントが配置されるアドレス割当を変更して前記セグメントの配置を変更するアドレス割当処理と、
前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、
前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、
前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、
を前記第２の情報処理装置に行わせるデバッグ用プログラムを格納することを特徴とする記憶媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明はプログラムデバッグ方法及びプログラム変換方法、それを用いるプログラムデバッグ装置及びプログラム変換装置並びにそのプログラムを格納する記憶媒体に関し、特にコンピュータプログラムにおけるメモリアクセスのデバッグを行う方法及び装置に関する。
【背景技術】
【０００２】
上記のプログラムデバッグ方法においては、コンピュータプログラムを実行することでなされるメモリアクセスについて、アクセスする先のアドレスやタイミングが、その時点で割り当てられたメモリセグメントの有効範囲に含まれるかを確認する、いわゆる境界検査を実行し、不正な範囲外アクセスを検出している。【０００３】
ＰＣ（Ｐｅｒｓｏｎａｌ  Ｃｏｍｐｕｔｅｒ）やワークステーション、組み込み装置向けに開発された各種のコンピュータプログラムの開発工程においては、作られたプログラムが仕様通りに問題なく動作することを確認するテスト工程や、発見された不具合の原因を特定し必要な修正を行うデバッグの工程が知られている。これらの工程は、プログラムを用いて動作する装置やシステムの信頼性を高めるために重要である。【０００４】
テストやデバッグの工程で行われる検査の一つに、メモリアクセスの境界検査（ｂｏｕｎｄａｒｙ  ｔｅｓｔ）がある。これは、プログラムを実行した結果なされるメモリアクセスの参照先アドレスが、その時点でプログラム実行用に割り当てられた有効なメモリ領域を指すか判定する検査である。【０００５】
Ｃ言語やＣ＋＋言語等、普及している各種のプログラミング言語では、ポインタ型の変数を使用することが可能である。ポインタ変数は、参照先に有効なデータが配置されているかによらず、任意のアドレス値を保持することが可能である。そのため、誤った実行指令を含むプログラムを記述すると、許可された範囲外へのメモリアクセスを行わせ、場合によっては、装置やシステムに重大な問題を生じさせることがある。境界検査は、このような意図しない範囲外の不正メモリアクセスを、プログラムから取り除くための検査である。【０００６】
境界検査の実施形態は様々である。一つは、テスト対象のプログラムを実環境か仮想的な実行環境上で動作させて、その際に発生するメモリアクセスをトレースし、メモリ割当状態との整合性を確認する実施形態がある。この実施形態では、メモリアクセスを監視しながらプログラムを実行するために、メモリアクセス信号の監視機能を備えたプロセッサやハードウェア、デバッグ用ソフトウェア、プロセッサの動作を模擬するシミュレータ等が使用される。あるいは、Ｃ言語で記述された実行指令を直接解釈するインタープリタを用いてプログラムを実行する場合もある。【０００７】
他には、与えられた検査対象のプログラムを解析しながら変換することで、対象プログラムに記述された本来の目的の処理とメモリアクセス境界検査とを自分自身で行う別のプログラムを生成し、これを適当な環境で実行する実施形態がある。このプログラム変換は、Ｃ言語やＣ＋＋言語で実行指令が記述されたプログラムに対して行うソースコードレベルの検査方式や、デバッグ情報を加えた実行形式のプログラムに対して、プログラムに含まれる機械語を実行指令として解釈しながら変換を行うバイナリレベルの方式がある。【０００８】
前者の方式の例としては、非特許文献１やＦａｉｌ  Ｓａｆｅ  Ｃ（非特許文献２）（但し、検査が主目的ではなく、実行時に不正な動作をしない安全なプログラムの生成が目的の技術である）がある。また、後者の方式の例としては、Ｖａｌｇｒｉｎｄ（非特許文献３）やＰｕｒｉｆｙ（非特許文献４）がある。さらに、特許文献１は、後者の方式に適用されるプログラム変換技術に関する発明である。【０００９】
ここで、ＶａｌｇｒｉｎｄやＰｕｒｉｆｙは、実行形式で与えられた対象プログラムを、様々な状態監視や検査の機能を備えたシミュレータで実行して、検査するのと等価な処理を仮想的に行うプログラムを作成する。この仮想的なシミュレータでは、実行中に使用される個々のメモリ格納値やＣＰＵ（中央処理装置）のレジスタに、検査用の補助情報を記憶させることが可能である。非特許文献２（Ｖａｌｇｒｉｎｄ）では、この情報をシャドウ値と呼んでいる。【００１０】
さて、本発明は、このように多様な形態で実施されるメモリアクセスの境界検査で使われる一つの技術として、プログラムの検査実行時にトレースされた個々のメモリアクセスが、メモリ割当に整合する有効なアクセスであるか、不正なアクセスであるかを判定する方法を提供する。この観点で、本発明に関連する技術について説明する。【００１１】
説明の前に、用語の定義として、プログラムがアクセスすることが許可された連続メモリ領域であり、境界検査における不正アドレス判定の境界を与える単位を、メモリセグメントもしくはセグメントと呼ぶことにする。【００１２】
セグメントには、（１）ヒープメモリ上に動的に配置され、動的に解放が行われるヒープセグメント、（２）プログラムの実行コード生成時またはプログラム実行開始時に配置が決定される静的セグメント、（３）スタックメモリ上に配置され、関数の呼び出し時に動的に与えられたスタックポインタを元に相対アドレス参照によってアクセスされるスタックセグメントがある。【００１３】
境界検査は、プログラム実行時にトレースされたメモリアクセスの参照先アドレスが、その時点で使用可能なメモリセグメントの一つを参照することを意図して計算されたアドレスであり、意図したセグメントの有効範囲内のアドレスを指している場合に限り、そのアクセスが正しいと判定する検査である。セグメント参照の意図は、そのセグメントに与えられた先頭アドレスを使って、アクセス先のアドレスが計算されたかどうかで判断される。【００１４】
この判定では、アドレス計算の基点としたアドレスを、検査実行時に特定する方法が課題である。ポインタ変数は、アドレス値しか格納しておらず、計算の基点としたアドレスや参照したいセグメントに関する情報が含まれない。基点とするアドレスを特定できないと、アドレスに加算されたオフセット値が分からず、その範囲が有効であるか否かを判断することができないためである。【００１５】
＜ガードゾーン方式＞
ガードゾーン方式は、確保された個々のセグメントの前後にガードゾーンと呼ばれるアクセス禁止域を設けた上で、メモリアクセスのトレースを取得しながらプログラムを実行し、ガードゾーンへのアクセスが発生した場合にそのアクセスを不正なアクセスと判定する境界検査手法である。【００１６】
ガードゾーン方式は、多くのプログラムデバッグツールで使用されている。例えば、上述したＶａｌｇｒｉｎｄのｍｅｍｃｈｅｃｋツールや、Ｐｕｒｉｆｙはガードゾーン方式に基づいて、境界検査を行う機能を備えている。【００１７】
ガードゾーン方式による境界検査処理について一例を挙げて説明する。図１３は検査対象のＣ言語プログラムであるとする。このプログラムは、３７行目及び３８行目でｃｈａｒ型の配列を２つ使用することを宣言しており、この検査では、両配列が格納される２つの静的セグメントｓｅｇ１，ｓｅｇ２を境界検査の単位とする。【００１８】
図１４は、ガードゾーン方式に従って、２つのセグメントｓｅｇ１，ｓｅｇ２をアドレス空間内に配置する一例を示す。この図において、アドレス増加方向は右であるとする。適当なアドレスを基点としてセグメントｓｅｇ１，ｓｅｇ２がこの順で配置される。セグメントｓｅｇ１，ｓｅｇ２は、ｃｈａｒ型変数を８個格納可能なセグメントである。セグメントｓｅｇ１の前、セグメントｓｅｇ１とセグメントｓｅｇ２の間、セグメントｓｅｇ２の後には、それぞれ不正アクセス検出のためのガードゾーンが配置される。ガードゾーン１個のサイズは１バイトとする。【００１９】
図１３のＣ言語プログラムの実行が開始されると、４１−４７行目のｍａｉｎ関数が最初に実行され、その中で４つの関数が順に呼び出される。この中で４３行目と４４行目の関数ｆｕｎｃ１、関数ｆｕｎｃ２の呼び出しを与える実行指令は、境界検査で検出されるべき不正メモリアクセスを発生させる例である。【００２０】
ポインタを用いる処理で頻出するパタンとして、繰り返し処理により連続メモリ領域にアクセスを行うものがある。図１３の４−１１行目の関数ｆｕｎｃ１はその例であり、引数ｐが示すアドレスに連続配置された９個のｃｈａｒ型整数に、０を書込む処理を行う。しかしながら、４３行目の関数ｆｕｎｃ１の呼び出しは、誤って８個の要素しか持たないセグメントｓｅｇ１へのポインタを引数として設定しているため、不正なメモリアクセスが生じる。【００２１】
このプログラムを、図１４のセグメント配置で実行すると、関数ｆｕｎｃ１は静的セグメントｓｅｇ１の先頭アドレスを示すポインタｐを引数として受け取り、連続する９個のｃｈａｒ変数に０を書込む。変数ｉが８の時、９行目のポインタによるアクセスで参照させる先が、ガードゾーンとして設定された領域になるため、この時点で不正なメモリアクセスが検出されたとして、プログラムを停止する。このように、ガードゾーン方式は、連続的にメモリアクセスを行う際のプログラム記述の誤りを検出するのに有効な方式である。【００２２】
ガードゾーン方式の欠点は、不連続に行われる不正なメモリアクセスの検出ができないことである。例えば、図１３のプログラム４４行目の関数ｆｕｎｃ２の呼び出しは、不正であるにも関わらず、ガードゾーン方式で検出できないメモリアクセスを発生させる実行指令の例である。【００２３】
図１３の関数ｆｕｎｃ２は、引数のポインタが指すセグメントの１３番目要素に０を設定する関数であるが、４４行目では８要素しか持たない不適切なセグメントｓｅｇ１を指定している。これを、図１４のメモリ配置で実行すると、１６行目の処理はセグメントｓｅｇ１の範囲外の不正メモリアクセスを発生させ、セグメントｓｅｇ２を破壊する問題を引き起こす。しかしながら、このアクセスはガードゾーン以外のメモリを参照するため、この問題を検出することはできない。【００２４】
プログラムのデバッグ工程においては、このような範囲外アクセスによるデータ破壊を即座に検出できないと、不具合原因の特定に時間を要する点で問題である。あるいは、プログラムのテスト工程において、範囲外アクセスが、検査時の動作条件では偶然に誤動作を引き起こさない場合、プログラムが抱える問題を検出する有効なテストにならない。この偶然要因には、セグメントの配置アドレスや順序も含まれる。【００２５】
例えば、Ｃ言語で記述されたプログラムの境界検査を実施する場合には、コンパイルツールが配置したセグメントの順序関係に依存して、偶然問題が検出されない可能性がある。このように、不連続な範囲外アクセスに対しては確率的な検出しか行えない点がガードゾーン方式の欠点である。【００２６】
＜ファットポインタ方式＞
ファットポインタ（もしくはセーフポインタ）は、ポインタ変数が保持する情報量を増やし、参照先のアドレス値に加え、参照するセグメント識別情報を持たせるようにした拡張ポインタである。ファットポインタを用いてポインタ変数を定義し、プログラム実行時に行われるメモリアクセスの前に、アドレス値の境界検査を動的に行う方式を、ファットポインタ方式と呼ぶ。その例として、ファットポインタを用いずに、通常のポインタ変数を用いて記述されたＣ言語プログラムを、ファットポインタを利用して動的検査を行うプログラムに変換する技術が、非特許文献１や非特許文献２に記載されている。【００２７】
ファットポインタ方式は、上述したガードゾーン方式と異なり、不連続なアクセスについても不正を検出できる利点を持つ。例えば、図１３のプログラムの関数ｆｕｎｃ２の呼び出しでは、引数のファットポインタｐが、基点とするセグメントｓｅｇ１を示す情報を保持しているので、呼び出された関数の内部で、有効な検査が可能である。この例では、１６行目のメモリアクセスが行われる前に、ポインタ（ｐ＋１２）がセグメントｓｅｇ１の有効範囲外を指すかどうかが検査され、アドレス値がセグメントｓｅｇ１の終端を越えていることからメモリアクセスの不正が検出される。【００２８】
ファットポインタ方式は、基本的に、Ｃ言語等のプログラミング言語で記述された形式のプログラムを検査対象とし、実行形式で与えられたプログラムに対しては通常適用できない。しかしながら、上述したＶａｌｇｒｉｎｄ検査ツール等が備えるシャドウ値付きの仮想実行環境を用いることで、実行形式のプログラムに対してファットポインタ方式による境界検査を実現できるようにした検査技術が、Ｎｅｔｈｅｒｃｏｔｅらにより開発されている（非特許文献５）。【００２９】
上記の非特許文献５に記載の方式は、プログラム実行中にメモリに格納される数値、及びレジスタの１個１個について、それが非ポインタ型であるかポインタ型であるかを示すフラグと、ポインタ型であるならば、基点としたセグメントの識別子をシャドウ値として記憶し、プログラムの実行を追跡しながら更新していく。例えば、ヒープからメモリを確保する関数を呼び出すと、戻り値のシャドウ値に、ポインタであることを示すフラグと基点セグメントのアドレスとが格納される。この変数を別のアドレスに置かれた変数にコピーすると、型情報も合わせてコピーされる。ポインタへの整数の加減算等のポインタ演算がなされる場合についても、適切な型情報の追跡が行われる。【００３０】
上記の非特許文献５に記載の方式は、メモリに保持される数値の型（ポインタ型か、非ポインタ型であるか）を、言語記述に頼ることなく、実行された機械語命令から判断する点が、通常のファットポインタ方式と異なる。しかしながら、上記の非特許文献５に記載の方式は、個々の数値に基点セグメントを連想記憶させて追跡するという点で、ファットポインタ方式の範疇に属すると解釈することができる。【００３１】
ファットポインタ方式に基づく境界検査手法の課題は、異なるセグメントを参照するポインタ間の減算や、ポインタ変数をアドレス値とみなして行われる任意の四則演算や論理演算、上位と下位へのアドレス分解に対応できない点である（非特許文献５、２．５章）。【００３２】
Ｃ言語では、これらの記述は、処理系依存とされており、あらゆるＣコンパイラや実行環境で動作する正当なプログラムではない。しかしながら、多くの環境では、これらの記述が許容されていて、一定の動作を行うので、このような記述を含むプログラムが多数存在する。あるいは、言語記述に含まなくても、生成された機械語命令に同等のアドレス演算処理を含むプログラムもある。【００３３】
図１３のプログラム４５行目の関数ｆｕｎｃ３の呼び出しは、ポインタ減算の例である。関数ｆｕｎｃ３は、ポインタｐにオフセットｄｉｆｆを加算して得られたポインタが指すメモリに、ｉｎｔ整数０を書込む関数である。４５行目は、セグメントｓｅｇ１の先頭アドレスをｐに設定し、セグメントｓｅｇ２とセグメントｓｅｇ１との先頭アドレスの差をｄｉｆｆとして渡す。【００３４】
ここで、セグメントｓｅｇ２とセグメントｓｅｇ１との差は、別セグメントを指すポインタの差分であるのでＣ言語の規格では許されていない記述である。しかしながら、多くのＣ言語コンパイラは、セグメントｓｅｇ２−セグメントｓｅｇ１がセグメントｓｅｇ２とセグメントｓｅｇ１とのアドレスの差を返し、関数ｆｕｎｃ３内で計算されるｐ＋ｄｉｆｆは、セグメントｓｅｇ２の先頭を指すように動作する。【００３５】
これに、ファットポインタに基づく境界検査を行うと、２２行目は、引数のポインタｐに整数値を加算する操作であるので、ポインタｑは、ポインタｐと同じセグメントｓｅｇ１を参照するポインタと解釈される。しかしながら、実際にはポインタｑはセグメントｓｅｇ２の先頭を指し、セグメントｓｅｇ１の範囲外を参照するため、実行時の検査により２３行目のアクセスが不正と判断されてしまう。【００３６】
図１３のプログラム４６行目の関数ｆｕｎｃ４の呼び出しは、整数への型変換と論理演算の例を示す。関数ｆｕｎｃ４は、３２，３３行目でアクセスするメモリのアドレスをポインタ変数ではなく、ｕｎｓｉｇｎｅｄ  ｉｎｔ型の整数で受け取る。処理系に依存するが、アドレス値がｕｎｓｉｇｎｅｄ  ｉｎｔ型で表すことが可能なコンパイラ環境では、このようなポインタとｕｎｓｉｇｎｅｄ  ｉｎｔ間の型変換は許容されている。【００３７】
関数ｆｕｎｃ４は、アドレスｐが示すｃｈａｒ変数に０を書込み（３２行目）、次に、排他的論理和（ＸＯＲ）演算を３回実行することで、変数ｐとｑを交換した後（２９−３１行目）、アドレスｑが示すｃｈａｒ変数に１を出力する（３３行目）。【００３８】
このような、別セグメント間のポインタの減算や、ポインタの整数への型変換を含むプログラムに対しては、単純なファットポインタ方式を適用することはできない。単純な型変換のみを含むプログラムであれば、上述したＦａｉｌ  Ｓａｆｅ  Ｃや、Ｎｅｔｈｅｒｃｏｔｅらの手法でも検査は可能であるが（Ｆａｉｌ  Ｓａｆｅ  Ｃは、変換された整数変数に基点セグメントを追跡記憶させるファット整数型を導入している。Ｎｅｔｈｅｒｃｏｔｅらの方式は、言語記述を利用せずに追跡する。）、任意の演算は対応不可能である。【００３９】
例えば、図１３のプログラム３０行目では、アドレス値の論理演算結果に１個のセグメントを関連付けることが実質的に不可能であるため、それ以降は有効な境界検査を行えない。このように、基点セグメント情報をポインタ変数に持たせるファットポインタ方式は、検査可能なプログラムの記述を制約することが課題である。【００４０】
【特許文献１】米国特許５１９３１８０
【非特許文献１】Ａｕｓｔｉｎ  ｅｔ  ａｌ．，Ｅｆｆｉｃｉｅｎｔ  Ｄｅｔｅｃｔｉｏｎ  ｏｆ  Ａｌｌ  Ｐｏｉｎｔｅｒ  ａｎｄ  Ａｒｒａｙ  Ａｃｃｅｓｓ  Ｅｒｒｏｒｓ，Ｃｏｍｐｕｔｅｒ  Ｓｃｉｅｎｃｅｓ  Ｄｅｐｔ．，Ｕｎｉｖ．ｏｆ  Ｗｉｓｃｏｎｓｉｎ−Ｍａｄｉｓｏｎ，ｐｐ．１−２９，１９９３．
【非特許文献２】Ｙｕｔａｋａ  Ｏｉｗａ，Ｔａｔｓｕｒｏｕ  Ｓｅｋｉｇｕｃｈｉ，Ｅｉｊｉｒｏ  Ｓｕｍｉｉ，Ａｋｉｎｏｒｉ  Ｙｏｎｅｚａｗａ，"Ｆａｉｌ−Ｓａｆｅ  ＡＮＳＩ−Ｃ  Ｃｏｍｐｉｌｅｒ：  Ａｎ  Ａｐｐｒｏａｃｈ  ｔｏ  Ｍａｋｉｎｇ  Ｃ  Ｐｒｏｇｒａｍｓ  Ｓｅｃｕｒｅ，"Ｉｎ  Ｌｅｃｔｕｒｅ  Ｎｏｔｅｓ  ｉｎ  Ｃｏｍｐｕｔｅｒ  Ｓｃｉｅｎｃｅ  Ｖｏｌ．２６０９，ｐｐ．３３７−３４２，２００３．
【非特許文献３】Ｎ．Ｎｅｔｈｅｒｃｏｔｅ  ａｎｄ  Ｊ．Ｓｅｗａｒｄ，"Ｖａｌｇｒｉｎｄ：Ａ  Ｆｒａｍｅｗｏｒｋ  ｆｏｒ  Ｈｅａｖｙｗｅｉｇｈｔ  Ｄｙｎａｍｉｃ  Ｂｉｎａｒｙ  Ｉｎｓｔｒｕｍｅｎｔａｔｉｏｎ，"Ｐｒｏｃｅｅｄｉｎｇｓ  ｏｆ  ＰＬＤＩ  ２００７，Ｓａｎ  Ｄｉｅｇｏ，Ｃａｌｉｆｏｒｎｉａ，ＵＳＡ，Ｊｕｎｅ  ２００７．
【非特許文献４】Ｒ．Ｈａｓｔｉｎｇｓ  ａｎｄ  Ｂ．Ｊｏｙｃｅ，"Ｐｕｒｉｆｙ：Ｆａｓｔ  ｄｅｔｅｃｔｉｏｎ  ｏｆ  ｍｅｍｏｒｙ  ｌｅａｋｓ  ａｎｄ  ａｃｃｅｓｓ  ｅｒｒｏｒｓ，"ｉｎ  Ｐｒｏｃｅｅｄｉｎｇｓ  ｏｆ  ｔｈｅ  Ｗｉｎｔｅｒ  ＵＳＥＮＩＸ  Ｃｏｎｆｅｒｅｎｃｅ，ｐｐ．１２５−１３６，１９９２．
【非特許文献５】Ｎ．Ｎｅｔｈｅｒｃｏｔｅ  ａｎｄ  Ｊ．Ｆｉｔｚｈａｒｄｉｎｇｅ，"Ｂｏｕｎｄｓ−Ｃｈｅｃｋｉｎｇ  Ｅｎｔｉｒｅ  Ｐｒｏｇｒａｍｓ  ｗｉｔｈｏｕｔ  Ｒｅｃｏｍｐｉｌｉｎｇ，"Ｉｎ  Ｉｎｆｏｒｍａｌ  Ｐｒｏｃｅｅｄｉｎｇｓ  ｏｆ  ＳＰＡＣＥ  ２００４，２００４．
【発明の開示】
【００４１】
以上述べたように、本発明に関連する技術では、プログラムに従ってなされるメモリアクセスについて、アクセス先のアドレスがセグメント内の有効なメモリ領域を指しているかどうかを判定する、いわゆる境界検査の方法として、従来ガードゾーン方式が用いられている。
【００４２】
しかしながら、本発明に関連する技術では、セグメント境界近傍の不正アクセスしか検出できず、不連続的になされる範囲外アクセスを確率的にしか検出することができないという課題がある。これは、プログラムデバッグの不具合原因の特定を遅らせ、また、テストの有効性を低下させる点で問題である。
【００４３】
また、この問題を解決する方法としては、ファットポインタを用いる方法が考案されているが、アドレス値と参照先セグメントとの間の１対１の対応関係を追跡する仕組みであるため、アドレス値に対してなされる任意の演算に対応できない制約があり、検査対象のプログラムを限定するという課題がある。
【００４４】
そこで、本発明が解決すべき課題は、効率の高いデバッグと確実なテストとを可能とし、かつ広範囲のプログラムに適用できる、メモリアクセスのセグメント境界検査を実施する方法または装置を提供することを課題とする。
【００４５】
より具体的には、有効なセグメント範囲外を参照する不正アクセスを、セグメント配置や実行条件の要因に左右されず確実に、即座に検出することが可能な、境界検査手法または装置を提供することが課題である。あるいは、セグメントを参照するアドレス値に関して、論理演算などの任意の計算を行うプログラムに対しても、境界検査を実施する方法または装置を提供することを課題とする。
【００４６】
つまり、本発明の目的は上記の課題を解消し、プログラム実行時になされるメモリアクセスのアドレス整合性検査を確実に行うことができるプログラムデバッグ方法及びプログラム変換方法、それを用いるプログラムデバッグ装置及びプログラム変換装置並びにそのプログラムを格納する記憶媒体を提供することにある。
【００４７】
本発明によるプログラムデバッグ方法は、プログラムの実行時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスをデバッグするプログラムデバッグ方法であって、前記記憶領域のアドレスのうち前記セグメントが割り当てられるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当ステップと、前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行ステップと、前記アドレス割当ステップと前記プログラム実行ステップとを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析ステップと、前記実行結果解析ステップにて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析ステップと、を備えることを特徴とする。
【００４８】
本発明によるプログラム変換方法は、第１の情報処理装置がプログラムを実行する時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスの検査処理を第２の情報処理装置に行わせるデバッグ用プログラムを、前記プログラムを変換して生成するプログラム変換方法であって、前記デバッグ用プログラムは、前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当処理と、前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、を前記第２の情報処理装置に行わせることを特徴とする。
【００４９】
本発明によるプログラムデバッグ装置は、プログラムの実行時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスをデバッグするプログラムデバッグ装置であって、前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当手段と、前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行手段と、前記アドレス割当手段と前記プログラム実行手段とにより前記プログラムを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析手段と、前記実行結果解析手段にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析手段と、を備えることを特徴とする。
【００５０】
本発明によるプログラム変換装置は、第１の情報処理装置がプログラムを実行する時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスの検査処理を第２の情報処理装置に行わせるデバッグ用プログラムを、前記プログラムを変換して生成するプログラム変換装置であって、前記デバッグ用プログラムは、前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当処理と、前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、を前記第２の情報処理装置に行わせることを特徴とする。
【００５１】
本発明による記憶媒体は、プログラムの実行時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスをデバッグするデバッグ用プログラムを格納する、コンピュータ読み出し可能な記憶媒体であって、前記記憶領域のアドレスのうち前記セグメントが配置されるアドレスのみを変更して前記セグメントの配置を変更するアドレス割当処理と、前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、をコンピュータに実行させるデバッグ用プログラムを格納することを特徴とする。
【００５２】
さらに、本発明による記憶媒体は、第１の情報処理装置がプログラムを実行する時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスの検査処理を第２の情報処理装置に行わせるデバッグ用プログラムを格納する記憶媒体であって、前記記憶領域のアドレスのうち前記セグメントが配置されるアドレス割当を変更して前記セグメントの配置を変更するアドレス割当処理と、前記セグメントの配置を変更された前記プログラムを実行するとともに前記プログラムの実行に伴ってなされる前記メモリアクセスをトレースして、前記メモリアクセスにより参照された参照先アドレスを得るとともに、前記プログラムが実行された結果を示す実行結果、前記メモリアクセスがなされた回数を示すアクセス回数または前記プログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得るプログラム実行処理と、前記アドレス割当処理と前記プログラム実行処理とを複数回実行して、得られた複数の前記実行結果、前記アクセス回数または前記実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析処理と、前記実行結果解析処理にて実行された全ての回において等しいと判定されたとき、複数の前記実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの前記参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析処理と、を前記第２の情報処理装置に行わせるデバッグ用プログラムを格納することを特徴とする。
【００５３】
本発明は、上記のようにセグメント配置のみを変更し、他の実行要因は同一に保ちながら検査対象のプログラムを複数回実行し、プログラム実行に伴ってなされるメモリアクセスをそれぞれトレースして複数の参照先アドレスとともに他の実行結果を得て、他の実行結果が不変であることを判定したうえで、解析対象の実行指令に従ってなされたメモリアクセスの参照先アドレスに基づいて解析を行うので、セグメント配置や実行条件の要因に左右されずに不正なメモリアクセスを確実に検出することができるという効果が得られる。
【図面の簡単な説明】
【００５４】
上述した目的、およびその他の目的、特徴および利点は、以下に述べる好適な実施の形態、およびそれに付随する以下の図面によってさらに明らかになる。
【図１】本発明の第１の実施の形態によるプログラムデバッグ装置の構成例を示すブ ロック図である。
【図２】本発明の第１の実施の形態によるプログラムデバッグ方法を示すフローチャートである。
【図３】本発明を実施する際のメモリセグメント配置方法を説明するための一例を示す図である。
【図４】本発明を実施する際のメモリセグメント配置方法を説明するための他の例を示す図である。
【図５】本発明の第１の実施の形態によるメモリアクセスを解析する処理を示すフローチャートである。
【図６】本発明の第２の実施の形態によるメモリアクセスを解析する処理を示すフローチャートである。
【図７】本発明の第６の実施の形態におけるプログラムデバッグ装置の動作を説明するためのＣ言語プログラム例を示す図である。
【図８】本発明の第６の実施の形態におけるプログラム実行時のスタック状態とスタックポインタの時間遷移とを示す図である。
【図９】本発明の第６の実施の形態においてスタック移動処理がなされた場合のスタック状態とスタックポインタの時間遷移とを示す図である。
【図１０】本発明の第８の実施の形態によるプログラムデバッグ装置の構成例を示すブロック図である。
【図１１】本発明の第８の実施の形態及び本発明の第９の実施の形態と本発明に関連する方式との違いを説明するための図である。
【図１２】本発明の第１０の実施の形態で行われるプログラム記述変換の特徴的な部分を示す図である。
【図１３】本発明に関連するメモリアクセス境界検査手法の課題を説明するためのＣ言語プログラム例を示す図である。
【図１４】本発明に関連するガードゾーン方式に基づく境界検査手法の課題を説明する図である。
【発明を実施するための最良の形態】
【００５５】
次に、本発明の実施の形態について図面を参照して説明する。図１は本発明の第１の実施の形態によるプログラムデバッグ装置の構成例を示すブロック図である。図１には、本発明の第１の実施の形態によるプログラムデバッグ装置において、Ｔ個のアドレス値を得るための手段の構成の一例を示している。尚、このプログラムデバッグ装置は、プログラムを作成したり、変換したりする情報処理装置、あるいはプログラムを実行して各種処理を行う情報処理装置等に搭載可能である。【００５６】
図１において、本発明の第１の実施の形態によるプログラムデバッグ装置１は、第１プログラム変換実行・メモリアクセストレース部１１−１、第２プログラム変換実行・メモリアクセストレース部１１−２、・・・、第Ｔプログラム変換実行・メモリアクセストレース部１１−Ｔ（以下、メモリアクセストレース部１１−１〜１１−Ｔとする）と、メモリセグメントアドレス割当部（以下、アドレス割当部）１２と、データ解析部１３と、を備えている。尚、図１に示す構成は、あくまでも一つの構成例を示すものであって、これと同様に、複数のアドレス値が得られる実施形態であれば、異なる構成であっても構わない。【００５７】
本実施形態のプログラムデバッグ装置１は、プログラムの実行時にセグメント単位で確保されて使用される記憶領域へのメモリアクセスをデバッグすることができ、特に当該プログラムの実行に伴ってなされるメモリアクセスを解析して境界判定を行うことができる。【００５８】
上記プログラムを格納する記憶領域は、プログラムデバッグ装置１に接続される外部の記憶装置であってもよいし、プログラムデバッグ装置１に備えられる記憶装置であってもよい。【００５９】
アドレス割当部１２は、記憶領域のアドレスのうちセグメントが割り当てられるアドレスのみを変更してセグメントの配置を変更することができる。【００６０】
メモリアクセストレース部１１−１〜１１−Ｔは、アドレス割当部１２にてセグメントの配置を変更されたプログラムを実行するとともにプログラムの実行に伴ってなされるメモリアクセスをトレースして、メモリアクセスにより参照された参照先アドレスを得るとともに、プログラムが実行された結果を示す実行結果、メモリアクセスがなされた回数を示すアクセス回数またはプログラムに内包される複数の実行指令が実行された順序を示す実行順序の少なくとも一つを得ることができる。【００６１】
データ解析部１３は、アドレス割当部１２とメモリアクセストレース部１１−１〜１１−Ｔとによりプログラムを複数回実行して、得られた複数の実行結果、アクセス回数または実行順序の少なくとも一つが、実行された全ての回において等しいか否かを判定する実行結果解析部１３１と、実行結果解析部１３１にて実行された全ての回において等しいと判定されたとき、複数の実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの参照先アドレスを解析して、解析対象メモリアクセスが適正であるか否か判定するメモリアクセス解析部１３２と、を含むことができる。【００６２】
上述したように、不連続に行われるメモリアクセスに対しても、確実な境界判定を行うためには、個々のメモリアクセスに対して、アクセス先のアドレスを計算する際の基点となったセグメントを特定する必要がある。しかしながら、ファットポインタを用いる方式は、プログラム中の実行指令の記述に制約があるため、本実施形態はこれとは異なる原理で、基点セグメントを特定する。【００６３】
本実施形態のプログラムデバッグ装置１は、検査対象のプログラムを図２に示すフローチャートのように実行することができる。すなわち、検査対象のプログラムのデバッグを開始すると、まずセグメントが割り当てられるアドレスのみを変更してセグメントの配置を変更し（ステップＳ２１）、アドレス以外の条件を同一に保ちながら、セグメントの配置が変更されたプログラムを実行するとともに、メモリアクセスをトレースする。このとき、メモリアクセスにより参照された参照先アドレスを得るとともに、プログラムが実行された結果を示す実行結果、メモリアクセスがなされた回数を示すアクセス回数またはプログラムに内包される複数の実行指令が実行された順序を示す実行順序等が得られる。ただし、上記の実行結果、アクセス回数または実行順序は少なくとも一つが得られればよい（ステップＳ２２）。そして、得られた実行結果、アクセス回数または実行順序の少なくとも一つが、プログラムが実行された全ての回において等しいか否かを判定する（ステップＳ２３）。等しいと判定されたとき（ステップＳ２３の真）、複数の実行指令のうち解析対象の実行指令に従ってなされた解析対象メモリアクセスの参照先アドレスに対してメモリアクセス解析処理を実行して、解析対象メモリアクセスが適正であるか否か判定する（ステップＳ２４）。なお、メモリアクセス解析処理の詳細については後述する。【００６４】
なお、上述した手順は、本実施形態に適用可能な手順の一例であり、その内容が相反しない範囲でその順序を変更可能である。【００６５】
本実施形態のプログラムデバッグ装置１は、セグメントのアドレス配置変更に対して不変な動作を再現することを検査対象のプログラムに要求する。異なるアドレス配置を与えても、他の入力や動作条件が同一であれば、等しい実行順序でプログラムが処理され、等しい実行結果が出力されることを前提とする。【００６６】
この前提が成立するならば、アドレス配置を変更してプログラムを複数回実行しても、メモリアクセスの回数、順番は等しく、互いに一致対応が取れるアクセスが存在する。よって、全てのメモリアクセスについては、トレース実行の組数分だけ、アクセス先アドレスを取り出すことができる。検査対象のプログラムが誤りを含んでいたために、異なる解釈順序でプログラムが実行された場合には、実行を開始してから対応関係が取れるまでのアクセスを検査対象とする。【００６７】
また、メモリアクセス解析部１３２は、解析対象メモリアクセスの参照先アドレスに基づいて解析対象メモリアクセスにおけるアドレス指定の基点である基点セグメントを特定する基点セグメント特定部１３３を含んでもよい。基点セグメント特定部１３３が基点セグメントを特定できないとき、解析対象メモリアクセスが適正ではないと判定してもよい。【００６８】
さらに、メモリアクセス解析部１３２は、基点セグメント特定部１３３により特定された基点セグメントに解析対象メモリアクセスの参照先アドレスが含まれるか否か判定する境界検査部１３４を含んでもよい。境界検査部１３４が、解析対象メモリアクセスにおける参照先アドレスがセグメントに含まれると判定するとき、解析対象メモリアクセスが適正と判定してもよく、解析対象メモリアクセスにおける参照先アドレスがセグメントに含まれないと判定するとき、解析対象メモリアクセスが適正ではないと判定してもよい。【００６９】
メモリアクセス解析部１３２が、基点セグメント特定部１３３および境界検査部１３４を備えることによって、解析対象メモリアクセスの基点セグメントを特定することができ、これに基づいて、解析対象メモリアクセスの境界検査を行うこともできる。【００７０】
ここで、説明のため、得られたアドレスの個数がＴ個、識別したいメモリセグメントがＫ個あるとし（Ｔは２以上の整数、Ｋは正整数）、第ｋセグメント（ｋ＝１，２，...，Ｋ）のサイズをｓk 、ｔ組目（ｔ＝１，２，...，Ｔ）のトレース実行において、第ｋセグメントに割り当てたメモリ領域の先頭アドレスをａk (t) で表す。【００７１】
プログラム中に正しく記述されたメモリアクセスは、その時点で有効な第ｋセグメントの先頭アドレスａk (t) に、オフセット値ｉを加算して得られたアドレスを用いて、メモリ中のデータを参照する。第ｔトレース実行時のアドレス値をｐ(t) で表すと、このアドレスがセグメントｋを基点として計算された場合、
ｐ(t) ＝ａk (t) ＋ｉ                            ・・・（１）
という式が全てのｔ＝１，２，...，Ｔに対して成立する。【００７２】
さらに、このアクセスが正しい領域を指す場合、オフセット値ｉは、
０≦ｉ≦ｓk −ｗ                                ・・・（２）
という式を満たす。ここで、ｗは同時にアクセスされるアドレスの個数であり、例えば１アドレスに１バイトが割り当てられ、同時に４バイトのアクセスがなされる場合、ｗ＝４である。【００７３】
上記基点セグメント特定処理は、アドレスｐ(1) ，・・・，ｐ(T) から、（１）式を満たすセグメントｋを特定する処理として解釈でき、上記セグメント境界検査処理は、（２）式を満たすかを判定する処理として解釈できる。プログラム実行が１回だけの場合（Ｔ＝１）、（１）式を方程式として解くことはできないが、Ｔ≧２の条件で、適切なアドレス割当がなされていれば、セグメントｋを求めることが可能である。【００７４】
（１）式からオフセット値ｉを除去すると、
ｐ(t+1) −ｐ(1) ＝ａk (t+1) −ａk (1)           ・・・（３）
という式が得られるので（ｔ＝１，２，・・・，Ｔ−１）、アドレス値からセグメント番号ｋを特定するには、ｔ＝１，２，・・・，Ｔ−１に対して（３）式を満たすセグメント番号ｋを探索すれば良い。その結果、（３）式を満たすセグメント番号ｋが存在しないとき、それは正しい計算により得られたアドレスを持たない不正なアクセスである。また、これを満たすセグメント番号ｋが一個だけ存在するとき、第ｋセグメントを基点セグメントとして特定することもできる。【００７５】
このため、メモリアクセスのトレース出力からアドレス計算の基点セグメントを特定できるようにするためには、アドレス割当を工夫し、
Ｄk ＝（ａk (2) −ａk (1) ，ａk (3) −ａk (1) ，・・・，
ａk (T) −ａk (1) ）                ・・・（４）
という式に示す（Ｔ−１）個の数値の組Ｄk が、セグメント番号ｋに対して一意な値を持つようにすれば良い。【００７６】
Ｄk をセグメント番号ｋに対して一意にするアドレス割当方法は多数考えられるが、ここでは効果的な方法を３つ説明する。トレース出力は２組あれば十分であるため、いずれの例でもＴ＝２とする。この場合、Ｄk は、
Ｄk ＝ａk (2) −ａk (1) ＝ｐ(2) −ｐ(1)         ・・・（５）
という式で表され、１組目と２組目との実行で得られたアドレスの差ｐ(2) −ｐ(1) に等しい。【００７７】
第１のアドレス割当方法は、Ｄk がセグメントの先頭アドレスａk (1) を含むように配置する方法である。これは、隣接するセグメント間の先頭アドレスの差が、２組目の実行時に１組目の２倍になるようにすれば可能である。この時、
ａk (2) −ａ1 (2) ＝２｛ａk (1) −ａ1 (1) ｝    ・・・（６）
という式が成立し、これに（５）式を代入すると、
ａk (1) ＝ｐ(2) −ｐ(1) −ａ1 (2) ＋２ａ1 (1)   ・・・（７）
というセグメントの先頭アドレスａk (1) を求める式を得ることができる。この方法は、２組目のプログラム実行時に２倍のメモリを必要とするが、アドレス計算の基点とされたセグメントを簡単に求めることが可能である。【００７８】
図３は、本実施形態の第２のアドレス割当方法（セグメント配置方法）を説明するための図である。第２のアドレス割当方法は、Ｄk がセグメント番号を含むように配置する方法である。これは、図３に示すように、セグメントのアドレス大小順が番号ｋに一致するように配置し、隣接するセグメントの間に置かれた空白域の大きさが、１回目と２回目の実行時で、一定の差Δを持つように割り当てることで、可能になる。【００７９】
この割当で成立する等式は、
ａk+1 (2) −ａk (2) ＝ａk+1 (1) −ａk (1) ＋Δ  ・・・（８）
という式で表される（ｋ＝１，２，...，Ｋ−１）。異なるｋにおける（８）式を合成することで、
ａk (2) −ａk (1) ＝ａ1 (2) −ａ1 (1) ＋（ｋ−１）Δ
・・・（９）
という式が求まる（ｋ＝１，２，...，Ｋ）。この（９）式の左辺に（５）式を代入することで、
ｋ＝１＋｛ｐ(2) −ｐ(1) −ａ1 (2) ＋ａ1 (1) ｝／Δ
・・・（１０）
という式が得られる。【００８０】
（１０）式は、トレースにより得られたアドレスｐ(1) ，ｐ(2) から、基点セグメント番号ｋを、１回の計算で効率良く特定できることを示している。得られたｋが非整数の場合や、有効なセグメント番号に該当しない場合には、そのアクセスを不正であると判断することができる。【００８１】
図４は、本実施形態の第３のアドレス割当方法（セグメント配置方法）を説明するための図である。第３の方法は、図４に示すように、１組目と２組目との実行時で、セグメント配置順を真逆にするものである。ここで、セグメント番号ｋが２組目における配置順に等しいとすると、ｋに対してアドレスａk (2) は単調増加であり、アドレスａk (1) は逆に単調減少である。よって、両者の差ａk (2) −ａk (1) ＝Ｄk はｋに対して単調増加であり、Ｄk がｋに対して一意であることを意味する。ゆえに、第３の方法に従ってアドレス割当を行うことで、２個のアドレス値から基点のセグメントを特定可能である。【００８２】
この第３の方法は、上述した第１の方法や第２の方法のように、単純な処理でセグメントを特定することはできない。しかしながら、（５）式を満たすｋの探索にＤk の単調性を利用した２分法を適用することができるため、計算時間は大きくならず、セグメント個数の対数時間で処理が可能である。また、第３の方法は、冗長なメモリ領域を必要としないため、メモリ使用効率の観点で優れている。【００８３】
本発明は、以上説明したようなセグメントへのアドレス割当で、プログラムを複数回実行し、その結果、トレースされたメモリアクセスのアドレス値を比較することで、個々のメモリアクセスについて、アドレス計算の基点とされたメモリセグメントを特定し、その境界判定を正しく行うことが可能である。【００８４】
本発明は、本発明に関連する技術で用いるガードゾーン方式のように、非連続なメモリアクセスを検出できないような制限を持たない。また、本発明は、本発明に関連する技術で用いるファットポインタ方式のように、プログラム中の変数やメモリの値に基点セグメントを記憶させる方法ではないため、アドレス値の論理演算や分解に対応できない等の制約がない。複数のパタンで与えたセグメントのアドレス配置に対して、プログラムが正常に動作する限り、本発明は、任意のアドレス値演算を含むプログラムについて、メモリアクセスの境界検査が可能である。【００８５】
図５は本発明の第１の実施の形態によるメモリアクセスを解析する処理を示すフローチャートである。図５を参照して本発明の第１の実施の形態によるメモリアクセスを解析する処理について説明する。尚、図５に示す処理は、図１に示すプログラムデバッグ装置１のＣＰＵ（中央処理装置）（図示せず）が、コンピュータで実行可能なプログラムを実行することで実現される。【００８６】
本実施の形態では、解析したいメモリアクセスについて、そのアクセスが参照する先のアドレスと、同一プログラムに異なるセグメント配置を与えて実行した場合に、同一アクセスが参照する参照先アドレスを取得する（ステップＳ１）。ここでは、合わせてＴ個の参照先アドレスが取得されたとし（Ｔは２以上の整数）、この参照先アドレスを、ｐ(1) ，ｐ(2) ，...，ｐ(T) で表す。また、その際のＴ組のセグメント配置を、上記と同様に、第ｋセグメント（ｋ＝１，２，...，Ｋ）のサイズをｓk 、ｔ組目（ｔ＝１，２，...，Ｔ）のトレース実行において、第ｋセグメントに割り当てたメモリ領域の先頭アドレスをａk (t) で表す。【００８７】
プログラムデバッグ装置１は、Ｔ個の参照先アドレスが得られると（ステップＳ１）、（３）式の条件式を満たすセグメント番号ｋを探索する（ステップＳ２，Ｓ３）。その結果、プログラムデバッグ装置１は、有効なセグメント番号ｋが存在しなければ（ステップＳ４の偽）、このアクセス（解析対象アクセス）はどのセグメントもアドレス計算の基点としない不正アクセスであると判定する（ステップＳ８）。有効なセグメント番号ｋが存在する場合（ステップＳ４の真）、プログラムデバッグ装置１は、セグメント番号ｋに該当する第ｋセグメントを基点セグメントとして特定する。【００８８】
ステップＳ５以降の処理は、上記の基点セグメント特定処理に続いて境界検査処理も連続して行う場合の手順である。プログラムデバッグ装置１は、基点アドレスに加算されたオフセットｉ（ｉ＝ｐ(1) −ａk (1) ）を求め（ステップＳ５）、オフセットｉが基点セグメントのサイズから当該参照先アドレスが指定するアドレスの数を減算した値以下の整数値である（０≦ｉ≦ｓk −ｗ）とき（ステップＳ６の真）、プログラムデバッグ装置１は、当該参照先アドレスがセグメントに含まれると判定し、当該メモリアクセス（解析対象メモリアクセス）が適正なものであると判定する（ステップＳ７）。また、上記範囲外であれば（ステップＳ６の偽）不正なアクセスであると判定する（ステップＳ８）。【００８９】
これらの手順は、上記の本発明を実施する際のメモリセグメント配置方法で示した基点セグメントの特定方法を具体化したものであり、個々のメモリアクセスに対して有効な境界検査を行うことが可能である。【００９０】
図６は本発明の第２の実施の形態によるメモリアクセスを解析する処理を示すフローチャートである。本発明の第２の実施の形態によるプログラムデバッグ装置は、図１に示す本発明の第１の実施の形態によるプログラムデバッグ装置１と同様の構成となっているので、これら図１及び図６を参照して本発明の第２の実施の形態によるメモリアクセスを解析する処理について説明する。尚、図６に示す処理は、図１に示すプログラムデバッグ装置１のＣＰＵが、コンピュータで実行可能なプログラムを実行することで実現される。【００９１】
本実施の形態において、プログラムデバッグ装置１は、上述した本発明の第１の実施の形態と同様にして、異なるアドレス配置の下でのプログラムを実行して得られたＴ個のアドレス値ｐ(1) ，ｐ(2) ，...，ｐ(T) を取得する（ステップＳ１１）。【００９２】
次に、プログラムデバッグ装置１は、全てのｔに対して、アドレスｐ(t) が含まれるセグメントｋ(t) を特定し、さらにオフセットｉ(t) を求める（ステップＳ１２〜Ｓ１６）。ここで、どの有効なセグメントにも含まれないアドレスｐ(t) が１個でも存在すれば（ステップＳ１４の偽）、このメモリアクセスは不正なアドレス計算によりなされたものと判定する（ステップＳ１９）。【００９３】
プログラムデバッグ装置１は、全てのｐ(t) に対し、包含するセグメントとオフセットとが求まったならば、その両方が全てのｔで一致するかどうかの比較を行う（ステップＳ１７）。比較処理の結果、プログラムデバッグ装置１は、一個でも一致しないものがあれば（ステップＳ１７の偽）、このアクセスが不正なアドレス計算によりなされたものであると判定する（ステップＳ１９）。【００９４】
これらの手順は、（１）式及び（２）式で示した条件式が、全てのｔに対して成立することを確認する処理となっている。これによって、本実施の形態では、メモリアクセスの境界検査を行うことが可能となる。【００９５】
本発明の第３の実施の形態は、静的に配置されるセグメントへのアクセスについて境界検査を行う方法の一例である。本実施の形態に必要な構成例について図１を参照して説明する。図１におけるメモリアクセストレース部１１−１〜１１−Ｔは、Ｃ言語で記述されたプログラム、またはＣ言語コンパイラでコンパイルした結果得られるオブジェクトファイル、スタティックライブラリから、実行形式のプログラムを生成して、シミュレータで実行し、メモリアクセスをトレースするＴ個の手段である（Ｔは２以上の整数）。【００９６】
より具体的に説明すると、メモリアクセストレース部１１−１〜１１−Ｔは、Ｃ言語コンパイラを用いて必要なオブジェクトファイルを生成した後、アドレス割当部１２の決定に基づいて、スタティックセグメントを適切なアドレスに配置しながらオブジェクトファイルを結合し、実行形式のプログラムを生成する。さらに、生成された実行形式のプログラムをシミュレータで実行し、その際に行われたメモリアクセスについて、アクセスした先のアドレスやアクセスを行わせる命令記述の位置情報をトレースし、データ解析部１３に出力する。【００９７】
アドレス割当部１２は、プログラムのオブジェクトファイルに書かれたスタティックセグメントの情報を調べ、使用されるセグメントに対するアドレス配置をＴ組決定し、メモリアクセストレース部１１−１〜１１−Ｔに指示を伝える。この配置は、例えば、上述した第１〜第３の方法で決定されるものとする。【００９８】
データ解析部１３は、メモリアクセストレース部１１−１〜１１−Ｔがプログラムを実行した時に行われた命令実行の順序やプログラムが外部に出力する結果が、アドレス配置やその他の偶発的な要因に依存するものを除き、論理的に等しいことを確認する。【００９９】
データ解析部１３は、等価性が成立しないと判断した場合、エラーを出して解析を終了する。データ解析部１３は、等価であった場合、個々のメモリアクセスについて、同一アクセスに対応するＴ組のトレース結果を取り出し、これが静的配置セグメントに対するメモリアクセスであるかを調べる。【０１００】
これは、例えば、アドレス値の大小に基づいて判断してもよいし、あるいは対応する実行指令の記述を調べて判断しても構わない。判断の結果、データ解析部１３は、このアクセスが検査対象であるならば、上述した本発明の第１の実施の形態や本発明の第２の実施の形態に示した境界検査部１３４と同様の構成を含み、そのメモリアクセスのアドレスがどのセグメントを基点として計算されたかを調べ、境界検査を行う。データ解析部１３は、不正アクセスであれば、不正を検出したという結果と、不正を発生させた実行指令の記述箇所を示す情報を提示する。【０１０１】
本実施の形態は、以上の手順で、静的に配置されたデータセグメントへのアクセスについて、それが有効な範囲のアドレスを示すアクセスであるか境界検査を実施することが可能である。【０１０２】
尚、境界検査の対象となるセグメントは、検査目的に合わせて適当な大きさのものが選択されるとする。例えば、名称の異なる個々のグローバル変数（配列を含む）を別のセグメントとして扱うのも一つの例であるし、あるいは、プログラムをファイル等の単位で適当に分割し、同一ファイルに含まれる変数をまとめて一セグメントとして扱うのも一つの例である。【０１０３】
Ｔ個のメモリアクセストレース部１１−１〜１１−Ｔは、実行形式に変換したプログラムをシミュレータで動作させて、メモリアクセスをトレースするとして説明したが、これらの手段は、これと同様の結果を得られる手段や構成であれば、別のものを用いて構わない。【０１０４】
例えば、メモリアクセスをトレースする機能を備えたプロセッサやハードウェアを利用するのも一つの例である。あるいは、与えられたプログラムに適当な命令記述を追加し、メモリアクセスが行われる前に、データ解析部１３にアドレス値を出力する処理がなされるようにしてもよい。この時、プログラムを変換する際には、元のプログラム記述において同一であったアクセスをトレース後に識別できるような工夫を持たせておく。あるいは、このようなＴ組のプログラム実行を同時に行いつつ、メモリアクセスの境界検査も自ら処理するプログラムを元プログラムから作成するのも一つの例である。【０１０５】
Ｔ個のメモリアクセストレース部１１−１〜１１−Ｔがプログラムを実行し、トレース結果をデータ解析部１３に伝える手段や、タイミングについては、同様の効果が得られるならばいかなる方法であっても構わない。例えば、Ｔ個のトレース手段を同時に動作させて、メモリアクセスがなされた時点で、データ解析部１３を動作させても良い。プログラムを最後まで実行して、得られたトレース結果をメモリやディスク装置等の記憶手段に出力した後、データ解析部１３は記憶されたＴ組のトレース結果を読み出しながら、検査を行う手順でも構わない。【０１０６】
セグメントへのアドレス配置は、オブジェクトファイルを結合して実行ファイルを作成する際に指定すると説明したが、同様の作用があるならば、いかなる方法であっても構わない。例えば、入力されたＣ言語プログラムに、アドレス値を明示的に記述しても良いし、実行形式で与えられたプログラムを解析して、命令記述を変更する方法でも構わない。【０１０７】
本発明の第４の実施の形態は、動的にヒープから割り当てられるメモリセグメントについて、境界検査を行う方法の一例である。本実施の形態は、上記の本発明の第３の実施の形態と同様に、図１に示す構成で実施される。ここでは、上記の本発明の第３の実施の形態との違いのみについて説明する。【０１０８】
本実施の形態では、セグメントの配置アドレスが決定されるのは、検査対象のプログラムが実行中にヒープメモリ操作関数を呼び出す時である。ヒープ操作用の関数とは、主として指定サイズを持つ連続メモリを確保する関数とこれを解放する関数との組からなる。これは、Ｃ言語の標準ライブラリを用いる場合はｍａｌｌｏｃ，ｆｒｅｅ関数、Ｃ＋＋言語ならばｎｅｗ，ｄｅｌｅｔｅ関数がこの例であり、実行環境のＯＳ（Ｏｐｅｒａｔｉｎｇ  Ｓｙｓｔｅｍ）が提供する関数を用いても良いし、同様の機能を持つならば、プログラム自身が備える独自の関数でも良い。【０１０９】
本実施の形態では、メモリアクセストレース部１１−１〜１１−ＴがＴ組のプログラム実行を行う際に、これらのヒープ操作関数の呼び出しが異なるアドレス割当結果を返すようにし、適切な範囲検査を行えるようにする。これは例えば、プログラムを、Ｃ言語記述やオブジェクトファイルの形式で入力し、これを実行形式に変換する際に結合するヒープ操作関数ライブラリを、検査用のアドレス割当が可能なものに置換するのが一例である。【０１１０】
あるいは、ヒープ操作関数として動的に結合されるライブラリ［Ｌｉｎｕｘでは共用ライブラリ、Ｗｉｎｄｏｗｓ（登録商標）ではＤＬＬがこの例にあたる］のものを使うように実行形式を作成し、実行時に使用するライブラリを置換するのも一つの例である。他には、シミュレータがプログラムを実行する際に、ヒープ操作関数の呼び出しを検査用の処理に置換する方法であっても良いし、プログラムを解析してから検査用のプログラムに変換する際に、検査用のアドレス割当が行われるようにしても良い。【０１１１】
本実施の形態では、メモリセグメントの確保と解放が動的に繰り返し行われるため、個々のアクセスの境界検査では、アドレス範囲の検査だけでなく、参照するセグメントがその時点で有効であるか、時間方向の検査も必要である。このため、本実施の形態では、ヒープ確保関数と解放関数の呼出もトレースし、メモリアクセスとの時間的な順序関係も検査できるようにする。この時、過去に使用され既に解放済みのセグメントを参照するアクセスと、新規に確保されたセグメントへのアクセスとを別個と認識するには、（４）式の値が全てのセグメント内で一意になるようにアドレスを割り当てる必要があるため、一度解放されたセグメントを再割り当てする際に注意が必要である。【０１１２】
以上の説明した構成によって、本実施の形態は、ヒープ上に配置されたデータセグメントへのアクセスについて境界検査を実施することが可能である。【０１１３】
本発明の第５の実施の形態は、スタック上に置かれるメモリセグメントについて境界検査を行う方法の一例である。本実施の形態も、本発明の第３の実施の形態と同様に、図１に示す構成で実施される。ここでは、本実施の形態と本発明の第３の実施の形態との違いのみについて説明する。【０１１４】
本実施の形態におけるスタック上のセグメントとは、Ｃ言語等で記述されたプログラムにおいて、関数内で宣言された自動変数（配列を含む）や、関数呼び出し時にスタック上に置かれる引数、戻りアドレスを包含する連続メモリ領域のことである。複数の変数をまとめて１セグメントとしても良く、その単位は検査目的に合わせて変えて良い。有効なセグメントの個数や配置は、プログラムの実行時に動的に変化する。配置先のアドレスは、プログラム実行時に与えられたスタックポインタを基点として、相対的に決定される。【０１１５】
Ｔ個のメモリアクセストレース部１１−１〜１１−Ｔは、このようなセグメントのアドレス割当を変更しながらプログラムを実行することが可能な環境とする。例えば、Ｃ言語で記述されたプログラムを入力とし、これを直接解釈しながら動作するインタープリタ型の実行環境を用いるのが一つの例である。【０１１６】
あるいは、Ｃ言語プログラムを実行形式に変換する際に、スタック利用の異なるプログラムを複数生成するのも一例である。複数のプログラムを生成せずに、スタックにアクセスする機械語命令が記述された位置をファイルに記録しておき、実行形式のプログラムを実行するシミュレータが、これを参照しながら動作を修正するのも一例である。【０１１７】
データ解析部１３による境界検査では、その時点で有効なセグメント配置が正しく認識される必要があるため、Ｃ言語記述を実行形式に変換する実施の形態の場合には、各々の関数で使用されるセグメント情報や、プログラム実行中に関数が呼ばれた順番、スタックポインタの値など、適切な情報をトレースする必要がある。【０１１８】
以上の説明した構成により、本実施の形態は、スタック上に配置されたデータセグメントへのアクセスについて境界検査を実施することが可能である。【０１１９】
本発明の第６の実施の形態は、スタック上に置かれるセグメントについて、関数単位で境界検査を行う方法の一例である。本実施の形態も、上記の本発明の第５の実施の形態と同様に、図１に示す構成で実施される。ここでは、本実施の形態と本発明の第５実施の形態との違いのみについて説明する。【０１２０】
本実施の形態では、検査単位のセグメントを、個々の関数からスタックポインタ経由でアクセスされる連続的なメモリ領域として定義する。有効なセグメントや配置は、プログラム実行中に動的に変化する。【０１２１】
本実施の形態のプログラムデバッグ装置１は、プログラムのセグメントが、関数もしくはその関数から呼び出される子関数を含む関数群に対して、一つの関数または関数群内で、スタックポインタを基点とする相対アドレス参照が許可される連続メモリ領域として定義されてもよい。そして、プログラムの実行中に、関数の呼出が発生した時点で、当該関数に対応するセグメントをスタックポインタと共に異なるアドレスに移動させ、当該関数から呼出元に戻る時点で当該セグメントをスタックポインタと共に元のアドレスに移動させてもよい。【０１２２】
また、本実施の形態のプログラムデバッグ装置１は、第１の関数または関数群の実行指令の中で、第２の関数または関数群が呼び出された状態では、第１の関数または関数群に対して定義された連続メモリ領域から、第２の関数または関数群に対して定義された連続メモリ領域と重複する領域を除去した領域を、第１の関数または関数群に対して定義されたセグメントとしてもよい。【０１２３】
より具体的に定義すると、ある関数ｆ1 の実行中、関数ｆ1 は関数ｆ2 から呼び出され、関数ｆ2 は関数ｆ3 から呼び出され、同様にして、関数ｆN-1 が関数ｆN から呼び出され（Ｎは１以上の整数）、関数ｆN が最初の関数である状態を考えると、この時、有効なセグメントは、Ｎ個定義される。【０１２４】
１つは、関数ｆ1 からスタックポインタを用いて間接的にアクセスされるスタック上の連続メモリ領域（これを関数ｆ1 のアクセス域と定義する）であり、２個目は、関数ｆ2 のアクセス域から関数ｆ1 のアクセス域を除いた連続メモリ領域、同様にしてＮ個目は、関数ｆN のアクセス域から関数ｆN-1 のアクセス域を除いた連続メモリ領域である。【０１２５】
ここで、関数ｆn （ｎは１以上の整数）のアクセス域は、スタックに積まれた関数ｆn の引数、戻りアドレス、関数ｆn 内で一時使用されるスタック領域（内部で別の関数を呼び出すために引数や戻り値を置く領域を含み、そこで呼び出される関数が内部で使用するスタック領域は含まない）、関数戻り値の出力に利用されるスタック領域（戻り値がレジスタで返す場合は存在しない）が含まれる。【０１２６】
図７は本発明の第６の実施の形態におけるプログラムデバッグ装置１の動作を説明するためのＣ言語プログラム例を示す図であり、図８は本発明の第６の実施の形態におけるプログラム実行時のスタック状態とスタックポインタの時間遷移とを示す図であり、図９は本発明の第６の実施の形態においてスタック移動処理がなされた場合のスタック状態とスタックポインタの時間遷移とを示す図である。【０１２７】
図８は、上記の定義を具体的に示す例であり、図７に示すＣ言語プログラム記述をコンパイルして実行した時のスタック使用状態とスタックポインタの時間遷移とを示している。この例では、ｃｄｅｃｌと呼ばれる呼び出し規約に基づいて関数が呼び出されるものとする。【０１２８】
この規約では、アドレスが大きい方から小さくなる方に順に、関数の引数と戻りアドレスがスタックに積まれる。図８（ａ）は、図７に示すプログラムの１２行目で関数ｆｕｎｃ２が呼び出された直後の状態であり、引数ｂ，ａ，戻りアドレスがこの順でスタックに置かれている。図８（ｂ）は、図７に示すプログラムの１４行目で関数ｆｕｎｃ１を呼ぶ機械語命令を実行する直前の状態であり、関数ｆｕｎｃ２で確保された配列変数ｂｕｆと、関数ｆｕｎｃ１に渡す引数ｐ，ｘがスタックに置かれている。【０１２９】
図８（ｃ）は、関数を呼ぶ機械語命令が実行された直後の状態であり、関数の戻りアドレスがスタックに積まれ、図８（ｄ）は関数ｆｕｎｃ１の実行中の状態、図８（ｅ）は関数から戻る直前の状態、図８（ｆ）は関数ｆｕｎｃ１から関数ｆｕｎｃ２に戻る機械語命令が実行された直後の状態である。【０１３０】
この例では、関数ｆｕｎｃ２のアクセス域は、図８（ｂ）に示す範囲のメモリ領域であり、（ａ）−（ｂ），（ｅ）−（ｆ）において、この範囲が関数ｆｕｎｃ２のセグメントである。図８（ｄ）において、関数ｆｕｎｃ１のアクセス域かつセグメントは、図８（ｄ）の左側に示したスタック領域である。この状態において、関数ｆｕｎｃ２のセグメントは、関数ｆｕｎｃ１との重複分が除かれるので、図８（ｄ）の右側に示す範囲の領域である。【０１３１】
本実施の形態に基づく境界検査も、上記の本発明の第５の実施の形態と同様に、図１に示す構成で実施される。但し、メモリアクセストレース部１１−１〜１１−Ｔが入力するプログラムは、Ｃ言語で記述されたものである必要はなく、実行形式に変換済みの形式で与えられても良い。その場合には、プログラムに含まれる関数を実行中に識別するための情報と、個々の関数がスタックポインタ経由でアクセスし得るセグメントのアドレス範囲が記述された情報を、補助情報として入力させるようにする。【０１３２】
スタック上のセグメント配置の変更処理は、メモリアクセストレース部１１−１〜１１−Ｔがシミュレータを用いてプログラムを実行する際に、シミュレータが処理される命令や命令の置かれたアドレスを監視し、関数の呼び出し命令と復帰命令とが実行されるタイミングで、スタックポインタとスタック上のセグメントの配置アドレスとを移動させる処理を、シミュレータに行わせることで実施する。【０１３３】
ここでは、上記の第１の方法に基づいて、これらのセグメントを配置して検査を行う例を示す。１組目のメモリアクセスのトレースを得る際は、図９に示すように、通常の場合と同様にプログラムを実行し、２組目のトレースを得る際には、Δバイトの隙間領域をセグメント間に挿入する。【０１３４】
図９は、２組目のトレースを得るために、図７と同じプログラムを実行した時のスタック使用とスタックポインタの時間遷移とを示している。隙間領域のサイズΔは４バイトであるとし、ｉｎｔ変数やポインタ変数の格納域も４バイトであるとする。図９（ｂ）は、関数ｆｕｎｃ１への引数のスタック積み込みを終えて、関数呼び出し命令を実行する前の状態である。【０１３５】
この直後に、関数ｆｕｎｃ１の呼び出し命令がシミュレータに検出されると、シミュレータには、関数ｆｕｎｃ１のセグメントをΔバイトだけアドレス減少方向に移動させる。具体的には、スタックに積まれた引数ｐ，ｘを左方向に移動し、スタックポインタの値を変更してから、関数呼び出しを処理し、図９（ｃ）に示す状態に移行する。【０１３６】
その後、図９（ｄ）で関数ｆｕｎｃ１を実行し、図９（ｅ）で関数ｆｕｎｃ２への復帰命令を実行したことがシミュレータにより検出されると、シミュレータは引数ｐ，ｘとスタックポインタを元の図９（ｂ）の状態に復元する処理を行い、関数ｆｕｎｃ２の残りの処理を実行する状態に移行する。【０１３７】
このような手順に従い、プログラムを実行してメモリアクセスをトレースすると、１組目のトレース実行時には、各々の状態で有効なセグメントが密に配置され、２組目のトレース時には、セグメント間にΔバイトの隙間領域が置かれる状態になり、関数に対応付けて定義されたセグメントに対して、図３に示す第１の方法に基づくアドレス割当がなされることが分かる。【０１３８】
本実施の形態では、この図９に示す配置で、プログラムを実行した時のメモリアクセスをトレースし、図８の配置の場合のトレース結果と比較することで、個々のメモリアクセスについて境界検査が可能である。【０１３９】
図７に示すプログラムを実行した場合について説明すると、図７に示すプログラムの６行目は関数ｆｕｎｃ１のセグメントを参照する正当なアクセス、図７に示すプログラムの７行目は関数ｆｕｎｃ２のセグメントを参照する範囲外のアクセスである。【０１４０】
これを、図８のスタック配置で実行すると、上記の６行目も７行目も共に変数ｒｅｓの置かれたアドレスへのメモリアクセスを発生させるので、単にメモリアクセスをトレースするだけでは両者を区別することができず、メモリアクセスの不正を検出することができない。【０１４１】
しかしながら、Δバイトの隙間を設けた図９では、７行目のアクセスが６行目と異なり、変数ｒｅｓではなく、戻りアドレスの置かれた隣のメモリ領域にアクセスを行う。この、図８に示す場合と図９に示す場合との違いから、７行目のアクセスと６行目のアクセスとのアドレス値から、６行目及び７行目のアクセスが参照するセグメントを特定することができ、これより、正しい境界検査が可能である。この場合には、６行目は問題なく実行され、７行目は範囲外のアクセスとして検出される。【０１４２】
尚、上記の説明では、プログラムに含まれる個々の関数について、スタックポインタを用いた相対アクセス参照が許可されたメモリの範囲を補助情報として入力するか、コンパイル時に取得する必要があるとしている。しかしながら、この情報を簡略化し、引数としてスタックに積まれるデータのバイト数のみとする発明の実施も可能である。【０１４３】
この場合には、実行中の関数のアクセス域の下限（図９の左方向の境界）が分からないので、例えばスタックとして与えられたメモリ領域の下限までをその関数のセグメントとする。呼び出しスタック中の関数については、それ以降に呼ばれた関数のセグメントと重複する領域が除外されるので、有効なセグメントの下限は関数呼び出し時のポインタと、引数のバイト数とから求めることができる。【０１４４】
上記の説明では、関数の呼び出し規約がｃｄｅｃｌ方式であるとしたが、他の呼び出し規約、例えばＰＡＳＣＡＬやｆａｓｔｃａｌｌ等の方式であっても構わない。また、上記の説明では、関数呼び出し命令をシミュレータが処理する直前と復帰命令を処理した直後に、スタック上のセグメント移動処理を行わせるようにしたが、これが関数呼び出し命令の実行直後や復帰命令の実行直前であっても良い。関数呼び出しに伴う戻りアドレスのスタック退避が、問題を引き起こさないように、セグメントの定義を修正する。【０１４５】
上記の説明では、１つの関数に対して１つのセグメントを定義したが、ある関数から呼び出される子関数や孫関数も含めて、これを一つの関数群として扱い、関数群にセグメントを１つ定義する実施であっても構わない。【０１４６】
本実施の形態は、以上説明した構成や動作によって、スタック上に配置されたセグメントへのアクセスについて関数単位で境界検査を実施することが可能である。【０１４７】
本発明の第７の実施の形態では、複数種類のセグメントへの検査を同時に行う例として、静的に配置されるセグメントとヒープ上のセグメントとに対する境界検査を同時に実施する例を示している。本実施の形態の構成は、上述した本発明の第１及び第２の実施の形態と同様に、図１で示される構成を用いている。【０１４８】
本実施の形態の各構成要素は、本発明の第１の実施の形態と本発明の第２の実施の形態とにそれぞれ示す動作の両方を行う。その動作は、本発明の第１の実施の形態と本発明の第２の実施の形態とでそれぞれ説明したものの単純な組み合わせであるため、詳細な説明を省略する。【０１４９】
複数の検査を組み合わせる際に注意すべき点は、トレースされたメモリアクセスのアクセス先がスタックであったか、ヒープであったか、種類を判別する方法である。これは、様々な実施の形態が考えられる。一つは、種類によらず全セグメントの中で、セグメントを特定するためのアドレス差分Ｄk ［上記の（４）式にて算出］を一意に設定する実施の形態がある。他には、得られたアクセス先のアドレスの範囲でセグメントの種類を絞り込んでから、種類毎に個別の検査を行う例がある。【０１５０】
このような点に注意すれば、本発明に基づいて複数種類のセグメントへのメモリアクセス境界検査を同時に実施することが可能である。これは、静的なセグメントとヒープセグメントとの組み合わせ以外であっても、同様である。【０１５１】
図１０は本発明の第８の実施の形態によるプログラムデバッグ装置２の構成例を示すブロック図である。図１０には、境界検査に利用される複数のメモリアクセストレース結果を得るための手段の構成や動作を示している。図１０において、本発明の第８の実施の形態によるプログラムデバッグ装置２は、複数コンテキスト並列実行部２１と、メモリセグメントアドレス割当部（以下、アドレス割当部）２２と、データ解析部２３とを備えている。  【０１５２】
ここで、データ解析部２３は、実行結果解析部２３１、メモリアクセス解析部２３２を有してもよい。さらに、メモリアクセス解析部２３２は、基点セグメント特定部２３３および境界検査部２３４を含んでもよい。本実施形態におけるアドレス割当部２２およびデータ解析部２３、またデータ解析部に内包される実行結果解析部２３１、メモリアクセス解析部２３２、基点セグメント特定部２３３および境界検査部２３４は、それぞれ第１の実施の形態にて説明したアドレス割当部１２、データ解析部１３、実行結果解析部１３１、メモリアクセス解析部１３２、基点セグメント特定部１３３および境界検査部１３４と同様の動作を行ってもよい。【０１５３】
本実施の形態では、プログラムの実行コンテキストを複数保持し、それらを同時に更新する複数コンテキスト並列実行部２１を用いて、複数のアドレス割当条件下でのプログラム実行とメモリアクセスのトレースとを行う。このプログラム実行は、実際に複数コンテキストを並列実行可能なハードウェアを用意して行っても良いし、仮想的に構築しても良い。【０１５４】
より具体的には、本実施形態のプログラムデバッグ装置２に備えられる複数コンテキスト並列実行部２１は、複数コンテキスト並列実行部２１が使用するレジスタとメモリとに複数の格納値を記憶させられる仮想実行環境を生成し、レジスタとメモリとに、アドレス割当部２２にて変更されたセグメントの配置に基づいてプログラムを実行した場合に得られる複数の格納値を記憶させることでプログラムを実行して参照先アドレスを求めてもよい。または、仮想実行環境を用いてプログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得てもよい。【０１５５】
例えば、上記の非特許文献２に記載のようなシャドウ値を備える仮想実行環境を構築し、１組目以外のコンテキストをシャドウ値として保存することで、検査を実施するのも一例である。この例で、実行コンテキストは、プロセッサが備えるレジスタ及びメモリの数値格納状態や、その他、プログラム実行手段の状態を意味する。【０１５６】
図１１（ａ）は、２組のプログラムを並列実行する過程でのメモリ状態を示している。図１１（ａ）においては、左側から３個のセグメントが、２つのコンテキストで異なるアドレスに配置されている。アドレス割当の影響を受けない変数ａ，ｂ，ｃは共通の値を保持し、ポインタ変数ｐは２つのコンテキストで違うアドレスを保持している。【０１５７】
上述したように、本発明は、検査対象のプログラムの論理的な動作がセグメントへのアドレス割当の変更に対して不変であることを前提とする。この条件の成立性は、複数コンテキスト間でプログラム実行順が一致するか、実行過程を逐次比較することで確認することが可能である。【０１５８】
この時、論理的には一致した動作であるが、アドレス割当に依存する除去できない分岐が含まれる時（例えば、アドレスの端数を切り詰める処理をｉｆ文で行うのがこれに該当する）には、これを不正と判断しないように回避するため、何らかの工夫を取り入れておく。例えば、この工夫としては、検査実行時に例外を指定させる方法や、プログラム記述を変換する方法、あるいはアドレス配置に制約を加える方法がある。【０１５９】
この実施の形態で、プログラム実行に要する時間を短縮する工夫として、全てのコンテキストで等しい処理が行われることが予測できる場合には、これを利用して複数回の命令実行処理を１回にすることで、シミュレーションに要する時間を短縮することも可能である。例えば、全てのコンテキスト間でレジスタの格納値が等しい状態で、メモリにアクセスする命令や、セグメントの配置アドレスに依存する数値を扱わない命令記述がなされている区間については、このような時間短縮が可能である。【０１６０】
他には、コンテキストの並列更新を簡易に行うため、上記のような論理動作の一致検査を省略し、１組目以外のコンテキストでのプログラム処理順が、１組目に全て一致すると仮定して、複数コンテキストの更新を行う方法もある。【０１６１】
以上説明した構成により、本実施の形態は、複数コンテキストの同時更新を行う実行環境を用いることで、一度の検査でメモリアクセスの境界違反を調べることが可能である。【０１６２】
本発明の第９の実施の形態は、上述した本発明の第８の実施の形態と同様に、一度の実行で複数コンテキストのトレース結果を得る例であり、図１０に示される構成と同様の構成で実行される。この実行環境として、上記の非特許文献２に記載のシャドウ値に類する仕組みを用いる。但し、本実施の形態は、本発明の第８の実施の形態とは異なり、１つのコンテキストを主コンテキストとして選択し、他のコンテキストの格納値をシャドウ値として、主コンテキストの格納値である主値に関連付けて記憶している。この関連付けは、論理的な意味で同一のセグメントの同一アドレスオフセットで参照されるデータ及びレジスタ同士を対応させる方法で行われる。【０１６３】
本実施形態のプログラムデバッグ装置２は、複数コンテキスト並列実行部２１は、プログラムで使用される変数に、複数の格納値を記憶させられる仮想実行環境を生成し、各々の変数に、アドレス割当部２２にて変更されたセグメントの配置に基づいてプログラムを実行した場合に得られる複数の格納値を記憶させることで、プログラムを実行して参照先アドレスを求めてもよい。もしくは、仮想実行環境を用いてプログラムを複数回実行する場合に等しく処理して参照先アドレスを得る検査プログラムを生成してこれを実行することで、参照先アドレスを得てもよい。【０１６４】
図１１は本発明の第８の実施の形態及び本発明の第９の実施の形態と本発明に関連する方式との違いを説明するための図である。図１１（ａ）は、本発明の第８の実施の形態の実行状態を示し、ここでは、２通りのセグメント配置で実行コンテキストが別個に保持される。【０１６５】
これに対して、本実施の形態を示す図１１（ｂ）では、１組目のコンテキストが主コンテキストとして扱われ、２組目のコンテキストは、シャドウ値として記憶される。さらに、シャドウ値の格納先アドレスは、２組目のコンテキストのアドレス配置ではなく、これと論理的に同一のデータが主コンテキストにおいて格納される先のアドレスである。【０１６６】
例えば、配列変数ｂ［５］の先頭要素ｂ［１］は、図１１（ａ）の第２コンテキストにおいて２ＣＨ番地に格納されるのに対して、図１１（ｂ）では、同様に２ＣＨ番地に格納されたコンテキストを仮想的に保持しつつ、実際の値の格納先は、第１コンテキストの格納先である２４Ｈ番地のデータのシャドウ領域である。尚、図１１（ｂ）にシャドウ値として格納される数値は、あくまでも図１１（ａ）の２重実行を仮定してのものであるので、２４Ｈ番地に格納されるポインタｐが指すアドレスのシャドウ値は、２４Ｈ番地ではなく２ＣＨ番地である。【０１６７】
この動作から分かるように、本実施の形態と本発明の第８の実施の形態とで行われる複数のプログラム実行は、本質的に等価な処理を行っており、本発明の第８の実施の形態と同等の境界検査を実施することが可能である。【０１６８】
本発明の第９の実施の形態を、Ｎｅｔｈｅｒｃｏｔｅらの方法（非特許文献５に記載の方法）と比較する。Ｎｅｔｈｅｒｃｏｔｅらの方法は、実行形式で与えられたプログラムの実行中に、セグメントのアドレスが代入されたレジスタやメモリの数値を追跡し、シャドウ値に、ポインタか、非ポインタかを示す情報と、参照セグメントを示す識別子（ここではセグメントの先頭アドレスとする）とを格納する。【０１６９】
図１１（ｃ）に、同じ検査をＮｅｔｈｅｒｃｏｔｅらの方法で行った場合の状態を示す。この状態と本実施の形態に基づく例［図１１（ｂ）］との違いは、シャドウ値に格納される情報の表現形式である。変数ｐが左から２組目のセグメントを指すポインタであることを、Ｎｅｔｈｅｒｃｏｔｅらの手法の図１１（ｃ）では、変数ｐの値が記憶される３８Ｈ番地のシャドウ値に、参照先セグメントの先頭アドレスの２０Ｈ番地を持たせることで記憶する。【０１７０】
これに対して、本実施の形態による図１１（ｂ）では、仮想コンテキストで実行した場合の値２ＣＨをシャドウ値として記憶し、シャドウ値と主値との差（２ＣＨ−２４Ｈ＝８）が、２組目のセグメントの先頭アドレスの仮想配置と主配置との差（２８Ｈ−２０Ｈ＝８）に一致することで、参照先セグメントを表現している。【０１７１】
本実施の形態は、Ｎｅｔｈｅｒｃｏｔｅらの方法と同等の検査を実行できるだけでなく、アドレス値に対する任意の演算がプログラムに含まれていたとしても、検査が可能となるという利点を備える。例えば、４バイトのポインタｐを、上位２バイトと下位２バイトとに分解して、他のメモリ領域に格納すると、Ｎｅｔｈｅｒｃｏｔｅらの方法はシャドウ値に参照セグメント情報を追跡記憶させることが不可能になるが、本実施の形態は２通りのコンテキストを保持すれば良いだけなので、特に制約を受けない。【０１７２】
従って、本実施の形態は、Ｎｅｔｈｅｒｃｏｔｅらの方法の課題を解決する改良手法と解釈することが可能である。アドレス値と所属セグメント識別子とからなるファットポインタは、本発明の原理に基づいて、アドレスの主値と、異なるアドレス割当でプログラムを実行した場合に代入されるアドレス値を仮想的に求めたシャドウ値との組で表現することが可能であり、これは計算自由度の点で優れる表現である。【０１７３】
尚、このように、シャドウ値を利用できる仮想実行環境を用いると、本実施の形態をＮｅｔｈｅｒｃｏｔｅらの方法と組み合わせて本発明を実施することも可能である。例えば、実行コンテキストのシャドウ値に、本発明のシャドウ値に加えて基点とするセグメントへのポインタの両方を持たせても良い。あるいは、どちらか片方の表現を選択するフラグを設け、基点セグメントへのポインタによる追随が不可能になった場合に限り、本発明の表現でシャドウ値を持たせる方法も一つの例である。【０１７４】
本発明の第１０の実施の形態は、上記の本発明の第９の実施の形態と同様に、異なるアドレス配置でプログラムを実行した場合の実行コンテキストを、シャドウ値として主コンテキストに組み合わせて記憶させる方法の例である。【０１７５】
本発明の第９の実施の形態では、実行形式プログラムを解釈して処理する際のレジスタやメモリ格納値を、プログラムの実行コンテキストと扱っているが、本実施の形態では、Ｃ言語等で記述された変数の状態を実行コンテキストとみなし、異なるアドレス配置条件で実行した場合に得られる数値を、個々の変数に多重記憶させている。【０１７６】
これを実施する方法としては、実行環境として多重のコンテキスト更新機能を備えたＣ言語インタープリタを用いる方法や、これと等価な動作を行う実行形式プログラムを直接生成する方式があるが、ここでは、検査したいＣ言語プログラムを、等価な動作を行うＣ言語やＣ＋＋言語のプログラムに変換してから、これを実行形式に変換して実行する手順により、検査を行う方法について説明する。【０１７７】
本実施の形態は、非特許文献２に記述されたＦａｉｌ  Ｓａｆｅ  Ｃコンパイラと同様な処理手段とこれを用いる手順で、入力されたプログラムを変換することで、有効なセグメント外を参照する危険性があるメモリアクセスの前に、アドレス値の境界検査を自ら行い、不正であれば停止し、妥当であればプログラムに記述された処理を継続する実行形式のプログラムを生成する。【０１７８】
本実施の形態で、Ｃ言語プログラムを解析して、実行時に境界検査を行わせる処理の内容は、境界検査の仕組みを除いて、Ｆａｉｌ  Ｓａｆｅ  Ｃと共通である。本実施の形態では、Ｆａｉｌ  Ｓａｆｅ  Ｃと同様に、セグメントメモリを参照するポインタ型変数を、参照先セグメントの情報を保持する倍のサイズを持つ拡張構造体変数に置換し、また、ポインタ型の型変換により得られたアドレスを保持する整数型変数を、拡張構造体の変数に置換する。【０１７９】
また、本実施の形態では、メモリセグメントを動的に確保する処理や、メモリセグメントのアドレスを得る処理に修正を加えて、前記の拡張構造体に適切な情報を設定する点と、メモリアクセス前に、アドレス値の境界検査を実施して、範囲外であるならば処理を中断する動作を追加する点も共通である。【０１８０】
本実施の形態とＦａｉｌ  Ｓａｆｅ  Ｃとの差異は、Ｆａｉｌ  Ｓａｆｅ  Ｃの境界検査がファットポインタ方式に基づくのに対して、本実施の形態は、本発明の第１の実施の形態、本発明の第２の実施の形態で説明した方法で境界検査が実施される点である。【０１８１】
図１２は本発明の第１０の実施の形態で行われるプログラム記述変換の特徴的な部分を示す図である。Ｆａｉｌ  Ｓａｆｅ  Ｃは、図１２に示すように、ＯｂｊＴｙｐｅ型のポインタ型変数をＦａｔＰｔｒ＜ＯｂｊＴｙｐｅ＞構造体変数に変換し、参照先セグメントの先頭を指すポインタｂａｓｅとオフセットｏｆｆｓｅｔとを記憶させている。【０１８２】
これに対し、本実施の形態では、ＤｕａｌＰｔｒ＜ＯｂｊＴｙｐｅ＞構造体に置換し、実行時の参照先を示すポインタ値ｖａｌｕｅと、アドレス割当を変更して別の実行をした場合に格納されるポインタ値ｓｈａｄｏｗ＿ｖａｌｕｅとを記憶させている。【０１８３】
また、ポインタを整数化した値が格納されるＶａｌＴｙｐｅ型変数については、Ｆａｉｌ  Ｓａｆｅ  ＣがこれをＦａｔＩｎｔ＜ＶａｌＴｙｐｅ＞型に置換し、本来の格納値ｖａｌｕｅに加えて、変換前のポインタの参照先セグメントをｂａｓｅに持たせるのに対して、本実施の形態は、これをＤｕａｌ＜ＶａｌＴｙｐｅ＞型に置換し、本来の格納値ｖａｌｕｅに加え、アドレス割当を変更して別の実行をした場合に格納される仮想的なポインタ値ｓｈａｄｏｗ＿ｖａｌｕｅを記憶させている。【０１８４】
さらなる相違点としては、Ｆａｉｌ  Ｓａｆｅ  Ｃが、ＶａｌＴｙｐｅ型として取りうる型を、アドレス値を表現するのに十分なビット幅を持つ型に制約し、ＦａｔＩｎｔ＜ＶａｌＴｙｐｅ＞型に置換される変数を限定しているが、本実施の形態は、これに満たない任意の数値型であって良いとし、Ｄｕａｌ＜ＶａｌＴｙｐｅ＞型に置換される変数を、セグメントの配置アドレスの変更により、格納値が変わりうる変数全てに拡大している。【０１８５】
ＤｕａｌＰｔｒ＜ＯｂｊＴｙｐｅ＞型、Ｄｕａｌ＜ＶａｌＴｙｐｅ＞型の変数に対して行われる代入、型変換、数値計算のプログラム記述は、変換前のプログラムが記述する動作がｖａｌｕｅメンバ間で行われ、それと同時にｓｈａｄｏｗ＿ｖａｌｕｅメンバ間でも等しい動作が行われるプログラムに変換する。その際、メモリセグメントのアドレスが含まれる記述、具体的には、アドレス演算子＆、配列名記述、ｍａｌｌｏｃ関数が返すアドレスを用いる記述は、ｖａｌｕｅメンバとｓｈａｄｏｗ＿ｖａｌｕｅメンバとで異なるアドレス値を用いるようにする。【０１８６】
これを具体的に説明すると、ｖａｌｕｅメンバの計算では、実行中のセグメントアドレスを利用し、ｓｈａｄｏｗメンバの計算では、例えば、上述した本発明の３つのアドレス割当方法のいずれかに従って配置されたセグメントのアドレスを使用するように変換する。尚、検査対象に含まれないセグメントを参照する場合には、ｓｈａｄｏｗ＿ｖａｌｕｅとｖａｌｕｅとに等しい値を格納する処理に変換する。【０１８７】
ＤｕａｌＰｔｒ＜ＯｂｊＴｙｐｅ＞型のポインタ変数に、間接参照演算子＊や配列参照演算子［］を作用させて行われるメモリアクセスについては、Ｆａｉｌ  Ｓａｆｅ  Ｃと同様に、境界検査を事前に行い、不正であればプログラム実行を中止する処理を追加する。境界検査の手順は、Ｆａｉｌ  Ｓａｆｅ  Ｃと異なり、２つのアドレスｖａｌｕｅとｓｈａｄｏｗ＿ｖａｌｕｅとを用いて本発明の第１の実施の形態、または本発明の第２の実施の形態に示した手順で行われる。【０１８８】
ポインタ変数が正しいアドレスを指すと判断した場合には、ｖａｌｕｅメンバが指すアドレスに置かれたＯｂｊＴｙｐｅ型の変数を参照して、元プログラムに記述された処理を行うようにする。ここで、ｓｈａｄｏｗ＿ｖａｌｕｅは、検査用に用意された仮想上のアドレスであるため、実際のメモリアクセスには使用されない。【０１８９】
ＤｕａｌＰｔｒ＜ＯｂｊＴｙｐｅ＞型、Ｄｕａｌ＜ＶａｌＴｙｐｅ＞型の変数を用いて、プログラムの解釈順序を分岐させる実行指令、具体的にはｉｆ，ｆｏｒ，ｗｈｉｌｅ等の制御命令文や、？，＆＆，｜｜演算子の評価式を含む実行指令文については、ｖａｌｕｅとｓｈａｄｏｗ＿ｖａｌｕｅとを評価した結果が同一の分岐先を返す場合に分岐先の処理を続行し、異なる結果を返した場合に異常であるとしてプログラム実行を停止する処理に置換して、実行形式を生成する。【０１９０】
以上説明したように、本実施の形態に基づいて、Ｃプログラムを実行形式に変換して、これを実行すると、プログラムの実行回数は１回でありながら、ＤｕａｌＰｔｒ型とＤｕａｌ型のｖａｌｕｅメンバとｓｈａｄｏｗ＿ｖａｌｕｅメンバとに、２通りのセグメント配置を与えてプログラムを個別に実行した場合と等価な結果が得られる。このアドレス値を用いることで、本発明に基づく有効な境界検査を実施することができる。【０１９１】
本発明に関連するファットポインタ方式に基づくＦａｉｌ  ｓａｆｅ  Ｃは、異なるセグメントを参照するＦａｔＰｔｒ＜ＯｂｊＴｙｐｅ＞型ポインタ間の減算を行うプログラム記述や、ＦａｔＩｎｔ＜ＶａｌＴｙｐｅ＞型に格納されたアドレス値に任意の論理演算を行うプログラム記述の検査を実施することができない。あるいは、ファットポインタ方式に基づくＦａｉｌ  ｓａｆｅ  Ｃは、ポインタの指すアドレスを上位と下位に分離して、アドレス値の半分のビット幅を持つ数値型に代入する処理の記述にも対応できない制約がある。【０１９２】
これに対して、本実施の形態は、ポインタ変数が参照するセグメントを記憶する方式ではないため、上記に示した制約を持たない。２つの値ｖａｌｕｅとｓｈａｄｏｗ＿ｖａｌｕｅとを得るために仮定したアドレス割当でプログラムが適切に動作する限り、有効な境界検査を行う実行形式が生成される。【０１９３】
尚、本実施の形態を変形して、本発明に関連するファットポインタ方式を組み合わせ、ＤｕａｌＰｔｒ，Ｄｕａｌ構造型にｂａｓｅポインタを追加することも可能であり、それも一つの例である。あるいは、２種類の表現をプログラム実行中に切り替えるプログラムを生成するのも本実施の形態の一例である。【０１９４】
この他、本実施の形態は、Ｃ言語のプログラムを検査の対象としたが、ポインタ変数が用意された別の言語で書かれたプログラムに対しても、上記と同様の実施の形態を構成することが可能である。【０１９５】
このように、本発明は、メモリセグメントへのアドレス割当を変更して検査対象のプログラムを実行した場合に、同一のプログラム記述によってなされる参照先アドレスを、実際にプログラムを複数回実行する方法で、もしくは仮想的に等価な方法で求め、この情報から、アドレス計算の基点となった参照先セグメントを特定し、セグメント境界への整合性を検査する。【０１９６】
参照先セグメントの特定は、変更前後のセグメント先頭アドレスの差分が、セグメントを識別するための情報を含むようにしておくことで可能である。この原理により、本発明は、プログラム実行時になされる個々のメモリアクセスについて、確実な方法でセグメント境界検査を実施可能である。特に、本発明に関連するガードゾーン方式で検出できない不連続な不正メモリアクセスについても、検出が可能である。この効果は、デバッグの効率性を高め、テストの有効性を高める上で重要である。【０１９７】
また、本発明は、上記のセグメントへのアドレス割当方法として、上述した第１のアドレス割当方法、第２のアドレス割当方法により、容易に実施できる参照先セグメントの特定方法を与えている。あるいは、本発明は、第３のアドレス割当方法により、メモリ使用効率に優れる参照先セグメントの特定方法を提供している。【０１９８】
なお、本発明のセグメントへのアドレス割当を行う手順について、第１実施形態において図２を用いてセグメントが割り当てられるアドレスのみを変更してセグメントの配置を変更した次に、対象のプログラムを実行してメモリアクセスをトレースするように説明した。しかし、ヒープ上に配置されたデータセグメントへのメモリアクセスについて境界検査を実施する第４の実施の形態やスタック上に配置されたデータセグメントへのアクセスについて境界検査を実施する第５の実施の形態においては、この順序とはならない。これらの実施の形態においては、セグメントへのアドレス割当は、プログラム実行中にメモリセグメントを確保する実行指令を解釈した時点で行う。すなわち、図２におけるステップＳ２２がステップＳ２１を内包するフローで実行される。【０１９９】
さらに、本発明は、本発明に関連するファットポインタ方式の境界検査と異なる原理に基づくため、本発明に関連する方式のように、アドレス値の任意演算操作に対応できないといった制約を持たず、広範囲のプログラムに対して、メモリアクセスの境界検査が可能である。【０２００】
さらに、本発明は、適切な情報を含むプログラム記述が与えられ、適切なトレース実行環境を用いて、複数のセグメント配置条件でのプログラム実行がなされる限り、対象とするセグメントの種類を問わない。本発明は、静的に配置されるセグメント、ヒープセグメント、スタック上のセグメント、いずれに対しても実施が可能である。【０２０１】
本発明は、複数回のアドレス値を求める手順として、単純に複数回の実行を行う実施形態や、１回の検査実行で複数コンテキストの実行結果を得る形態等、様々な手順の実施形態が可能である。また、本発明は、本発明に関連するファットポインタ方式に基づく実行形式プログラムの境界検査手法や、Ｃ言語記述から動的な境界検査を行うプログラムを生成する手法と組み合わせて実施することも可能である。このように、本発明は、検査目的や状況に合わせて、適切な形態を選択可能である。【０２０２】
本発明は、適切な条件の下で、Ｃ言語のようにポインタ変数を用いる各種の言語で記述されたソースファイルや、ソースファイルを実行形式にした実行形式ファイルに対しても適用可能である。また、ソースファイルをコンパイルした結果得られるオブジェクトファイルであってもよい。プログラムの実行環境については、適切な機能を備え、適切な構成で動作する限り、ハードウェア上の実動作環境、シミュレータ、インタープリタであっても、プログラムを変換して検査を自ら行うプログラムを生成する方法であっても、本発明をそれらに適用することが可能である。【０２０３】
以上、実施形態を参照して本願発明を説明したが、本願発明は上記実施形態に限定されるものではない。本願発明の構成や詳細には、本願発明のスコープ内で当業者が理解し得る様々な変更をすることができる。【０２０４】
この出願は、２００７年１２月１２日に出願された日本出願特願２００７−３２０２７８を基礎とする優先権を主張し、その開示の全てをここに取り込む。
【図１】
2009075116.tif 000003
【図２】
2009075116.tif 000004
【図３】
2009075116.tif 000005
【図４】
2009075116.tif 000006
【図５】
2009075116.tif 000007
【図６】
2009075116.tif 000008
【図７】
2009075116.tif 000009
【図８】
2009075116.tif 000010
【図９】
2009075116.tif 000011
【図１０】
2009075116.tif 000012
【図１１】
2009075116.tif 000013
【図１２】
2009075116.tif 000014
【図１３】
2009075116.tif 000015
【図１４】
2009075116.tif 000016
【国際調査報告】
2009075116.tif 000017
2009075116.tif 000018
2009075116.tif 000019
2009075116.tif 000020