(57)【要約】【課題】システムの運用時においても利用可能な低負荷で、容易に適用可能なプログラムへの監視用コードの挿入方法を提案する。【解決手段】プログラムの読み込み時に監視対象の関数の実行コード中に監視コードを埋め込む。この際にスタブ関数を経由して実行することで、監視対象の関数以外の実行には負荷をかけることなく関数実行の監視を行うことが可能となる。【選択図】  図１
2004164554.tif 000002
【特許請求の範囲】
【請求項１】
複数の関数を含むプログラムを格納するプログラム記憶手段と、
上記記憶部から読み出したプログラムの関数が監視対象の関数であるかを判達する手段と、
監視対象の関数に対して監視処理が施されるようにプログラムに監視コードを挿入する監視コード挿入手段と、
監視コードが挿入された関数を実行して当該関数及び当該関数に対する監視処理を実行するプログラム実行手段とを備えたプログラム実行監視装置。
【請求項２】
請求項１において、前記監視コード挿入手段は、監視する関数の先頭と、関数からの復帰をおこなう命令の直前に監視コードを挿入することを特徴とするプログラム実行監視装置。
【請求項３】
請求項１において、前記監視コード挿入手段は、監視対象の関数を呼び出すためのアドレスあるいは関数の名称を変更し、前記監視コードと、名称の変更された関数を呼び出す命令を含む監視用関数を生成し、プログラムに前記監視用関数を挿入することを特徴とするプログラム実行監視装置。
【請求項４】
請求項３において、前記監視コード挿入手段は、監視用に生成する関数のひな形のソースを生成して、利用者の修正を許した後コンパイルして得られるプログラムコードから監視用の関数を取り出し、これを監視用関数として使用することを特徴とするプログラム実行監視装置。
【請求項５】
請求項１において、前記監視コードは複数の実行コードからなる監視用モジュール、他の監視コードライブラリを呼び出す関数呼び出しコードであることを特徴とするプログラム実行監視装置。
【請求項６】
複数の関数を含むプログラムを格納するプログラム記憶部と、該記憶部からプログラムを読み出して実行するプログラム実行部とを備えるコンピュータにおけるプログラムの実行監視方法であって、
記憶部から読み出したプログラムの関数が監視対象の関数であるかを判定し、監視対象の関数に対して監視処理が施されるように当該プログラムに監視コードを挿入することを特徴とするプログラムの実行監視方法。
【請求項７】
請求項６において、前記監視コードを挿入するステップにおいて、監視する関数の先頭と、関数からの復帰をおこなう命令の直前に監視コードを挿入することを特徴とするプログラム実行監視方法。
【請求項８】
請求項６において、前記監視コードを挿入するステップは、監視対象の関数を呼び出すためのアドレスあるいは関数の名称を変更し、前記監視コードと、名称の変更された関数を呼び出す命令を含む監視用関数を生成し、プログラムに前記監視用関数を挿入することを特徴とするプログラム実行監視方法。
【請求項９】
請求項８において、前記監視コードを挿入するステップは、監視用に生成する関数のひな形のソースを生成して、利用者の修正を許した後コンパイルして得られるプログラムコードから監視用の関数を取り出し、これを監視用関数として使用することを特徴とするプログラム実行監視方法。
【請求項１０】
請求項６において、前記監視コードは複数の実行コードからなる監視用モジュール、他の監視コードライブラリを呼び出す関数呼び出しコードであることを特徴とするプログラム実行監視方法。
【請求項１１】
請求項８において、前記監視コードを挿入するステップは、複数の監視用の関数を入れ子にして順番に呼び出すように挿入することで、複数の監視コードを１つの呼出で実行することを特徴とするプログラム実行監視方法。
【請求項１２】
請求項１１において、監視用の関数を入れ子で挿入する際の順序を指定可能であることを特徴とするプログラム実行監視方法。
【請求項１３】
請求項３において、前記監視コードを挿入するステップは、複数の監視用の関数を入れ子にして順番に呼び出すように挿入することで、複数の監視コードを１つの呼出で実行することを特徴とするプログラム実行監視装置。
【請求項１４】
請求項１３において、監視用の関数を入れ子で挿入する際の順序を指定可能であることを特徴とするプログラム実行監視装置。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明はコンピュータのプログラム実行に際してプログラム実行を効率良く監視する方法に関する。
【０００２】
【従来の技術】
コンピュータで実行するプログラムの実行監視としては、例えばプログラムのソースに、ログの出力コードを埋め込んでコンパイルし、これを実行することで実行ログを得る方法は非常に一般的で、プログラム開発の基本手法である（特許文献１等）。
【０００３】
また現在存在する殆どのデバッガはプログラムにデバッグ用コードを挿入することでその機能を実現している。例えばソフトウェア割り込みを発生させる命令をプログラム中に埋め込むことで、そのコードが実行されると割り込みが発生し、プログラムの実行を容易に検出することが可能となっている（特許文献2等）
プログラム実行のボトルネックを検出するために、プログラムのどの部分でどれだけ時間がかかっているか等を計測するためのプロフアイリングを行うツールも存在し、これらもプログラムの最適化工程ではしばしば利用されている。これらは、プログラムの読み込み時にプログラムに監視用のコードを挿入し、その監視用のコードが実行されることでプログラムの実行状態を監視する。
【０００４】
【特許文献１】
特開平6−314221号公報
【特許文献２】
特開平11−184727号公報
【０００５】
【発明が解決しようとする課題】
上記ログの出力コードを埋め込む方式は、実施にプログラムソースとこのコンパイル環境が必要であり、いずれかが欠けても実現不可能である。デバッガはプログラム開発時に利用することを念頭に開発されており、実行時に少ない負荷で利用することが難しい上、インタプリタのプログラム実行環境では使用できない。
また、プロフアイリングを行うツールでは、監視コードをプログラムの動作に影響を極力与えずに挿入するには、複雑な処理が必要となる（例えば、引数の監視を行うためにはスタックの操作が必要となる等）。本発明では、システムの運用時においても利用可能な低負荷で、容易に適用可能なプログラムヘの監視用コードの挿入方法を提案する。
【０００６】
【発明を解決するための手段】
上記の課題を解決するために、複数の関数を含むプログラムを格納するプログラム記憶部と、該記憶部からプログラムを読み出して実行するプログラム実行部とを備えるコンピュータでプログラムを実行するに際し、記憶部から読み出したプログラムの関数が監視対象の関数であるかを判定し、監視対象の関数に対して監視処理が施されるように当該プログラムに監視コードを挿入する。
【０００７】
このときに、監視コードを、監視する関数の先頭と、関数からの復帰をおこなう命令の直前に挿入しておく。監視コードを挿入された関数を、プログラムの実行部が実行することにより監視コードが実行されて関数実行の状況がわかるようになる。
【０００８】
また、監視対象の関数を呼び出すためのアドレスあるいは関数の名称を変更し、名称の変更された関数を呼び出す命令を含む監視用関数と前述した監視コードとからなる監視用関数を生成し、プログラムに前記監視用関数を挿入するようにしてもよい。
【０００９】
この場合にユーザが任意に作成した監視コードを、一旦コンパイラでコンパイルし、これを変形して監視用関数とすれば、ユーザの作成した任意のコードを監視コードとして使用することが出来るため、自由度の高い実行監視を実現できる。
【００１０】
【発明の実施の形態】
以下、図面を用いて本発明の実施例を説明する。なお、本発明が実施例に限定されるものではない。
【００１１】
図1は本発明の一実施例の全体構成を示す。本発明は、コンピュータ上で動作するプログラム実行部10が、プログラム格納部20に格納されたプログラムファイル50を読込み実行する一般的なプログラム実行装置に、監視命令挿入部11と監視命令挿入制御ファイル30、監視プログラム60を更に備える構成からなる。
【００１２】
プログラム実行部10は、インタプリタ実行系と機械語を実行する通常の実行系とが考えられるいずれもCPUが実行主体となる。プログラム格納部20は、ディスク装置、メモリカード、磁気テープなどプログラムを記録可能な全ての装置である。監視命令挿入制御ファイル30は実行するプログラム中の関数が監視対象の関数であるかどうかを決める情報を格納する。単純なファイルで構成されてもよいが、他あるいは同一のコンピュータ上で動作する別のプログラムであってもよい。
【００１３】
プログラム実行装置は、プログラム実行部10、プログラム格納部20のほかに、プログラム実行部10が実行するプログラム格納部等から読み出したプログラムやデータを一時格納するワークメモリ12、プログラムの実行等の指示を操作者が装置へ入力するための入力装置13、プログラムの実行経過、実行結果等を可視出力するためのディスプレイ14、通信路を介した他の装置との通信を制御する通信制御部15、監視プログラム、監視命令挿入制御ファイル等のデータがCD−ROM等の記憶媒体に格納されて取引される場合に、記憶媒体の内容を読み取ってプログラム格納部20ヘインストールするための媒体読み取り装置16を備え、それぞれが内部バスブリッジ17で接続される。なお、図中のバスブリッジ17はワークメモリ、入力装置、ディスプレイ等とのインターフェースコントローラも兼ねている。
【００１４】
図2はプログラムファイル50の構成を示す。プログラムファイル50は任意個の関数510を持つ。関数は1つあるいは複数の実行コード520で構成される。実行コード520としては、通常のプログラム実行系では機械語が考えられ、インタブリタ実行系では中間コード（バイトコードとも呼ばれる）が考えられる。プログラムファイル50には関数テーブル530を持つ。関数テーブル530は関数がプログラムファイルのうちどの部分を構成しているか、どのような属性を持っているか等の関数に関する情報を持つ。なお、図2では、関数テーブル530をプログラムファイル50の中に持たせる構造としているが、例えば一般的なコンパイラで出力されるMAPファイルのように別のファイルとして存在させてもよい。
【００１５】
図3は関数テーブルの構造の一例を示す。関数テーブル530は、インデックス531、関数名532、開始アドレス533、終了アドレス534、および属性535からなる。プログラムファイル内の関数の情報が格納される。
【００１６】
図4は本発明のプログラム実行部10がプログラムファイル50を読み込みつつ監視コードを挿入する処理を示したフローチャートである。まずプログラム実行部10はプログラムファイル50から関数を1つ読み込み監視命令挿入部11に処理を譲る（ステップ1000）。監視命令挿入部11は監視命令挿入制御ファイル30の情報を元に、それが監視対象の関数かどうかを判定し（ステップ1010）、監視対象であればその関数に監視コードを挿入し（ステップ1020）、挿入したコードの長さだけ挿入部以降の実行コードのアドレス情報および、関数テーブル530を変更し（ステップ1030）、注目している監視対象向けの監視コードを全て挿入するまでステップ1020と1030を繰り返した後、その関数をプログラム実行部10に渡す（ステップ1040）。これを全ての関数について行う（ステップ1050）。プログラム実行部10はステップ1040で監視命令挿入部11から渡された関数を並行して実行する。
【００１７】
図5は図4で示した監視コードの挿入方法によって監視コードが挿入された関数の構成を示した図である。図の上側が先に実行され、順番に下の命令が実行される。本方式ではまず関数の先頭部分に監視コード530を埋め込み、次に実行コードのうち関数終了のコード、つまりこのコードを実行することで関数を呼び出した箇所に戻るコード521、の直前に監視コード531を挿入する。
【００１８】
プログラム実行部10は監視命令挿入部11によって監視コードが上記の通り挿入されたプログラムファイルを順次実行するので、関数に実行が移った直後と終了直前に監視コードを実行することになり、当該関数の実行時間、実行回数および呼出時に渡された引数などを監視することが可能となる。
【００１９】
なお、監視コードは、それ自体が複数の実行コードで実装されたモジュールであってもよいし、他の監視コードライブラリを呼び出す関数呼出コードであってもよいし、機械語実行の場合ではソフトウェア割り込みを発生させるようなコードでもよい。監視コードの動作としては、外部のハードウェアの制御、ログの出力、変数の値の変更等が例として考えられる。また、監視コードは関数実行時のみ、あるいは関数実行終了前のいずれかに挿入するだけでも良い。
【００２０】
次に図6を用いて監視コード挿入方式の他の例を説明する。この方法では、まず監視する関数（例えばここでは関数A）（610）をプログラム実行上において別の関数に見えるように変更する（615）。これは例えば関数をアドレスで呼び出す実行方式であれば、関数テーブルを（620）を参照して、利用可能な別のアドレスに関数を移動する方式が考えられる。インタブリタ言語で多く採用されている、関数テーブル（620）へのインデックスを指定して関数を呼び出す実行方式であれば、関数テーブル（620）に新たにエントリを追加して、別の名前を付け、その他の情報については元の情報をコピーすることで実現できる。次に、従来の関数Aとして呼び出した場合に呼び出されるスタブ関数（611）を挿入する。このスタプ関数（611）には改名された関数Aを呼び出すコード（613）を記述する。これにより、関数A（610）の呼出は、一旦スタブ関数（611）を経由してから「改名された関数A」（620）を呼び出すことになる。この際に、スタブ関数（611）の改名された関数Aの呼出コード（613）の前に監視コード（612）が存在すれば、改名された関数A（615）に先だって監視コード（612）の内容が実行され、同様に後ろの監視コード（614）は改名された関数A（615）の実行の後で呼び出されることになる。この監視コード中で、関数Aに渡されるはずである引数の値の監視や変更をしたり、関数Aからの戻り値を監視及び変更することも可能となる。
【００２１】
図7は図6で示した方式の監視コード挿入処理のフローチャートである。図4で説明した処理と異なるのはステップ1015の部分だけであるので、その部分だけを抜き出して説明する。本フローではプログラム実行部10の関数の呼出方式が、関数テーブル530のインデックス531を使用して関数を実行する場合について説明する。読み込んだ関数を別名の関数にするために、ます関数テーブルにエントリを新規に作成する（ステップ2000）。次にその新規作成したエントリに図4のステップ1000で読み込んだ関数を、プログラム中で別の関数として見えるように登録する（ステップ2010）。次に、監視用のスタブ関数を挿入し（ステップ2020）、このスタプ関数からステップ2010で操作した監視対象の関数の呼出をするコードを挿入し（ステップ2030）、監視コードも挿入する（ステップ2040）。最後に、ステップ2020で挿入したスタブ関数が監視対象として機能するように関数テーブルを変更する。
【００２２】
このような処理を行うことで、ステップ2020で挿入したスタブ関数を経由して監視対象の関数の実行を監視することが可能となる。
【００２３】
図7のステップ2020から2040ではスタブ関数をプログラム的に生成した．この場合、利用者が監視コードの振る舞いを細かく制御するためには監視命令挿入部11にこれに対応する機能を実装する必要がある。一方、監視対象のスタブ関数に利用者が記述したコードを利用すればこれを変形して挿入するだけでよい。任意の監視コード挿入を容易に実現できる。
【００２４】
この手順について図8のフローを用いて説明する。図7で示した処理と異なるのはステップ2015の部分だけであるので、その部分だけを抜き出して説明する。まず、監視対象の関数の呼出規約を取得する（ステップ3000）。呼出規約とは、関数がどのような引数、返値を持つかなど、関数を呼び出す際に必要な規約である。次に得られた呼出規約を元に、スタブ関数のソースコードを生成する（ステップ3010）。これはファイルに出力しても良いし、GUI上にウィンドウを生成して出力しても良い。使用者はこのソースを必要に応じて修正し（ステップ3020）、ソースをコンパイルする（ステップ3030）。コンパイルのタイミングは、監視命令挿入部11が使用者による変更を検出して行っても良いし、使用者が行っても良い。コンパイルが終了したらコンパイルされたコードからスタブ関数として作成、コンパイルして部分を抽出しこれをスタブ関数として挿入する（ステップ3040）。最後に挿入したスタブ関数ゐ内容がプログラム実行に矛盾しないかをチェックして、必要なら修正する（ステップ3050）
前述した手順ではスタブのソース出力（ステップ3010）からソースのコンパイル（ステップ3030）を挿入時に行うように記したが、この処理を利用者がプログラム実行の前にあらかじめ行っておき、どの監視コードを挿入するかという情報を監視命令挿入制御部30から取得して、挿入時にはステップ3040,3050の処理だけを行うことで、高速化する方法も考えられる。あるいは、ステップ3000から3030までの処理を行う部分だけを別のプログラムとして実装することも可能である。
【００２５】
また、前述の実施例では、１つの監視対象の関数に対して様々な種類の監視操作を行う場合に、１つのスタブ関数にそれらの複数の処理を既述するように既述した。次に一つの監視対象関数に対して、複数の監視コードを挿入する方式について説明する。
【００２６】
図９にこの方式の概要を示した。図６に監視コードの挿入方法を図示したが、これは、スタブ関数を１つ使用する方式し、その中に監視コードを実装する方式である。一方、図９で示したのは、複数のスタブ関数としてスタブ関数Ｂと、スタブ関数Ｃの複数の関数を挿入する方法である（図９では２つの関数を挿入する例を示した）。この状態ではＡに改名されたスタブ関数Ｃ(700)を呼び出すと、まず監視コードＺ(612)が実行され、スタブ関数Ｂの呼出(704)が起こる。さらに、スタブ関数Ｂ(701)は改名された関数Ａを呼び出し(705)、終了後に監視コードＹ(703)を実行する。このような構成でスタブ関数を入れ子で呼び出すことで複数の監視コードを１つの呼出で実行できる。
【００２７】
図１０にはこの関数Ａに対して、どのスタブ関数を挿入するかを監視命令挿入制御部30に入力するテーブルの例である。この図では、監視対象の関数(801)と、挿入する関数の対応(802)が一行になっており、同一の監視対象関数に対して、複数の関数を挿入することが可能である。図では、関数Ａに対して、スタブ関数Ｂとスタブ関数Ｃを挿入する場合の例を示した。この行の既述順序が挿入順、呼出順に反映するように実装することで、監視の精度を高めることが出来る。例えば、関数の実行時間の測定は出来るだけ監視対象の直前で行う必要があり、このような利用者の意図を反映できることで、監視の精度を高めることが可能となる。
【００２８】
挿入処理は、一旦、監視対象の関数名に改名されたスタブを次の処理では監視対象と見なすことで、図４と図８のフローチャートがそのまま適用可能である。
【００２９】
上記実施例では、ソースを生成してコンパイルする方法を示したが、より容易な方法として、例えばアセンブラ言語を使用してアセンブラで実行可能形式に変換してもよい。また、機械語あるいはインタブリタのバイトコードをユーザが入力し、このコードで監視実行する方式も考えられる。
【００３０】
【発明の効果】
本発明によれば、監視するプログラムのソースコードやコンパイル作業をすることなくプログラム中の特定のあるいは全ての関数の実行を監視することができる。本発明を用いて（監視の必要な）特定の関数にだけ監視コードを挿入する場合には他の関数実行に負荷をかけずに監視を行うことができる。スタブ関数を挿入する方式を採用した場合には利用者の記述した任意の監視コードを挿入することができ、自由度の高い実行監視が可能となる。
【図面の簡単な説明】
【図１】本発明の一実施例における全体構成を示すブロック図。
【図２】プログラムファイルの構成を示す図。
【図３】関数テーブルの構成を示す図。
【図４】監視コード挿入の手順を示したフローチャート。
【図５】監視コードが挿入された関数の構成を示す図。
【図６】監視コード挿入の他の例を説明する図。
【図７】スタブ関数挿入方式による監視コード導入の手順を示すフローチャート
【図８】スタブ関数挿入方式による他の例の手順を示すフローチャート。
【図９】複数のスタブ関数を使用する場合の構成を示す図。
【図１０】複数のスタブ関数を使用する場合の挿入順序指定方式を示す図。
【符号の説明】
10…プログラム実行部、11・‥監視命令挿入部、20…プログラム格納部、30…監視命令挿入制御部、41‥・監視コード、50・・・プログラムファイル、510…関数、520…実行コード、530…関数テーブル。
【図１】
2004164554.tif 000003
【図２】
2004164554.tif 000004
【図３】
2004164554.tif 000005
【図４】
2004164554.tif 000006
【図５】
2004164554.tif 000007
【図６】
2004164554.tif 000008
【図７】
2004164554.tif 000009
【図８】
2004164554.tif 000010
【図９】
2004164554.tif 000011
【図１０】
2004164554.tif 000012