(57)【要約】【課題】処理のループの発生を抑止する。【解決手段】情報処理装置１０は、書き換え手段１１と実行手段１３とを有している。書き換え手段１１は、プログラム１に定義された関数１ａ内のトレース位置に記述された第１の命令４を、トレースコード２の実行を指示する第２の命令に書き換えると共に、第１の命令を記憶手段１２に格納する。実行手段１３は、関数１ａ実行中のトレース位置の実行時に、第２の命令５に基づいてトレースコード２を実行する。トレースコード２内に関数１ａを呼び出す第３の命令６が含まれる場合、実行手段１３は、第３の命令６の実行時には、関数１ａ内のトレース位置の第２の命令を、記憶手段１２に格納した第１の命令４に置き換えて、関数１ａを実行する。【選択図】図１
2015069437.tif 000002
【特許請求の範囲】
【請求項１】
プログラムの実行中に、トレースコードに基づいてトレース処理を実行するための処理プログラムであって、
コンピュータに、
前記プログラムに定義された関数内のトレース位置に記述された第１の命令を、前記トレースコードの実行を指示する第２の命令に書き換えると共に、前記第１の命令を記憶手段に格納し、
前記関数実行中の前記トレース位置の実行時に、前記第２の命令に基づいて前記トレースコードを実行し、
前記トレースコード内に前記関数を呼び出す第３の命令が含まれる場合、前記第３の命令の実行時には、前記関数内の前記トレース位置の前記第２の命令を、前記記憶手段に格納した前記第１の命令に置き換えて、前記関数を実行する、
処理を実行させることを特徴とする処理プログラム。
【請求項２】
前記トレース位置が前記関数の先頭である場合、
前記第１の命令を格納する際には、前記第１の命令に続けて、前記関数における前記トレース位置の次の命令へのジャンプを指示する第４の命令を、前記記憶手段に格納し、
前記トレースコード実行中の前記第３の命令の実行時には、前記記憶手段に格納された前記第１の命令と第４の命令とを順に実行する、
ことを特徴とする請求項１記載の処理プログラム。
【請求項３】
前記トレース位置が前記関数の先頭である場合、前記第１の命令を格納する際には、前記第３の命令の呼び出し先となる関数のアドレスを示す情報を、前記第１の命令のアドレスに変更する、
ことを特徴とする請求項２記載の処理プログラム。
【請求項４】
前記第１の命令を格納する際には、前記第１の命令に続けて、前記関数におけるトレース位置の次の命令へのジャンプを指示する第４の命令を、前記記憶手段に格納し、
前記トレースコードの実行中の前記第３の命令の実行時には、前記第３の命令に基づいて前記関数の先頭から実行を開始し、前記関数の実行位置が前記トレース位置になると、前記記憶手段に格納された前記第１の命令と第４の命令とを順に実行する、
ことを特徴とする請求項１記載の処理プログラム。
【請求項５】
前記関数の実行位置が前記トレース位置となり、前記トレースコードの実行を開始したときに、前記プログラムを実行している処理単位の識別情報を前記記憶手段に格納し、
前記関数の実行位置が前記トレース位置となったときに、前記プログラムを実行している処理単位の識別情報が既に保存されている場合、前記トレースコードの実行に代えて、前記記憶手段に格納された前記第１の命令と第４の命令とを順に実行することを特徴とする請求項４記載の処理プログラム。
【請求項６】
前記第１の命令を保存する際には、前記第１の命令に続けて、前記関数における前記トレース位置の次の命令へのジャンプを指示する第４の命令を、前記記憶手段１２に格納し、
前記トレースコードの実行を開始する際に、前記トレース位置が前記関数の先頭か否かを判断し、
前記トレース位置が前記関数の先頭の場合、前記トレースコード実行中の前記第３の命令の実行時には、前記記憶手段に格納された前記第１の命令と第４の命令とを順に実行する、
前記トレース位置が前記関数の先頭ではない場合、前記トレースコードの実行中の前記第３の命令の実行時には、前記第３の命令に基づいて前記関数の先頭から実行を開始し、前記関数の実行位置が前記トレース位置になると、前記記憶手段に格納された前記第１の命令と第４の命令とを順に実行する、
ことを特徴とする請求項１記載の処理プログラム。
【請求項７】
プログラムの実行中に、トレースコードに基づいてトレース処理を実行するトレース方法であって、
コンピュータが、
前記プログラムに定義された関数内のトレース位置に記述された第１の命令を、前記トレースコードの実行を指示する第２の命令に書き換えると共に、前記第１の命令を記憶手段に格納し、
前記関数実行中の前記トレース位置の実行時に、前記第２の命令に基づいて前記トレースコードを実行し、
前記トレースコード内に前記関数を呼び出す第３の命令が含まれる場合、前記第３の命令の実行時には、前記関数内の前記トレース位置の前記第２の命令を、前記記憶手段に格納した前記第１の命令に置き換えて、前記関数を実行する、
トレース方法。
【請求項８】
プログラムの実行中に、トレースコードに基づいてトレース処理を実行する情報処理装置であって、
前記プログラムに定義された関数内のトレース位置に記述された第１の命令を、トレースコードの実行を指示する第２の命令に書き換えると共に、前記第１の命令を記憶手段に格納する書き換え手段と、
前記関数実行中の前記トレース位置の実行時に、前記第２の命令に基づいて前記トレースコードを実行し、前記トレースコード内に前記関数を呼び出す第３の命令が含まれる場合、前記第３の命令の実行時には、前記関数内の前記トレース位置の前記第２の命令を、前記記憶手段に格納した前記第１の命令に置き換えて、前記関数を実行する実行手段と、
を有する情報処理装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラム間の呼び出し制御を行うトレース方法、処理プログラ、および情報処理装置に関する。
【背景技術】
【０００２】
近年、ＯＳ（Operating System）の機能強化・拡張に伴い、ＯＳの規模が肥大化し、ＯＳにおいて生じる障害は複雑化している。ＯＳの障害の調査手法の一つにトレース技術がある。トレース技術では、プログラム中の特定のコードを実行する時点での、コンピュータの状態に関する情報を採取する技術である。トレース技術では、例えば特定のコードを実行するときのレジスタの内容などの情報が採取される。トレース技術は特に原因解明の困難な複雑化した障害に対して用いられ、今後さらに発展し複雑化していくＯＳの障害調査にはトレース技術を進展させることが重要である。
【０００３】
障害調査に有用な技術としては、例えばプログラムの同一の場所で例外が発生した場合であっても、プロセス毎に例外処理を変えることを可能とするデバッグ方法がある。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開２００６−２６８２９８号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
トレース処理において、ＯＳで用意されたＡＰＩ（Application Program Interface）などのプログラムを呼び出して処理を実行することができれば、トレース処理の自由度が高まる。例えばトレース処理中にストレージ装置内のファイル操作用のＡＰＩを呼び出すことができれば、トレースで採取した情報をストレージ装置に退避させることができる。なお、ＯＳで用意されたＡＰＩなどのプログラムで障害が発生する場合がある。その場合、ＡＰＩなどのプログラムをトレース対象として、トレース処理を実施することとなる。
【０００６】
しかし、従来のトレース技術では、トレース処理中に呼び出されるＡＰＩなどのプログラムをトレース対象とすると、トレース処理内でそのプログラムが再帰的に呼び出されてしまい、処理が無限ループに陥る。そのため、トレース処理中で呼び出されるプログラムをトレース対象とすることができない。
【０００７】
１つの側面では、本件は、トレース処理を実行することによる処理のループの発生を抑止することを目的とする。
【課題を解決するための手段】
【０００８】
１つの案では、プログラムの実行中に、トレースコードに基づいてトレース処理を実行するための処理プログラムであって、コンピュータに以下の処理を実行させる処理プログラムが提供される。当該プログラムを実行するコンピュータは、プログラムに定義された関数内のトレース位置に記述された第１の命令を、トレースコードの実行を指示する第２の命令に書き換えると共に、第１の命令を記憶手段に格納する。またコンピュータは、関数実行中のトレース位置の実行時に、第２の命令に基づいてトレースコードを実行する。トレースコード内に関数を呼び出す第３の命令が含まれる場合、コンピュータは、第３の命令の実行時には、関数内のトレース位置の第２の命令を、記憶手段に格納した第１の命令に置き換えて、関数を実行する。
【発明の効果】
【０００９】
１態様によれば、トレース処理を実行することによる処理のループの発生が抑止される。
【図面の簡単な説明】
【００１０】
【図１】第１の実施の形態に係る情報処理装置の一例を示す図である。
【図２】本実施の形態に用いるコンピュータのハードウェアの一構成例を示す図である。
【図３】トレース機能の一例を示すブロック図である。
【図４】トレースの処理の概要を示す図である。
【図５】ハンドラにおいてトレースポイントを含む関数を呼び出さない場合の命令の一例を示す図である。
【図６】ハンドラにおいてトレースポイントを含む関数を呼び出すことによるループ発生例を示す図である。
【図７】第２の実施の形態におけるハンドラからのトレース対象のプログラムの呼び出し例を示す図である。
【図８】トレース設定ファイルの一例を示す図である。
【図９】トレース設定処理の手順の一例を示すフローチャートである。
【図１０】トレース管理テーブルの一例を示す図である。
【図１１】トレース管理テーブル作成処理の手順を示すフローチャートである。
【図１２】トレース設定ファイル読み込み処理の手順の一例を示すフローチャートである。
【図１３】ＩＡＴ書き換え処理の手順の一例を示すフローチャートである。
【図１４】ＡＰＩリストの一例を示す図である。
【図１５】トラップ例外処理の手順の一例を示すフローチャートである。
【図１６】トレースデータ採取処理の手順の一例を示すフローチャートである。
【図１７】先頭以外の箇所をトレースポイントとした場合のループ発生例を示す図である。
【図１８】第３の実施の形態におけるハンドラからのトレース対象の関数の呼び出し例を示す図である。
【図１９】第３の実施の形態におけるトレース設定ファイルの一例を示す図である。
【図２０】第３の実施の形態におけるトレース設定処理の手順の一例を示すフローチャートである。
【図２１】第３の実施の形態におけるトラップ例外処理の手順の一例を示すフローチャートである。
【図２２】ＴＩＤ管理テーブルの一例を示す図である。
【図２３】スレッド判別処理の手順の一例を示すフローチャートである。
【図２４】第３の実施の形態におけるトレースデータ採取処理の手順の一例を示すフローチャートである。
【図２５】第４の実施の形態におけるトレース管理テーブルの一例を示す図である。
【図２６】第４の実施の形態におけるトレース設定ファイル読み込み処理の手順の一例を示すフローチャートである。
【図２７】トラップ例外処理の手順の一例を示すフローチャートである。
【図２８】トレースアドレス判別処理の手順の一例を示すフローチャートである。
【発明を実施するための形態】
【００１１】
以下、本実施の形態について図面を参照して説明する。なお各実施の形態は、矛盾のない範囲で複数の実施の形態を組み合わせて実施することができる。
〔第１の実施の形態〕
図１は、第１の実施の形態に係る情報処理装置の一例を示す図である。第１の実施の形態に係る情報処理装置１０は、プログラム１の実行中に、トレースコード２に基づいてトレース処理を実行する。トレース処理は、例えば、プログラム１実行中の所定の時点でのメモリやレジスタの内容を取得する処理である。情報処理装置１０は、トレース処理を実現するために、書き換え手段１１、記憶手段１２、および実行手段１３を有する。情報処理装置１０は、例えばプロセッサやメモリを有するコンピュータである。
【００１２】
書き換え手段１１は、プログラム１に定義された関数１ａ内のトレース位置に記述された第１の命令４を、トレースコード２の実行を指示する第２の命令５に書き換える（ステップＳ１）。例えばトレースコード２が例外処理を実行するハンドラ内に記述されたコードの場合、第２の命令５は例外命令である。命令の書き換えは、メモリ上で行われる。例えばプログラム１が展開されたメモリ内の第１の命令４が格納された記憶領域に、第２の命令５が書き込まれる。これにより、プログラム１内にトレースコードをフック（処理を追加すること）することができる。
【００１３】
トレースコード２には、プログラム１における第１の命令４の実行時に採取すべき情報の採取手順が記述されている。ここでトレースコード２において高度な処理を行うために、プログラム１内の関数１ａの処理が有効な場合がある。その場合、トレースコード２内に関数１ａを呼び出す第３の命令６が記述される。
【００１４】
また書き換え手段１１は、第２の命令５に書き換えられた第１の命令４を、記憶手段１２に格納する（ステップＳ２）。例えば書き換え手段１１は、第１の命令４に続けて、プログラム１におけるトレース位置の次の命令へのジャンプを指示する第４の命令７を記述したスタブ３を生成する。そして書き換え手段１１は、スタブ３を記憶手段１２に格納する。
【００１５】
記憶手段１２は、第１の命令４を記憶する。例えば記憶手段１２は、第１の命令４を含むスタブ３を記憶する。
実行手段１３は、関数１ａ実行中のトレース位置の実行時に、第２の命令５に基づいてトレースコード２を実行する（ステップＳ３）。例えば第２の命令５が例外命令であれば、実行手段１３は、例外ハンドラとして定義されているトレースコード２を呼び出し、呼び出したトレースコード２を実行する。
【００１６】
実行手段１３は、トレースコード２内に関数１ａを呼び出す第３の命令６が含まれる場合、第３の命令６の実行時には、関数１ａ内のトレース位置の第２の命令５を、記憶手段１２に格納した第１の命令４に置き換えて、関数１ａを実行する。
【００１７】
例えば実行手段１３は、第３の命令６に基づいて、プログラム１内の関数１ａを呼び出して、関数１ａを実行する（ステップＳ４）。そして実行手段１３は、関数１ａの実行中に第２の命令５の実行順になると、第２の命令５に示されているトレースコード２の実行に代えて、スタブ３を実行する（ステップＳ５）。
【００１８】
スタブ３には、第１の命令４が記述されている。そのため、スタブ３を実行することにより、第２の命令５の実行に代えて、第１の命令４が実行されることとなる。第１の命令４の実行後、実行手段１３がスタブ３に記述されている第４の命令７を実行することにより、関数１ａにおけるトレース位置の次の命令に処理が進められる（ステップＳ６）。
【００１９】
その後、実行手段１３により関数１ａのトレース位置の次の命令から順に処理が実行される。関数１ａの実行が終了すると、第３の命令６に基づくサブルーチンの処理が終了したこととなり、トレースコード２の第３の命令６の次の命令に処理が進められる（ステップＳ７）。実行手段１３は、トレースコード２の実行が終了すると、次にスタブ３を実行する（ステップＳ８）。トレースコード２の後にスタブ３を実行することにより、第２の命令５によって書き換えられた第１の命令４が実行される。スタブ３の実行が終了すると、関数１ａ内のトレース位置の次の命令に処理が進められる（ステップＳ９）。
【００２０】
このようにして、プログラム１内の関数１ａの実行中に挿入するトレースコード２において関数１ａの呼び出しが可能となる。すなわち、トレースコード２においてプログラムを呼び出しても、処理のループが発生しない。その結果、トレースコード２に課される制約が抑止され、トレースコード２で実行する処理の自由度が高くなる。
【００２１】
例えばプログラム実行中の障害解析を行う場合、デバッグ対象のプログラムは様々である。障害解析に関する処理をトレースコード２で記述しておき、プログラム１内の関数１ａの実行中に障害が発生したときに、その関数１ａ内の位置をトレース位置に指定して障害解析を行う場合がある。このとき第１の実施の形態に示すようなループの発生を抑止する処理を実施しないと、トレースコード２中で呼び出す関数１ａについては、障害の解析ができなくなってしまう。コンピュータの障害解析において、解析ができないプログラムは少ない方がよく、そのためには、障害解析の処理が記述されたトレースコード２において、他のプログラムの呼び出しを行わないようにすることとなる。ところが、障害解析で使用できるプログラムに制限があると、高度な障害解析が難しくなってしまう。特にＯＳで提供される処理（例えばファイルアクセス）を用いるには、その処理に対応するＡＰＩなどの関数の呼び出しを行うことになる。解析処理においてそのようなＡＰＩの呼び出しができなければ、ＯＳの機能を利用した高度な障害解析が困難となる。
【００２２】
他方、第１の実施の形態に示す処理を実施することで、障害解析の手順を記述したトレースコード２中で、ＡＰＩなどの各種関数の呼び出しが可能となる。その結果、高度な障害解析が可能となる。
【００２３】
しかも、関数１ａ内のトレース位置に、トレースコード２をフックするようにすることで、トレースコード２を関数１ａと同じスレッドで実行することができる。同じスレッドで実行させることで、トレースコード２の実行開始前後でコンテキストスイッチを行わずに済む。コンテキストスイッチを行わないことで、トレース位置での関数１ａの実行状態を変化させずに済み、正しい情報のトレースが可能となる。
【００２４】
さらに、第１の命令４の第２の命令５への書き換えを、メモリ上で行うことで、プログラム１の実行ファイルの内容を編集せずに済む。その結果、再コンパイルなしに、トレース処理を行うことができる。
【００２５】
なお、図１に示す書き換え手段１１と実行手段１３とは、例えば情報処理装置１０が有するプロセッサにより実現することができる。また、記憶手段１２は、例えば情報処理装置１０が有するメモリにより実現することができる。
【００２６】
また、図１に示した各要素間を接続する線は通信経路の一部を示すものであり、図示した通信経路以外の通信経路も設定可能である。
〔第２の実施の形態〕
次に第２の実施の形態について説明する。第２の実施の形態は、ＯＳで用意されたＡＰＩの実行開始時におけるコンピュータの状態を示す情報をトレース（データ採取）するものである。ＡＰＩには、ＯＳの機能を利用するための関数などのプログラムが含まれており、アプリケーションプログラムなどを実行中にＡＰＩを呼び出すことで、ＯＳの機能を利用することができる。
【００２７】
図２は、本実施の形態に用いるコンピュータのハードウェアの一構成例を示す図である。コンピュータ１００は、プロセッサ１０１によって装置全体が制御されている。プロセッサ１０１には、バス１０９を介してメモリ１０２と複数の周辺機器が接続されている。プロセッサ１０１は、マルチプロセッサであってもよい。プロセッサ１０１は、例えばＣＰＵ（Central Processing Unit）、ＭＰＵ（Micro Processing Unit）、またはＤＳＰ（Digital Signal Processor）である。プロセッサ１０１の機能の少なくとも一部を、ＡＳＩＣ（Application Specific Integrated Circuit）、ＰＬＤ（Programmable Logic Device）などの電子回路で実現してもよい。
【００２８】
メモリ１０２は、コンピュータ１００の主記憶装置として使用される。メモリ１０２には、プロセッサ１０１に実行させるＯＳのプログラムやアプリケーションプログラムの少なくとも一部が一時的に格納される。また、メモリ１０２には、プロセッサ１０１による処理に必要な各種データが格納される。メモリ１０２としては、例えばＲＡＭ（Random Access Memory）などの揮発性の半導体記憶装置が使用される。
【００２９】
バス１０９に接続されている周辺機器としては、ＨＤＤ（Hard Disk Drive）１０３、グラフィック処理装置１０４、入力インタフェース１０５、光学ドライブ装置１０６、機器接続インタフェース１０７およびネットワークインタフェース１０８がある。
【００３０】
ＨＤＤ１０３は、内蔵したディスクに対して、磁気的にデータの書き込みおよび読み出しを行う。ＨＤＤ１０３は、コンピュータ１００の補助記憶装置として使用される。ＨＤＤ１０３には、ＯＳのプログラム、アプリケーションプログラム、および各種データが格納される。なお、補助記憶装置としては、フラッシュメモリなどの不揮発性の半導体記憶装置を使用することもできる。
【００３１】
グラフィック処理装置１０４には、モニタ２１が接続されている。グラフィック処理装置１０４は、プロセッサ１０１からの命令に従って、画像をモニタ２１の画面に表示させる。モニタ２１としては、ＣＲＴ（Cathode Ray Tube）を用いた表示装置や液晶表示装置などがある。
【００３２】
入力インタフェース１０５には、キーボード２２とマウス２３とが接続されている。入力インタフェース１０５は、キーボード２２やマウス２３から送られてくる信号をプロセッサ１０１に送信する。なお、マウス２３は、ポインティングデバイスの一例であり、他のポインティングデバイスを使用することもできる。他のポインティングデバイスとしては、タッチパネル、タブレット、タッチパッド、トラックボールなどがある。
【００３３】
光学ドライブ装置１０６は、レーザ光などを利用して、光ディスク２４に記録されたデータの読み取りを行う。光ディスク２４は、光の反射によって読み取り可能なようにデータが記録された可搬型の記録媒体である。光ディスク２４には、ＤＶＤ（Digital Versatile Disc）、ＤＶＤ−ＲＡＭ、ＣＤ−ＲＯＭ（Compact Disc Read Only Memory）、ＣＤ−Ｒ（Recordable）／ＲＷ（ReWritable）などがある。
【００３４】
機器接続インタフェース１０７は、コンピュータ１００に周辺機器を接続するための通信インタフェースである。例えば機器接続インタフェース１０７には、メモリ装置２５やメモリリーダライタ２６を接続することができる。メモリ装置２５は、機器接続インタフェース１０７との通信機能を搭載した記録媒体である。メモリリーダライタ２６は、メモリカード２７へのデータの書き込み、またはメモリカード２７からのデータの読み出しを行う装置である。メモリカード２７は、カード型の記録媒体である。
【００３５】
ネットワークインタフェース１０８は、ネットワーク２０に接続されている。ネットワークインタフェース１０８は、ネットワーク２０を介して、他のコンピュータまたは通信機器との間でデータの送受信を行う。
【００３６】
以上のようなハードウェア構成によって、第２の実施の形態の処理機能を実現することができる。なお、第１の実施の形態に示した情報処理装置１０も、図２に示したコンピュータ１００と同様のハードウェアにより実現することができる。
【００３７】
コンピュータ１００は、例えばコンピュータ読み取り可能な記録媒体に記録されたプログラムを実行することにより、第２の実施の形態の処理機能を実現する。コンピュータ１００に実行させる処理内容を記述したプログラムは、様々な記録媒体に記録しておくことができる。例えば、コンピュータ１００に実行させるプログラムをＨＤＤ１０３に格納しておくことができる。プロセッサ１０１は、ＨＤＤ１０３内のプログラムの少なくとも一部をメモリ１０２にロードし、プログラムを実行する。またコンピュータ１００に実行させるプログラムを、光ディスク２４、メモリ装置２５、メモリカード２７などの可搬型記録媒体に記録しておくこともできる。可搬型記録媒体に格納されたプログラムは、例えばプロセッサ１０１からの制御により、ＨＤＤ１０３にインストールされた後、実行可能となる。またプロセッサ１０１が、可搬型記録媒体から直接プログラムを読み出して実行することもできる。
【００３８】
図３は、トレース機能の一例を示すブロック図である。図３には、コンピュータ１００が有する機能のうち、トレースによる情報採取に関係する機能を抜き出したものである。コンピュータ１００は、プログラム記憶部１１０、コマンド部１２０、ドライバ部１３０、およびプール領域１４０を有する。なお、コンピュータ１００は、図３に示した機能以外にも、ＯＳにより実現される機能を有している。
【００３９】
プログラム記憶部１１０は、トレース対象のプログラムを記憶する。例えばプログラム記憶部１１０は、メモリ１０２内の記憶領域である。
コマンド部１２０は、ユーザから、トレース指示のコマンドの入力を受け付ける。そしてコマンド部１２０は、トレース要求をドライバ部１３０に送信する。またコマンド部１２０は、ドライバ部１３０からトレース結果を取得し、トレース結果を含むログファイルを出力する。なおコマンド部１２０は、ＯＳのユーザモードで動作する。
【００４０】
ドライバ部１３０は、コマンド部１２０からのトレース要求に応じて、プログラム記憶部１１０に格納されたトレース対象のプログラムのトレースを行う。ドライバ部１３０は、トレースにより取得した情報を、プール領域１４０に格納する。またドライバ部１３０は、トレースに用いるスタブも、プール領域１４０に格納する。またドライバ部１３０は、トレースが完了すると、トレース結果をコマンド部１２０に送信する。なおドライバ部１３０は、ＯＳのカーネルモードで動作する。
【００４１】
プール領域１４０は、トレースデータやスタブの記憶領域である。例えばプール領域１４０は、メモリ１０２内の記憶領域である。
なお、コマンド部１２０は、例えば「trace.exe」というファイル名の実行形式のファイルをコンピュータ１００が実行することで実現する機能である。またドライバ部１３０は、例えば「TraceDriver.sys」というファイル名の実行形式のファイルをコンピュータ１００が実行することで実現する機能である。
【００４２】
このような機能によりトレースが実行される。
図４は、トレースの処理の概要を示す図である。ユーザは、キーボード２２などの入力デバイスを操作し、トレースの実行を指示するコマンド３１を入力する。コマンド３１では、例えばトレース対象のプログラム１１１が指定される。またコマンド３１では、トレースの実行条件が定義されたトレース設定ファイル３２が指定される。
【００４３】
入力されたコマンド３１は、ユーザモードで動作するコマンド部１２０で受け取られる。コマンド部１２０は、例えばコマンド３１で指定されたトレース設定ファイル３２を参照し、トレースの実行条件を認識する。そしてコマンド部１２０は、トレースの実行条件を含むトレース要求を出力する。
【００４４】
トレース要求は、ＯＳのＩ／Ｏマネージャ１５１を介して、カーネルモードで動作するドライバ部１３０に入力される。ドライバ部１３０は、トレース要求に従って、トレース処理を実行する。トレース処理は、トレース要求取得時に実行するトレース設定処理と、トレースポイントにおける例外発生時に実行するトレースデータ収集処理とに大別される。図４では、トレース設定処理を実線の矢印で示し、トレースデータ収集処理を破線の矢印で示している。
【００４５】
トレース設定処理では、ドライバ部１３０は、トレース対象のプログラム１１１のトレースポイントとなる位置の命令を、割り込み命令１１１ａに書き換える。またドライバ部１３０は、ＩＤＴ（Interrupt Descriptor Table）における例外割り込み用のハンドラのアドレスを、ドライバ部１３０が有するハンドラ１３１のアドレスに書き換える。さらにドライバ部１３０は、プログラム１１１の書き換えによって上書きされた命令を実行するスタブ１４１を生成し、プール領域１４０に格納する。
【００４６】
その後、コンピュータ１００においてプログラム１１１の実行が開始され、実行位置がトレースポイントに達すると、割り込み命令１１１ａが実行される。割り込み命令１１１ａが実行されると、ＯＳによってＩＤＴ１５２が参照され、その割り込み命令１１１ａに対応する例外割り込み用のハンドラ１３１のアドレスが取得される。そしてハンドラ１３１の実行が開始される。ハンドラ１３１は、トレースデータを収集し、収集したトレースデータ１４２をプール領域１４０に格納する。トレースデータの収集が完了すると、ハンドラ１３１は、スタブ１４１を起動する。するとコンピュータ１００においてスタブ１４１が実行される。スタブ１４１の実行後、コンピュータ１００は、プログラム１１１内の割り込み命令１１１ａより後の命令を実行する。
【００４７】
ドライバ部１３０は、トレースデータ１４２をＩ／Ｏマネージャ１５１経由でコマンド部１２０に送信する。するとコマンド部１２０は、トレースデータ１４２を含むログファイル３３を生成する。ログファイル３３は、例えばＨＤＤ１０３に格納される。
【００４８】
このような手順でプログラム実行中の所定のトレースポイントにおけるコンピュータの状態を示す情報（レジスタの値など）が収集される。どのような情報を収集するかは、ハンドラ１３１に定義されている。トレースポイントとしては、例えばプログラム１１１内に定義されたＡＰＩなどの関数に含まれる命令を指定することができる。ここで、ハンドラ１３１において、トレースポイントとして指定された命令を含む関数を呼び出すか否かにより、トレースの手順が異なる。
【００４９】
図５は、ハンドラにおいてトレースポイントを含む関数を呼び出さない場合の命令の一例を示す図である。図５の例では、プログラム４０内に「FunctionA」という関数４０−１が定義されている。そして関数４０−１の実行開始時にトレースを実行するものとする。この場合、関数４０−１の先頭の命令４１が、メモリ１０２内で例外命令４２に書き換えられる。元の命令４１は、メモリ１０２のアドレス「fffff800`014e6610」から「4883ec10」と記述されている。この命令４１をニーモニックで表すと「sub rsp,10h」となる。書き換え後の例外命令４２は、メモリ１０２のアドレス「fffff800`014e6610」から「cc」と記述されている。この例外命令４２をニーモニックで表すと「int 3」となる。
【００５０】
例外命令４２は、書き換え元の命令４１よりも命令長が短い。そのため、命令４１が格納されたメモリ１０２内の領域の一部が例外命令４２で上書きされ、他の領域には不完全な命令４３が残される。そこで、元の命令４１を実行するためのスタブ１４１ａが生成される。スタブ１４１ａには、例外命令４２によって上書きされた元の命令４１と同じ内容の命令４４が含まれている。またスタブ１４１ａの最後には、元のプログラム４０において、書き換えられた命令４１の次に実行することになっていた命令４６へのジャンプ命令４５が記述されている。
【００５１】
命令書き換え後のプログラム４０ａ内の関数４０ａ−１が実行されると、まず例外命令４２が実行される。例外命令４２が実行されることで、例外処理に対応するハンドラ１３１ａが起動される。そしてハンドラ１３１ａが実行されることによって、データが採取される。ハンドラ１３１ａの実行が終了すると、スタブ１４１ａが実行される。すると、スタブ１４１ａ内に記述された、書き換え元の命令４１と同じ内容の命令４４が実行される。次に、プログラム４０ａ内の命令４６へのジャンプ命令４５が実行される。その後、プログラム４０ａの命令４６以降の各命令が実行される。
【００５２】
このようにして、プログラム４０をトレース対象として、プログラム４０の開始時点での状態をトレースすることができる。ただし、図５の例では、ハンドラ１３１ａ内に、トレースポイントを含む関数４０ａ−１の呼出命令が含まれていない。ハンドラ１３１ａ内に、関数４０ａ−１の呼出命令が含まれている場合、図５と同様の処理を行うと、処理のループが発生する。
【００５３】
図６は、ハンドラにおいてトレースポイントを含む関数を呼び出すことによるループ発生例を示す図である。図６の例では、トレース処理の内容が記述されたハンドラ１３１ｂ内に、トレースポイントを有する関数４０ａ−１を呼び出す命令５１が含まれている。この場合、トレース実施中に関数４０ａ−１が実行されると、まず例外命令４２が実行され、ハンドラ１３１ｂが呼び出される。呼び出されたハンドラ１３１ｂ内の命令が先頭から実行される。そして命令５１が実行されることで、関数４０ａ−１が呼び出され、先頭の例外命令４２が実行される。すると、再度例外処理が発生し、ハンドラ１３１ｂが呼び出される。
【００５４】
このように、トレース対象のプログラムをハンドラ１３１ｂ内で呼び出している場合、ループ処理が繰り返される。処理が何度もループしていると、再帰的な割り込みの繰り返しにより、処理の呼び出しを管理するスタックがオーバーフローする。その結果、トレース処理がエラー終了する。
【００５５】
第２の実施の形態では、ハンドラ１３１ｂ内でトレース対象の関数４０ａ−１を呼び出す場合の呼び出し先をスタブ１４１ａに変更することで、図６に示すようなループの発生を回避する。ハンドラ１３１ｂ内での呼び出し先の変更は、例えばＩＡＴ（Import Address Table）の内容を変更することで実現できる。ＩＡＴは、外部ファイルで定義されたＡＰＩの先頭アドレスが記述されたデータテーブルである。
【００５６】
図７は、第２の実施の形態におけるハンドラからのトレース対象のプログラムの呼び出し例を示す図である。ドライバ部１３０は、データセクション１３２、コードセクション１３３，ＩＡＴ１３４などを有している。データセクション１３２は、ドライバ部１３０の処理の実行に使用するデータが格納される。コードセクション１３３は、ドライバ部１３０が実行する処理内容を示すプログラムコードが格納される。なおハンドラ１３１ｂも、コードセクション１３３に含まれる。ＩＡＴ１３４には、ドライバ部１３０が処理の実行に使用するＡＰＩの名称に対応付けて、そのＡＰＩを定義する外部ファイルの先頭アドレスが設定されている。
【００５７】
関数４０ａ−１をトレース対象としてトレースを実施する場合において、ハンドラ１３１ｂ内に関数４０ａ−１の呼び出し命令（call命令）があると、ドライバ部１３０は、自身が有するＩＡＴの書き換えを行う。例えばドライバ部１３０は、関数４０ａ−１の名前「FunctionA」の先頭アドレス「fffff800`014e6610」を、スタブ１４１ａの先頭アドレスに変更する。
【００５８】
その後、関数４０ａ−１が実行されると、例外命令４２によりハンドラ１３１ｂが呼び出される。そしてハンドラ１３１ｂに基づいて、データが収集される。ハンドラ１３１ｂにおける関数４０ａ−１呼び出しの命令５１が実行されると、ＩＡＴ１３４が参照され、命令５１で示されるＡＰＩの名称に対応付けられたアドレスのプログラムが呼び出される。該当アドレスは、予めスタブ１４１ａの先頭アドレスに変更されているため、スタブ１４１ａが呼び出され、実行される。
【００５９】
スタブ１４１ａを実行することで、例外命令４２で上書きされた命令４１と同じ内容の命令４４が実行され、関数４０ａ−１の命令４６に処理が遷移する。その後、関数４０ａ−１の命令４６以降の処理が実行される。関数４０ａ−１が最後まで実行されると、呼出元のハンドラ１３１ｂに処理が遷移する。
【００６０】
ハンドラ１３１ｂからの呼び出しによる関数４０ａ−１の処理が終了すると、ハンドラ１３１ｂの残りの処理が実行される。ハンドラ１３１ｂの処理が完了すると、スタブ１４１ａ内の命令４４が実行される。次に、ジャンプ命令４５により、関数４０ａ−１の命令４６にジャンプする。その後、関数４０ａ−１の命令４６以降の処理が実行される。
【００６１】
次に、トレース設定処理について詳細に説明する。トレース設定処理は、トレース設定ファイル３２に基づいて行われる。
図８は、トレース設定ファイルの一例を示す図である。トレース設定ファイル３２には、例えばデータバッファサイズやトレースポイントが指定される。図８の例では、［ＳＥＴＴＩＮＧ］の欄に、採取したデータを格納するデータバッファのサイズが設定されている。また［ＴＲＡＣＥＰＯＩＮＴ］の欄に、トレースポイントが指定されている。トレースポイントは、例えばトレース対象のプログラムの名称（シンボル名）で指定される。トレースポイントがシンボル名のみで示された場合、そのシンボル名に対応するプログラムの先頭の位置がトレースポイントとなる。また、トレースポイントをメモリ内でのアドレスで指定することもできる。
【００６２】
次に、トレース設定処理の手順について説明する。
図９は、トレース設定処理の手順の一例を示すフローチャートである。
［ステップＳ１０１］ドライバ部１３０は、トレース管理テーブルを作成する。トレース管理テーブルは、トレースポイントにおける命令と、その命令を実行するためのスタブアドレスとを管理するデータテーブルである。トレース管理テーブル作成処理の詳細は後述する（図１１参照）。
【００６３】
［ステップＳ１０２］ドライバ部１３０は、ＩＡＴの書き換えを行う。ＩＡＴ書き換え処理の詳細は後述する（図１３参照）。なお書き換えられたＩＡＴの内容は、トレース処理を伴う情報解析が終了したときに、元に戻される。
【００６４】
［ステップＳ１０３］ドライバ部１３０は、ハンドラを置き換える。例えばドライバ部１３０は、例外処理が発生したときに、トレース処理を行うハンドラ１３１ｂが実行されるように、ＯＳの設定内容を更新する。
【００６５】
［ステップＳ１０４］ドライバ部１３０は、トレースポイントとなっているアドレスに記述されている命令を、例外命令に置き換える。
このような手順でトレースの実行環境が整えられる。トレースポイントは、トレース管理テーブルに示される。
【００６６】
図１０は、トレース管理テーブルの一例を示す図である。トレース管理テーブル６０には、トレースアドレス、元の命令、およびスタブアドレスの欄が設けられている。トレースアドレスの欄には、トレースポイントとなる命令が格納されたメモリ１０２のアドレス（トレースアドレス）が設定される。元の命令の欄には、例外命令に書き換える前に、トレースアドレスに述されていた命令が設定される。スタブアドレスの欄には、元の命令を実行するためのスタブの先頭アドレスが設定される。
【００６７】
次にトレース管理テーブル作成処理について詳細に説明する。
図１１は、トレース管理テーブル作成処理の手順を示すフローチャートである。
［ステップＳ１１１］ドライバ部１３０は、トレース設定ファイル読み込み処理を行う。トレース設定ファイル読み込み処理により、トレース管理テーブル６０のトレースアドレスの欄に、トレースポイントのアドレスが設定される。この処理の詳細は後述する（図１２参照）。ここで、トレース管理テーブル６０に設定されたトレースポイントの数をｍとする（ｍは１以上の整数）。
【００６８】
［ステップＳ１１２］ドライバ部１３０は、変数ｉに０を設定する。
［ステップＳ１１３］ドライバ部１３０は、ｉの値がトレースポイント数ｍと同じか否かを判断する。ｉの値がトレースポイント数ｍと同じ場合、トレース管理テーブル作成処理が終了する。ｉの値がトレースポイント数ｍと異なる場合、処理がステップＳ１１４に進められる。
【００６９】
［ステップＳ１１４］ドライバ部１３０は、トレース管理テーブル６０のｉ番目のレコードのトレースポイントに記述されている命令を、そのレコードの元の命令の欄に格納する。
【００７０】
［ステップＳ１１５］ドライバ部１３０は、スタブの格納領域をメモリ１０２内に作成する。
［ステップＳ１１６］ドライバ部１３０は、スタブの格納領域の先頭のアドレスを、トレース管理テーブル６０のｉ番目のレコードのスタブアドレスの欄に格納する。
【００７１】
［ステップＳ１１７］ドライバ部１３０は、ｉの値に１を加算し、処理をステップＳ１１３に進める。
次にトレース設定ファイル読み込み処理の手順について説明する。
【００７２】
図１２は、トレース設定ファイル読み込み処理の手順の一例を示すフローチャートである。
［ステップＳ１２１］ドライバ部１３０は、トレース設定ファイル３２の［ＳＥＴＴＩＮＧ］の欄から、データサイズを読み取る。ドライバ部１３０は、読み取ったデータサイズ分の記憶領域を、トレースデータ１４２（図４参照）の格納領域としてメモリ１０２内に確保する。
【００７３】
［ステップＳ１２２］ドライバ部１３０は、変数ｉに０を設定する。
［ステップＳ１２３］ドライバ部１３０は、ｉの値がトレースポイント数ｍと同じか否かを判断する。ｉの値がトレースポイント数ｍと同じ場合、トレース管理テーブル作成処理が終了する。ｉの値がトレースポイント数ｍと異なる場合、処理がステップＳ１２４に進められる。
【００７４】
［ステップＳ１２４］ドライバ部１３０は、トレース設定ファイル３２の［ＴＲＡＣＥＰＯＩＮＴ］の欄に設定されている全ｍ個のトレースポイントそれぞれの定義行から、ｉ番目のトレースポイントの定義情報を読み取る。
【００７５】
［ステップＳ１２５］ドライバ部１３０は、トレースポイントがシンボル名で定義されているか否かを判断する。トレースポイントがシンボル名で定義されていれば、処理がステップＳ１２６に進められる。トレースポイントがアドレスで定義されていれば、処理がステップＳ１２７に進められる。
【００７６】
［ステップＳ１２６］ドライバ部１３０は、シンボル名をアドレスに変換する。例えばドライバ部１３０は、ＯＳに用意されたＡＰＩを用いて、シンボル名に対応するプログラム（関数などのＡＰＩを含む）の先頭アドレスを、ＯＳから取得する。そしてドライバ部１３０は、取得したアドレスを、ｉ番目のトレースポイントのトレースアドレスと認識する。
【００７７】
［ステップＳ１２７］ドライバ部１３０は、ｉ番目のトレースポイントのトレースアドレスを、トレース管理テーブル６０に登録する。
［ステップＳ１２８］ドライバ部１３０は、ｉの値に１を加算し、処理をステップＳ１２３に進める。
【００７８】
図１１、図１２に示した処理により、トレース管理テーブル６０が作成される。トレース管理テーブル６０が作成されると、ＩＡＴの書き換えが行われる。
図１３は、ＩＡＴ書き換え処理の手順の一例を示すフローチャートである。
【００７９】
［ステップＳ１３１］ドライバ部１３０は、ドライバ部１３０の処理内容を記述した実行形式のファイル（TraceDriver.sys）のロードアドレス（メモリに読み込まれたファイルの先頭アドレス）を、ＯＳから取得する。
【００８０】
［ステップＳ１３２］ドライバ部１３０は、ドライバ部１３０の処理内容を記述した実行形式のファイルを解析し、ＩＡＴ１３４が格納された領域のアドレスを取得する。
［ステップＳ１３３］ドライバ部１３０は、ＩＡＴ１３４に基づいて、ハンドラ内で使用されているＡＰＩのリスト（ＡＰＩリスト）を作成する。例えばドライバ部１３０は、ハンドラ内で使用されているＡＰＩの名前をアドレスに変換し、アドレス順にソートする。
【００８１】
図１４は、ＡＰＩリストの一例を示す図である。ＡＰＩリスト６２には、ＡＰＩ名とアドレスとの欄が設けられている。ＡＰＩ名には、ハンドラ１３１ｂ内で使用されるＡＰＩの名称が設定される。アドレスの欄には、対応するＡＰＩなどの関数が格納された領域のアドレスが設定される。ＡＰＩ名とアドレスとの組は、ＩＡＴから取得できる。ＡＰＩ名とアドレスとの組からなる各レコードは、例えばアドレスが昇順となるようにソートされている。ここでＡＰＩリスト６２に登録されたＡＰＩ数をｎ（ｎは１以上の整数）とする。
【００８２】
図１３の説明に戻る。
［ステップＳ１３４］ドライバ部１３０は、変数ｉに０を設定する。
［ステップＳ１３５］ドライバ部１３０は、ｉの値がＡＰＩ数ｎと同じか否かを判断する。ｉの値がＡＰＩ数ｎと同じ場合、ＩＡＴ書き換え処理が終了する。ｉの値がＡＰＩ数ｎと異なる場合、処理がステップＳ１３６に進められる。
【００８３】
［ステップＳ１３６］ドライバ部１３０は、ＡＰＩリスト６２のｉ番目のＡＰＩがトレース対象か否かを判断する。例えばｉ番目のＡＰＩのアドレスと同じアドレスが、トレース管理テーブル６０のトレースアドレスの欄に登録されている場合、ｉ番目のＡＰＩがトレース対象であると判断される。ｉ番目のＡＰＩがトレース対象の場合、処理がステップＳ１３７に進められる。ｉ番目のＡＰＩがトレース対象ではない場合、処理がステップＳ１３８に進められる。
【００８４】
［ステップＳ１３７］ドライバ部１３０は、ＡＰＩリスト６２のｉ番目のＡＰＩに対応するＩＡＴ内のエントリを、そのＡＰＩに対応するスタブのアドレスに変換する。例えばドライバ部１３０は、ＡＰＩリスト６２のｉ番目のＡＰＩのアドレスとトレースアドレスとするレコードを、トレース管理テーブル６０から取得する。次にドライバ部１３０は、取得したレコードからスタブアドレスを抽出する。そしてドライバ部１３０は、ＡＰＩリスト６２のｉ番目のＡＰＩに対応するＩＡＴ内のエントリのアドレスと、抽出したスタブアドレスに書き換える。
【００８５】
［ステップＳ１３８］ドライバ部１３０は、ｉの値に１を加算し、処理をステップＳ１３５に進める。
このようにしてＩＡＴの書き換えが行われる。その後、図９に示すように、ハンドラの置き換えとトレースポイントの命令の置き換えが行われ、トレース設定が完了する。トレース設定が完了した後に、トレース対象のＡＰＩが呼び出されると、例外命令が実行される。その結果、トラップ例外処理が開始される。
【００８６】
図１５は、トラップ例外処理の手順の一例を示すフローチャートである。
［ステップＳ１４１］ドライバ部１３０は、トレースアドレスで発生した例外か否かを判断する。例えばドライバ部１３０は、トレース管理テーブル６０を参照し、例外を発生させた例外命令のアドレスが、トレースアドレスとして登録されている場合、トレースアドレスで発生した例外であると判断する。トレースアドレスで発生した例外の場合、処理がステップＳ１４３に進められる。トレースアドレス以外で発生した例外の場合、処理がステップＳ１４２に進められる。
【００８７】
［ステップＳ１４２］ドライバ部１３０は、トレースアドレス以外で発生した例外であれば、ステップＳ１０３（図９参照）による置き換え前の例外ハンドラを呼び出す。すると、呼び出された例外ハンドラが実行され、トレース処理を伴わない例外処理が行われる。その後、トラップ例外処理が終了する。
【００８８】
［ステップＳ１４３］ドライバ部１３０は、ハンドラ１３１ｂに基づいて、トレースデータの採取処理を行う。この処理の詳細は後述する（図１６参照）。
［ステップＳ１４４］ドライバ部１３０は、トレース対象の関数に対応するスタブを実行する。例えばハンドラ１３１ｂの最後の命令として、スタブ１４１ａの先頭へのジャンプ命令が記載されている。ドライバ部１３０は、その命令を実行することで、処理対象をスタブ１４１ａに遷移させ、スタブ１４１ａに記述された命令を実行する。
【００８９】
［ステップＳ１４５］ドライバ部１３０は、例外発生元に処理を戻す。これにより、例外発生元のプログラムを実行しているスレッドにより、例外発生アドレスの次の命令以降の処理が実行される。
【００９０】
次に、トレースデータ採取処理について詳細に説明する。
図１６は、トレースデータ採取処理の手順の一例を示すフローチャートである。
［ステップＳ１５１］ドライバ部１３０は、ハンドラ１３１ｂを呼び出し、ハンドラ１３１ｂ内の次に実行する命令を解釈する。
【００９１】
［ステップＳ１５２］ドライバ部１３０は、実行対象の命令が、例外発生元の関数（ＡＰＩ）の呼び出し命令か否かを判断する。該当関数の呼び出し命令の場合、処理がステップＳ１５４に進められる。該当関数の呼び出し命令でなければ、処理がステップＳ１５３に進められる。
【００９２】
［ステップＳ１５３］ドライバ部１３０は、ハンドラ１３１ｂの次に実行する命令が、例外発生元のＡＰＩの呼び出し命令でなければ、その命令を実行する。その後、処理がステップＳ１５７に進められる。
【００９３】
［ステップＳ１５４］ドライバ部１３０は、ハンドラ１３１ｂの次に実行する命令が、例外発生元のＡＰＩの呼び出し命令であれば、該当関数に対応するスタブを実行する。例えばドライバ部１３０は、ＩＡＴ１３４を参照し、例外発生元の関数に対応付けて設定されたスタブアドレスを取得する。そしてドライバ部１３０は、取得したスタブアドレスに格納されているスタブ内の命令を実行する。そのスタブには、例外発生元の関数において、例外命令に置き換えられた命令、および例外発生元の関数における例外命令の次の命令へのジャンプ命令が記述されている。従って、ドライバ部１３０がスタブを実行することにより、例外命令に置き換えられた命令が実行され、例外発生元の関数における例外命令の次の命令へのジャンプ命令が実行される。
【００９４】
［ステップＳ１５５］ドライバ部１３０は、例外発生元の関数における例外発生アドレスの次の命令以降の処理を実行する。
［ステップＳ１５６］ドライバ部１３０は、例外発生元の関数の処理が最後まで終了すると、処理がハンドラ１３１ｂに戻す。
【００９５】
［ステップＳ１５７］ドライバ部１３０は、ハンドラ１３１ｂの処理が終了したか否かを判断する。未処理の命令があれば、処理がステップＳ１５１に進められる。ハンドラ１３１ｂの処理が終了していれば、トレースデータ採取処理が終了する。
【００９６】
以上のようにして、トレースデータを収集するハンドラ１３１ｂ内で、トレースポイントとなっているＡＰＩなどの関数を呼び出しても、処理のループを発生させずに済む。そのため、ハンドラ１３１ｂ内でＯＳのＡＰＩなどの各種の関数を利用することができる。その結果、自由度の高いトレースデータの収集処理が可能となる。例えばトレース用のハンドラ１３１ｂ内でファイルアクセスのＡＰＩを呼び出せるようになることで、メモリ１０２内に保存したトレースデータを、適宜、ＨＤＤ１０３などの他の記録媒体に書き出すことが可能となる。その結果、収集可能なトレースデータのデータ量が、プール領域１４０の容量に依存しなくなり、大量のトレースデータの収集が可能となる。
【００９７】
しかも第２の実施の形態では、ＩＡＴ１３４を予め書き換えるだけで、ハンドラ１３１ｂ内での関数４０ａ−１の呼び出し命令実行時に、スタブ１４１ａを実行させることができ、簡単な手順により例外命令４２で上書きされた命令４４を実行することができる。従って、トレース処理時の処理効率を低下させずに済む。
【００９８】
さらに、トレースコードが記載されたハンドラを、プログラムへフックすることで実行するため、同じトレースポイントを含む関数を実行するスレッドと同じスレッドでハンドラを実行できる。その結果、ハンドラ実行時にコンテキストスイッチが発生せず、レジスタやメモリの内容を、関数実行状態のまま維持できる。その結果、関数実行時の状態を正しくトレースできる。
【００９９】
さらに、トレースポイントの命令を書き換える際に、メモリ上で書き換えを行うため、プログラムの実行ファイルには手を加えずに済む。そのためプログラムの再コンパイルをせずにトレース処理を行うことができる。
【０１００】
またトレース対象の関数として、例えばＯＳで用意されたＡＰＩのようなカーネルで動作する関数を指定できるため、カーネルで動作する関数についても、実行状態をトレースすることができる。
【０１０１】
〔第３の実施の形態〕
次に第３の実施の形態について説明する。第３の実施の形態では、ＡＰＩなどの関数中の任意の箇所をトレースポイントとすることを可能とするものである。以下、第３の実施の形態における、第２の実施の形態と相違する部分について説明する。
【０１０２】
図１７は、先頭以外の箇所をトレースポイントとした場合のループ発生例を示す図である。図１７の例では、図５に示した関数４０−１の先頭から２番目の命令をトレースポイントとしている。この場合、関数４０−１の２行目の命令が、例外命令４２に書き換えられる。命令書き換え後のプログラム４０ｂ内の関数４０ｂ−１が実行されると、例外命令４２によりハンドラ１３１ｂが呼び出される。ハンドラ１３１ｂ内には、関数４０ｂ−１を呼び出す命令５１が含まれている。この場合、命令５１が実行されると関数４０ｂ−１が呼び出され、再度、例外命令４２が実行される。その結果、処理のループが発生する。
【０１０３】
なお、ハンドラ１３１ｂはプログラム４０ｂにフックする形式で実行されており、図１７に示すような処理は、１つのスレッドで実行される。すなわち、関数４０ｂ−１が繰り返し呼び出され、例外命令４２が何度も実行されても、その例外命令４２を実行するスレッドのスレッドＩＤ（ＴＩＤ）は同じである。そこで第３の実施の形態では、ドライバ部１３０は、例外処理のハンドラ１３１ｂを呼び出したスレッドのＴＩＤに基づいて、同じスレッドからの呼び出し回数をカウントする。そしてドライバ部１３０は、特定のスレッドからのハンドラの呼び出し回数に応じた処理を行うことで、ループの発生を抑止する。
【０１０４】
図１８は、第３の実施の形態におけるハンドラからのトレース対象の関数の呼び出し例を示す図である。関数４０ｂ−１の実行が開始され、実行箇所が例外命令４２に達すると、例外が発生し、ハンドラ１３１ｃが呼び出される。
【０１０５】
ハンドラ１３１ｃの先頭にはＴＩＤのチェック命令７１が記述されている。ＴＩＤのチェック命令７１の実行により、ハンドラ１３１ｃを呼び出したスレッド（プログラム４０ｂを実行しているスレッド）のＴＩＤが取得される。そして取得したＴＩＤがメモリ１０２に記憶される。さらに、以前に同じＴＩＤを取得しているかどうかが判定される。
【０１０６】
１度目の呼び出しでは、同じＴＩＤを以前に取得していないと判定される。この場合、ハンドラ１３１ｃ内のＴＩＤのチェック命令７１以降の命令が実行される。そして関数４０ｂ−１を呼び出す命令５１の実行により、関数４０ｂ−１が呼び出される。
【０１０７】
関数４０ｂ−１が呼び出されると、関数４０ｂ−１が先頭から実行される。そして例外命令４２に達すると、再度、例外が発生し、ハンドラ１３１ｃが呼び出される。ハンドラ１３１ｃが呼び出されると、まずＴＩＤのチェック命令７１が実行される。ＴＩＤのチェック命令７１の実行により、呼出元のスレッドのＴＩＤに基づいて、関数４０ｂ−１からの２度目の呼び出しであると判断される。２度目の呼び出しの場合、ハンドラ１３１ｃに示されたデータ採取処理に代えて、スタブ１４１ｂが呼び出される。
【０１０８】
スタブ１４１ｂには、例外命令４２により書き換えられた命令７２と、例外命令４２の次の命令へのジャンプ命令７３とが記述されている。従って、スタブ１４１ｂが実行されることにより、命令７２が実行された後、関数４０ｂ−１の例外命令４２の次の命令に処理がジャンプする。そして、関数４０ｂ−１のジャンプ先の命令以降の処理が実行される。
【０１０９】
関数４０ｂ−１の処理が最後まで終了すると、関数４０ｂ−１の呼び出し元（ハンドラ１３１ｃの命令５１）に処理が戻される。そしてハンドラ１３１ｃ内の命令５１以降の処理が実行され、データ採取が行われる。ハンドラ１３１ｃの処理が終了すると、スタブ１４１ｂ内の命令７２が実行される。その後、ジャンプ命令７３により、関数４０ｂ−１の例外命令４２の次の命令に処理がジャンプする。そして、関数４０ｂ−１のジャンプ先の命令以降の処理が実行される。
【０１１０】
このように、ＴＩＤを管理することで、同一スレッドからのハンドラ１３１ｃの呼び出し回数が判別可能となる。そして、２度目の呼び出しではハンドラ１３１ｃ内のデータ採取処理を省略することで、ループの発生が抑止される。
【０１１１】
なお、第３の実施の形態では、トレース設定ファイルにおいて、関数４０ｂ−１の先頭以外の部分を、トレースポイントとして指定できる。
図１９は、第３の実施の形態におけるトレース設定ファイルの一例を示す図である。トレース設定ファイル３２ａでは、トレース対象の関数の名称と、その関数中でのトレースポイントの先頭からのオフセット（シンボル名＋オフセット）により、トレースポイントを指定可能となっている。この場合、トレース対象の関数中の、先頭からオフセットで指定された位置が、トレースポイントとなる。
【０１１２】
次に、トレース設定処理について説明する。
図２０は、第３の実施の形態におけるトレース設定処理の手順の一例を示すフローチャートである。第３の実施の形態では、トレース管理テーブル作成処理（ステップＳ２０１）、例外ハンドラの置き換え処理（ステップＳ２０２）、およびトレースポイントの命令の例外命令への置き換え処理（ステップＳ２０３）が、ドライバ部１３０によって行われる。ステップＳ２０１〜Ｓ２０３の各処理の詳細は、それぞれ、図９に示した第２の実施の形態におけるトレース設定処理のステップＳ１０１，Ｓ１０３，Ｓ１０４と同様である。すなわち、第３の実施の形態におけるトレース設定処理は、第２の実施の形態のトレース設定処理から、ＩＡＴの書き換え処理（ステップＳ１０２）を除いた処理となる。
【０１１３】
次に、例外処理発生時に実行されるトラップ例外処理の手順について説明する。
図２１は、第３の実施の形態におけるトラップ例外処理の手順の一例を示すフローチャートである。
【０１１４】
［ステップＳ２１１］ドライバ部１３０は、トレースアドレスで発生した例外か否かを判断する。トレースアドレスで発生した例外の場合、処理がステップＳ２１３に進められる。トレースアドレス以外で発生した例外の場合、処理がステップＳ２１２に進められる。
【０１１５】
［ステップＳ２１２］ドライバ部１３０は、トレースアドレス以外で発生した例外であれば、ステップＳ２０２（図２０参照）による置き換え前の例外ハンドラを呼び出す。すると、呼び出された例外ハンドラが実行され、トレース処理を伴わない例外処理が行われる。その後、トラップ例外処理が終了する。
【０１１６】
［ステップＳ２１３］ドライバ部１３０は、スレッド判別処理を行う。スレッド判別処理では、例外発生元のスレッドが、ハンドラ１３１ｃの実行により再帰的に呼び出されたスレッドか否かの判定が行われる。スレッド判別処理の詳細は後述する（図２３参照）。
【０１１７】
なおドライバ部１３０は、スレッド判別処理の過程で、ＴＩＤ管理テーブルを作成する。ＴＩＤ管理テーブルは、例外を発生させたスレッドのＴＩＤを管理するデータテーブルである。
【０１１８】
図２２は、ＴＩＤ管理テーブルの一例を示す図である。図２２の例では、ＴＩＤ管理テーブル６３には、トレースアドレスとＴＩＤとの欄が設けられている。トレースアドレスの欄には、トレースアドレスが設定される。ＴＩＤの欄には、対応するトレースアドレスで例外を発生させた１以上のスレッドのＴＩＤが設定される。例えば、異なるスレッドそれぞれにおいて、トレース対象のＡＰＩが個別に呼び出されることがある。このような場合には、１つのトレースアドレスに、複数のＴＩＤが対応付けられる。
【０１１９】
以下、図２１の説明に戻る。
［ステップＳ２１４］ドライバ部１３０は、ステップＳ２１３により、再帰的に呼ばれたスレッドであると判定されたか否かを判断する。再帰的に呼ばれたスレッドであると判定された場合、処理がステップＳ２１７に進められる。再帰的に呼ばれたスレッドではないと判定された場合、処理がステップＳ２１５に進められる。
【０１２０】
［ステップＳ２１５］ドライバ部１３０は、再帰的に呼ばれたスレッドでなければ、トレースデータ採取処理を行う。トレースデータ採取処理の詳細は後述する（図２４参照）。
【０１２１】
［ステップＳ２１６］ドライバ部１３０は、ＴＩＤ管理テーブル内の、例外発生元のトレースアドレスに対応付けられているＴＩＤのリストの中から、例外発生元となっているトレース対象の関数を実行しているスレッドのＴＩＤを削除する。
【０１２２】
［ステップＳ２１７］ドライバ部１３０は、トレース対象の関数に対応するスタブを実行する。
［ステップＳ２１８］ドライバ部１３０は、例外発生元に処理を戻す。これにより、例外発生元の関数を実行しているスレッドにより、例外発生アドレスの次の命令以降の処理が実行される。
【０１２３】
次に、スレッド判別処理について詳細に説明する。
図２３は、スレッド判別処理の手順の一例を示すフローチャートである。
［ステップＳ２２１］ドライバ部１３０は、ＴＩＤ管理テーブル６３から、例外発生元のトレースアドレスを検索する。
【０１２４】
［ステップＳ２２２］ドライバ部１３０は、例外発生元のトレースアドレスがＴＩＤ管理テーブル６３に登録されているか否かを判断する。トレースアドレスが登録されている場合、処理がステップＳ２２４に進められる。トレースアドレスが登録されていない場合、処理がステップＳ２２３に進められる。
【０１２５】
［ステップＳ２２３］ドライバ部１３０は、ＴＩＤ管理テーブル６３へ、例外発生元のトレースアドレスを登録する。その後、処理がステップＳ２２６に進められる。
［ステップＳ２２４］ドライバ部１３０は、ＴＩＤ管理テーブル６３に、例外発生元のトレースアドレスに対応付けて、今回の例外を発生させたスレッドのＴＩＤが登録されているか否かを判断する。該当するＴＩＤが登録されていれば、処理がステップＳ２２５に進められる。該当するＴＩＤが登録されていなければ、処理がステップＳ２２６に進められる。
【０１２６】
［ステップＳ２２５］ドライバ部１３０は、例外を発生させたスレッドのＴＩＤが、例外発生元のトレースアドレスに対応付けて登録されていれば、例外を発生させたスレッドは、再帰的に呼び出されたスレッドであると判別する。その後、スレッド判別処理が終了する。
【０１２７】
［ステップＳ２２６］ドライバ部１３０は、例外を発生させたスレッドのＴＩＤが、例外発生元のトレースアドレス対応付けて登録されていない場合、ＴＩＤ管理テーブル６３へ、例外発生元のトレースアドレスに対応付けて、例外を発生させたスレッドのＴＩＤを登録する。
【０１２８】
［ステップＳ２２７］ドライバ部１３０は、例外を発生させたスレッドは、再帰的に呼び出されたスレッドではないと判別する。その後、スレッド判別処理が終了する。
次に、第３の実施の形態におけるトレースデータ採取処理の手順について説明する。
【０１２９】
図２４は、第３の実施の形態におけるトレースデータ採取処理の手順の一例を示すフローチャートである。
［ステップＳ２３１］ドライバ部１３０は、ハンドラ１３１ｃを呼び出し、ハンドラ１３１ｂ内の命令を次に実行する命令を解釈する。
【０１３０】
［ステップＳ２３２］ドライバ部１３０は、実行対象の命令が、例外発生元の関数（ＡＰＩ）の呼び出し命令か否かを判断する。該当関数の呼び出し命令の場合、処理がステップＳ２３４に進められる。該当関数の呼び出し命令でなければ、処理がステップＳ２３３に進められる。
【０１３１】
［ステップＳ２３３］ドライバ部１３０は、ハンドラ１３１ｃの次に実行する命令が、例外発生元のＡＰＩの呼び出し命令でなければ、その命令を実行する。その後、処理がステップＳ２４１に進められる。
【０１３２】
［ステップＳ２３４］ドライバ部１３０は、ハンドラ１３１ｃの次に実行する命令が、例外発生元のＡＰＩの呼び出し命令であれば、呼び出し命令に従って、例外発生元の関数を再帰的に呼び出す。
【０１３３】
［ステップＳ２３５］ドライバ部１３０は、呼び出した関数内の命令を先頭から順に解釈する。
［ステップＳ２３６］ドライバ部１３０は、例外発生元の関数内の次に実行する命令が、例外命令か否かを判断する。例外命令であれば、処理がステップＳ２３７に進められる。例外命令でなければ、処理がステップＳ２３８に進められる。
【０１３４】
［ステップＳ２３７］ドライバ部１３０は、実行する処理が例外命令であれば、例外を発生させる。これにより、図２１に示したトラップ例外処理が実行される。その後、処理がステップＳ２３９に進められる。
【０１３５】
［ステップＳ２３８］ドライバ部１３０は、次に実行する命令が例外命令でなければ、その命令を実行する。
［ステップＳ２３９］ドライバ部１３０は、例外発生元の関数（ＡＰＩ）の処理が終了したか否かを判断する。処理が終了した場合、処理がステップＳ２４０に進められる。処理が終了していなければ、処理がステップＳ２３５に進められ、例外発生元の関数中の次に実行する命令が解釈される。
【０１３６】
［ステップＳ２４０］ドライバ部１３０は、例外発生元の関数の処理が終了すると、処理をハンドラ１３１ｃに戻し、例外発生元の関数の呼び出し命令の次の命令を、次の実行対象の命令とする。
【０１３７】
［ステップＳ２４１］ドライバ部１３０は、ハンドラ１３１ｃの処理が終了したか否かを判断する。未処理の命令があれば、処理がステップＳ２３１に進められる。ハンドラ１３１ｃの処理が終了していれば、トレースデータ採取処理が終了する。
【０１３８】
このようにして、トレース対象のＡＰＩなどの関数の先頭以外がトレースポイントであっても、データのトレース処理を記述したハンドラ内に、トレース対象の関数の呼び出し命令を含めることが可能となる。従って、柔軟性の高いトレースデータの採取処理が可能となる。
【０１３９】
なお第３の実施の形態では、トレースポイントがトレース対象の関数の先頭以外の場合の例を示しているが、トレースポイントがトレース対象の関数の先頭であっても、同様の処理でデータのトレースが可能である。
【０１４０】
〔第４の実施の形態〕
次に、第４の実施の形態について説明する。第４の実施の形態は、第２の実施の形態と第３の実施の形態とを組み合わせたものである。第４の実施の形態では、トレース対象のプログラムである複数の関数にトレースポイントをセットし、各関数内に設定するトレースポイントが１箇所である場合に、トレースポイントが関数の先頭か否かに応じて、トレースデータ採取処理を切り替える。例えば第４の実施の形態では、トレースポイントがトレース対象の関数の先頭であれば、図７に示した第２の実施の形態の処理によりトレースデータを採取する。また第４の実施の形態では、トレースポイントがトレース対象の関数の先頭以外であれば、図１８に示した第３の実施の形態の処理によりトレースデータを採取する。
【０１４１】
第４の実施の形態では、トレースポイントが、トレース対象の関数の先頭か否かを、トレース管理テーブルを用いて管理する。
図２５は、第４の実施の形態におけるトレース管理テーブルの一例を示す図である。第４の実施の形態におけるトレース管理テーブル６４には、トレースアドレス、元の命令、スタブアドレス、およびフラグの欄が設けられている。トレースアドレス、元の命令、およびスタブアドレスの欄には、図１０に示した第２の実施の形態のトレース管理テーブル６０における同名の欄と同種の情報が設定される。
【０１４２】
フラグの欄には、トレースアドレスで示されるトレースポイントが、トレース対象の関数の先頭かを示すフラグが設定される。例えば、トレースポイントがトレース対象の関数の先頭であれば、フラグの欄に「ＴＲＵＥ」と設定される。またトレースポイントがトレース対象の関数の先頭でなければ、フラグの欄に「ＦＡＬＳＥ」と設定される。
【０１４３】
第４の実施の形態におけるトレース設定処理は、図９に示した第２の実施の形態のトレース設定処理と同様の手順で行われる。ただしトレース管理テーブル作成処理内のトレース設定ファイル読み込み処理（ステップＳ１０１）が、第２の実施の形態と異なる。またＩＡＴの書き換え処理（ステップＳ１０２）が適用されるのは、トレースポイントがトレース対象の関数（ＡＰＩ）の先頭の場合である。なお第４の実施の形態では、図１９に示した第３の実施の形態のトレース設定ファイル３２ａと同様に、トレースポイントを、シンボル名＋オフセットで指定可能である。
【０１４４】
図２６は、第４の実施の形態におけるトレース設定ファイル読み込み処理の手順の一例を示すフローチャートである。なお図２６に示した処理のうち、ステップＳ３０１〜Ｓ３０７，Ｓ３１２の処理は、それぞれ図１２に示したステップＳ１２１〜Ｓ１２８の処理と同様である。以下、第２の実施の形態と異なる処理（ステップＳ３０８〜Ｓ３１１）について説明する。
【０１４５】
［ステップＳ３０８］ドライバ部１３０は、トレース管理テーブル６４に登録したトレースアドレスを、「ＡＰＩ名＋オフセット」の形式に変換する。ＡＰＩ名は、例えばトレース対象の関数を示すシンボル名である。アドレスから「ＡＰＩ名＋オフセット」への変換は、例えばＯＳに用意されたＡＰＩなどを利用して行うことができる。
【０１４６】
［ステップＳ３０９］ドライバ部１３０は、オフセットが０か否かを判断する。例えばトレースポイントがトレース対象の関数の先頭の場合、オフセットが０となる。オフセットが０であれば、処理がステップＳ３１１に進められる。オフセットが０でなければ、処理がステップＳ３１０に進められる。
【０１４７】
［ステップＳ３１０］ドライバ部１３０は、オフセットが０でなければ、トレース管理テーブル６４における、ステップＳ３０４で読み取ったトレースポイントに対応するフラグを、「ＦＡＬＳＥ」にセットする。すなわち、トレースポイントが、トレース対象の関数の先頭ではないことが、フラグに設定される。その後、処理がステップＳ３１２に進められる。
【０１４８】
［ステップＳ３１１］ドライバ部１３０は、オフセットが０であれば、トレース管理テーブル６４における、ステップＳ３０４で読み取ったトレースポイントに対応するフラグを、「ＴＲＵＥ」にセットする。すなわち、トレースポイントが、トレース対象の関数の先頭であることが、フラグに設定される。その後、処理がステップＳ３１２に進められる。
【０１４９】
このようにして、トレースポイントが関数の先頭か否かを示すフラグを含むトレース管理テーブル６４が作成される。そしてトラップ例外が発生すると、トレース管理テーブル６４に基づいて、レースポイントが関数の先頭か否かが判断される。そして判断結果に応じた手順でトレースデータの採取が行われる。以下、第４の実施の形態におけるトラップ例外処理について詳細に説明する。
【０１５０】
図２７は、トラップ例外処理の手順の一例を示すフローチャートである。なお図２７に示した処理のうち、ステップＳ３２１，Ｓ３２２，Ｓ３２６〜Ｓ３３１の処理は、それぞれ図２１に示したステップＳ２１１〜Ｓ２１８の処理と同様である。以下図２７に示す処理のうち、第２または第３の実施の形態と相違する処理（ステップＳ３２３〜Ｓ３２５）について説明する。
【０１５１】
［ステップＳ３２３］ドライバ部１３０は、トレースアドレス判別処理を行う。トレースアドレス判別処理では、例外発生元のトレースアドレスが、トレース対象の関数の先頭か否か判別される。なおトレースアドレス判別処理の詳細は後述する（図２８参照）。
【０１５２】
［ステップＳ３２４］ドライバ部１３０は、トレースアドレスがトレース対象の関数の先頭か否かを判断する。トレースアドレスがトレース対象の関数の先頭であれば、処理がステップＳ３２５に進められる。またトレースアドレスがトレース対象関数の先頭でなければ、処理がステップＳ３２６に進められ、第３の実施の形態と同様の手順でトレースデータの採取が行われる。
【０１５３】
［ステップＳ３２５］ドライバ部１３０は、第２の実施の形態と同様の手順で、トレースデータを採取する。この処理の詳細は、図１６に示した処理と同様である。その後、処理がステップＳ３３０に進められる。
【０１５４】
次に、トレースアドレス判別処理について詳細に説明する。
図２８は、トレースアドレス判別処理の手順の一例を示すフローチャートである。
［ステップＳ３４１］ドライバ部１３０は、トレース管理テーブル６４から、現在実行している例外処理の発生元のトレースアドレスに対応するフラグを取得する。
【０１５５】
［ステップＳ３４２］ドライバ部１３０は、取得したフラグが「ＴＲＵＥ」か否かを判断する。フラグが「ＴＲＵＥ」であれば、処理がステップＳ３４３に進められる。フラグが「ＦＡＬＳＥ」であれば、処理がステップＳ３４４に進められる。
【０１５６】
［ステップＳ３４３］ドライバ部１３０は、フラグが「ＴＲＵＥ」の場合、トレースポイントがトレース対象の関数の先頭であると判定し、トレースアドレス判別処理を終了する。
【０１５７】
［ステップＳ３４４］ドライバ部１３０は、フラグが「ＦＡＬＳＥ」の場合、トレースポイントがトレース対象の関数の先頭ではないと判定し、トレースアドレス判別処理を終了する。
【０１５８】
このようにして、トレースポイントがトレース対象の関数の先頭かどうかにより、データ採取の手法を変更することができる。ここで、トレースポイントがトレース対象の関数の先頭であれば、スレッドのＴＩＤを管理せずに済み、簡便な処理でデータを採取でき、負荷が少なくて済む。従って、第４の実施の形態によれば、トレースポイントが関数の先頭でない場合でもデータの採取を可能としながらも、第３の実施の形態よりも少ない処理負荷でデータのトレースを行うことができる。
【０１５９】
以上、実施の形態を例示したが、実施の形態で示した各部の構成は同様の機能を有する他のものに置換することができる。また、他の任意の構成物や工程が付加されてもよい。さらに、前述した実施の形態のうちの任意の２以上の構成（特徴）を組み合わせたものであってもよい。
【符号の説明】
【０１６０】
１  プログラム
１ａ  関数
２  トレースコード
３  スタブ
４  第１の命令
５  第２の命令
６  第３の命令
７  第４の命令
１０  情報処理装置
１１  書き換え手段
１２  記憶手段
１３  実行手段
【図１】
2015069437.tif 000003
【図２】
2015069437.tif 000004
【図３】
2015069437.tif 000005
【図４】
2015069437.tif 000006
【図５】
2015069437.tif 000007
【図６】
2015069437.tif 000008
【図７】
2015069437.tif 000009
【図８】
2015069437.tif 000010
【図９】
2015069437.tif 000011
【図１０】
2015069437.tif 000012
【図１１】
2015069437.tif 000013
【図１２】
2015069437.tif 000014
【図１３】
2015069437.tif 000015
【図１４】
2015069437.tif 000016
【図１５】
2015069437.tif 000017
【図１６】
2015069437.tif 000018
【図１７】
2015069437.tif 000019
【図１８】
2015069437.tif 000020
【図１９】
2015069437.tif 000021
【図２０】
2015069437.tif 000022
【図２１】
2015069437.tif 000023
【図２２】
2015069437.tif 000024
【図２３】
2015069437.tif 000025
【図２４】
2015069437.tif 000026
【図２５】
2015069437.tif 000027
【図２６】
2015069437.tif 000028
【図２７】
2015069437.tif 000029
【図２８】
2015069437.tif 000030