プログラム診断装置及びプログラム診断方法ならびにそのプログラム
【課題】プログラムのソースコードの記述を改変することなく、また精度良く、競合状態を発生させる命令コードの検出および修正をプログラムの製作者が容易に行うことが可能となるプログラム診断装置を提供する。
【解決手段】上述の処理によれば、Java(登録商標)言語のソースコードから中間コードを生成し、その中間コードから、メモリ参照/書き込みを示す命令コードを検出する。そして、その命令コードの仮実行において、操作する変数がアンロック状態で実行される命令コードであると判定した場合には、その命令コードが記述されているソースコードの位置を画面に表示する。
【解決手段】上述の処理によれば、Java(登録商標)言語のソースコードから中間コードを生成し、その中間コードから、メモリ参照/書き込みを示す命令コードを検出する。そして、その命令コードの仮実行において、操作する変数がアンロック状態で実行される命令コードであると判定した場合には、その命令コードが記述されているソースコードの位置を画面に表示する。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態を、プログラムソースコード中から検出するプログラム診断装置及びプログラム診断方法ならびにそのプログラムに関する。
【背景技術】
【0002】
従来、コンピュータシステムにおいては排他制御という技術が利用されている。ここで、排他制御を行わない場合の預金管理システムと、排他制御を行う場合の預金管理システムとについて、具体例を用いて説明する。まず、排他制御を行わない預金管理システムにおいて、入金プログラムが、50,000円(共有変数)の預金残高へ、30,000円を入金処理し、80,000円を預金金額として登録する場合を例に説明する。ここで、入金プログラムと出金プログラムとが同タイミングに実行された場合、出金プログラムは、入金プログラムが処理を行っている間に、預金残高50,000円を読み取り、その預金残高から10,000円を出金処理した40,000円を計算し、入金プログラムの処理完了後に、40,000円の金額の情報を預金金額へ登録する可能性がある。このような場合、預金残高は入金プログラムの処理を反映していない40,000円と記録されてしまい、50,000円(預金残高)+30,000(入金金額)−10,000(出金金額)=70,000円で算出されるような正確な金額とならない。このようなプログラムの競合状態を回避するためには、排他制御を行う必要がある。つまり、共有変数に対して入金プログラムが実行されている間は共有変数をロックし、共有変数に対する出金プログラムの処理をロック(実行させないよう処理)し、これにより、預金残高が正確な値の70,000円となるよう制御する必要がある。
【0003】
同様に、インターネットに接続されたウェブサーバの処理でも競合状態が発生する。図19で示す図はウェブサーバにおける競合状態を示す図である。この図が示すように、クライアント端末Aを利用するユーザAと、クライアント端末Bを利用するユーザBが同時にウェブサーバにアクセスしている状態において、クライアントAからの処理を制御するプログラムとクライアントBからの処理を制御するプログラムが競合した場合、クライアント端末Aに対して、クライアント端末Bへ送信するウェブページを送信してしまう可能性がある。そして、これらの競合状態がウェブサーバのプログラムで発生しないかどうかのプログラム診断を行なう技術が特許文献1に開示されている。
【特許文献1】特開2007−257397号公報
【発明の開示】
【発明が解決しようとする課題】
【0004】
ここで、上述の特許文献1の技術では、平行・並列動作を行なうプログラム中で共有変数の読み込み処理と、共有変数の書き込み処理とを検出し、共有変数の読み込み処理における当該共有変数の値と、共有変数の書き込み処理の直前における共有変数の値を比較する。そしてその比較において値が一致しない場合に競合状態であると検出して、その競合状態が発生するプログラム中の箇所にassert文を追加したソースコードを出力している。しかしながら、特許文献1の技術では、仮想マシンの動的解析によって、競合状態が発生したかどうかを検出できるものの、プログラムにおいて競合状態が発生しないように修正しなければならない場合、そのプログラムの記述位置を特定することができない。またプログラムのソースコードにassert文を追加するため、プログラム自体を改変してしまうこととなる。さらに、特許文献1の技術では、仮想マシンの動的解析中に競合状態が発生しなければ、それを検出することができないという問題がある。
【0005】
そこでこの発明は、プログラムのソースコードの記述を改変することなく、また精度良く、競合状態を発生させる命令コードの検出および修正をプログラムの製作者が容易に行うことが可能となるプログラム診断装置及びプログラム診断方法ならびにそのプログラムを提供することを目的としている。
【課題を解決するための手段】
【0006】
上記目的を達成するために、本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置であって、前記プログラムの入力を受け付けるプログラム入力受付手段と、前記プログラムの中間コードを生成する中間コード生成手段と、前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段と、を備えることを特徴とするプログラム診断装置である。
【0007】
また本発明は、上述のプログラム診断装置において、前記検出した命令コードが記述されている前記プログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示する検出命令コード位置表示手段と、を備えることを特徴とする。
【0008】
また本発明は、上述のプログラム診断装置において、前記中間コードに記述されている命令コードを仮実行する命令コード仮実行手段と、前記仮実行の結果に基づいて、当該仮実行した命令コードと、該命令コードが読み書きを行なうオブジェクト変数の識別情報と、該命令コードの前記中間コードにおける記載位置と、他の命令コードの並列実行を許可する識別子と、を関連付けた履歴テーブルを作成する履歴テーブル作成手段と、を備え、前記命令コード検出手段は、前記履歴テーブルにおいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記録されている命令コードを検出することを特徴とする。
【0009】
また本発明は、上述のプログラム診断装置において、前記検出した命令コードに関連付けて前記履歴テーブルに記録されている中間コードの記載位置に基づいて、当該命令コードが記述されている前記プログラムソースコード中の行を特定する命令コード位置特定手段と、を備えることを特徴とする。
【0010】
また本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置におけるプログラム診断方法であって、前記プログラムの入力を受け付け、前記プログラムの中間コードを生成し、前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出することを特徴とするプログラム診断方法である。
【0011】
また本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置のコンピュータを、前記プログラムの入力を受け付けるプログラム入力受付手段、前記プログラムの中間コードを生成する中間コード生成手段、前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段、として機能させるためのプログラムである。
【発明の効果】
【0012】
本発明によれば、プログラムのソースコードから中間コードを生成し、その中間コードから、メモリ参照/書き込みを示す命令コードを検出する。そして、その命令コードの仮実行において、操作する変数がアンロック状態で実行される命令コードであると判定した場合には、その命令コードが記述されているソースコードの位置を画面に表示している。従って、ユーザは、ソースコードの記述が改変されることなく、どのソースコードの位置の記述を、競合状態が発生しないように変更すべきかを検出でき、またその修正を行うことができる。また、メモリ参照/書き込みを示す命令コードを全て検出できるため、精度良く、競合状態を発生させる命令コードに対応するソースコードの位置を検出することができる。
【発明を実施するための最良の形態】
【0013】
以下、本発明の一実施形態によるプログラム診断装置を図面を参照して説明する。
図1は同実施形態によるプログラム診断装置の構成を示すブロック図である。
この図において、符号1はプログラム診断装置である。そして、プログラム診断装置1は、Webアプリケーション解析部11、診断実行部12、競合状態条件判定部13、表示部14、命令コード記憶部15、オペランドスタック16、メモリ監視履歴DB(データベース)17を備えている。
【0014】
そして、プログラム診断装置1は、並列実行されるプログラムの共通資源へのアクセス競合状態を、プログラムソースコード中から検出するものであり、まず、プログラムの入力を受け付ける。次に、プログラムの中間コードを生成する。そして、中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられる命令コードを検出する。さらに、検出した命令コードが記述されているプログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示する処理を行う。これにより、プログラムのソースコードの記述を改変することなく、また精度良く、競合状態を発生させる命令コードの検出および修正をプログラムの製作者が容易に行うことができるよう画面をモニタへ出力している。
【0015】
図2はプログラム診断装置の処理概要を示す図である。
この図が示すように、本実施形態によるプログラム診断装置1は、Java(登録商標)言語のプログラムソースコードをJava(登録商標)言語の中間コード(バイトコード)にコンパイルし、その中間コードを用いて、ソースコードの脆弱性、つまり、並列実行されるプログラムの共通資源へのアクセス競合状態が発生しないかどうかの診断を、データベースに記録された情報に基づいて行なう。そして、Java(登録商標)言語のプログラムソースコード中の、競合状態を発生させる可能性のある命令コードに対応する記述の行に警告マーカ等を表示する処理を行う。
【0016】
ここで、本実施形態において診断を行なうプログラムは、ウェブアプリケーションサーバにおいて、クライアントからのリクエスト情報の受信に応じて処理を開始するフィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラム等である。これらのプログラムは、ユーザの操作するクライアント端末からリクエスト情報を受信することを契機に動作するプログラムである。電子決済サイト等では、ウェブアプリケーションサーバにおける競合状態の発生の削減を厳しくチェックする必要があり、本実施形態によるプログラム診断が特に行なわれるべきプログラムである。なお、本実施形態のプログラム診断装置1による診断方法は、ウェブアプリケーションサーバの、フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラム以外の、他のサーバで動作するプログラムの競合状態の診断に用いるようにしてもよい。また、本実施形態においては、Java(登録商標)言語のプログラムソースコードをJava(登録商標)言語の中間コード(バイトコード)にコンパイルしているが、これは、中間コードがソースコードに比べて、処理情報の粒度が細かく表れており、変数やオブジェクトの状態等の属性情報が含まれるためである。これらの属性情報を利用して、精度の良い診断を実行することとなる。
【0017】
図3は並列実行されるプログラムの共通資源へのアクセス競合状態の概要を示す図である。
この図が示すように、ウェブアプリケーションサーバ上で2つのスレッドが実行された場合、ある共通資源(変数やオブジェクト等)が両方のスレッドからのアクセスを受け付け可能な状態(アンロック(Unlock)状態)となっている場合、アクセス競合状態が発生し、共通資源の持つデータ値が所望の値と異なってしまう可能性がある。従って、一方の1つのスレッドがある共通資源にアクセスしている場合には、その命令コードによっては、他の1つ又は複数のスレッドが、その共通資源へのアクセスができないような状態(ロック(Lock)状態)に制御することが必要となる。そして、プログラム中から、競合状態が発生する可能性のある共通資源へのアクセス処理を行っている記述がみつかれば、その箇所が、競合状態の発生する可能性のプログラム中の記述であると判定することができる。
【0018】
図4はプログラム診断装置の処理フローを示す第1の図である。
次に、プログラム診断装置1の処理フローの全体像について説明する。まず、ウェブアプリケーション解析部11が、ウェブアプリケーションサーバを構成する全てのソースファイルから、全ての「ユーザリクエスト受信時処理開始メソッド」を読み込む(ステップS1)。この「ユーザリクエスト受信時処理開始メソッド」は、ウェブアプリケーションサーバの、フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラム等の、ユーザ端末からのリクエスト情報を受け付けて、処理を開始するクラス内に含まれている。ここでメソッドとは、オブジェクト指向プログラミングにおいて、各オブジェクトが持っている自身に対する操作命令のコマンドを記述したプログラムである。
【0019】
そして、ウェブアプリケーション解析部11は、1つの「ユーザリクエスト受信時処理開始メソッド」から、「実行モジュール群」を生成する(ステップS2)。そして、ウェブアプリケーション解析部11は生成した「実行モジュール群」が含まれるソースコードがコンパイル済みかを判定し(ステップS3)、コンパイルされていなければ、そのソースコードをコンパイルして中間コードを生成する(ステップS31)。そして、ウェブアプリケーション解析部11は、中間コードに記述されている命令コードを、ユーザ端末からのリクエスト情報に対応して実行する処理の順に、命令コード記憶部15に格納する(ステップS4)。
【0020】
次に、診断実行部12が、命令コード記憶部15から命令コードを読み込み、オペランドスタック16上でエミュレート実行(擬似実行)させ、ウェブアプリケーションが使用する共有メモリの操作を行う命令コード(メモリ操作命令コード)のバイトコード位置(命令コードの中間(バイト)コード内のメソッドの先頭を0とした何バイト目かを示す値)を命令コード記憶部15から読み込む(ステップS5)。そして診断実行部12は、メモリ操作命令コードのバイトコード位置と、メモリ操作命令コードによって変更される共有メモリの状態などの履歴をメモリ監視履歴DB17のメモリ監視履歴テーブルに書き込む(ステップS6)。次に、競合状態条件判定部13が、メモリ監視履歴テーブルを読み込み、競合条件(オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記録されている命令コードかどうかの条件)が、真となる変数に対応したメモリ操作命令コードのバイトコード位置を読み込む(ステップS7)。そして、競合状態条件判定部13の読み込んだメモリ操作命令コードのバイトコード位置から、実行モジュール群の位置情報を計算し、表示部14へ通知する(ステップS8)。また表示部14では、モニタなどの外部表示装置へ、実行モジュール群の位置情報を出力する(ステップS9)。
【0021】
次に、上記ステップS1〜ステップS9の処理の詳細について説明する。
図5はプログラム診断装置の処理フローを示す第2の図である。
この図より、上記ステップS1においては、まず、ウェブアプリケーション解析部11が、ウェブアプリケーションを構成するソースファイルが格納されたディレクトリ・パスを読み込む(ステップS11)。そしてウェブアプリケーション解析部11は、そのディレクトリ・パス配下に格納されているウェブアプリケーション配備記述子(デプロイメントディスクリプタ)を読み込み、その記述子から、ウェブアプリケーションサーバの、フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラムの各名称を読み込む(ステップS12)。また、ウェブアプリケーション解析部11は、名称を特定した対象ソースファイル(ウェブアプリケーションを構成するソースファイル)から、ステップS12で特定した名称を持つクラスのスーパークラスを求め、そのスーパークラスごとに、「ユーザリクエスト受信時処理開始メソッド一覧」で定義されたメソッドを、「ユーザリクエスト受信時処理開始メソッド」としてメモリへ保存する(ステップS13)。
【0022】
図6はユーザリクエスト受信時処理開始メソッド一覧を示す図である。
「ユーザリクエスト受信時処理開始メソッド一覧」は、予め記憶部等で記憶しており、図6で示すように、クラスごとに1つまたは複数のメソッドが記述されている。
【0023】
図7はプログラム診断装置の処理フローを示す第3の図である。
次に、上記ステップS2においては、まず、ウェブアプリケーション解析部11が、ステップS13においてメモリへ保存した「ユーザリクエスト受信時処理開始メソッド」のリストから1つのメソッドを読み込む(ステップS21)。そして、ウェブアプリケーション解析部11は、そのメソッド内で実行される全ての命令コードを読み込み、命令コードのリストを生成する(ステップS22)。次にウェブアプリケーション解析部11は、命令コードのリストを「実行モジュール群(「ユーザリクエスト受信時処理開始メソッド」を始点とした一連の処理内で実行されるメソッド内の命令コードの集合)」としてメモリ内のデータテーブルに一時的に追加記録する(ステップS23)。そして、ウェブアプリケーション解析部11は、メモリに一時記録されたデータテーブルにおいて、実行モジュール群における命令コードのリストが空かどうかを判定し(ステップS24)、空であれば、処理を終了し、空でなければ、命令コードのリストから1つの命令コードを読み込む(ステップS25)。そして命令コードがメソッド呼び出しを実行する命令コードかを判定する(ステップS26)。メソッド呼び出しを実行する命令コードでなければ、ステップS25に戻り、次の命令コードを読み込む。またメソッド呼び出しを実行する命令コードであれば、呼び出したメソッド(他のメソッド)についてステップS22以降の処理を再帰的に実行する(ステップS27)。
【0024】
そして、上記ステップS3,ステップS31、ステップS4で示したように、ウェブアプリケーション解析部11は生成した「実行モジュール群」が含まれるソースコードがコンパイル済みかを判定し、コンパイルされていなければ、そのソースコードをコンパイルして中間コードを生成する。そして、ウェブアプリケーション解析部11は、中間コードに記述されている命令コードを、ユーザ端末からのリクエスト情報に対応して実行する処理の順に、命令コード記憶部15に格納する。
【0025】
図8は命令コード記憶部内に格納されるデータ例<中間(バイト)コード>を示す図である。
この図で示すように、命令コード記憶部15の中間(バイト)コードのテーブルにおいて、ウェブアプリケーション解析部11によって格納された命令コードが記述される。各命令コードは1バイト単位で記録され、各命令コードに対応付けて、その1バイト単位の順番を示すバイトコード位置(命令コードの中間(バイト)コード内のメソッドの先頭を0とした何バイト目かを示す値)が記録される。なお、命令コード記憶部15における命令コードのバイトコード位置と、ウェブアプリケーションのソースコードにおける記述位置(行番号)が、中間(バイト)コードに記述されているものとする。
【0026】
図9はプログラム診断装置の処理フローを示す第4の図である。
図10はプログラム診断装置の処理フローを示す第5の図である。
次に、上述のステップS5においては、まず、診断実行部12が、オペランドスタック16上において命令コードのエミュレート実行(擬似実行)を指示されると、命令コード記憶部15に記録されているデータテーブルから1つの命令コードを読み取る。そして、診断実行部12は、読み取った命令コードが、クラス変数(オブジェクト変数)の参照またはそのクラス変数への書き込みを行なうコード(getstaticまたはputstaticか?)かどうかを判定する(ステップS51)。そして、Yesであれば、共有メモリの操作を行う命令コードであると判定し、Noであれば、共有メモリの操作を行う命令コードでないと判定する。また診断実行部12は、読み取った命令コードが、インスタンス変数(オブジェクト変数)の参照またはそのインスタンス変数への書き込みを行なうコード(getfieldまたはputfieldか?)かどうかを判定する(ステップS52)。また診断実行部12は、読み取った命令コードの参照または書き込み対象となるインスタンス変数(オブジェクト変数)が、ウェブアプリケーションのインスタンスかどうかを判定する(ステップS53)。これは命令コードの第1引数が表す判別情報で判別する。そして、ステップS53でYesであれば、共有メモリの操作(参照/書き込み)を行う命令コードであると判定する。また、ステップS52でNoまたはステップS53でNoと判定した場合には、共有メモリの操作を行う命令コードでないと判定する。
【0027】
次に診断実行部12は、共有メモリの操作を行う命令コードであると判定された命令コードを順に読み込む(ステップS501)。そして、診断実行部12は、読み込んだ命令コードのバイトコード位置を、命令コード記憶部15から読み込む(ステップS502)。そして、そのバイトコード位置を出力する(ステップS503)。共有メモリの操作を行う命令コードであると判定された命令コードと、そのバイトコード位置は、一時的にメモリ等に格納される。
【0028】
図11はプログラム診断装置の処理フローを示す第6の図である。
次に、診断実行部12は、前記一時的にメモリに格納された、共有メモリの操作を行う命令コードであると判定された命令コードを取得する(ステップS61)。そして、その命令コードがメモリ参照を示す命令コード(getstatic/putstatic/getfield/putfield)かを判定する(ステップS62)。そしてYesの場合は、ステップS51〜ステップS53の処理により、共有メモリの操作(参照/書き込み)を行う命令コードと判定されているかの情報がTrueであれば、その命令コードと、そのバイトコード位置を対応付けて、メモリ監視履歴DB内のメモリ監視履歴テーブルに対応付けて書き込む(ステップS63)。そして、その命令コードが、命令コードの実行時に共通資源へのアクセスができないよう制御するロックコマンド(monitorenter)によってロックされるかを判定する(ステップS64)。そして、ロックされる場合であれば、下記に説明するロック/ロック解除対象の変数取得処理によって取得した変数と、その変数が「ロック状態」である旨を示す情報とを対応付けて、メモリ監視履歴テーブルに書き込む(ステップS64)。
【0029】
また命令コードが、命令コードの実行時に共通資源へのアクセスができない制御の解除を示すロック解除コマンド(monitorexit)によってロック解除されたかを判定する(ステップS65)。そして、ロック解除コマンドによってロック解除されたと判定できれば、下記に説明するロック/ロック解除対象の変数取得処理によって取得した変数と、その変数が「アンロック状態」である旨を示す情報とを対応付けて、メモリ監視履歴テーブルに書き込む(ステップS66)。そして、実行モジュール群の全ての命令コードについて、仮実行を完了したかを判定し(ステップS67)、全ての命令コードについて仮実行の完了を判定した場合には処理を終了する。
【0030】
図12はプログラム診断装置の処理フローを示す第7の図である。
図12は、上述のロック/ロック解除対象の変数取得処理を示す図である。この処理においてはロックコマンド(monitorenter)またはロック解除コマンド(monitorexit)である場合には、その命令コードを読み込む(ステップS601)。そして、オペランドスタック16から変数名を読み取り(ステップS602)、その変数名を出力する(ステップS603)
【0031】
図13はメモリ監視履歴テーブルの例を示す図である。
この図が示すように、メモリ監視履歴テーブルは、共有メモリの操作を行う命令コードであると判定された命令コードと、そのバイトコード位置と、その命令コードが操作する共通資源である変数(オブジェクト)と、その命令コードの実行時に当該変数がロック状態となるかアンロック状態となるかを示す状態の情報と、を対応付けて記憶するテーブルである。
【0032】
図14はメモリ監視履歴テーブルと競合条件の判定処理の概要を示す図である。
図14に示すように、本実施形態においては、メモリ参照を示す命令コードは、putfield(インスタンス変数に値を格納)、getfield(インスタンス変数から値を取得)、putstatic(クラス変数に値を格納)、getstatic(クラス変数から値を取得)のいずれかであり、これらの命令コードと、その命令コードの実行時において共通資源である変数(オブジェクト)が「アンロック状態」となることを示す情報がメモリ監視履歴テーブルに対応付けられている場合にのみ、その命令コードが競合状態を発生する可能性があると判定する。なお、monitorenter(モニタ開始)と、monitorexit(モニタ終了)は、Java(登録商標)言語で記述されたソースコードにおいて「synchronized修飾子」の記述をバイトコードに変換したものである。
【0033】
そして、monitorenterと、monitorexitの命令コードの間のバイトコード位置に命令コード記憶部15に記録される全ての命令コードは、その命令コードの実行時において、共通資源に対して必ずロック状態とするものであるため、メモリ監視履歴テーブルにおいては、monitorenterとmonitorexitの間に入る命令コードの操作する変数の状態は、全て「ロック状態」を示す状態の情報が登録されることとなる。monitorenterとmonitorexitの組合せが複数ある場合には、monitorenterがメモリ監視履歴テーブルに記述される数と、その後monitorexitがメモリ監視履歴テーブルに記述される数によって、monitorenterとmonitorexitの組合せが全て出現したかを判定し、それらの組合せの間の命令コードの操作する変数の状態は全て「ロック状態」となり、monitorenterとmonitorexitの組合せの出現が終了したと判定した後は、「アンロック状態」である旨を示す情報が登録される。
【0034】
図15はオペランドスタック上での命令コード仮実行による状態取得の概要を示す図である。
この図が示すように、まず、Java(登録商標)のソースコードをバイトコードに変換する。そして、バイトコード上にはLockまたはUnlockの情報が静的に記述されていない。しかしながら、このバイトコード中の各命令コードを実行するにあたり、ソースコード中のshynchronized識別子に対応するバイトコード内の命令コードがmonitorengerとなり、この命令コードにより、変数(オブジェクト)の状態がLockされたと判定している。
【0035】
図16はプログラム診断装置の処理フローを示す第8の図である。
次に、上述のステップS7においては、まず、競合状態条件判定部13が、メモリ監視履歴DB17に格納されているメモリ監視履歴テーブルから1つの命令コードのレコードを読み込む(ステップS701)。そして、命令コードが、メモリ参照を示す命令コードのgetstatic、putstatic、getfield、putfieldのいずれかであり、かつ、その命令コードの実行時において操作する変数がアンロック状態である旨を示す情報(Unlock)と対応付けられてレコードに記録されているかを判定する(ステップS702)。そして、Yesの場合には、競合状態の発生する可能性があり危険であると判断し、その命令コードに対応付けられて記録されているバイトコード位置をメモリ監視履歴テーブルから読み取ってメモリ等に一時記録しておく(ステップS703)。そして、メモリ監視履歴テーブルに記録されている全ての命令コードのレコードについて処理を行ったかを判定し(ステップS704)、処理が終了していなければ、ステップS701〜S704の処理を繰り返す。
【0036】
図17はプログラム診断装置の処理フローを示す第9の図である。
次に、上述のステップS8においては、まず、競合状態条件判定部13が、ステップS703で一時的にメモリ等に記録された、メモリ参照を示す命令コードであって操作する変数がアンロック状態である旨を示す命令コードのバイトコード位置を読み取る(ステップS81)。そして、処理対象のウェブアプリケーションを構成するソースファイル(フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラムのいずれかのソースファイル)における、バイトコード位置に対応する、ソースコード内の記述位置(行番号)を読み込む(ステップS82)。例えば、上述したように、命令コード記憶部15における命令コードのバイトコード位置と、ウェブアプリケーションのソースコードにおける記述位置(行番号)が、中間(バイト)コードに格納されているので、この中間(バイト)コードから読み込むようにすれば良い。そして、そのソースコード位置を表示部14に出力する(ステップS83)。そして、ステップS9の処理において、表示部14が、モニタなどの外部表示装置へ、競合状態の発生する可能性があると検出した命令コードが記述されているプログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示して外部表示装置へ出力する処理を行う。
【0037】
図18は表示画面の例を示す図である。
図18で示すように、表示画面にはソースコード中に警告マーカが表示される。この警告マーカは、当該マーカが付される行のプログラムの記述が、競合状態の発生する可能性があることを示している。ユーザはこの行にsynchronized修飾子を記述することにより、警告マーカが付されている箇所の記述により競合が発生することを回避する。そして、再度、プログラム診断装置1によって診断を行なうことにより、警告マーカが外れた表示画面が出力されることとなる。また、表示画面では、図18の左下の子画面で示すように、検出結果としてソースコードの行数と、競合状態の発生確度とを示す一覧の画面を表示するようにしてもよい。
【0038】
以上、本発明の実施形態について説明したが、上述の処理によれば、Java(登録商標)言語のソースコードから中間コードを生成し、その中間コードから、メモリ参照/書き込みを示す命令コードを検出する。そして、その命令コードの仮実行において、操作する変数がアンロック状態で実行される命令コードであると判定した場合には、その命令コードが記述されているソースコードの位置を画面に表示している。従って、ユーザは、ソースコードの記述が改変されることなく、どのソースコードの位置の記述を、競合状態が発生しないように変更すべきかを検出でき、またその修正を行うことができる。また、メモリ参照/書き込みを示す命令コード全て検出できるため、精度良く、競合状態の発生させる命令コードに対応するソースコードの位置を検出することができる。
【0039】
なお、上述のプログラム診断装置は内部に、コンピュータシステムを有している。そして、上述した各処理の過程は、プログラムの形式でコンピュータ読み取り可能な記録媒体に記憶されており、このプログラムをコンピュータが読み出して実行することによって、上記処理が行われる。ここでコンピュータ読み取り可能な記録媒体とは、磁気ディスク、光磁気ディスク、CD−ROM、DVD−ROM、半導体メモリ等をいう。また、このコンピュータプログラムを通信回線によってコンピュータに配信し、この配信を受けたコンピュータが当該プログラムを実行するようにしても良い。
【0040】
また、上記プログラムは、前述した機能の一部を実現するためのものであっても良い。さらに、前述した機能をコンピュータシステムにすでに記録されているプログラムとの組み合わせで実現できるもの、いわゆる差分ファイル(差分プログラム)であっても良い。
【図面の簡単な説明】
【0041】
【図1】プログラム診断装置の構成を示すブロック図である。
【図2】プログラム診断装置の処理概要を示す図である。
【図3】並列実行されるプログラムの共通資源へのアクセス競合状態の概要を示す図である。
【図4】プログラム診断装置の処理フローを示す第1の図である。
【図5】プログラム診断装置の処理フローを示す第2の図である。
【図6】ユーザリクエスト受信時処理開始メソッド一覧を示す図である。
【図7】プログラム診断装置の処理フローを示す第3の図である。
【図8】命令コード記憶部内に格納されるデータ例<中間(バイト)コード>を示す図である。
【図9】プログラム診断装置の処理フローを示す第4の図である。
【図10】プログラム診断装置の処理フローを示す第5の図である。
【図11】プログラム診断装置の処理フローを示す第6の図である。
【図12】プログラム診断装置の処理フローを示す第7の図である。
【図13】メモリ監視履歴テーブルの例を示す図である。
【図14】メモリ監視履歴テーブルと競合条件の判定処理の概要を示す図である。
【図15】オペランドスタック上での命令コード仮実行による状態取得の概要を示す図である。
【図16】プログラム診断装置の処理フローを示す第8の図である。
【図17】プログラム診断装置の処理フローを示す第9の図である。
【図18】表示画面の例を示す図である。
【図19】ウェブサーバにおける競合状態を示す図である。
【符号の説明】
【0042】
1・・・プログラム診断装置
11・・・ウェブアプリケーション解析部
12・・・診断実行部
13・・・競合状態条件判定部
14・・・表示部
15・・・命令コード記憶部
16・・・オペランドスタック
17・・・メモリ監視履歴DB
【技術分野】
【0001】
本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態を、プログラムソースコード中から検出するプログラム診断装置及びプログラム診断方法ならびにそのプログラムに関する。
【背景技術】
【0002】
従来、コンピュータシステムにおいては排他制御という技術が利用されている。ここで、排他制御を行わない場合の預金管理システムと、排他制御を行う場合の預金管理システムとについて、具体例を用いて説明する。まず、排他制御を行わない預金管理システムにおいて、入金プログラムが、50,000円(共有変数)の預金残高へ、30,000円を入金処理し、80,000円を預金金額として登録する場合を例に説明する。ここで、入金プログラムと出金プログラムとが同タイミングに実行された場合、出金プログラムは、入金プログラムが処理を行っている間に、預金残高50,000円を読み取り、その預金残高から10,000円を出金処理した40,000円を計算し、入金プログラムの処理完了後に、40,000円の金額の情報を預金金額へ登録する可能性がある。このような場合、預金残高は入金プログラムの処理を反映していない40,000円と記録されてしまい、50,000円(預金残高)+30,000(入金金額)−10,000(出金金額)=70,000円で算出されるような正確な金額とならない。このようなプログラムの競合状態を回避するためには、排他制御を行う必要がある。つまり、共有変数に対して入金プログラムが実行されている間は共有変数をロックし、共有変数に対する出金プログラムの処理をロック(実行させないよう処理)し、これにより、預金残高が正確な値の70,000円となるよう制御する必要がある。
【0003】
同様に、インターネットに接続されたウェブサーバの処理でも競合状態が発生する。図19で示す図はウェブサーバにおける競合状態を示す図である。この図が示すように、クライアント端末Aを利用するユーザAと、クライアント端末Bを利用するユーザBが同時にウェブサーバにアクセスしている状態において、クライアントAからの処理を制御するプログラムとクライアントBからの処理を制御するプログラムが競合した場合、クライアント端末Aに対して、クライアント端末Bへ送信するウェブページを送信してしまう可能性がある。そして、これらの競合状態がウェブサーバのプログラムで発生しないかどうかのプログラム診断を行なう技術が特許文献1に開示されている。
【特許文献1】特開2007−257397号公報
【発明の開示】
【発明が解決しようとする課題】
【0004】
ここで、上述の特許文献1の技術では、平行・並列動作を行なうプログラム中で共有変数の読み込み処理と、共有変数の書き込み処理とを検出し、共有変数の読み込み処理における当該共有変数の値と、共有変数の書き込み処理の直前における共有変数の値を比較する。そしてその比較において値が一致しない場合に競合状態であると検出して、その競合状態が発生するプログラム中の箇所にassert文を追加したソースコードを出力している。しかしながら、特許文献1の技術では、仮想マシンの動的解析によって、競合状態が発生したかどうかを検出できるものの、プログラムにおいて競合状態が発生しないように修正しなければならない場合、そのプログラムの記述位置を特定することができない。またプログラムのソースコードにassert文を追加するため、プログラム自体を改変してしまうこととなる。さらに、特許文献1の技術では、仮想マシンの動的解析中に競合状態が発生しなければ、それを検出することができないという問題がある。
【0005】
そこでこの発明は、プログラムのソースコードの記述を改変することなく、また精度良く、競合状態を発生させる命令コードの検出および修正をプログラムの製作者が容易に行うことが可能となるプログラム診断装置及びプログラム診断方法ならびにそのプログラムを提供することを目的としている。
【課題を解決するための手段】
【0006】
上記目的を達成するために、本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置であって、前記プログラムの入力を受け付けるプログラム入力受付手段と、前記プログラムの中間コードを生成する中間コード生成手段と、前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段と、を備えることを特徴とするプログラム診断装置である。
【0007】
また本発明は、上述のプログラム診断装置において、前記検出した命令コードが記述されている前記プログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示する検出命令コード位置表示手段と、を備えることを特徴とする。
【0008】
また本発明は、上述のプログラム診断装置において、前記中間コードに記述されている命令コードを仮実行する命令コード仮実行手段と、前記仮実行の結果に基づいて、当該仮実行した命令コードと、該命令コードが読み書きを行なうオブジェクト変数の識別情報と、該命令コードの前記中間コードにおける記載位置と、他の命令コードの並列実行を許可する識別子と、を関連付けた履歴テーブルを作成する履歴テーブル作成手段と、を備え、前記命令コード検出手段は、前記履歴テーブルにおいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記録されている命令コードを検出することを特徴とする。
【0009】
また本発明は、上述のプログラム診断装置において、前記検出した命令コードに関連付けて前記履歴テーブルに記録されている中間コードの記載位置に基づいて、当該命令コードが記述されている前記プログラムソースコード中の行を特定する命令コード位置特定手段と、を備えることを特徴とする。
【0010】
また本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置におけるプログラム診断方法であって、前記プログラムの入力を受け付け、前記プログラムの中間コードを生成し、前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出することを特徴とするプログラム診断方法である。
【0011】
また本発明は、並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置のコンピュータを、前記プログラムの入力を受け付けるプログラム入力受付手段、前記プログラムの中間コードを生成する中間コード生成手段、前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段、として機能させるためのプログラムである。
【発明の効果】
【0012】
本発明によれば、プログラムのソースコードから中間コードを生成し、その中間コードから、メモリ参照/書き込みを示す命令コードを検出する。そして、その命令コードの仮実行において、操作する変数がアンロック状態で実行される命令コードであると判定した場合には、その命令コードが記述されているソースコードの位置を画面に表示している。従って、ユーザは、ソースコードの記述が改変されることなく、どのソースコードの位置の記述を、競合状態が発生しないように変更すべきかを検出でき、またその修正を行うことができる。また、メモリ参照/書き込みを示す命令コードを全て検出できるため、精度良く、競合状態を発生させる命令コードに対応するソースコードの位置を検出することができる。
【発明を実施するための最良の形態】
【0013】
以下、本発明の一実施形態によるプログラム診断装置を図面を参照して説明する。
図1は同実施形態によるプログラム診断装置の構成を示すブロック図である。
この図において、符号1はプログラム診断装置である。そして、プログラム診断装置1は、Webアプリケーション解析部11、診断実行部12、競合状態条件判定部13、表示部14、命令コード記憶部15、オペランドスタック16、メモリ監視履歴DB(データベース)17を備えている。
【0014】
そして、プログラム診断装置1は、並列実行されるプログラムの共通資源へのアクセス競合状態を、プログラムソースコード中から検出するものであり、まず、プログラムの入力を受け付ける。次に、プログラムの中間コードを生成する。そして、中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられる命令コードを検出する。さらに、検出した命令コードが記述されているプログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示する処理を行う。これにより、プログラムのソースコードの記述を改変することなく、また精度良く、競合状態を発生させる命令コードの検出および修正をプログラムの製作者が容易に行うことができるよう画面をモニタへ出力している。
【0015】
図2はプログラム診断装置の処理概要を示す図である。
この図が示すように、本実施形態によるプログラム診断装置1は、Java(登録商標)言語のプログラムソースコードをJava(登録商標)言語の中間コード(バイトコード)にコンパイルし、その中間コードを用いて、ソースコードの脆弱性、つまり、並列実行されるプログラムの共通資源へのアクセス競合状態が発生しないかどうかの診断を、データベースに記録された情報に基づいて行なう。そして、Java(登録商標)言語のプログラムソースコード中の、競合状態を発生させる可能性のある命令コードに対応する記述の行に警告マーカ等を表示する処理を行う。
【0016】
ここで、本実施形態において診断を行なうプログラムは、ウェブアプリケーションサーバにおいて、クライアントからのリクエスト情報の受信に応じて処理を開始するフィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラム等である。これらのプログラムは、ユーザの操作するクライアント端末からリクエスト情報を受信することを契機に動作するプログラムである。電子決済サイト等では、ウェブアプリケーションサーバにおける競合状態の発生の削減を厳しくチェックする必要があり、本実施形態によるプログラム診断が特に行なわれるべきプログラムである。なお、本実施形態のプログラム診断装置1による診断方法は、ウェブアプリケーションサーバの、フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラム以外の、他のサーバで動作するプログラムの競合状態の診断に用いるようにしてもよい。また、本実施形態においては、Java(登録商標)言語のプログラムソースコードをJava(登録商標)言語の中間コード(バイトコード)にコンパイルしているが、これは、中間コードがソースコードに比べて、処理情報の粒度が細かく表れており、変数やオブジェクトの状態等の属性情報が含まれるためである。これらの属性情報を利用して、精度の良い診断を実行することとなる。
【0017】
図3は並列実行されるプログラムの共通資源へのアクセス競合状態の概要を示す図である。
この図が示すように、ウェブアプリケーションサーバ上で2つのスレッドが実行された場合、ある共通資源(変数やオブジェクト等)が両方のスレッドからのアクセスを受け付け可能な状態(アンロック(Unlock)状態)となっている場合、アクセス競合状態が発生し、共通資源の持つデータ値が所望の値と異なってしまう可能性がある。従って、一方の1つのスレッドがある共通資源にアクセスしている場合には、その命令コードによっては、他の1つ又は複数のスレッドが、その共通資源へのアクセスができないような状態(ロック(Lock)状態)に制御することが必要となる。そして、プログラム中から、競合状態が発生する可能性のある共通資源へのアクセス処理を行っている記述がみつかれば、その箇所が、競合状態の発生する可能性のプログラム中の記述であると判定することができる。
【0018】
図4はプログラム診断装置の処理フローを示す第1の図である。
次に、プログラム診断装置1の処理フローの全体像について説明する。まず、ウェブアプリケーション解析部11が、ウェブアプリケーションサーバを構成する全てのソースファイルから、全ての「ユーザリクエスト受信時処理開始メソッド」を読み込む(ステップS1)。この「ユーザリクエスト受信時処理開始メソッド」は、ウェブアプリケーションサーバの、フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラム等の、ユーザ端末からのリクエスト情報を受け付けて、処理を開始するクラス内に含まれている。ここでメソッドとは、オブジェクト指向プログラミングにおいて、各オブジェクトが持っている自身に対する操作命令のコマンドを記述したプログラムである。
【0019】
そして、ウェブアプリケーション解析部11は、1つの「ユーザリクエスト受信時処理開始メソッド」から、「実行モジュール群」を生成する(ステップS2)。そして、ウェブアプリケーション解析部11は生成した「実行モジュール群」が含まれるソースコードがコンパイル済みかを判定し(ステップS3)、コンパイルされていなければ、そのソースコードをコンパイルして中間コードを生成する(ステップS31)。そして、ウェブアプリケーション解析部11は、中間コードに記述されている命令コードを、ユーザ端末からのリクエスト情報に対応して実行する処理の順に、命令コード記憶部15に格納する(ステップS4)。
【0020】
次に、診断実行部12が、命令コード記憶部15から命令コードを読み込み、オペランドスタック16上でエミュレート実行(擬似実行)させ、ウェブアプリケーションが使用する共有メモリの操作を行う命令コード(メモリ操作命令コード)のバイトコード位置(命令コードの中間(バイト)コード内のメソッドの先頭を0とした何バイト目かを示す値)を命令コード記憶部15から読み込む(ステップS5)。そして診断実行部12は、メモリ操作命令コードのバイトコード位置と、メモリ操作命令コードによって変更される共有メモリの状態などの履歴をメモリ監視履歴DB17のメモリ監視履歴テーブルに書き込む(ステップS6)。次に、競合状態条件判定部13が、メモリ監視履歴テーブルを読み込み、競合条件(オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記録されている命令コードかどうかの条件)が、真となる変数に対応したメモリ操作命令コードのバイトコード位置を読み込む(ステップS7)。そして、競合状態条件判定部13の読み込んだメモリ操作命令コードのバイトコード位置から、実行モジュール群の位置情報を計算し、表示部14へ通知する(ステップS8)。また表示部14では、モニタなどの外部表示装置へ、実行モジュール群の位置情報を出力する(ステップS9)。
【0021】
次に、上記ステップS1〜ステップS9の処理の詳細について説明する。
図5はプログラム診断装置の処理フローを示す第2の図である。
この図より、上記ステップS1においては、まず、ウェブアプリケーション解析部11が、ウェブアプリケーションを構成するソースファイルが格納されたディレクトリ・パスを読み込む(ステップS11)。そしてウェブアプリケーション解析部11は、そのディレクトリ・パス配下に格納されているウェブアプリケーション配備記述子(デプロイメントディスクリプタ)を読み込み、その記述子から、ウェブアプリケーションサーバの、フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラムの各名称を読み込む(ステップS12)。また、ウェブアプリケーション解析部11は、名称を特定した対象ソースファイル(ウェブアプリケーションを構成するソースファイル)から、ステップS12で特定した名称を持つクラスのスーパークラスを求め、そのスーパークラスごとに、「ユーザリクエスト受信時処理開始メソッド一覧」で定義されたメソッドを、「ユーザリクエスト受信時処理開始メソッド」としてメモリへ保存する(ステップS13)。
【0022】
図6はユーザリクエスト受信時処理開始メソッド一覧を示す図である。
「ユーザリクエスト受信時処理開始メソッド一覧」は、予め記憶部等で記憶しており、図6で示すように、クラスごとに1つまたは複数のメソッドが記述されている。
【0023】
図7はプログラム診断装置の処理フローを示す第3の図である。
次に、上記ステップS2においては、まず、ウェブアプリケーション解析部11が、ステップS13においてメモリへ保存した「ユーザリクエスト受信時処理開始メソッド」のリストから1つのメソッドを読み込む(ステップS21)。そして、ウェブアプリケーション解析部11は、そのメソッド内で実行される全ての命令コードを読み込み、命令コードのリストを生成する(ステップS22)。次にウェブアプリケーション解析部11は、命令コードのリストを「実行モジュール群(「ユーザリクエスト受信時処理開始メソッド」を始点とした一連の処理内で実行されるメソッド内の命令コードの集合)」としてメモリ内のデータテーブルに一時的に追加記録する(ステップS23)。そして、ウェブアプリケーション解析部11は、メモリに一時記録されたデータテーブルにおいて、実行モジュール群における命令コードのリストが空かどうかを判定し(ステップS24)、空であれば、処理を終了し、空でなければ、命令コードのリストから1つの命令コードを読み込む(ステップS25)。そして命令コードがメソッド呼び出しを実行する命令コードかを判定する(ステップS26)。メソッド呼び出しを実行する命令コードでなければ、ステップS25に戻り、次の命令コードを読み込む。またメソッド呼び出しを実行する命令コードであれば、呼び出したメソッド(他のメソッド)についてステップS22以降の処理を再帰的に実行する(ステップS27)。
【0024】
そして、上記ステップS3,ステップS31、ステップS4で示したように、ウェブアプリケーション解析部11は生成した「実行モジュール群」が含まれるソースコードがコンパイル済みかを判定し、コンパイルされていなければ、そのソースコードをコンパイルして中間コードを生成する。そして、ウェブアプリケーション解析部11は、中間コードに記述されている命令コードを、ユーザ端末からのリクエスト情報に対応して実行する処理の順に、命令コード記憶部15に格納する。
【0025】
図8は命令コード記憶部内に格納されるデータ例<中間(バイト)コード>を示す図である。
この図で示すように、命令コード記憶部15の中間(バイト)コードのテーブルにおいて、ウェブアプリケーション解析部11によって格納された命令コードが記述される。各命令コードは1バイト単位で記録され、各命令コードに対応付けて、その1バイト単位の順番を示すバイトコード位置(命令コードの中間(バイト)コード内のメソッドの先頭を0とした何バイト目かを示す値)が記録される。なお、命令コード記憶部15における命令コードのバイトコード位置と、ウェブアプリケーションのソースコードにおける記述位置(行番号)が、中間(バイト)コードに記述されているものとする。
【0026】
図9はプログラム診断装置の処理フローを示す第4の図である。
図10はプログラム診断装置の処理フローを示す第5の図である。
次に、上述のステップS5においては、まず、診断実行部12が、オペランドスタック16上において命令コードのエミュレート実行(擬似実行)を指示されると、命令コード記憶部15に記録されているデータテーブルから1つの命令コードを読み取る。そして、診断実行部12は、読み取った命令コードが、クラス変数(オブジェクト変数)の参照またはそのクラス変数への書き込みを行なうコード(getstaticまたはputstaticか?)かどうかを判定する(ステップS51)。そして、Yesであれば、共有メモリの操作を行う命令コードであると判定し、Noであれば、共有メモリの操作を行う命令コードでないと判定する。また診断実行部12は、読み取った命令コードが、インスタンス変数(オブジェクト変数)の参照またはそのインスタンス変数への書き込みを行なうコード(getfieldまたはputfieldか?)かどうかを判定する(ステップS52)。また診断実行部12は、読み取った命令コードの参照または書き込み対象となるインスタンス変数(オブジェクト変数)が、ウェブアプリケーションのインスタンスかどうかを判定する(ステップS53)。これは命令コードの第1引数が表す判別情報で判別する。そして、ステップS53でYesであれば、共有メモリの操作(参照/書き込み)を行う命令コードであると判定する。また、ステップS52でNoまたはステップS53でNoと判定した場合には、共有メモリの操作を行う命令コードでないと判定する。
【0027】
次に診断実行部12は、共有メモリの操作を行う命令コードであると判定された命令コードを順に読み込む(ステップS501)。そして、診断実行部12は、読み込んだ命令コードのバイトコード位置を、命令コード記憶部15から読み込む(ステップS502)。そして、そのバイトコード位置を出力する(ステップS503)。共有メモリの操作を行う命令コードであると判定された命令コードと、そのバイトコード位置は、一時的にメモリ等に格納される。
【0028】
図11はプログラム診断装置の処理フローを示す第6の図である。
次に、診断実行部12は、前記一時的にメモリに格納された、共有メモリの操作を行う命令コードであると判定された命令コードを取得する(ステップS61)。そして、その命令コードがメモリ参照を示す命令コード(getstatic/putstatic/getfield/putfield)かを判定する(ステップS62)。そしてYesの場合は、ステップS51〜ステップS53の処理により、共有メモリの操作(参照/書き込み)を行う命令コードと判定されているかの情報がTrueであれば、その命令コードと、そのバイトコード位置を対応付けて、メモリ監視履歴DB内のメモリ監視履歴テーブルに対応付けて書き込む(ステップS63)。そして、その命令コードが、命令コードの実行時に共通資源へのアクセスができないよう制御するロックコマンド(monitorenter)によってロックされるかを判定する(ステップS64)。そして、ロックされる場合であれば、下記に説明するロック/ロック解除対象の変数取得処理によって取得した変数と、その変数が「ロック状態」である旨を示す情報とを対応付けて、メモリ監視履歴テーブルに書き込む(ステップS64)。
【0029】
また命令コードが、命令コードの実行時に共通資源へのアクセスができない制御の解除を示すロック解除コマンド(monitorexit)によってロック解除されたかを判定する(ステップS65)。そして、ロック解除コマンドによってロック解除されたと判定できれば、下記に説明するロック/ロック解除対象の変数取得処理によって取得した変数と、その変数が「アンロック状態」である旨を示す情報とを対応付けて、メモリ監視履歴テーブルに書き込む(ステップS66)。そして、実行モジュール群の全ての命令コードについて、仮実行を完了したかを判定し(ステップS67)、全ての命令コードについて仮実行の完了を判定した場合には処理を終了する。
【0030】
図12はプログラム診断装置の処理フローを示す第7の図である。
図12は、上述のロック/ロック解除対象の変数取得処理を示す図である。この処理においてはロックコマンド(monitorenter)またはロック解除コマンド(monitorexit)である場合には、その命令コードを読み込む(ステップS601)。そして、オペランドスタック16から変数名を読み取り(ステップS602)、その変数名を出力する(ステップS603)
【0031】
図13はメモリ監視履歴テーブルの例を示す図である。
この図が示すように、メモリ監視履歴テーブルは、共有メモリの操作を行う命令コードであると判定された命令コードと、そのバイトコード位置と、その命令コードが操作する共通資源である変数(オブジェクト)と、その命令コードの実行時に当該変数がロック状態となるかアンロック状態となるかを示す状態の情報と、を対応付けて記憶するテーブルである。
【0032】
図14はメモリ監視履歴テーブルと競合条件の判定処理の概要を示す図である。
図14に示すように、本実施形態においては、メモリ参照を示す命令コードは、putfield(インスタンス変数に値を格納)、getfield(インスタンス変数から値を取得)、putstatic(クラス変数に値を格納)、getstatic(クラス変数から値を取得)のいずれかであり、これらの命令コードと、その命令コードの実行時において共通資源である変数(オブジェクト)が「アンロック状態」となることを示す情報がメモリ監視履歴テーブルに対応付けられている場合にのみ、その命令コードが競合状態を発生する可能性があると判定する。なお、monitorenter(モニタ開始)と、monitorexit(モニタ終了)は、Java(登録商標)言語で記述されたソースコードにおいて「synchronized修飾子」の記述をバイトコードに変換したものである。
【0033】
そして、monitorenterと、monitorexitの命令コードの間のバイトコード位置に命令コード記憶部15に記録される全ての命令コードは、その命令コードの実行時において、共通資源に対して必ずロック状態とするものであるため、メモリ監視履歴テーブルにおいては、monitorenterとmonitorexitの間に入る命令コードの操作する変数の状態は、全て「ロック状態」を示す状態の情報が登録されることとなる。monitorenterとmonitorexitの組合せが複数ある場合には、monitorenterがメモリ監視履歴テーブルに記述される数と、その後monitorexitがメモリ監視履歴テーブルに記述される数によって、monitorenterとmonitorexitの組合せが全て出現したかを判定し、それらの組合せの間の命令コードの操作する変数の状態は全て「ロック状態」となり、monitorenterとmonitorexitの組合せの出現が終了したと判定した後は、「アンロック状態」である旨を示す情報が登録される。
【0034】
図15はオペランドスタック上での命令コード仮実行による状態取得の概要を示す図である。
この図が示すように、まず、Java(登録商標)のソースコードをバイトコードに変換する。そして、バイトコード上にはLockまたはUnlockの情報が静的に記述されていない。しかしながら、このバイトコード中の各命令コードを実行するにあたり、ソースコード中のshynchronized識別子に対応するバイトコード内の命令コードがmonitorengerとなり、この命令コードにより、変数(オブジェクト)の状態がLockされたと判定している。
【0035】
図16はプログラム診断装置の処理フローを示す第8の図である。
次に、上述のステップS7においては、まず、競合状態条件判定部13が、メモリ監視履歴DB17に格納されているメモリ監視履歴テーブルから1つの命令コードのレコードを読み込む(ステップS701)。そして、命令コードが、メモリ参照を示す命令コードのgetstatic、putstatic、getfield、putfieldのいずれかであり、かつ、その命令コードの実行時において操作する変数がアンロック状態である旨を示す情報(Unlock)と対応付けられてレコードに記録されているかを判定する(ステップS702)。そして、Yesの場合には、競合状態の発生する可能性があり危険であると判断し、その命令コードに対応付けられて記録されているバイトコード位置をメモリ監視履歴テーブルから読み取ってメモリ等に一時記録しておく(ステップS703)。そして、メモリ監視履歴テーブルに記録されている全ての命令コードのレコードについて処理を行ったかを判定し(ステップS704)、処理が終了していなければ、ステップS701〜S704の処理を繰り返す。
【0036】
図17はプログラム診断装置の処理フローを示す第9の図である。
次に、上述のステップS8においては、まず、競合状態条件判定部13が、ステップS703で一時的にメモリ等に記録された、メモリ参照を示す命令コードであって操作する変数がアンロック状態である旨を示す命令コードのバイトコード位置を読み取る(ステップS81)。そして、処理対象のウェブアプリケーションを構成するソースファイル(フィルタプログラム、リスナプログラム、Java(登録商標)サーブレットプログラム、Java(登録商標)サーバページプログラムのいずれかのソースファイル)における、バイトコード位置に対応する、ソースコード内の記述位置(行番号)を読み込む(ステップS82)。例えば、上述したように、命令コード記憶部15における命令コードのバイトコード位置と、ウェブアプリケーションのソースコードにおける記述位置(行番号)が、中間(バイト)コードに格納されているので、この中間(バイト)コードから読み込むようにすれば良い。そして、そのソースコード位置を表示部14に出力する(ステップS83)。そして、ステップS9の処理において、表示部14が、モニタなどの外部表示装置へ、競合状態の発生する可能性があると検出した命令コードが記述されているプログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示して外部表示装置へ出力する処理を行う。
【0037】
図18は表示画面の例を示す図である。
図18で示すように、表示画面にはソースコード中に警告マーカが表示される。この警告マーカは、当該マーカが付される行のプログラムの記述が、競合状態の発生する可能性があることを示している。ユーザはこの行にsynchronized修飾子を記述することにより、警告マーカが付されている箇所の記述により競合が発生することを回避する。そして、再度、プログラム診断装置1によって診断を行なうことにより、警告マーカが外れた表示画面が出力されることとなる。また、表示画面では、図18の左下の子画面で示すように、検出結果としてソースコードの行数と、競合状態の発生確度とを示す一覧の画面を表示するようにしてもよい。
【0038】
以上、本発明の実施形態について説明したが、上述の処理によれば、Java(登録商標)言語のソースコードから中間コードを生成し、その中間コードから、メモリ参照/書き込みを示す命令コードを検出する。そして、その命令コードの仮実行において、操作する変数がアンロック状態で実行される命令コードであると判定した場合には、その命令コードが記述されているソースコードの位置を画面に表示している。従って、ユーザは、ソースコードの記述が改変されることなく、どのソースコードの位置の記述を、競合状態が発生しないように変更すべきかを検出でき、またその修正を行うことができる。また、メモリ参照/書き込みを示す命令コード全て検出できるため、精度良く、競合状態の発生させる命令コードに対応するソースコードの位置を検出することができる。
【0039】
なお、上述のプログラム診断装置は内部に、コンピュータシステムを有している。そして、上述した各処理の過程は、プログラムの形式でコンピュータ読み取り可能な記録媒体に記憶されており、このプログラムをコンピュータが読み出して実行することによって、上記処理が行われる。ここでコンピュータ読み取り可能な記録媒体とは、磁気ディスク、光磁気ディスク、CD−ROM、DVD−ROM、半導体メモリ等をいう。また、このコンピュータプログラムを通信回線によってコンピュータに配信し、この配信を受けたコンピュータが当該プログラムを実行するようにしても良い。
【0040】
また、上記プログラムは、前述した機能の一部を実現するためのものであっても良い。さらに、前述した機能をコンピュータシステムにすでに記録されているプログラムとの組み合わせで実現できるもの、いわゆる差分ファイル(差分プログラム)であっても良い。
【図面の簡単な説明】
【0041】
【図1】プログラム診断装置の構成を示すブロック図である。
【図2】プログラム診断装置の処理概要を示す図である。
【図3】並列実行されるプログラムの共通資源へのアクセス競合状態の概要を示す図である。
【図4】プログラム診断装置の処理フローを示す第1の図である。
【図5】プログラム診断装置の処理フローを示す第2の図である。
【図6】ユーザリクエスト受信時処理開始メソッド一覧を示す図である。
【図7】プログラム診断装置の処理フローを示す第3の図である。
【図8】命令コード記憶部内に格納されるデータ例<中間(バイト)コード>を示す図である。
【図9】プログラム診断装置の処理フローを示す第4の図である。
【図10】プログラム診断装置の処理フローを示す第5の図である。
【図11】プログラム診断装置の処理フローを示す第6の図である。
【図12】プログラム診断装置の処理フローを示す第7の図である。
【図13】メモリ監視履歴テーブルの例を示す図である。
【図14】メモリ監視履歴テーブルと競合条件の判定処理の概要を示す図である。
【図15】オペランドスタック上での命令コード仮実行による状態取得の概要を示す図である。
【図16】プログラム診断装置の処理フローを示す第8の図である。
【図17】プログラム診断装置の処理フローを示す第9の図である。
【図18】表示画面の例を示す図である。
【図19】ウェブサーバにおける競合状態を示す図である。
【符号の説明】
【0042】
1・・・プログラム診断装置
11・・・ウェブアプリケーション解析部
12・・・診断実行部
13・・・競合状態条件判定部
14・・・表示部
15・・・命令コード記憶部
16・・・オペランドスタック
17・・・メモリ監視履歴DB
【特許請求の範囲】
【請求項1】
並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置であって、
前記プログラムの入力を受け付けるプログラム入力受付手段と、
前記プログラムの中間コードを生成する中間コード生成手段と、
前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段と、
を備えることを特徴とするプログラム診断装置。
【請求項2】
前記検出した命令コードが記述されている前記プログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示する検出命令コード位置表示手段と、
を備えることを特徴とする請求項1に記載のプログラム診断装置。
【請求項3】
前記中間コードに記述されている命令コードを仮実行する命令コード仮実行手段と、
前記仮実行の結果に基づいて、当該仮実行した命令コードと、該命令コードが読み書きを行なうオブジェクト変数の識別情報と、該命令コードの前記中間コードにおける記載位置と、他の命令コードの並列実行を許可する識別子と、を関連付けた履歴テーブルを作成する履歴テーブル作成手段と、を備え、
前記命令コード検出手段は、前記履歴テーブルにおいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記録されている命令コードを検出する
ことを特徴とする請求項1または請求項2に記載のプログラム診断装置。
【請求項4】
前記検出した命令コードに関連付けて前記履歴テーブルに記録されている中間コードの記載位置に基づいて、当該命令コードが記述されている前記プログラムソースコード中の行を特定する命令コード位置特定手段と、
を備えることを特徴とする請求項3に記載のプログラム診断装置。
【請求項5】
並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置におけるプログラム診断方法であって、
前記プログラムの入力を受け付け、
前記プログラムの中間コードを生成し、
前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する
ことを特徴とするプログラム診断方法。
【請求項6】
並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置のコンピュータを、
前記プログラムの入力を受け付けるプログラム入力受付手段、
前記プログラムの中間コードを生成する中間コード生成手段、
前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段、
として機能させるためのプログラム。
【請求項1】
並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置であって、
前記プログラムの入力を受け付けるプログラム入力受付手段と、
前記プログラムの中間コードを生成する中間コード生成手段と、
前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段と、
を備えることを特徴とするプログラム診断装置。
【請求項2】
前記検出した命令コードが記述されている前記プログラムソースコード中の行を、当該プログラムソースコードの表示画面に表示する検出命令コード位置表示手段と、
を備えることを特徴とする請求項1に記載のプログラム診断装置。
【請求項3】
前記中間コードに記述されている命令コードを仮実行する命令コード仮実行手段と、
前記仮実行の結果に基づいて、当該仮実行した命令コードと、該命令コードが読み書きを行なうオブジェクト変数の識別情報と、該命令コードの前記中間コードにおける記載位置と、他の命令コードの並列実行を許可する識別子と、を関連付けた履歴テーブルを作成する履歴テーブル作成手段と、を備え、
前記命令コード検出手段は、前記履歴テーブルにおいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記録されている命令コードを検出する
ことを特徴とする請求項1または請求項2に記載のプログラム診断装置。
【請求項4】
前記検出した命令コードに関連付けて前記履歴テーブルに記録されている中間コードの記載位置に基づいて、当該命令コードが記述されている前記プログラムソースコード中の行を特定する命令コード位置特定手段と、
を備えることを特徴とする請求項3に記載のプログラム診断装置。
【請求項5】
並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置におけるプログラム診断方法であって、
前記プログラムの入力を受け付け、
前記プログラムの中間コードを生成し、
前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する
ことを特徴とするプログラム診断方法。
【請求項6】
並列実行されるプログラムの共通資源へのアクセス競合状態をプログラムソースコード中から検出するプログラム診断装置のコンピュータを、
前記プログラムの入力を受け付けるプログラム入力受付手段、
前記プログラムの中間コードを生成する中間コード生成手段、
前記中間コードに基づいて、オブジェクト変数の読み書きを行なう命令コードのうち、他の命令コードの並列実行を許可する識別子に関連付けられて記載されている命令コードを検出する命令コード検出手段、
として機能させるためのプログラム。
【図1】
【図2】
【図3】
【図4】
【図5】
【図6】
【図7】
【図8】
【図9】
【図10】
【図11】
【図12】
【図13】
【図14】
【図15】
【図16】
【図17】
【図18】
【図19】
【図2】
【図3】
【図4】
【図5】
【図6】
【図7】
【図8】
【図9】
【図10】
【図11】
【図12】
【図13】
【図14】
【図15】
【図16】
【図17】
【図18】
【図19】
【公開番号】特開2009−245184(P2009−245184A)
【公開日】平成21年10月22日(2009.10.22)
【国際特許分類】
【出願番号】特願2008−91323(P2008−91323)
【出願日】平成20年3月31日(2008.3.31)
【出願人】(000102728)株式会社エヌ・ティ・ティ・データ (438)
【Fターム(参考)】
【公開日】平成21年10月22日(2009.10.22)
【国際特許分類】
【出願日】平成20年3月31日(2008.3.31)
【出願人】(000102728)株式会社エヌ・ティ・ティ・データ (438)
【Fターム(参考)】
[ Back to top ]