(57)【要約】【課題】マルチプロセッサシステムにおいて発生する問題を改修のための適切な情報を収集できるようにする。【解決手段】複数のＣＰＵを搭載したコンピュータシステムに、プログラムの実行中にレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイントを、そのプログラム内において順次設定する収集ポイント設定部１０４と、設定された取得ポイントにおいて取得処理を行うプログラム情報収集部１０７と、アクセスがあるごとにインクリメントしたカウント値を出力するカウンタ部１７と、取得処理のたびに、カウンタ部１７からカウント値を取得するカウント値取得部１０１と、取得されたプログラム情報を、対応するカウント値とともに出力して保存する履歴情報出力手段１１０と、を設けておく。【選択図】図５
2008123438.tif 000002
【特許請求の範囲】
【請求項１】
複数のＣＰＵを搭載したコンピュータシステムであって、
プログラムの実行中に前記ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイントを、当該プログラム内において順次設定する取得ポイント設定手段と、
前記プログラムの処理が前記取得ポイントの箇所に来るごとに、前記取得処理を行うプログラム情報取得手段と、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタと、
前記プログラム情報取得手段によって前記取得処理が行われるごとに、前記カウンタにアクセスして前記カウント値を取得するカウント値取得手段と、
前記取得処理で取得された前記プログラム情報を、前記カウント値取得手段によって取得された当該プログラム情報に対応する前記カウント値とともに保存するプログラム情報保存手段と、
を有することを特徴とするコンピュータシステム。
【請求項２】
前記プログラム情報取得手段および前記カウント値取得手段は、それぞれ、前記ＣＰＵごとに設けられており、
前記カウンタは、前記ＣＰＵごとに設けられた前記各カウント値取得手段から共通にアクセスされるように設けられており、
前記プログラム情報取得手段は、それぞれに対応する前記ＣＰＵから前記レジスタ値を取得する、
請求項１記載のコンピュータシステム。
【請求項３】
ユーザから指定される、前記プログラム情報の取得対象を受け付ける取得対象受付手段と、
前記取得対象受付手段が受け付けた前記取得対象が関数であった場合に、当該関数内において前記取得ポイントを順次設定する関数内設定手段と、
を有する請求項１または２記載のコンピュータシステム。
【請求項４】
複数のＣＰＵを搭載したコンピュータシステムであって、
プログラムの実行中に所定のデータがアクセスされる際に当該プログラムをブレークさせるための設定を行うブレーク設定手段と、
前記プログラムの実行中にブレークが発生したときに、前記ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理を行うプログラム情報取得手段と、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタと、
前記プログラム情報取得手段によって前記取得処理が行われるごとに、前記カウンタにアクセスして前記カウント値を取得するカウント値取得手段と、
前記取得処理で取得された前記プログラム情報を、前記カウント値取得手段によって取得された当該プログラム情報に対応する前記カウント値とともに保存するプログラム情報保存手段と、
を有することを特徴とするコンピュータシステム。
【請求項５】
複数のＣＰＵを搭載したコンピュータシステムでのプログラムの実行中に当該ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイントを、当該プログラムに対して設定する第１ステップと、
前記プログラムの処理が前記取得ポイントの箇所に来たときに前記取得処理を行う第２ステップと、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタに、前記取得ポイントにおいて前記取得処理が行われたときにアクセスして、前記カウント値を取得する第３ステップと、
前記取得処理で取得された前記プログラム情報を、前記第３ステップで取得された当該プログラム情報に対応する前記カウント値とともに保存する第４ステップとを有し、
前記第１ステップの処理によって前記プログラム内に順次設定される前記各取得ポイントについて、前記第２ステップ、前記第３ステップ、および前記第４ステップの処理を行う、
ことを特徴とするプログラム情報収集方法。
【請求項６】
複数のＣＰＵを搭載したコンピュータに、
プログラムの実行中に当該ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイントを、当該プログラムに対して設定する第１ステップと、
前記プログラムの処理が前記取得ポイントの箇所に来たときに前記取得処理を行う第２ステップと、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタに、前記取得ポイントにおいて前記取得処理が行われたときにアクセスして、前記カウント値を取得する第３ステップと、
前記取得処理で取得された前記プログラム情報を、前記第３ステップで取得された当該プログラム情報に対応する前記カウント値とともに保存する第４ステップと、を実行させ、
その際に、
前記第１ステップの処理によって前記プログラム内に順次設定される前記各取得ポイントについて、前記第２ステップ、前記第３ステップ、および前記第４ステップの処理を実行させる、
ことを特徴とするコンピュータプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、複数のＣＰＵを搭載したコンピュータにおいて発生した問題についての解析に用いるプログラム情報を収集するための方法などに関する。
【背景技術】
【０００２】
汎用サーバなどのサーバ機で発生した問題を改修する場合、一般に、問題の発生時にスナップショット的に収集されたダンプ情報を基にして解析を行い、問題を再現するための再現試験を繰り返して、その原因を追究することが行われる。
【０００３】
解析に必要な情報を収集するための方法として、一般に、問題の発生時点のメモリの状態を凍結し、そのメモリの状態およびＣＰＵ（プロセッサ）の状態についての情報を収集しそれをダンプ情報として蓄積することが行われている。しかし、このようにして収集された情報は、静的な情報であるため、問題が検出された箇所は特定できるが、問題の原因となるポイントを見つけることは困難なことが多い。そこで、命令の実行の経過をたどる（トレースする）ことができる履歴情報（走行履歴情報）を収集することが求められる。そのための方法として、特許文献１のような方法が提案されている。
【０００４】
特許文献１によれば、ヘッダ領域とログデータ領域とからなるログエリアをメモリ上に割り当て、そのヘッダ領域にはログデータの取得に必要な情報を格納し、ログルーチン実行時にはそのヘッダ領域を参照してそこに格納されている情報に基づいて、ログデータ領域にログデータを取得させる。
【０００５】
ところで、現在の汎用サーバは、複数のＣＰＵが並列に命令を実行するマルチプロセッサシステムが一般的となっている。マルチプロセッサシステムでは、複数のＣＰＵで処理が競合することによってデータが破壊されるなどの問題が発生することがある。このような問題は、競合のタイミングに依存するため再現性に乏しく解析が困難である。マルチプロセッサシステムで発生する問題の原因を追究するためには十分な履歴情報を収集する必要があるが、上記のような従来の方法では、それを行うことが難しい。
【０００６】
マルチプロセッサシステムにおいて履歴情報を収集するための方法として、特許文献２のような方法が提案されている。
【０００７】
特許文献２によれば、マルチプロセッサ構成からなる監視対象マイクロプロセッサシステムの、一のマイクロプロセッサシステムが実行するプログラムのトレースを行なうトレース装置が、プログラムの各命令段階の実行の度に、各命令を実行した時刻の情報と、トレース結果情報の履歴とを記録し、その時刻の情報とトレース結果情報とを対応させて出力する。そして、その履歴を編集して出力部に表示させる。
【特許文献１】特開平８−１７１５０１号公報
【特許文献２】特開平１０−２６０８６４号公報
【発明の開示】
【発明が解決しようとする課題】
【０００８】
しかし、特許文献２によると、メモリのバスの情報をコピーして出力することでそれを履歴情報としている。すなわち、メモリのリードまたはライトのみを対象としているので、問題発生時の解析に必要な情報を収集できない場合がある。
【０００９】
また、従来、履歴情報を出力するために専用のハードウェアを用いる方法があった。しかし、この方法では、汎用サーバ向けに提供されている汎用のボードを使用している場合に、その技術の更新が早いため、ボード自体のアップグレードを頻繁に行う必要が生じ、その度に専用のハードウェアを追加しなければならなくなる。それによって、余分なコストがかかってしまう。加えて、品質的にも不安定になる危険性がある。
【００１０】
本発明は上記のような問題点に鑑み、マルチプロセッサシステムにおいて発生する問題の改修のために必要な情報を収集することを目的とする。
【課題を解決するための手段】
【００１１】
本発明に係るコンピュータシステムは、複数のＣＰＵを搭載したコンピュータシステムであって、プログラムの実行中（起動中）に前記ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイント（プログラム停止位置）を、当該プログラム内において順次設定する取得ポイント設定手段と、前記プログラムの処理が前記取得ポイントの箇所に来るごとに、前記取得処理を行うプログラム情報取得手段と、アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタと、前記プログラム情報取得手段によって前記取得処理が行われるごとに、前記カウンタにアクセスして前記カウント値を取得するカウント値取得手段と、前記取得処理で取得された前記プログラム情報を、前記カウント値取得手段によって取得された当該プログラム情報に対応する前記カウント値とともに保存するプログラム情報保存手段と、を有する。
【００１２】
好ましくは、前記プログラム情報取得手段および前記カウント値取得手段は、それぞれ、前記ＣＰＵごとに設けられており、前記カウンタは、前記ＣＰＵごとに設けられた前記各カウント値取得手段から共通にアクセスされるように設けられており、前記プログラム情報取得手段は、それぞれに対応する前記ＣＰＵから前記レジスタ値を取得する。
【００１３】
また好ましくは、ユーザから指定される、前記プログラム情報の取得対象を受け付ける取得対象受付手段と、前記取得対象受付手段が受け付けた前記取得対象が関数であった場合に、当該関数内において前記取得ポイントを順次設定する関数内設定手段と、を有する。
【００１４】
本発明に係る他の形態のコンピュータシステムは、プログラムの実行中に所定のデータがアクセスされる際に当該プログラムをブレークさせるための設定を行うブレーク設定手段と、前記プログラムの実行中にブレークが発生したときに、前記ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理を行うプログラム情報取得手段と、アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタと、前記プログラム情報取得手段によって前記取得処理が行われるごとに、前記カウンタにアクセスして前記カウント値を取得するカウント値取得手段と、前記取得処理で取得された前記プログラム情報を、前記カウント値取得手段によって取得された当該プログラム情報に対応する前記カウント値とともに保存するプログラム情報保存手段と、を有する。
【発明の効果】
【００１５】
マルチプロセッサシステムにおいて発生する問題の改修のために必要な情報を収集することができる。
【発明を実施するための最良の形態】
【００１６】
図１は本発明に係るコンピュータ１のハードウェア構成の例を示す図、図２はメモリ空間に格納されたプロセスを示す図である。
【００１７】
図１に示すようにコンピュータ１は、複数のＣＰＵ（Central Processing Unit）１１ａ，１１ｂ，…、メモリ１２、ハードディスク１３、および通信インターフェース１４を有する。コンピュータ１は、マルチプロセッサに対応したパーソナルコンピュータまたはワークステーションなどであり、例えば汎用サーバなどのサーバ機として用いられる。以下、ＣＰＵ１１ａ，１１ｂ，…について、それぞれまたは全部を「ＣＰＵ１１」と記載することがある。他の符号についても同様である。
【００１８】
ハードディスク１３には、ＯＳ（Operating System）および各種ツールなどに関する種々のプログラムがインストールされている。これらのプログラムは、その実行に際して読み出され、プロセスなどの実行単位でメモリ１２のメモリ空間に格納される。プロセスは、例えば、図２に示されるような、プロセスＩＤおよびスタック情報（プロセススタック情報）を含むプロセス構造体によって構成される。このようなプロセスが順次実行されることによって、プログラムの処理が行われる。
【００１９】
通信インターフェース１４は、ＬＡＮ、ＷＡＮ、またはインターネットなどの通信回線を介して他の装置と通信を行うためのインターフェースである。この通信インターフェース１４には、ＮＩＣ（Network Interface Card）、モデム、ＵＳＢ、その他種々のインターフェースが含まれる。
【００２０】
また、コンピュータ１には、ユーザが指令を入力するための入力装置であるキーボード２、マウス３、および表示装置であるディスプレイ４が接続されている。
【００２１】
コンピュータ１においては、ユーザが予め指定したプログラムの実行中に、リソースの使用状況などに関するログ（履歴情報）が出力され収集される。本実施形態では、ＣＰＵのレジスタに関する情報（レジスタ情報）およびメモリに保持されるプロセスに関する情報（プロセス情報）などがログとして収集される。ログを収集する対象（ログ収集対象）として、特定の関数または特定のデータを指定することも可能である。その場合は、指定された関数またはデータに関する処理においてログが出力される。以下、ログの収集に関する処理について説明する。
〔機能構成の説明〕
図３はコンピュータ１の機能的構成の例を示す図、図４はプロセス情報取得の処理を説明するための図、図５は履歴情報出力処理部１５の構成の例を示す図、図６はレジスタ情報取得の処理を説明するための図である。
【００２２】
図３に示すようにコンピュータ１は、履歴情報出力処理部１５、プロセス情報取得部１６、およびカウンタ部１７などによって構成される。
【００２３】
履歴情報出力処理部１５ａ，１５ｂ，…は、それぞれ、各ＣＰＵ１１ａ，１１ｂ，…に対応付けられて設けられている。すなわち、履歴情報出力処理部１５ａとＣＰＵ１１ａ、履歴情報出力処理部１５ｂとＣＰＵ１１ｂのように、履歴情報出力処理部１５とＣＰＵ１１とが１対１で対応付けられている。履歴情報出力処理部１５は、所定のプログラムの実行中にログを出力するための処理を行う。以下、このログを「履歴情報ＤＲ」と記載することがある。出力された履歴情報ＤＲは、メモリ１２またはハードディスク１３などの記憶装置の所定の領域に保存される。
【００２４】
プロセス情報取得部１６は、図４に示すように、メモリ空間に格納されているプロセスＩＤおよびスタック情報を取得するための処理を行う。ここで取得されたプロセスＩＤおよびスタック情報は、履歴情報出力処理部１５に出力され、履歴情報ＤＲの生成に用いられる。
【００２５】
なお、プロセスＩＤはプロセススタック上にあるプロセス構造体を参照することで収集できる。また、スタック情報を収集することで、プロセスのバックトレース情報を知ることができる。以下、これらプロセスＩＤおよびスタック情報をまとめて「プロセス情報」と記載することがある。
【００２６】
カウンタ部１７は、ログの出力をカウントするための数値（カウント値）を保持しており、履歴情報出力処理部１５からアクセスされる度に、そのカウント値を一つインクリメント（またはディクリメント）して出力する。なお、出力した後にカウント値をインクリメントするようにしてもよい。カウンタ部１７は、複数のＣＰＵ１１ａ、１１ｂ、…に対して共通に（１つだけ）設けられているので、ＣＰＵ１１に対して排他的なカウント値を出力することになる。出力されたカウント値は、履歴情報出力処理部１５において履歴情報ＤＲの生成に用いられる。
【００２７】
さて、図５に示すように履歴情報出力処理部１５は、カウント値取得部１０１、レジスタ値取得部１０２、収集対象指定受付部１０３、収集ポイント設定部１０４、収集対象関数設定部１０５、収集対象データ設定部１０６、プログラム情報収集部１０７、履歴情報生成部１０８、出力先指定受付部１０９、および履歴情報出力部１１０などによって構成される。
【００２８】
なお、図３および図５の各部の処理を実現するためのプログラムおよびデータは、ハードディスク１３にインストールされている。これらのプログラムおよびデータは必要に応じてメモリ１２に読み出され、ＣＰＵ１１によってそのプログラムが実行される。
【００２９】
カウント値取得部１０１は、カウンタ部１７にアクセスし、そこからカウント値を取得する。レジスタ値取得部１０２は、図６に示すように、対応するＣＰＵ１１のレジスタ情報としてレジスタの値（レジスタ値）を取得する。なお、「対応するＣＰＵ１１」とは、そのレジスタ値取得部１０２が属する履歴情報出力処理部１５に対応するＣＰＵ１１のことである。履歴情報出力処理部１５に含まれる他の各部についても同様に表現する。
【００３０】
収集対象指定受付部（収集対象選択部）１０３は、ログ収集対象についてのユーザから指定を受け付け、指定されたログ収集対象がプログラム、関数、またはデータのいずれであるかを判別し、その判別に応じて、指定されたログ出力対象を収集ポイント設定部１０４、収集対象関数設定部１０５、または収集対象データ設定部１０６に通知する。すなわち、プログラムが指定された場合は、収集ポイント設定部１０４に対して、そのプログラムを通知する。関数が指定された場合は、収集対象関数設定部１０５に対してその関数を通知する。データが指定された場合は、収集対象データ設定部１０６に対してそのデータを通知する。
【００３１】
収集ポイント設定部１０４、収集対象関数設定部１０５、および収集対象データ設定部１０６は、実行中のプログラムの処理を一時的に停止して履歴情報ＤＲの収集を開始する位置、すなわちログの収集の契機となる位置（以下、「プログラム停止位置」と記載することがある。）を設定する。なお、収集ポイント設定部１０４は、指定されたプログラム内において全ての履歴情報ＤＲを収集できるようにプログラム停止位置を設定する。収集対象関数設定部１０５は、指定された関数内においてプログラム停止位置を設定する。収集対象データ設定部１０６は、指定されたデータに対してプログラム停止位置を設定する。
【００３２】
プログラム情報収集部１０７は、レジスタ値取得部１０２からレジスタ値を取得し、プロセス情報取得部からプロセス情報を取得する。以下、レジスタ値およびプロセス情報をまとめて「プログラム情報」と記載することがある。
【００３３】
履歴情報生成部１０８は、プログラム情報収集部１０７が収集したプログラム情報を、必要に応じて加工し形式を変換するなどして履歴情報ＤＲを生成する。
【００３４】
生成された履歴情報ＤＲをどのような場所（出力先）にどのような方法（出力方法）で出力するのかは、予めユーザによって指定される。例えば、以下のような内容が指定される。
【００３５】
（１）メモリ空間内にデータ領域を確保しそこに出力する。
【００３６】
（２）予め設けられた標準の出力先に出力する。
【００３７】
（３）特定のファイルに出力する。
【００３８】
（４）指定したＩＰアドレス（サーバなど）へ通信回線を介して送信（パケット送信）する。
【００３９】
１つの履歴情報ＤＲに対して複数の出力先を指定することも可能である。その場合は、指定された出力先のそれぞれに対してその履歴情報ＤＲが出力される。
【００４０】
出力先指定受付部（出力選択部）１０９は、履歴情報ＤＲの出力先などについてのユーザからの指定を受け付け、それを履歴情報出力部１１０に通知する。
【００４１】
履歴情報出力部（履歴保持部）１１０は、履歴情報生成部１０８が生成した履歴情報ＤＲを、出力先指定受付部１０９から通知された出力先に対して出力する。
【００４２】
以下、履歴情報ＤＲを収集する際の各部の処理を、第１の方法、第２の方法、および第３の方法に大別してさらに詳しく説明する。なお、以下において、履歴情報ＤＲの出力先として、ＣＰＵ１１ごとに設けられたメモリ１２内の領域が指定されているものとする。
〔第１の方法〕
図７は第１の方法による履歴情報ＤＲの収集の処理の流れを説明するためのフローチャート、図８はプログラム停止位置の設定の処理を説明するための図、図９は履歴情報ＤＲの例を示す図、図１０は各ＣＰＵ１１について出力された履歴情報ＤＲを示す図である。
【００４３】
履歴情報ＤＲの収集のために、ユーザは、ログ収集対象のプログラム（以下、「プログラムＰ１」と記載する。）を指定する（＃１００）。収集対象指定受付部１０３は、その指定を受け付ける。
【００４４】
プログラムＰ１の開始に先立って、収集ポイント設定部１０４は、収集対象指定受付部１０３が受け付けたユーザからの指定に基づいてプログラムＰ１に対してプログラム停止位置の設定を行う。ここで、プログラム停止位置の設定について、図８を参照して説明する。
【００４５】
図８において、メモリ１２のメモリ空間にプログラムＰ１が格納されている。プログラム停止位置の設定に際して、収集ポイント設定部１０４は、まず、プログラムＰ１の先頭アドレスを取得する（＃１０１）。図８の（ｉ）に示されるように、その先頭アドレスに格納されている命令Ｍ１を、メモリ空間内に予め用意されている命令退避用領域（データ退避領域）にコピーすることによって退避させる（＃１０２）。さらに、図８の（ｉｉ）に示されるように、プログラムＰ１の先頭アドレスの内容をトラップ命令に置き換える（＃１０３）。これによって、プログラムＰ１の先頭アドレスがプログラム停止位置として設定される。なお、命令とは、例えばプロセスなどの実行単位である。
【００４６】
プログラムＰ１の処理が開始されると、先頭アドレスに格納されたトラップ命令が実行される（＃１０４）。それによってプログラム情報収集部１０７が起動され動作を開始する。なお、トラップ命令には、例えば、プログラム情報収集部１０７を起動する旨の命令および次に処理されるべき命令（ジャンプ先）のアドレスなどが含まれている。
【００４７】
プログラム情報収集部１０７は、動作を開始すると、プログラムＰ１の処理を一時的に停止させる。そして、その時点でのプログラム情報を収集するための処理を行う（＃１０５）。
【００４８】
プログラム情報の収集に際して、プログラム情報収集部１０７は、レジスタ値取得部１０２に指示して対応するＣＰＵ１１からそのＣＰＵ１１のレジスタ情報を取得させる。また、これと並行してまたは前後して、プロセス情報取得部１６に対して、プロセス情報を取得するように指示する。そして、それらレジスタ情報およびプロセス情報を、それぞれ、レジスタ値取得部１０２およびプロセス情報取得部１６から受け取る。
【００４９】
履歴情報生成部１０８は、プログラム情報収集部１０７が収集したプログラム情報（レジスタ情報およびプロセス情報）を受け取り、それを用いて履歴情報ＤＲを生成するための処理を行う。この処理に際して、履歴情報生成部１０８は、カウント値取得部１０１に対してカウント値の取得を指示する。その指示に基づいてカウント値取得部１０１は、カウンタ部１７にアクセスしカウント値を取得する（＃１０６）。
【００５０】
このとき、カウンタ部１７は、自身で保持するカウント値を１つ増やす。これによって、次にアクセスされたときに、今回出力したカウント値よりも１大きいカウント値が出力される。すなわち、各プログラム情報に対して全体として一意となるシーケンシャルなカウント値の払い出しが行われる。
【００５１】
カウント値を取得すると、カウント値取得部１０１は、それを履歴情報生成部１０８に対して出力する。履歴情報生成部１０８は、プログラム情報収集部１０７から受け取ったプログラム情報に対して、そのカウント値を付与する。さらに、プログラム情報に示される内容を並べ替え、わかりやすくなるように冗長化し、または不要な情報を削除するなどの加工処理を必要に応じて行って、図９に示すような履歴情報ＤＲを生成する。
【００５２】
図９に示されるように、履歴情報ＤＲには、カウント値、レジスタ値、プロセスＩＤ、およびスタック情報の他、「ＣＰＵ識別情報」および「命令」などが含まれる。
【００５３】
「ＣＰＵ識別情報」には、各ＣＰＵ１１ａ，１１ｂ，…を識別するための情報が示される。なお、上の例では、命令Ｍ１を実行するＣＰＵのＣＰＵ識別情報を取得することでもよい。「命令」には、ＣＰＵが実行した命令文が示される。なお、ここでは、説明簡単のため、カウント値として図９に示すような値を用いたが、実際には、３２ビット程度の値が用いられる。
【００５４】
履歴情報出力部１１０は、対応するＣＰＵ１１に対して設けられたメモリ１２内の領域（履歴格納エリア）に、履歴情報生成部１０８が生成した履歴情報ＤＲを出力して保存する（＃１０７）。
【００５５】
この後、プログラム情報収集部１０７は、命令退避用領域に退避された命令Ｍ１を実行し（＃１０８）、実行の後は、その命令Ｍ１をメモリ空間の元のアドレス、すなわちトラップ命令が格納されているアドレスに戻す（＃１０９）。なお、この場合に、プログラム情報収集部１０７は、命令Ｍ１の実行を支援するようにしてもよい。すなわち、命令Ｍ１のアドレスをＣＰＵ１１に渡し、実際の命令Ｍ１の処理はＣＰＵ１１が実行するようにしてもよい。後に説明する〔第２の方法〕における図１１のステップ＃２０８についても同様である。
【００５６】
さらに、プログラム情報収集部１０７は、収集ポイント設定部１０４に対して、次のプログラム停止位置の設定を指示する。収集ポイント設定部１０４は、その指示に基づいて、プログラムＰ１において、命令Ｍ１の次に実行される命令（次の命令）のアドレスを求める。
【００５７】
次の命令のアドレスは、通常、命令Ｍ１が格納されているアドレスの次のアドレスとなるが、命令Ｍ１が関数呼び出しに係る命令である場合は、呼び出す先のアドレスが次の命令のアドレスとなる。分岐命令などの場合はレジスタ情報を参照して、次の命令のアドレスを求める。
【００５８】
次の命令（ここでは、「命令Ｍ２」と記載する。）のアドレスが求まると（＃１１０および＃１１１でＹｅｓ）、その命令Ｍ２を命令退避用領域に退避させ（＃１１２）、そのアドレスの内容をトラップ命令に置き換える（＃１１３）。
【００５９】
ステップ＃１１３までの処理が終了すると、プログラムＰ１の処理が続行される。そして、その処理が命令Ｍ２に差し掛かる（達する）と、ステップ＃１１３において命令Ｍ２のアドレスに格納されたトラップ命令が実行される（＃１０４）。そして、命令Ｍ２についてのステップ＃１０５からステップ＃１０９までの処理が行われる。その後、ステップ＃１１０において、さらに次の命令のアドレスが決定され、同様の処理が繰り返される。
【００６０】
以上の処理によって、図１０に示すように、ＣＰＵ１１ごとに、順次、プログラムＰ１に含まれるすべの命令についての履歴情報ＤＲが出力される。すなわち、複数のＣＰＵ１１に跨って、実行された命令を順次トレースできるプログラム走行履歴を得ることができる。
〔第２の方法〕
図１１は第２の方法による履歴情報ＤＲの収集の処理の流れを説明するためのフローチャートである。ここでは、ユーザが任意に指定した関数の実行時にのみ履歴情報ＤＲを収集する場合について説明する。なお、〔第１の方法〕において説明したものと同様の処理については詳細な説明は省略する。
【００６１】
ユーザがログ収集対象の関数（ここでは、「関数Ｋ１」と記載する。）を指定すると、収集対象指定受付部１０３は、その指定を受け付ける（＃２００）。
【００６２】
収集対象関数設定部１０５は、収集対象指定受付部１０３から関数Ｋ１の関数名を受け取り、プログラム上のシンボル情報を基にメモリ空間内でのその関数Ｋ１の開始アドレスおよび範囲を求める（＃２０１）。さらに、求めた開始アドレスに示される命令（ここでは、「命令Ｍ３」と記載する。）を命令退避用領域に退避させ（＃２０２）、その開始アドレスの内容をトラップ命令によって置き換える（＃２０３）。これによって、その開始アドレスがプログラム停止位置に設定される。
【００６３】
関数Ｋ１を含むプログラム（ここでは、「プログラムＰ２」と記載する。）が開始されその処理が関数Ｋ１に差し掛かると、関数Ｋ１の先頭アドレスに格納されたトラップ命令が実行される（＃２０４）。それによってプログラム情報収集部１０７が起動され動作を開始する。プログラム情報収集部１０７は、動作を開始すると、プログラムＰ２の処理を一時的に停止させる。そして、その時点でのプログラム情報を収集する（＃２０５）。
【００６４】
履歴情報生成部１０８は、プログラム情報収集部１０７が収集したプログラム情報を受け取り、それを用いて履歴情報ＤＲを生成するための処理を行う。この処理に際して、履歴情報生成部１０８は、カウント値取得部１０１に対してカウント値の取得を指示する。その指示に基づいてカウント値取得部１０１は、カウンタ部１７にアクセスしカウント値を取得する（＃２０６）。
【００６５】
このとき、カウンタ部１７は、自身で保持するカウント値を１つ増やす。これによって、次にアクセスされたときに、今回出力したカウント値よりも１大きいカウント値が出力される。
【００６６】
履歴情報生成部１０８は、カウント値取得部１０１が取得したカウント値およびプログラム情報収集部１０７から受け取ったプログラム情報を用いて履歴情報ＤＲを生成する。
【００６７】
履歴情報出力部１１０は、対応するＣＰＵ１１に対して設けられたメモリ１２内の領域に、履歴情報生成部１０８が生成した履歴情報ＤＲを出力して保存する（＃２０７）。
【００６８】
この後、プログラム情報収集部１０７は、命令退避用領域に格納されている命令Ｍ３を実行し（＃２０８）、その命令Ｍ３をメモリ空間の元のアドレス、すなわちトラップ命令が格納されているアドレスに戻す（＃２０９）。
【００６９】
さらに、プログラム情報収集部１０７は、収集対象関数設定部１０５に対して、次のプログラム停止位置の設定を指示する。収集対象関数設定部１０５は、その指示に基づいて、関数Ｋ１において、命令Ｍ３の次に実行される命令（次の命令）のアドレスを求める。
【００７０】
次の命令のアドレスは、通常は現在の命令のアドレスの次のアドレスであるが、分岐命令等の場合はレジスタ情報を参照し、次の命令のアドレスを求める。現在の命令が関数呼び出しの命令である場合は、関数呼び出しから復帰した際に実行されるアドレスとなる。
【００７１】
次の命令（ここでは、「命令Ｍ４」と記載する。）のアドレスが求まると（＃２１０および＃２１１でＹｅｓ）、その命令Ｍ４を命令退避用領域に退避させ（＃２１２）、そのアドレスの内容をトラップ命令に置き換える（＃２１３）。
【００７２】
ステップ＃２１３までの処理が終了すると、プログラム本体であるプログラムＰ２の処理が続行される。そして、命令Ｍ４の処理に差し掛かると、ステップ＃２１３において命令Ｍ４のアドレスに格納されたトラップ命令が実行される（＃２０４）。そして、命令Ｍ４についてのステップ＃２０５からステップ＃２０９までの処理が行われる。その後、ステップ＃２１０において、さらに次の命令のアドレスが決定され、同様の処理が繰り返される。
【００７３】
なお、関数Ｋ１が他の関数から呼び出されるものである場合は、関数Ｋ１の実行が終了し呼び出し元の関数に戻るときに、関数Ｋ１の先頭アドレスの命令を命令退避用領域に退避してトラップ命令と置き換えておく。これは、次に関数Ｋ１が動作したときにもプログラム情報収集部１０７を動作させるためである。
【００７４】
以上の処理によって、ユーザが指定した関数Ｋ１の範囲内での履歴情報ＤＲが蓄積され関数Ｋ１についての動作をトレースできる情報を得ることができる。
【００７５】
なお、第２の方法において、複数の関数をログ収集対象として指定するようにしてもよい。その場合も、履歴情報ＤＲが出力される順（命令の実行順）に、各履歴情報ＤＲに対して一意でシーケンシャルなカウント値が対応付けられるので、その履歴情報ＤＲによって、複数の関数間における命令の実行順序および実行したＣＰＵ１１を特定することができる。
〔第３の方法〕
図１２は第３の方法による履歴情報ＤＲの収集の処理の流れを説明するためのフローチャート、図１３はブレークの設定および発生の際の処理を説明するための図である。ここでは、ユーザが任意に指定したデータがアクセスされたときにのみ履歴情報ＤＲを収集する場合について説明する。なお、〔第１の方法〕および〔第２の方法〕において説明したものと同様の処理については詳細な説明は省略する。
【００７６】
ユーザがログ収集対象のデータ（ここでは、「データＤ１」と記載する。）を指定すると、収集対象指定受付部１０３は、その指定を受け付ける（＃３００）。
【００７７】
収集対象データ設定部１０６は、収集対象指定受付部１０３からデータＤ１の名前（データ名）を受け取り、図１３の（ｉ）に示すように、データＤ１に対して「リードブレーク」および「ライトブレーク」を設定する（＃３０１）。
【００７８】
「リードブレーク」とは、それが設定されたデータが読み出されようとしたときにその読み出しに係る実行中のプログラムをブレーク（中断）させる機能である。「ライトブレーク」とは、それが設定されたデータへの書き込み（更新）が行われようとしたときにその書き込みに係る実行中のプログラムをブレークさせる機能である。なお、本実施形態では、リードブレークまたはライトブレークによってブレークが発生したときにプログラム情報収集部１０７が起動され動作を開始する。または、データＤ１へのアクセスが行われたときに、収集対象データ設定部１０６が実行中のプログラムの処理を中断させ、プログラム情報収集部１０７を起動するようにしてもよい。リードブレークおよびライトブレークの設定によって、データＤ１のアドレスがプログラム停止位置に設定される。
【００７９】
プログラムの実行中に、リードブレークおよびライトブレークを設定されたデータへの読み込みまたは書き込みについてのアクセスがあると、ブレークが発生する（＃３０２）。これによって、プログラム情報収集部１０７が起動される（図１３の（ｉｉ））。
【００８０】
プログラム情報収集部１０７は、動作を開始すると、その時点でのプログラム情報を収集する（＃３０３）。
【００８１】
履歴情報生成部１０８は、プログラム情報収集部１０７が収集したプログラム情報を受け取り、それを用いて履歴情報ＤＲを生成するための処理を行う。この処理に際して、履歴情報生成部１０８は、カウント値取得部１０１に対してカウント値の取得を指示する。その指示に基づいてカウント値取得部１０１は、カウンタ部１７にアクセスしカウント値を取得する（＃３０４）。
【００８２】
このとき、カウンタ部１７は、自身で保持するカウント値を１つ増やす。これによって、次にアクセスされたときに、今回出力したカウント値よりも１大きいカウント値が出力される。
【００８３】
履歴情報生成部１０８は、カウント値が取得したカウント値およびプログラム情報収集部１０７から受け取ったプログラム情報を用いて履歴情報ＤＲを生成する。
【００８４】
履歴情報出力部１１０は、対応するＣＰＵ１１に対して設けられたメモリ１２内の領域に、履歴情報生成部１０８が生成した履歴情報ＤＲを出力して保存する（＃３０５）。
【００８５】
この後、通常どおり元のデータＤ１についての読み込みまたは書き込みの処理が行われその後の処理が続行される（＃３０６）。処理の実行中に、再びデータＤ１がアクセスされたときは、ステップ＃３０２以降の処理が行われる。
【００８６】
なお、ログ収集対象のデータを複数個指定することも可能である。その場合は、収集対象データ設定部１０６によって、それら複数のデータに対してリードブレークおよびライトブレークが設定される。そして、それらのデータのいずれかにアクセスがあったときにブレークが発生し、それによって、ステップ＃３０２以降の処理が行われる。
【００８７】
以上の処理によって、ユーザが指定したデータＤ１の参照または更新の際に履歴情報ＤＲが蓄積され、データＤ１についての処理をトレースできる情報を得ることができる。
【００８８】
なお、リードブレークまたはライトブレークのいずれを設定するのかをユーザが指定できるようにしてもよい。
【００８９】
ところで、複数のＣＰＵを有するコンピュータにおいて問題が発生した場合、その原因となる操作（または処理）を追求するために、ＣＰＵごとにプログラム走行履歴を収集し、実行された命令を複数のＣＰＵに跨って時系列にトレースする必要がある。
【００９０】
本実施形態によれば、問題が発生した際の解析（障害解析）に有効なプログラム情報（レジスタ情報およびプロセス情報）が出力される。また、ＣＰＵ１１ごとに履歴情報出力処理部１５が設けられかつ全てのＣＰＵ１１に対して１つのカウンタ部１７が設けられていることによって、出力される各プログラム情報に対して一意でシーケンシャルなカウント値が付与される。これによって、プログラム情報が実行命令単位の時系列な履歴情報として蓄積される。すなわち、命令の実行順序および実行したＣＰＵ１１を特定できる情報を収集することができる。
【００９１】
発生した問題の解析の際にキーとなる情報（関数およびデータなど）は、既存のダンプファイルの内容から事前に想定できている場合がある。そのような場合、実行された全ての命令についてプログラム情報を収集すると、解析に無関係であることが既に分かっている情報まで出力されることになり、それによってメモリ領域（リソース）が無駄に消費されてしまう。また、真に解析に必要な情報が紛れてしまうことによって、解析の作業に支障をきたしてしまう恐れがある。
【００９２】
収集する情報の量を削減するために、タイマなどを使用し、一定の時間間隔で収集を行うことも考えられる。しかし、この方法では、収集が行われるべき時点で収集が行われずに必要な情報が欠落してしまうことがある。そうすると、解析の作業に支障をきたしてしまう。
【００９３】
上述の第２または第３の方法によると、解析のためにプログラム情報の収集が必要な関数またはデータが予めユーザによって指定され、その関数内の各命令またはそのデータの単位でプログラム情報が収集される。このように必要な部分のみについてのプログラム情報を収集することによって、解析に必要な情報を収集しつつ無駄にリソースが消費されることを防止できる。また、効率的なトレースが可能となる。
【００９４】
また、本実施形態によれば、ユーザ自らが、履歴情報ＤＲの出力先として、高速なメディア、大容量のメディア、または通信回線（ネットワーク）を介した他の装置のメディアなど、ユーザ環境のことなる種々の場所（記録エリア）を指定できる。よって、リソースの使用状況などに応じた適切な場所に履歴情報ＤＲを出力することができ、利便性が向上する。
【００９５】
さらに、本実施形態によれば、問題発生時の解析に必要な情報の収集をソフトウェアによって実現できるので、特別なハードウェアを追加する必要がなく、コストを抑えることができる。
【００９６】
すなわち、本実施形態によれば、問題発生時の解析の作業を飛躍的に効率化でき、原因の解明が不可能であった問題について解明できる可能性を高くできる。更に、収集する情報を絞り込むことで、高速化かつ効率化を実現でき、加えて、解析作業の効率をも向上できる。
【００９７】
図１４は第１から第３の方法を併用した場合のプログラム停止位置の設定の処理を説明するための図、図１５は他の例による履歴情報の収集の処理の流れを説明するためのフローチャートである。
【００９８】
本実施形態においては、第１の方法、第２の方法、および第３の方法を個々に行う場合について説明したが、これらを併用することも可能である。すなわち、ログ収集対象としてプログラムＰ４、関数Ｋ２、およびデータＤ２が指定された場合は、図１４に示すように、収集ポイント設定部１０４によってプログラムＰ４および関数Ｋ２の先頭アドレスにトラップ命令が格納され、データ２に対してリードブレークおよびライトブレークが設定される。そして、プログラムＰ４の先頭アドレスに格納されたトラップ命令の実行を契機として第１の方法による履歴情報ＤＲの収集が行われる。関数Ｋ２の先頭アドレスに格納されたトラップ命令の実行を契機として第２の方法による履歴情報ＤＲの収集が行われる。また、データＤ２へのアクセスを契機として第３の方法による履歴情報ＤＲの収集が行われる。
【００９９】
本実施形態では、コンピュータ１として複数のＣＰＵを有するものを用いたが、単一のＣＰＵを有するコンピュータを用いてもよい。その場合は、履歴情報出力処理部１５を１つだけ設けておけばよい。
【０１００】
また、カウント値を履歴情報ＤＲに含めるのではなく、履歴情報ＤＲとともに指定の出力先に出力して保存するようにしてもよい。
【０１０１】
第１の方法および第２の方法において、ユーザなどによって予め指定された命令についてのみプログラム停止位置を設定するようにし、それによって、指定された命令についての履歴情報ＤＲだけを収集するようにしてもよい。
【０１０２】
または、次のようにして履歴情報ＤＲを収集してもよい。予め履歴情報ＤＲの収集対象とする全ての命令を命令退避用領域に退避させて（図１５（ａ）の＃４００）、それぞれをトラップ命令に置き換えておく（＃４０１）。そして、プログラムが開始されたら（図１５（ｂ）の＃５００）、ステップ＃４０１において置き換えられた各トラップ命令の箇所において履歴情報ＤＲを収集するための処理、すなわち図７のステップ＃１０４からステップ＃１０９までの処理または図１１のステップ＃２０４からステップ＃２０９までの処理を実行するようにする。なお、図１５（ａ）に示す各ステップについては、ユーザ自らが手動で行うようにしてもよい。
【０１０３】
本実施形態では、第１の方法および第２の方法において、ある命令についての履歴情報ＤＲの収集が行われた後に次の命令についてのプログラム停止位置の設定を行ったが、プログラム停止位置の設定を、履歴情報ＤＲを収集する対象となる全ての命令に対して予め行っておくようにしてもよい。
【０１０４】
なお、履歴情報ＤＲを生成することによって履歴の管理を支援する履歴情報生成部１０８を「履歴管理部」と呼ぶことができる。履歴についてのデータを一旦保持し、出力する履歴情報出力部１１０を「履歴保持部」と呼ぶことができる。
【０１０５】
その他、コンピュータ１の各部の構成、機能、各データが示す内容、処理の内容または順序などは、本発明の趣旨に沿って適宜変更することができる。
【０１０６】
上に述べた実施例には、以下に述べるような付記も開示されている。
（付記１）
複数のＣＰＵを搭載したコンピュータシステムであって、
プログラムの実行中に前記ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイントを、当該プログラム内において順次設定する取得ポイント設定手段と、
前記プログラムの処理が前記取得ポイントの箇所に来るごとに、前記取得処理を行うプログラム情報取得手段と、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタと、
前記プログラム情報取得手段によって前記取得処理が行われるごとに、前記カウンタにアクセスして前記カウント値を取得するカウント値取得手段と、
前記取得処理で取得された前記プログラム情報を、前記カウント値取得手段によって取得された当該プログラム情報に対応する前記カウント値とともに保存するプログラム情報保存手段と、
を有することを特徴とするコンピュータシステム。
（付記２）
前記プログラム情報取得手段および前記カウント値取得手段は、それぞれ、前記ＣＰＵごとに設けられており、
前記カウンタは、前記ＣＰＵごとに設けられた前記各カウント値取得手段から共通にアクセスされるように設けられており、
前記プログラム情報取得手段は、それぞれに対応する前記ＣＰＵから前記レジスタ値を取得する、
付記１記載のコンピュータシステム。
（付記３）
ユーザから指定される、前記プログラム情報の取得対象を受け付ける取得対象受付手段と、
前記取得対象受付手段が受け付けた前記取得対象が関数であった場合に、当該関数内において前記取得ポイントを順次設定する関数内設定手段と、
を有する付記１または２記載のコンピュータシステム。
（付記４）
前記取得対象受付手段が受け付けた前記取得対象がデータであった場合に、前記プログラムの実行中に当該データがアクセスされる際に当該プログラムをブレークさせるための設定を行うブレーク設定手段を有し、
前記プログラム情報取得手段は、前記プログラムの実行中にブレークが発生したときに前記取得処理を行う、
付記３記載のコンピュータシステム。
（付記５）
ユーザから指定される、前記プログラム情報の保存先を受け付ける保存先受付手段を有し、
前記プログラム情報保存手段は、前記保存先受付手段が受け付けた保存先に前記プログラム情報を保存する、
付記１ないし４のいずれかに記載のコンピュータシステム。
（付記６）
複数のＣＰＵを搭載したコンピュータシステムであって、
プログラムの実行中に所定のデータがアクセスされる際に当該プログラムをブレークさせるための設定を行うブレーク設定手段と、
前記プログラムの実行中にブレークが発生したときに、前記ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理を行うプログラム情報取得手段と、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタと、
前記プログラム情報取得手段によって前記取得処理が行われるごとに、前記カウンタにアクセスして前記カウント値を取得するカウント値取得手段と、
前記取得処理で取得された前記プログラム情報を、前記カウント値取得手段によって取得された当該プログラム情報に対応する前記カウント値とともに保存するプログラム情報保存手段と、
を有することを特徴とするコンピュータシステム。
（付記７）
複数のＣＰＵを搭載したコンピュータシステムでのプログラムの実行中に当該ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイントを、当該プログラムに対して設定する第１ステップと、
前記プログラムの処理が前記取得ポイントの箇所に来たときに前記取得処理を行う第２ステップと、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタに、前記取得ポイントにおいて前記取得処理が行われたときにアクセスして、前記カウント値を取得する第３ステップと、
前記取得処理で取得された前記プログラム情報を、前記第３ステップで取得された当該プログラム情報に対応する前記カウント値とともに保存する第４ステップとを有し、
前記第１ステップの処理によって前記プログラム内に順次設定される前記各取得ポイントについて、前記第２ステップ、前記第３ステップ、および前記第４ステップの処理を行う、
ことを特徴とするプログラム情報収集方法。
（付記８）
複数のＣＰＵを搭載したコンピュータに、
プログラムの実行中に当該ＣＰＵのレジスタ値およびプロセス情報を含むプログラム情報を取得する取得処理の開始の契機となる取得ポイントを、当該プログラムに対して設定する第１ステップと、
前記プログラムの処理が前記取得ポイントの箇所に来たときに前記取得処理を行う第２ステップと、
アクセスがあるごとにインクリメントしまたはディクリメントしたカウント値を出力するカウンタに、前記取得ポイントにおいて前記取得処理が行われたときにアクセスして、前記カウント値を取得する第３ステップと、
前記取得処理で取得された前記プログラム情報を、前記第３ステップで取得された当該プログラム情報に対応する前記カウント値とともに保存する第４ステップと、を実行させ、
その際に、
前記第１ステップの処理によって前記プログラム内に順次設定される前記各取得ポイントについて、前記第２ステップ、前記第３ステップ、および前記第４ステップの処理を実行させる、
ことを特徴とするコンピュータプログラム。
【図面の簡単な説明】
【０１０７】
【図１】本発明に係るコンピュータのハードウェア構成の例を示す図である。
【図２】メモリ空間に格納されたプロセスを示す図である。
【図３】コンピュータの機能的構成の例を示す図である。
【図４】プロセス情報取得の処理を説明するための図である。
【図５】履歴情報出力処理部の構成の例を示す図である。
【図６】レジスタ情報取得の処理を説明するための図である。
【図７】第１の方法による履歴情報の収集の処理の流れを説明するためのフローチャートである。
【図８】プログラム停止位置の設定の処理を説明するための図である。
【図９】履歴情報の例を示す図である。
【図１０】各ＣＰＵについて出力された履歴情報を示す図である。
【図１１】第２の方法による履歴情報の収集の処理の流れを説明するためのフローチャートである。
【図１２】第３の方法による履歴情報の収集の処理の流れを説明するためのフローチャートである。
【図１３】ブレークの設定および発生の際の処理を説明するための図である。
【図１４】第１から第３の方法を併用した場合のプログラム停止位置の設定の処理を説明するための図である。
【図１５】他の例による履歴情報の収集の処理の流れを説明するためのフローチャートである。
【符号の説明】
【０１０８】
１  コンピュータ（コンピュータシステム、コンピュータ）
１１  ＣＰＵ
１７  カウンタ部（カウンタ）
１０１  カウント値取得部（カウント値取得手段）
１０３  収集対象指定受付部（取得対象受付手段）
１０４  収集ポイント設定部（取得ポイント設定手段）
１０５  収集対象関数設定部（取得ポイント設定手段、関数内設定手段）
１０６  収集対象データ設定部（ブレーク設定手段）
１０７  プログラム情報収集部（プログラム情報取得手段）
１１０  履歴情報出力部（プログラム情報保存手段）
Ｄ１、Ｄ２  データ（取得対象）
Ｋ１、Ｋ２  関数（プログラム、取得対象）
Ｐ１、Ｐ２  プログラム（取得対象）
【図１】
2008123438.tif 000003
【図２】
2008123438.tif 000004
【図３】
2008123438.tif 000005
【図４】
2008123438.tif 000006
【図５】
2008123438.tif 000007
【図６】
2008123438.tif 000008
【図７】
2008123438.tif 000009
【図８】
2008123438.tif 000010
【図９】
2008123438.tif 000011
【図１０】
2008123438.tif 000012
【図１１】
2008123438.tif 000013
【図１２】
2008123438.tif 000014
【図１３】
2008123438.tif 000015
【図１４】
2008123438.tif 000016
【図１５】
2008123438.tif 000017