(57)【要約】【課題】異常終了の原因となった関数を特定可能な情報処理装置、及び情報処理プログラムを提供する。【解決手段】複数の関数による処理が異常終了した際に異常終了の原因となった変数情報を異常変数情報として特定すると共に、異常終了の原因となったアドレスを異常アドレスとして特定し、使用する際に、特定された異常アドレスにアクセスしたアクセス関数を、スタック情報により特定し、特定されたアクセス関数が演算した結果が異常変数情報である場合には、当該アクセス関数を異常終了の原因として特定し、異常変数情報がアクセス関数による演算した結果ではないと判定された場合には、アクセス関数が異常変数情報に代入した他の変数情報を異常変数情報とし、他の変数情報が記憶されているアドレスを異常アドレスとするように異常変数情報及び異常アドレスを更新する。【選択図】図４
2010102454.tif 000002
【特許請求の範囲】
【請求項１】
複数の関数の各々を使用する際にアクセスしたアドレスを含むスタック情報、及び前記複数の関数に使用された変数を示す変数情報を記憶する記憶手段と、
前記複数の関数による処理が異常終了した際に異常終了の原因となった変数情報を異常変数情報として特定すると共に、異常終了の原因となったアドレスを異常アドレスとして特定する第１の特定手段と、
使用する際に、前記第１の特定手段により特定された前記異常アドレスにアクセスしたアクセス関数を、前記スタック情報により特定する第２の特定手段と、
前記第２の特定手段により特定された前記アクセス関数が演算した結果が前記異常変数情報である場合には、当該アクセス関数を異常終了の原因として特定する第３の特定手段と、
前記第３の特定手段により前記異常変数情報が前記アクセス関数による演算した結果ではないと判定された場合には、前記アクセス関数が前記異常変数情報に代入した他の変数情報を前記異常変数情報とし、前記他の変数情報が記憶されているアドレスを前記異常アドレスとするように前記異常変数情報及び前記異常アドレスを更新する更新手段と、
を有する情報処理装置。
【請求項２】
前記記憶手段は、実行中の関数が他の関数にスイッチングされた場合にも、前記実行中の関数が使用していたスタック情報を記憶する請求項１に記載の情報処理装置。
【請求項３】
前記第３の特定手段は、前記第２の特定手段が関数を特定したスタック情報が前記記憶手段に記憶された順番が新しい順に、前記第２の特定手段により特定された関数が前記異常原因情報を演算したか否かを判定する請求項１又は請求項２に記載の情報処理装置。
【請求項４】
コンピュータを、
複数の関数の各々を使用する際にアクセスしたアドレスを含むスタック情報、及び前記複数の関数に使用された変数を示す変数情報を記憶する記憶手段と、
前記複数の関数による処理が異常終了した際に異常終了の原因となった変数情報を異常変数情報として特定すると共に、異常終了の原因となったアドレスを異常アドレスとして特定する第１の特定手段と、
使用する際に、前記第１の特定手段により特定された前記異常アドレスにアクセスしたアクセス関数を、前記スタック情報により特定する第２の特定手段と、
前記第２の特定手段により特定された前記アクセス関数が演算した結果が前記異常変数情報である場合には、当該アクセス関数を異常終了の原因として特定する第３の特定手段と、
前記第３の特定手段により前記異常変数情報が前記アクセス関数による演算した結果ではないと判定された場合には、前記アクセス関数が前記異常変数情報に代入した他の変数情報を前記異常変数情報とし、前記他の変数情報が記憶されているアドレスを前記異常アドレスとするように前記異常変数情報及び前記異常アドレスを更新する更新手段と、
して機能させるための情報処理プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理装置、情報処理プログラムに関する。
【背景技術】
【０００２】
プログラムが異常終了した際の原因を特定するための技術は、従来より数多く提案されている。例えば、特許文献１及び特許文献２には、異常終了した機械語命令のアドレスを用いて、ソースコードマップからその命令を含む関数を特定し、引数とともに表示して異常解析を支援する技術が開示されている。
【０００３】
また、特許文献３には、プログラムが異常終了したときに、実行中のプログラムのスタック情報を解析し、異常解析に有用なメモリ情報のみを吸い上げる技術が開示されている。
【特許文献１】特開平５−１５１０３０号公報
【特許文献２】特開平７−１６８７４３号公報
【特許文献３】特開２００７−１７２４１４号公報
【発明の開示】
【発明が解決しようとする課題】
【０００４】
本発明は、異常終了の原因となった関数を特定可能な情報処理装置、及び情報処理プログラムを提供することを目的とする。
【課題を解決するための手段】
【０００５】
上記目的を達成するために、請求項１の発明は、複数の関数の各々を使用する際にアクセスしたアドレスを含むスタック情報、及び前記複数の関数に使用された変数を示す変数情報を記憶する記憶手段と、前記複数の関数による処理が異常終了した際に異常終了の原因となった変数情報を異常変数情報として特定すると共に、異常終了の原因となったアドレスを異常アドレスとして特定する第１の特定手段と、使用する際に、前記第１の特定手段により特定された前記異常アドレスにアクセスしたアクセス関数を、前記スタック情報により特定する第２の特定手段と、前記第２の特定手段により特定された前記アクセス関数が演算した結果が前記異常変数情報である場合には、当該アクセス関数を異常終了の原因として特定する第３の特定手段と、前記第３の特定手段により前記異常変数情報が前記アクセス関数による演算した結果ではないと判定された場合には、前記アクセス関数が前記異常変数情報に代入した他の変数情報を前記異常変数情報とし、前記他の変数情報が記憶されているアドレスを前記異常アドレスとするように前記異常変数情報及び前記異常アドレスを更新する更新手段と、を有する。
【０００６】
また、請求項２の発明は、請求項１の発明において、前記記憶手段は、実行中の関数が他の関数にスイッチングされた場合にも、前記実行中の関数が使用していたスタック情報を記憶する。
【０００７】
請求項３の発明は、請求項１又は請求項２の発明において、前記第３の特定手段は、前記第２の特定手段が関数を特定したスタック情報が前記記憶手段に記憶された順番が新しい順に、前記第２の特定手段により特定された関数が前記異常原因情報を演算したか否かを判定する。
【０００８】
上記目的を達成するために、請求項４の発明は、コンピュータを、複数の関数の各々を使用する際にアクセスしたアドレスを含むスタック情報、及び前記複数の関数に使用された変数を示す変数情報を記憶する記憶手段と、前記複数の関数による処理が異常終了した際に異常終了の原因となった変数情報を異常変数情報として特定すると共に、異常終了の原因となったアドレスを異常アドレスとして特定する第１の特定手段と、使用する際に、前記第１の特定手段により特定された前記異常アドレスにアクセスしたアクセス関数を、前記スタック情報により特定する第２の特定手段と、前記第２の特定手段により特定された前記アクセス関数が演算した結果が前記異常変数情報である場合には、当該アクセス関数を異常終了の原因として特定する第３の特定手段と、前記第３の特定手段により前記異常変数情報が前記アクセス関数による演算した結果ではないと判定された場合には、前記アクセス関数が前記異常変数情報に代入した他の変数情報を前記異常変数情報とし、前記他の変数情報が記憶されているアドレスを前記異常アドレスとするように前記異常変数情報及び前記異常アドレスを更新する更新手段と、して機能させるための情報処理プログラムである。
【発明の効果】
【０００９】
請求項１及び請求項４記載の発明によれば、本発明を適用しない場合に比較して、より確実に異常終了の原因となった関数を特定することができる、という効果が得られる。
【００１０】
また、請求項２記載の発明によれば、スイッチ毎にスタック情報を記憶することにより、各関数実行時の直近のスタック情報から関数の内部状態を復元することができるようになり、より確度の高い解析を行うことが可能となる、という効果が得られる。
【００１１】
また、請求項３記載の発明によれば、新しい順にスタック情報を遡ることにより、異常の伝播の観点から関数の探索範囲を絞りこむことが可能となる。１つ以上の関数で構成されるタスク単位でも、スイッチ前後のスタック情報を差分比較することができるようになるので、スタック情報の差分に異常が検出されれば、スイッチ後に実行されたタスクに絞り込むことが可能となる、という効果が得られる。
【発明を実施するための最良の形態】
【００１２】
以下、図面を参照して、本発明の実施の形態について詳細に説明する。なお、本実施の形態では、情報処理装置をコンピュータとして説明する。
【００１３】
まず、図１を用いて、コンピュータ１０の構成について説明する。コンピュータ１０は、ＣＰＵ１２と、ＨＤＤ１４と、ＲＡＭ１６と、ネットワークＩ／Ｆ部１８と、ＲＯＭ２０と、表示部２２と、操作入力部２４と、バス２６とを含む。
【００１４】
ＣＰＵ１２は、コンピュータ１０の全体の動作を司るものであり、後述するコンピュータ１０の処理を示すフローチャートは、ＣＰＵ１２により実行される。ＨＤＤ１４は、各関数を示すプログラム、ＯＳ（Operating System）などが記録される不揮発性の記憶装置である。ＲＡＭ１６は、複数の関数の各々を使用する際にアクセスしたアドレスを含むスタック情報（以下、単にスタックと記す）、及び複数の関数に使用された変数を示す変数情報を記憶する記憶手段であり、その他ＯＳやプログラムが展開される揮発性の記憶装置である。ネットワークＩ／Ｆ部１８は、ネットワークに接続するためのものであり、ＮＩＣやそのドライバで構成される。ＲＯＭ２０は、コンピュータ１０の起動時に動作するブートプログラムなどが記憶されている不揮発性の記憶装置である。表示部２２は、コンピュータ１０に関する情報を利用者に表示するものである。操作入力部２４は、利用者がコンピュータ１０の操作や情報を入力する際に用いられるものである。バス２６は、情報のやりとりが行われる際に使用される。
【００１５】
以下、上述した構成により実行される処理の詳細について説明する。まず図２を用いて、本実施の形態におけるスタック制御方法について説明する。本実施の形態におけるスタックは、コールされた関数からコールした関数に処理が戻っても、コールされた関数実行時のスタックが消去されないものとなっている。
【００１６】
具体的に図２を用いて説明する。図２には、スタック領域を示すメモリマップが示されており、同図において、「ｆｐ」はフレームポインタを示し、「ｓｐ」はスタックポインタを示す。ｆｐは、参照するスタックの先頭アドレスを示し、ｓｐは新たなスタックを積み上げるアドレスを示している。また、一般的に知られているように、スタックは、ＣＰＵ１２が複数の関数の各々を使用する際にアクセスしたアドレスを含む他に一時的な変数などに使用されるものである。
【００１７】
まず、（１）の状態は、ある関数Ａがある関数Ｂをコールした状態である。スタックＡは関数Ａで使用されるスタックであり、スタックＢは、関数Ｂで使用されるスタックである。
【００１８】
次の（２）状態は、関数Ｂが関数Ｃをコールした状態である。スタックＣは、関数Ｃで使用されるスタックである。次の（３）の状態は、関数Ｃが終了し、処理が関数Ｂに戻った状態である。
【００１９】
この場合、通常のｓｐは、スタックＢの位置を示すが、本実施の形態におけるスタック制御方法では、スタックＣの位置を示す。これにより、次の（４）の状態に示すように、処理が終了した関数が使用したスタックが消去されずに残ることとなる。
【００２０】
次の（４）の状態は、関数Ｂが関数Ｄをコールした状態である。スタックＤは、関数Ｄで使用されるスタックであり、ｓｐの位置に示されるように、スタックＤは（３）の状態からスタックＣの上に積まれるので、関数Ｃが戻っても、関数Ｃ実行時のスタックは消去されない。
【００２１】
次に、図３を用いて、異常終了を示す例を説明する。同図には、関数Ａ、Ｂ各々のコード（Ｃ言語）と、メモリマップが示されている。メモリマップに示されるように、有効なアドレスは、0x0000000〜0x1FFFFFFであり、それ以外にアクセスしようとした場合には、ＣＰＵ１２により異常終了となる。
【００２２】
また、関数Ａ、Ｂによる処理の概要は、ある数字を２倍するというものであるが、関数Ａのコードに誤りがあり、それが原因で異常終了することとなる。
【００２３】
まず、（１）で、関数Ａは、ポインタｐ１を0x1000000で初期化する。そして、（２）で、ｐ１が示すアドレス0x1000000に数値(1234)を記憶する。次に、（３）で関数Ｂをコールする。この関数コールの引数は、本来「ｐ１」（＝0x1000000）とするところであるが、誤ってｐ１の先頭アドレスを示す「&p1」を引数としている。
【００２４】
関数コールにより、処理は関数Ｂの処理となる。関数Ｂは、引数「&p1」を関数Ｂのスタック「ｐ２」で受け取るので、ｐ２＝&ｐ１となる。
【００２５】
そして、（４）でｐ２が示す変数情報を示す*ｐ２を２倍したものを改めて*ｐ２とする。ｐ２＝&ｐ１であるので、ｐ２が示す変数情報である*ｐ２は、0x1000000であり、２倍することで、*ｐ２＝0x2000000となり、ｐ１＝0x2000000となる。
【００２６】
なお、上記（３）で誤りがない場合は、ｐ２＝ｐ１＝0x1000000であるので、ｐ２が示す変数情報である*ｐ２は、アドレス0x1000000に記憶された1234であり、２倍することで*ｐ２＝2468となる。
【００２７】
２倍する処理が終了すると、関数Ａに処理が戻り、（５）において、変数ｄ１にｐ１が示す変数情報*ｐ１が代入される。ｐ１＝0x2000000であるので、アドレス0x2000000に記憶された値となるが、上述したように、0x2000000はアドレスの範囲0x0000000〜0x1FFFFFFに含まれないため、関数Ａは異常終了することとなる。
【００２８】
次に、図４を用いて本実施の形態に係る情報処理プログラムの処理の流れについて説明する。この処理の前提として、まずＯＳが提供している機能について説明する。通常、ＯＳは、異常（例外処理）の種別、異常が発生したメモリアドレス、実行中の命令アドレス(プログラムカウンタ)、異常が発生した関数やタスク等を通知する機能を有する。
【００２９】
異常データの格納アドレスは、異常発生時のメモリ、実行時の関数やタスクのスタック、プログラムオブジェクトのシンボル情報およびソースコードから特定することができる。
【００３０】
この解析は、ソースレベルデバッガ(シンボリックデバッガ)では一般的に行われているものである。プログラムオブジェクトには、実行中の命令アドレスとソースコードを対応付け可能なシンボル情報を含めることが可能であり、実行中の命令アドレスからソースコードのどの関数が実行されているか判断することができる。さらに、メモリおよびスタックにより関数実行時の内部状態を知ることができ、異常データが格納されているメモリアドレスを特定することができる。
【００３１】
メモリ、タスクのスタック、シンボル情報、ソースコードから、関数の内部状態を復元することにより、ある関数があるアドレスにアクセスしているかどうかを判定することができる。
【００３２】
多くの場合、メモリやスタックに残されている情報は、関数により異常終了する前にアクセスされているので、スタックに多くの内部情報を残すようにしたり、図２で説明したように関数の処理が進行してもスタックが上書きされないように実装することにより、異常終了した後でも関数の内部状態の復元が容易となるようにし、また、復元が不完全な場合でも異常が発生したアドレスに対するアクセスの有無が推測できるようにする。
【００３３】
これを前提に、図４に示されるフローチャートの説明をする。まず、ステップ１０１で、処理が異常終了した際に異常終了の原因となった変数情報を異常変数情報（異常データ）として特定すると共に、当該異常変数情報が記憶されているアドレスを異常アドレスとして特定し、ステップ１０２で、変数dataに異常データ、変数addrに異常アドレスを代入する。
【００３４】
次のステップ１０３で、異常アドレスにアクセスしたアクセス関数を、スタックにより特定する。そして、次のステップ１０４で、アクセス関数がaddrが示すデータを書き換えているか否か判定する。否定判定した場合には、ステップ１０３に戻り、addrにアクセスしている他の関数を特定する。
【００３５】
一方、ステップ１０４で肯定判定した場合には、ステップ１０５で、アクセス関数が演算した結果がdataか否か判定する。このステップ１０４で肯定判定した場合には、ステップ１０６でこの関数が異常終了の原因と特定して処理を終了する。
【００３６】
また、ステップ１０５で否定判定した場合には、他の関数の演算結果を参照していることから、ステップ１０７でアクセス関数が参照して異常変数情報に代入した他の変数情報をdataとし、他の変数情報が記憶されているアドレスをaddrとするようにdata及びaddrを更新して、再びステップ１０２の処理に戻る。
【００３７】
上記フローチャートを先ほど説明した図３の場合に適用すると、ステップ１０１で異常データ及びアドレスを特定し、ステップ１０２で異常の原因となった異常データ0x2000000と異常アドレス&p1を、それぞれdata、addrに代入する。
【００３８】
次のステップ１０３で、異常発生時のスタックｐ１の情報から、異常アドレス&p1にアクセスしている関数が、関数Ａであることを特定する。ステップ１０４で、関数Ａが異常アドレス&p1に0x2000000を書き込んでいるかどうか判断する。
【００３９】
今の場合、関数Ａには、&p1に0x2000000を書き込む処理は検出されないので、ステップ１０３で、異常アドレス&p1にアクセスしている他の関数を探す。次に、ステップ１０３で、スタックｐ２から、&p1にアクセスしている関数Ｂを特定する。次にステップ１０４で、関数Ｂが異常アドレス&p1に0x2000000を書きこんでいるか判断する。
【００４０】
関数Ｂに0x2000000を書き込んでいるのでステップ１０５で、関数Ｂが、0x2000000を演算しているか、他のアドレスのデータの参照で求めているか判定する。関数Ｂが演算して、0x2000000を算出しているので、ステップ１０６で、関数Ｂを異常終了の原因として特定する。
【００４１】
次に、実行中の関数が他の関数にスイッチングされた場合にも、実行中の関数が使用していたスタックを記憶することと、異常アドレスにアクセスした関数を特定したスタックが記憶された順番が新しい順に、特定された関数が異常原因情報を演算したか否かを判定することについて説明する。ここでタスクとは、１つ以上の関数で構成され、予め定められた処理を行なうものであるが、マルチタスクのシステムでは、処理の実行単位はタスクに分割され、ディスパッチャによりタスクに割り当てられた優先度や時分割に従って処理される。すなわち、ある関数実行時に他の関数にスイッチングされることとなる。
【００４２】
具体的に、図５を用いて説明する。図５は、処理されるタスクの順番の例、及び記憶されるスタックを示している。
【００４３】
同図に示されるタスクスイッチ例では、タスクＡの実行中にスイッチングが発生し、タスクＡの関数の処理は一時中断され、タスクＢの処理が開始される。
【００４４】
さらに、タスクＢの関数の実行中にスイッチングが発生し、タスクＣの処理が開始される。タスクＣの処理が完了すると、スイッチングが発生し、中断されていたタスクＢの関数の処理が再開される。タスクＢの関数の実行中に優先度の高いタスクＤが発生すると、タスクＢの関数の処理が一時中断され、タスクＤの処理が開始される。
【００４５】
また、同図に示される「記憶されるスタック」に示されるように、スイッチングによりタスクが切り替わる毎に、ＣＰＵ１２は、切り替わり前のタスクのスタックを記憶する。タスクＡがＢへタスクスイッチする際、ＣＰＵ１２は、タスクＡのスタックをスタックＡ１として記憶する。
【００４６】
さらに、同図に示されるように、タスクＢからタスクＣへのスイッチング（スタックＢ１）、タスクＣからタスクＢへのスイッチング（スタックＣ１）、タスクＢからタスクＤへのスイッチング（スタックＢ２）の際にも、切り替わり前のタスクのスタックが記録される。
【００４７】
保存されているスタックの履歴は、図４に記述したフローチャートのステップ１０３でaddrにアクセスしている関数を特定するために利用される。タスクスイッチの新しいもの順にスタックの履歴を遡ることで、異常の伝播の観点から関数の探索範囲を絞りこむことが可能である。
【００４８】
同図の場合、最終的にスタックＦ、スタックＢ２、スタックＣ１、スタックＢ１、スタックＡ１が記憶されており、この順番で古くなっていくので、本実施の形態では、特定された関数が異常原因情報を演算したか否かをスタックＦから順に判定することとなる。
【００４９】
また、図５の例では、タスクＢは一時中断後、再開されている。このとき、記憶されたスタックには、一時中断された際のスタックＢ１と、タスクＢがタスクＤにスイッチングした際のスタックＢ２が記憶されている。
【００５０】
スタックＢ１とスタックＢ２との差分比較により、スタックＢ１には示されなかったaddrへのアクセスが、スタックＢ２にはあることが判明すれば、それらの間に実行されたタスク(この場合はタスクＣ)の処理に異常の原因があることが特定できる。
【００５１】
なお、以上説明したフローチャートの処理の流れは一例であり、本発明の主旨を逸脱しない範囲内で処理順序を入れ替えたり、新たなステップを追加したり、不要なステップを削除したりすることができることは言うまでもない。
【図面の簡単な説明】
【００５２】
【図１】実施の形態に係るコンピュータの構成を示す図である。
【図２】実施の形態におけるスタック制御方法の説明図である。
【図３】異常終了例を示す図である。
【図４】情報処理プログラムの処理の流れを示すフローチャートである。
【図５】タスクスイッチ例を示す図である。
【符号の説明】
【００５３】
１０  コンピュータ
１２  ＣＰＵ
１４  ＨＤＤ
１６  ＲＡＭ
【図１】
2010102454.tif 000003
【図２】
2010102454.tif 000004
【図３】
2010102454.tif 000005
【図４】
2010102454.tif 000006
【図５】
2010102454.tif 000007