(57)【要約】      （修正有）【課題】動作が対となって行われるべき関数による処理が正常に終了したかどうかを判定可能とする。【解決手段】第３のモジュール９２は、第１のモジュール９１から第２のモジュール９３内の関数への呼び出しを仲介し処理のログを取得する。取得された前記ログから、関数の属性情報と前記関数について与えられた識別子とを抽出し、抽出された前記関数のうち第１の関数の属性情報及び前記第１の関数について与えられた識別子とを登録する。次に、抽出された前記関数のうち第２の関数の属性情報及び第２の関数について与えられた識別子と、前記登録手段の登録内容に基づいて、前記第２のモジュール９３における処理が正常に終了したか否かを判定する。【選択図】図４
2006172205.tif 000002
【特許請求の範囲】
【請求項１】
第１のモジュールと、第２のモジュールと、前記第１のモジュールから前記第２のモジュール内の関数への呼び出しを仲介し、前記呼び出しに応じた前記第２のモジュールにおける処理のログを取得するための第３のモジュールと、を実行する情報処理装置であって、
前記ログを前記第３のモジュールから取得するログ取得手段と、
取得された前記ログから、関数の属性情報と前記関数について与えられた識別子とを抽出する抽出手段と、
抽出された前記関数のうち第１の関数の属性情報及び前記第１の関数について与えられた識別子とを登録する登録手段と、
抽出された前記関数のうち第２の関数の属性情報及び第２の関数について与えられた識別子と、前記登録手段の登録内容に基づいて、前記第２のモジュールにおける処理が正常に終了したか否かを判定する終了判定手段と
を備えることを特徴とする情報処理装置。
【請求項２】
前記終了判定手段は、前記登録手段に、前記第２の関数の属性情報と共通する属性情報と、前記第２の関数について与えられた識別子と同一の識別子とを有する第１の関数が登録されている場合に、該第１及び第２の関数による処理が正常に終了したと判定することを特徴とする請求項１に記載の情報処理装置。
【請求項３】
前記終了判定手段により、該第１及び第２の関数による処理が正常に終了したと判定された場合に、前記登録手段に登録されている該第１の関数の属性情報と識別子とが削除されることを特徴とする請求項２に記載の情報処理装置。
【請求項４】
前記抽出手段が、取得された前記ログから全ての関数の属性情報及び識別子を抽出し、抽出された全ての関数について前記終了判定手段による判定が行われた後も、前記登録手段から削除されずに登録されたままの前記第１の関数の属性情報と識別情報とがある場合、前記終了判定手段は、該登録されたままの第１の関数による処理は正常に終了していないと判定することを特徴とする請求項３に記載の情報処理装置。
【請求項５】
前記終了判定手段は、前記登録手段に、前記第２の関数の属性情報と共通する属性情報、及び、前記第２の関数について与えられた識別子と同一の識別子とを有する第１の関数が登録されていない場合に、該第２の関数に基づく処理が正常に終了していないと判定することを特徴とする請求項１に記載の情報処理装置。
【請求項６】
前記登録手段には、既に登録されている第１の関数と、少なくとも前記識別子が異なる第１の関数が登録されることを特徴とする請求項１乃至５のいずれかに記載の情報処理装置。
【請求項７】
前記終了判定手段は更に、前記登録手段に登録されない第１の関数があった場合に、該登録されない第１の関数に基づく前記第２のモジュールにおける処理が正常に終了していないと判定することを特徴とする請求項６に記載の情報処理装置。
【請求項８】
第１のモジュールと、第２のモジュールと、前記第１のモジュールから前記第２のモジュール内の関数への呼び出しを仲介し、前記呼び出しに応じた前記第２のモジュールにおける処理のログを取得するための第３のモジュールと、を実行する情報処理装置の制御方法であって、
前記ログを前記第３のモジュールから取得するログ取得工程と、
取得された前記ログから、関数の属性情報と前記関数について与えられた識別子とを抽出する抽出工程と、
抽出された前記関数のうち第１の関数の属性情報及び前記第１の関数について与えられた識別子とを登録部に登録する登録工程と、
抽出された前記関数のうち第２の関数の属性情報及び第２の関数について与えられた識別子と、前記登録部の登録内容に基づいて、前記第２のモジュールにおける処理が正常に終了したか否かを判定する終了判定工程と
を備えることを特徴とする情報処理装置の制御方法。
【請求項９】
前記終了判定工程では、前記登録部に、前記第２の関数の属性情報と共通する属性情報と、前記第２の関数について与えられた識別子と同一の識別子とを有する第１の関数が登録されている場合に、該第１及び第２の関数による処理が正常に終了したと判定されることを特徴とする請求項８に記載の情報処理装置の制御方法。
【請求項１０】
前記終了判定工程において、該第１及び第２の関数による処理が正常に終了したと判定された場合に、前記登録部に登録されている該第１の関数の属性情報と識別子とが削除されることを特徴とする請求項９に記載の情報処理装置の制御方法。
【請求項１１】
前記抽出工程において、取得された前記ログから全ての関数の属性情報及び識別子が抽出され、抽出された全ての関数について前記終了判定工程における判定が行われた後も、前記登録部から削除されずに登録されたままの前記第１の関数の属性情報と識別情報とがある場合、該登録されたままの第１の関数による処理は正常に終了していないと判定されることを特徴とする請求項１０に記載の情報処理装置の制御方法。
【請求項１２】
前記終了判定工程では、前記登録部に、前記第２の関数の属性情報と共通する属性情報、及び、前記第２の関数について与えられた識別子と同一の識別子とを有する第１の関数が登録されていない場合に、該第２の関数に基づく処理が正常に終了していないと判定されることを特徴とする請求項８に記載の情報処理装置の制御方法。
【請求項１３】
前記登録部には、既に登録されている第１の関数と、少なくとも識別子が異なる第１の関数が登録されることを特徴とする請求項８乃至１２のいずれかに記載の情報処理装置の制御方法。
【請求項１４】
前記終了判定工程では更に、前記登録部に登録されない第１の関数があった場合に、該登録されない第１の関数に基づく前記第２のモジュールにおける処理が正常に終了していないと判定することを特徴とする請求項１３に記載の情報処理装置の制御方法。
【請求項１５】
請求項８乃至１４のいずれかに記載の情報処理装置の制御方法をコンピュータに実行させるためのコンピュータプログラム。
【請求項１６】
請求項１５に記載のコンピュータプログラムを記憶したコンピュータで読み取り可能な記憶媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理装置及びその制御方法、コンピュータプログラム及び記憶媒体に関する。
【背景技術】
【０００２】
再現率の低いソフトウェアの障害に対しては、ソフトウェアの処理ログを取得することによって対処している場合が多いが、従来、処理ログの取得はアプリケーションソフトウェアのモジュール自体に手を加えて、処理ログ取得ルーチンを追加することによって行なわれている。しかし、ログ取得コードを埋め込む等のアプリケーションソフトウェアの修正を必要とする上記の方式では、修正処理が煩雑化する。
【０００３】
そこで、複数にモジュール分けされているソフトウェアにおいて、アプリケーションソフトウェアに相当するモジュールから別のモジュール内に存在する関数への呼び出しを仲介し、当該呼び出しに応じた別モジュールにおける処理のログを取得するログ取得用モジュールを提供することにより、アプリケーションソフトウェア自体の煩雑な修正を行わずとも、処理ログを取得可能とする方法が提案されている（特許文献１参照）。
【特許文献１】特開２００４−３８３１１号公報
【発明の開示】
【発明が解決しようとする課題】
【０００４】
上記のソフトウェアにおいて実行される処理の中には、メモリ確保/解放、デバイス起動/終了といった、動作が対となり関数を呼び出し後に必ず決まった終了関数を呼ばなければならない処理が存在する。このとき、終了関数が呼ばれておらず処理が終了されていない処理がある場合には、他の処理の実行に影響を与えることとなるため、終了関数が呼ばれたか否かを確実に判定する必要がある。
【０００５】
そこで、本発明は、動作が対となって行われるべき関数による処理が正常に終了したかどうかを判定可能とすることを目的とする。
【課題を解決するための手段】
【０００６】
上記の課題を解決するための本発明は、第１のモジュールと、第２のモジュールと、前記第１のモジュールから前記第２のモジュール内の関数への呼び出しを仲介し、前記呼び出しに応じた前記第２のモジュールにおける処理のログを取得するための第３のモジュールと、を実行する情報処理装置であって、前記ログを前記第３のモジュールから取得するログ取得手段と、取得された前記ログから、関数の属性情報と前記関数について与えられた識別子とを抽出する抽出手段と、抽出された前記関数のうち第１の関数の属性情報及び前記第１の関数について与えられた識別子とを登録する登録手段と、抽出された前記関数のうち第２の関数の属性情報及び第２の関数について与えられた識別子と、前記登録手段の登録内容に基づいて、前記第２のモジュールにおける処理が正常に終了したか否かを判定する終了判定手段とを備える。
【発明の効果】
【０００７】
本発明によれば、動作が対となって行われるべき関数による処理が正常に終了したかどうかを判定することができる。
【発明を実施するための最良の形態】
【０００８】
以下、添付する図面を参照して本発明の実施形態を説明する。
【０００９】
図１は、本実施形態に対応する情報処理装置の構成の一例を示す図である。説明を簡略化するために、本実施形態では、情報処理システムが１台のPC内部に構築されるものとするが、本発明の特徴は１台のPC内部に構築されるか、あるいは複数のPCにネットワークシステムとして構築されるかによらず有効である。
【００１０】
本情報処理装置には、CPU１、チップセット２、RAM３、ハードディスクコントローラ４、ディスプレイコントローラ５、ハードディスクドライブ６、CD-ROMドライブ７、ディスプレイ８が搭載されている。また、CPU１とチップセット２とを繋ぐ信号線１１、チップセット２とRAM３とを繋ぐ信号線１２、チップセット２と各種周辺機器４、５とを繋ぐ周辺機器バス１３、ハードディスクコントローラ４とハードディスクドライブ６とを繋ぐ信号線１４、ハードディスクコントローラ４とCD-ROMドライブ７とを繋ぐ信号線１５、ディスプレイコントローラ５とディスプレイ８とを繋ぐ信号線１６が搭載されている。
【００１１】
本実施形態に対応する情報処理装置を説明するために、まず図２を参照して、複数のモジュールに分かれたソフトウェアが、通常の状態でどのようにメモリにロードされるかを説明する。図２は、RAMの内部構成の一例を示す図である。
【００１２】
通常、複数のモジュールに分割されたソフトウェアは、全体の制御を行なう実行ファイルEXE(２３)と、モジュールとして存在しEXEの補完的な役割を担うダイナミックリンクライブラリDLL(２７)とに分かれて存在する。そして、RAM３にはEXEとDLLの両方がロードされる。EXEはコードセグメント(２８)とデータセグメント(２９)、及び、インポート関数アドレステーブル(２２)で構成される。このうち、インポート関数アドレステーブルは、関数の所属するDLLによって更に分割されており(２１及び２４)、DLLごとにそれぞれの関数がロードされたアドレスが書かれている(３０〜３５)。
【００１３】
DLLの関数の実体は、DLLごとに分けて(２５,２６)ロードされ、それぞれの関数は該当するDLLの一部としてロードされる(３６〜４１)。この図では、１本のEXEがA.DLL及びB.DLLの２つのダイナミックリンクライブラリ内の関数を使用している例を示しており、実際に使用される関数はFunc AA, Func AB, Func AC, Func BA, Func BB, Func BCの６個となっている。
【００１４】
EXEのコードセグメント２８内にあるコードが関数Func AAを呼び出す場合には、まずインポート関数アドレステーブル内に書かれたFunc AAのアドレス(３０)が読み込まれる。ここには実際にはA.DLLの一部として読み込まれたFunc AAコード(３６)のアドレスが書かれており、そのアドレスをコールすることによって、EXEのコードはA.DLLのFunc AAを呼び出すことができる。
【００１５】
次に、ログ取得用のコードとしてIAT Patch(Import Address Table Patch)という手法を用いて関数呼び出しを仲介する場合の、情報処理装置のメモリ構成の一例を図３を参照して説明する。
【００１６】
ログ取得が開始されると、メモリ内にはIAT Patch用のDLLであるC.DLL(５８)がロードされる。C.DLLはインポート関数アドレステーブル(５２)内に書かれた関数のアドレスを、C.DLL内のログ取得コードであるFunc CAA, Func CAB, Func CAC, Func CBA, Func CBB, Func CBCのアドレスに書き換える(６１〜６６)。C.DLL内のFunc CAA, Func CAB, Func CAC, Func CBA, Func CBB, Func CBCのコード(７３〜７８)は、ログを記録すると共に、元々関数呼び出しを受けるべくメモリにロードされている、該当する関数であるFunc AA, Func AB, Func AC, Func BA, Func BB, Func BC(６７〜７２)を呼び出す。
【００１７】
図４は、図３におけるIAT Patchの処理をあらわすタイミングチャートである。説明を簡略化するために、この図ではEXEがA.DLL内のFunc AAを呼び出す際に、IAT Patchによるログ取得コードがどのように動作するかの例をあらわしている。他の関数の場合についても同様の処理が行われることはいうまでもない。
【００１８】
EXE(９１)がFunc AAをコールすると(９４)、C.DLL内にあるログ取得コードがDLL名/関数名をメモリに保存し、呼び出し時刻をメモリに保存し、呼び出し時のパラメータをメモリに保存し、呼び出し時のポインタパラメータの指すメモリ内容を、メモリに保存する(９５)。その後C.DLLは本来呼び出されるはずであった、A.DLL(９３)内のFunc AAをコールする(９６)。A.DLLのFunc AA処理(９７)が終了し、C.DLLに制御がリターンすると(９８)、C.DLLはリターン時の時刻をメモリに保存し、戻り値をメモリに保存し、リターン時にポインタパラメータが指すメモリ内容を、メモリに保存する(９９)。その後、C.DLLは保存したログ情報をファイルに書き込み(１００)、あたかもA.DLLのFunc AAが通常通りに終了したかのように、EXEにリターンする(１０１)。
【００１９】
図５は、本実施形態に対応する情報処理装置において実行形式ファイルＥＸＥが実行される場合の動作の一例を示す図である。通常は実行形式のEXE(１１３)が、DLL-１(１１６)やDLL-２(１１７)内の関数を呼び出すが、ここではAPIトレーサと呼ばれるログ取得コードを埋め込み(１１４)、処理ログを生成している(１１５)。APIトレーサは、DLL-１やDLL-２の関数定義を記述したファイル(１１１)と、どのDLLのどの関数のインポート関数テーブルを書き換えてログを取得するかの設定シナリオ(１１２)を元に動作する。
【００２０】
図６は、本実施形態に対応する情報処理装置において、実行ファイルEXE(１１８)がCOM(Component Object Model：コンポーネント・オブジェクト・モデル)サーバでエクスポートされているインターフェースのインスタンスを作成する場合の、メモリ構成の一例を示す図である。
【００２１】
通常、インターフェースのインスタンス作成を行うと、COMサーバ内で、要求されたインターフェース(１２１, １２２)と、そのメソッド(１３０〜１３５)が作成され、それらは共にメモリ上にロードされる。ここで、virtual address tableは作成された各インターフェース毎に作られ(１１８, １２０)、作成要求を行ったEXEに渡される。このvirtual address tableには各メソッドについて作成されたアドレスが書かれている(１２４〜１２９)。EXEはこれら情報を利用し、各インターフェースに対して呼び出しを行う。図６では、１本のEXEがInterface A及びInterface Bの２つのインターフェースのインスタンスを作成しており、そのインターフェース内部のメソッドを使用している例を示しており、実際に使用されているメソッドは、Method AA, Method AB, Method AC, Method BA, Method BB, Method BCとなっている。
【００２２】
EXEのコードが関数Method AAを呼び出す場合には、まずvirtual address table内に書かれたMethod AAのアドレス(１２４)が読み込まれる。このアドレス（１２４）にはCOMサーバのInterface Aの一部として作成されたMethod AAコード(１３０)のアドレスが書かれており、そのアドレスをコールすることによって、EXEのコードはInterface AのMethod AAを呼び出すことができる。
【００２３】
図７は、本実施形態に対応する情報処理装置のメモリ構成をあらわす図であり、図６とは、ログ取得用のコードとしてVTable Patch(virtual address table Patch)という手法を用いて、メソッド呼び出しを仲介しているという点で異なっている。
【００２４】
ログ取得が開始されると、メモリ内にはVTable Patch用のDLL(１４３)がロードされる。このDLLはvirtual address table(１３６, １３８)内に書かれたメソッドのアドレスを、DLL内のログ取得コードであるMethod A'A, Method A'B, Method A'C, Method B'A, Method B'B, Method B'Cのアドレスに書き換える(１４５〜１５０)。DLL内のMethod A'A, Method A'B, Method A'C, Method B'A, Method B'B, Method B'Cのコード(１５７〜１６２)は、ログを記録すると共に、元々のメソッド呼び出しを受けるべくメモリにロードされていたMethod AA, Method AB, Method AC, Method BA, Method BB, Method BC(１５７〜１６２)を呼び出す。
【００２５】
図８は、図７におけるVTable Patchの処理をあらわすタイミングチャートである。説明を簡略化するために、この図ではEXEがCOMサーバ内のInterface AのMethod AAを呼び出す際に、VTable Patchによるログ取得コードがどのように動作するかの例をあらわしている。他のメソッドの場合についても同様の処理が行われることはいうまでもない。
【００２６】
EXE(１６３)がMethod AAをコールすると(１６６)、DLL内にあるログ取得コードがモジュール名/インターフェース名/メソッド名をメモリに保存し、呼び出し時刻をメモリに保存し、呼び出し時のパラメータをメモリに保存し、呼び出し時のポインタパラメータの指すメモリ内容を、メモリに保存する(１６７)。その後DLLは本来呼び出されるはずであった、COMサーバ(１６５)内のMethod AAをコールする(１６８)。COMサーバのMethod AA処理(１６９)が終了し、DLLに制御がリターンすると(１７０)、DLLはリターン時の時刻をメモリに保存し、戻り値をメモリに保存し、リターン時にポインタパラメータが指すメモリ内容を、メモリに保存する(１７１)。その後、DLLは保存したログ情報をファイルに書き込み(１７２)、あたかもCOMサーバのMethod AAが通常通りに終了したかのように、EXEにリターンする(１７３)。
【００２７】
図９は、本実施形態に対応する情報処理装置において実行形式ファイルＥＸＥが実行される場合の動作の一例を示す図である。通常は実行形式のEXE(１７６)が、COMサーバ-１(１７９)やCOMサーバ-２(１８０)内のメソッドを呼び出すが、ここではAPIトレーサと呼ばれるログ取得コードを埋め込み(１７７)、処理ログを生成している(１７８)。APIトレーサは、COMサーバ-１(１７９)やCOMサーバ-２の関数定義を記述したファイル(１７４)と、どのCOMサーバのどのインターフェースのどのメソッドのvirtual address tableを書き換えてログを取得するかの設定シナリオ(１７５)を元に動作する。
【００２８】
図１０は、本実施形態に対応する情報処理装置でハンドルチェック処理を行なう場合に、ハンドルチェックの対象となる処理の一例を示す図である。本実施形態において、ハンドルとは、関数を識別するための識別子に相当する。
【００２９】
図１０では、アプリケーション(１００１)から、ログ取得用モジュール(１０１１)を介してデバイス制御モジュール(１００５)を呼び出し、デバイス(１０１０)を制御するための場合を記載している。即ち、図１０において、アプリケーション(１００１)は、図４におけるEXE(９１)及び図８におけるEXE(１６３)に相当する。また、ログ取得用モジュール(１０１１)は、図４におけるC.DLL(９２)及び図８におけるDLL(１６４)に相当する。さらに、デバイス制御モジュール(１００５)は、図４におけるA.DLL(９３)及び図８のCOMサーバ(１６５)に相当する。
【００３０】
ここで、OpneDevice関数(１００２)は、デバイスの電源を投入し(１００７)、デバイスに対する制御ハンドルを取得・確保し(１００６)、そのハンドルを上位アプリケーションに返す(１００３)関数である。
【００３１】
また、CloseDevice関数(１００４)は、OpenDevice関数で取得したハンドルをもとに、デバイスの電源断を行ない(１００９)、制御ハンドルを解放する関数である。OpenDevice関数を使用した場合には、ハンドル領域の開放とデバイスの電源断のために、CloseDevice関数(１００４)を必ず呼ぶ必要がある。仮に、OpenDevice(１００３)とCloseDevice(１００４)とが対に呼ばれていない場合には、デバイスの電源がOnのままで、かつハンドル確保領域の解放が行なわれないこととなるので、他のアプリケーション実行時に弊害を引き起こす可能性があり、問題となる。
【００３２】
図１１は、本実施形態に対応するハンドル属性定義ファイルの一例を示す図であり、情報処理装置のハンドルチェック用アプリケーションが保有し、図１０の関数をチェックするために利用される。ハンドル属性定義ファイル(１１０１)には、ハンドルチェック対象DLL(１１０２)と、対象DLLの関数定義ファイル(１１０３)とが記載されている。ここで、ハンドルチェック対象DLLは、図１０におけるデバイス制御モジュール(１００５)に対応し、関数定義ファイル(１１０３)には、対象DLLの関数の戻り値やパラメータといった情報が記載されており、ログ取得用モジュール(１０１１)に格納されているログデータからハンドルチェックを行うために必要な情報を抽出するために利用される。また、関数定義ファイル(１１０３)は、図５及び図９における関数定義１１１、１７４に対応している。
【００３３】
ハンドル属性定義ファイル(１１０１)において、ハンドル属性の設定は関数毎に、TraceFun(１１０４)、GroupID(１１０５)、FuncProperty(１１０６)、ParaError(１１０７)で定義される。より具体的には、TraceFunc(１１０４)には関数名が設定され、GropuID(１１０５)はハンドル属性を定義する関数グループが設定される。FuncProperty(１１０６)はその関数が、ハンドル属性として、Open、Close、OpenCloseのいずれを持つかが設定される。ParaError(１１０７)は関数の戻り値または、どの引数がOpen/Close属性定義されるか設定でき、さらには、その戻り値または引数が、特定の値で有った場合にハンドルチェック処理から除外する設定が可能である。
【００３４】
図１０に対応する本実施形態では、TraceFunc=OpenDevice(１１０４)はOpenDevice関数について定義される。このOpenDevice関数に対してGroupID=０ｘ０１(１１０５)でグループ ０x０１に属し、FuncProperty=０x０２(１１０６)でOpen属性を持ち、ParaError= ０,DWORD,０x０２,!=,０(１１０７)では、戻り値であるDWORD型の値をOpenの値とし、値が０で無いときにのみハンドルチェック処理を行なうと定義される。
【００３５】
さらに、TraceFunc=CloseDevice(１１０８)は関数CloseDeviceに対して定義を行う。このCloseDevice関数に対してGroupID=０ｘ０１(１１０９)でOpenDeviceと同じグループである、グループ ０x０１に属し、FuncProperty=０x０１(１１１０)でClose属性を持ち、ParaError= １,DWORD,０x０１,!=,０(１１１１)では、第１引数であるDWORD型の値をCloseの値とし、値が０で無いときにのみハンドルチェック処理を行なうと定義される。これらの定義により、OpenDevice関数の戻り値と、CloseDevice関数の第１引数でハンドルチェックを行なうためのハンドル属性設定となる。
【００３６】
図１２は、本実施形態に対応する情報処理装置でハンドルチェック処理を行なう場合に、ハンドルチェックの対象となる処理の他の一例を示す図である。図１２では、アプリケーション(１２０１)から、ログ取得用モジュール(１２１６)を介してメモリ確保モジュール(１２０７)を呼び出し、OS(１２１３)に対してメモリ確保・解放を要求する関数である。即ち、図１２において、アプリケーション(１２０１)は、図４におけるEXE(９１)及び図８におけるEXE(１６３)に相当する。また、ログ取得用モジュール(１２１６)は、図４におけるC.DLL(９２)及び図８におけるDLL(１６４)に相当する。さらに、メモリ確保モジュール(１２０７)は、図４におけるA.DLL(９３)及び図８のCOMサーバ(１６５)に相当する。
【００３７】
MemoryAlloc関数(１２０２)はOSに対してメモリ確保要求を出し(１２０８)、確保されたメモリのハンドルを取得し(１２０９)、そのハンドルを上位アプリケーションに返す(１２０３)関数である。MemoryFree関数(１２０６)はMemoryAlloc関数で取得したハンドルを元に、OSへ対してメモリの解放を要求する(１２１２)関数である、MemoryAlloc関数を使用した場合には、OS上のメモリを解放するために、必ず呼ぶ必要が有る。MemoryAllocとMemoryFreeが対に呼ばれていない場合には、OS上にメモリが確保されたままとなり、メモリリークする。
【００３８】
ここまでは、第１０図の例とほぼ同様であるが、図１２では、さらにMemoryRealloc関数(１２０４)が存在する。MemoryRealloc関数はMemoryAlloc関数で確保したメモリ領域を元にメモリを再確保する(１２１０)関数である。MemoryRealloc関数を使用した場合、MemoryAlloc関数のハンドルをベースにOSに対してメモリ再確保要求(１２１０)を行なう。OS側では、メモリの再確保処理を行ないそのハンドルを返す(１２１１)。このときOSではメモリ確保状況により、ハンドルが元となるメモリと同じである場合と、異なる場合が存在する。
【００３９】
図１３は、本実施形態に対応するハンドル属性定義ファイルの他の一例を示す図であり、情報処理装置のハンドルチェック用アプリケーションが保有し、図１２の関数をチェックするために利用される。
【００４０】
ハンドル属性定義ファイル(１３０１)は、図１１に示した内容と同様なハンドル属性の設定に加え、ハンドル属性としてOpenCloseを持つMemoryRealloc関数への定義(１３１２〜１３１６)が含まれる。MemoryAlloc関数への定義(１３０４〜１３０７)とMemoryFree関数への定義(１３０８〜３１１)に関しては図１１の内容と同様である。
【００４１】
MemoryRealloc関数の定義では、FuncProperty=０ｘ０４(１３１４)でOpenClose属性が設定されている。そのため、ParaErrorは２個の設定を持ち、ParaError= １,DWORD,０x０１,!=,０ (１３１５)では、第１引数のDWORD型の値をCloseの値とし、値が０で無いときにのみハンドルチェック処理を行なうと定義される。
【００４２】
さらに、ParaError= ０,DWORD,０x０２,!=,０(１３１６)では、戻り値のDWORD型の値をOpenの値とし、値が０で無いときにのみハンドルチェックを行なうと定義される。これらの定義により、MemoryAlloc関数の戻り値と、MemoryFree関数の第１引数、MemoryRealloc関数の戻り値と第１引数でハンドルチェックを行なうためのハンドル属性設定となる。
【００４３】
図１４は、本実施形態に対応する情報処理装置において、ハンドルチェック用アプリケーションを実行してログの解析処理を行なう場合のフローチャートである。ハンドルチェック用アプリケーションは、図１におけるHDD６に格納され、RAM３に読み出されて、CPU１により実行される。
【００４４】
まず、ハンドルチェック用アプリケーションは、図１１や図１３に示すハンドル属性定義ファイルに基づいて、ログ取得用モジュールからハンドルチェック対象DLLについてのログを取得する（S1401）。このログには、関数名、関数グループ、ハンドル属性といった関数の属性情報と、関数の識別子としてのハンドルが含まれている。
【００４５】
ハンドルチェック処理は取得したログの先頭から終端までを順にチェックして行なう(S１４０２、S１４１９)。まず、ログとして取得された関数がハンドル属性定義で設定されているかを判定し(S１４０３)、定義されていないと判定されればその関数は処理されない。一方、定義されていると判定された場合には、当該関数について、ハンドル属性定義ファイルのFuncProperty 設定が、Open、Close、OpenClose属性のいずれであるかを判定する(S１４０４)。
【００４６】
Open属性であると判定された場合には、ParaError設定に従いハンドルの値を取得し、その値がハンドルとして有効な値であるかを判定する(S１４０５)。ここで、有効な値であるか否かは、ハンドル属性定義ファイルのParaErrorにおける設定内容に従うこととなり、図１１や図１３の場合では、値が０でないときにのみハンドルチェック処理を行うと定義されているので、０でなければ有効な値と判定される。
【００４７】
もし、ここで有効な値でないと判定された場合にはハンドルチェック処理は行なわれず、S１４０３に戻って別の関数について処理する。一方、有効な値と判断された場合には、ハンドルチェック処理でアンマッチな関数を登録するハンドル登録テーブルに、GroupIDが同じ関数で、Open属性のハンドルを持つ関数が登録され、かつ、そのハンドル値が現在の関数のハンドル値と異なるか否かを判定する(S１４０８)。登録されている当該関数のハンドル値が同じ場合にはOpen処理の結果が不正であるとし、ハンドルチェック処理対象の関数にエラーフラグを立てる(S１４１２)。一方、当該関数が登録されていない場合や、当該関数は登録されているがハンドル値が異なる場合には、ハンドル登録テーブルに関数情報と、Open属性のハンドル値を保存する(S１４１１)。
【００４８】
一方、関数の属性がClose属性であった場合には、ParaError設定に従いハンドルの値を取得し、その値がハンドルとして有効な値であるかを判定する(S１４０６)。有効であるか否かの判定基準は、Open属性の場合と同様である。有効な値でないと判定された場合にはチェック処理は行なわれず、S１４０３に戻って別の関数について処理を継続する。一方、有効な値であると判定された場合には、ハンドル登録テーブルに、GroupIDが同じ関数で、Open属性又はOpenClose属性のハンドルを持つ関数があり、かつ、そのハンドル値が現在の関数のハンドル値と同じであるか否かを判定する(S１４０９)。ハンドル登録テーブルに、当該関数が登録されていない場合や、当該関数は登録されているがハンドル値が異なる場合は、Open処理無しで呼ばれたClose処理とし、ハンドルチェック処理対象の関数にエラーフラグを立てる(S１４１４)。ハンドル値が同じ場合には、正しくOpen/Close処理が行なわれているので、ハンドル登録テーブルに存在する関数の情報とハンドル値を削除する(S１４１３)。
【００４９】
関数の属性がOpenClose属性であった場合には、ParaError設定に従いClose属性のハンドル値を取得し、その値がハンドルとして有効な値であるかを判定する(S１４０７)。この判定手法も上記と同様である。有効な値でないと判定された場合にはチェック処理は行なわれず、S１４０３に戻って他の関数について処理を継続する。一方、有効な値であった場合には、ハンドル登録テーブルに、GroupIDが同じ関数で、Open属性のハンドルを持つ関数が登録されており、かつ、そのハンドル値が現在の関数のハンドル値と同じであるか否かを判定する(S１４１０)。
【００５０】
当該関数が登録されていない場合や、当該関数は登録されているがハンドル値が異なる場合にはOpen処理無しで呼ばれたClose処理とし、ハンドルチェック処理対象の関数に対しエラーフラグを立てる(S１４１５)。ハンドル値が同じ場合には、正しくOpen/Close処理が行なわれているので、ハンドル登録テーブルに存在する関数の情報とハンドル値とを削除する(S１４１５)。
【００５１】
さらに、ParaError設定に従いOpen属性のハンドル値を取得し、その値がハンドルとして有効な値であるかを判定する(S１４１７)。有効な値でないと判定された場合には、当該関数についての処理を終了して、S１４０３において別の関数についての処理を継続する。有効な値と判定された場合には、Open属性の関数と同様(S１４０８、S１４１１、S１４１２)な処理(S１４１８)を行なう。
【００５２】
以上の処理を繰り返すことにより、ログに登録されている全ての関数についてハンドルチェック処理を終了した場合には、その時点でハンドル登録テーブルに残っている関数は、全てClose処理されていないOpen処理なので、対応する関数についてエラーフラグを立てる(S１４２０)。
【００５３】
以上により、ログ中の全ての関数についてハンドルチェック処理が終了し、処理結果をディスプレイ８に表示する（S１４２１）。処理結果の表示画面には、ログに含まれる全ての関数がリストされるが、ハンドルチェック処理においてエラーフラグが立てられた関数については、ハンドルチェックエラーの発生を示す表示がなされる。
【００５４】
図１５は、図１４のS１４２１において、ディスプレイ８に表示される処理結果の表示画面の一例を示す図である。ここで、ログのハンドルチェックエラー部(１５０１)に×でエラー情報が表示される。この×が付された関数が、ハンドルチェック処理においてエラーフラグが立てられた関数である。
【００５５】
図１５において、ログ１行目(１５０４)の関数は、モジュールがHandleCheck.dllで、関数はOpenDevice、引数は無く、戻り値がDWORD handleで値が０x５０３４２０６Dであることを示す。ハンドルチェック処理では、この段階でアンマッチテーブルにこの関数の情報が追加される。
【００５６】
２行目(１５０３)は１行目の関数に対するClose処理であるCloseDevice関数であり、Close属性で定義されている第一引数が１行目のハンドルチェック定義と同値の０x５０３４２０６D で呼ばれている。この処理で、１行目のOpenDeviceと２行目のCloseDeviceは正しく処理されているので、テーブルから１行目の関数は削除され、ハンドルチェックエラーにはエラー情報が表示されない。
【００５７】
３行目（１５０４）のCloseDevice関数では、引数が既に２行目でCloseされている１行目のOpen関数と同値になっており、テーブルにはこの値と同じ戻り値を持つOpenDeviceが存在しない。そのため、ハンドルチェックエラーにエラー表示される。４行目(１５０５)では、MemoryAllocされ、テーブルに情報が追加される。その後、ハンドルチェック処理をログ終端まで行なってもClose処理であるMemoryFreeが呼ばれていないためにエラーとなる。
【００５８】
また、７行目(１５０８)のMemoryFree関数では、６行目(１５０７)のMemoryRealloc関数で既にCloseされている５行目(１５０６)のMemoryAlloc関数と同じハンドル値なため、エラーとなっている。８行目(１５０９)のMemoryFree関数は、６行目(１５０７)のMemoryRealloc関数で再確保されOpenされた値と同値であり、正常に処理がされている。
【００５９】
なお、本発明の特徴は、IAT Patch及びVTable Patchとハンドルチェックを組み合わせることにより、関数/メソッドのハンドルに関わる処理を、関数/メソッドのコードに変更を加えることなくチェックすることにある。このため、ハンドルのチェック処理自体は、上記以外の方法に限定されるものではない。
【００６０】
以上のように、本実施形態に対応する本発明によれば、対となる関数の識別子となるハンドルを定義しておくことで、取得したログに基づいて正常に終了されていない処理を検出することができる。
【００６１】
また、より具体的に本発明によれば、関数のOpen/Close処理の漏れがないかをチェックすることができ、その結果、処理が正しく終了していない、デバイスの電源On/Offや、メモリリークといった不具合を容易に検出できるので、デバッグや評価工数の削減が可能となる。
【００６２】
［その他の実施形態］
なお、本発明は、複数の機器（例えばホストコンピュータ、インタフェイス機器、リーダ、プリンタなど）から構成されるシステムに適用しても、一つの機器からなる装置（例えば、複写機、ファクシミリ装置など）に適用してもよい。
【００６３】
また、本発明の目的は、前述した実施形態の機能を実現するソフトウェアのプログラムコードを記録した記憶媒体（または記録媒体）を、システムあるいは装置に供給し、そのシステムあるいは装置のコンピュータ（またはＣＰＵやＭＰＵ）が記憶媒体に格納されたプログラムコードを読み出し実行することによっても、達成されることは言うまでもない。この場合、記憶媒体から読み出されたプログラムコード自体が前述した実施形態の機能を実現することになり、そのプログラムコードを記憶した記憶媒体は本発明を構成することになる。また、コンピュータが読み出したプログラムコードを実行することにより、前述した実施形態の機能が実現されるだけでなく、そのプログラムコードの指示に基づき、コンピュータ上で稼働しているオペレーティングシステム（ＯＳ）などが実際の処理の一部または全部を行い、その処理によって前述した実施形態の機能が実現される場合も含まれることは言うまでもない。
【００６４】
さらに、記憶媒体から読み出されたプログラムコードが、コンピュータに挿入された機能拡張カードやコンピュータに接続された機能拡張ユニットに備わるメモリに書込まれた後、そのプログラムコードの指示に基づき、その機能拡張カードや機能拡張ユニットに備わるＣＰＵなどが実際の処理の一部または全部を行い、その処理によって前述した実施形態の機能が実現される場合も含まれることは言うまでもない。
【図面の簡単な説明】
【００６５】
【図１】本発明の実施形態に対応する情報処理装置の構成の一例を示す図である。
【図２】本発明の実施形態に対応する情報処理装置のメモリに、複数のモジュールに分割されたソフトウェアがロードされる場合を説明する図である。
【図３】本発明の実施形態に対応する、ログ取得用のコードとしてIAT Patchを用いて関数呼び出しを仲介する場合の、情報処理装置のメモリ構成の一例を示す図である。
【図４】本発明の実施形態に対応する情報処理装置において、IAT Patchの処理を実行した場合のタイミングチャートの一例を示す図である。
【図５】本発明の実施形態に対応する情報処理装置において実行形式ファイルＥＸＥが実行される場合の動作の一例を示す図である。
【図６】本発明の実施形態に対応する情報処理装置において、実行ファイルEXEがCOMサーバでエクスポートされているインターフェースのインスタンスを作成する場合の、メモリ構成の一例を示す図である。
【図７】本発明の実施形態に対応する情報処理装置のメモリ構成をあらわす図である。
【図８】本発明の実施形態に対応する情報処理装置において、VTable Patchの処理を実行した場合のタイミングチャートの一例を示す図である。
【図９】本発明の実施形態に対応する情報処理装置において実行形式ファイルＥＸＥが実行される場合の動作の一例を示す図である。
【図１０】本発明の実施形態に対応する情報処理装置でハンドルチェック処理を行なう場合に、ハンドルチェックの対象となる処理の一例を示す図である。
【図１１】本発明の実施形態に対応するハンドル属性定義ファイルの一例を示す図である。
【図１２】本発明の実施形態に対応する情報処理装置でハンドルチェック処理を行なう場合に、ハンドルチェックの対象となる処理の他の一例を示す図である。
【図１３】本発明の実施形態に対応するハンドル属性定義ファイルの他の一例を示す図である。
【図１４】本発明の実施形態に対応する情報処理装置において、ハンドルチェック用アプリケーションを実行してログの解析処理を行なう場合のフローチャートである。
【図１５】図１４のフローチャートのステップ１４２１において、ディスプレイ８に表示される処理結果の表示画面の一例を示す図である。
【図１】
2006172205.tif 000003
【図２】
2006172205.tif 000004
【図３】
2006172205.tif 000005
【図４】
2006172205.tif 000006
【図５】
2006172205.tif 000007
【図６】
2006172205.tif 000008
【図７】
2006172205.tif 000009
【図８】
2006172205.tif 000010
【図９】
2006172205.tif 000011
【図１０】
2006172205.tif 000012
【図１１】
2006172205.tif 000013
【図１２】
2006172205.tif 000014
【図１３】
2006172205.tif 000015
【図１４】
2006172205.tif 000016
【図１５】
2006172205.tif 000017