JP2014038467A - 一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法 - Google Patents

一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法 Download PDF

Info

Publication number
JP2014038467A
JP2014038467A JP2012180236A JP2012180236A JP2014038467A JP 2014038467 A JP2014038467 A JP 2014038467A JP 2012180236 A JP2012180236 A JP 2012180236A JP 2012180236 A JP2012180236 A JP 2012180236A JP 2014038467 A JP2014038467 A JP 2014038467A
Authority
JP
Japan
Prior art keywords
variable
instruction
update
list
parallel
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
JP2012180236A
Other languages
English (en)
Inventor
Toshio Touchi
敏夫 登内
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
NEC Corp
Original Assignee
NEC Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by NEC Corp filed Critical NEC Corp
Priority to JP2012180236A priority Critical patent/JP2014038467A/ja
Publication of JP2014038467A publication Critical patent/JP2014038467A/ja
Pending legal-status Critical Current

Links

Images

Landscapes

  • Debugging And Monitoring (AREA)
  • Stored Programmes (AREA)

Abstract

【課題】一貫性破壊の障害検出を短い時間で行え、かつ誤検出が少ない一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法を提供する。
【解決手段】一貫性破壊検出装置2000は、並行メソッド抽出部2200、更新系メソッド抽出部2400、及びプローブ挿入部2600を有する。並行メソッド抽出部2200は、プログラム10から並行実行されうるメソッドである並行メソッドを抽出する。更新系メソッド抽出部2400は、並行メソッドのうち、スレッド間の共有変数を更新するものをスレッドアンセーフな並行メソッドとし、スレッド間で共有され、かつスレッドアンセーフな並行メソッドが更新する変数を更新変数とし、「スレッドアンセーフな並行メソッド、更新変数」の組み合わせを抽出する。プローブ挿入部2600は、上記スレッドアンセーフな並行メソッド内において、上記更新変数を更新する命令の前又は後ろにプローブを挿入する。
【選択図】図1

Description

本発明は、一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法に関する。
コンピュータプログラムの信頼性を向上させるため、テスト時や運用時において、プログラムの並行実行により発生する一貫性破壊を検出することが求められている。ここでいう一貫性破壊とは、変数を共有する複数のスレッドが、その共有されている変数に対して同時にアクセスすることにより、プログラムの実行状態が、プログラマの意図とは異なる状態になることを指す。
特許文献1には、静的解析技術とモデル検査技術を使って、並行性による一貫性破壊 (データレース)の発生のエラートレースを、実行時前に発見する方法を提案している。
非特許文献1には、静的解析によりJava(登録商標)プログラムのバグの可能性を実行前に検出するツールが記載されている。上記ツールでは、プログラムの実行前に、そのプログラムに含まれるスレッドアンセーフなメソッドに対して、スレッドアンセーフであることを示す注釈(annotation)をプログラマが与える。そして、上記ツールは、注釈が与えられたメソッドに対し、並行同時実行する可能性があるかを静的に解析する。
特開2009−123216号公報
Nathaniel Ayewah、J. David Morgenthaler、William Pugh、「Evaluating Static Analysis Defect Warnings On Production Software」、7th ACM SIGPLAN-SIGSOFT Workshop on Program Analysis for Software Tools and Engineering、Advanced Computing Machinery (ACM)、2007年6月13日
一貫性破壊検出装置による一貫性破壊の障害検出にかかる時間を短くする必要がある。特許文献1に記載されているようなモデル検査を用いる検出方法は、プログラムの大きさに対し、指数的に検査に要する時間が長くなる。そのため、モデル検査を用いる方法を、実用的な規模のプログラムの検査に用いると、一貫性破壊の障害検出に長い時間を要する。また、非特許文献1に記載されている技術は、プログラムに注釈を記述する作業に時間がかかるため、一貫性破壊検出にかかる時間が長い。これは、非特許文献1に記載されている技術の場合、プログラマが人手でプログラムを解読し、一貫性破壊の障害が起こりうる箇所を見つけ出して注釈を入れる必要があるためである。
本発明の目的は、一貫性破壊の障害検出を短い時間で行う一貫性破壊検出装置、及びコンピュータが一貫性破壊検出を行うためのプログラム、及びコンピュータが一貫性破壊の検出を行う方法を提供することである。
本発明が提供する一貫性破壊検出装置は、プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出手段と、前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出手段と、前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムに検査用の命令列を挿入するプローブ挿入手段を有する。
本発明が提供する一貫性破壊検出プログラムは、コンピュータに、並行実行されるプログラムにおける一貫性破壊を検出する機能を持たせる。当該プログラムは、前記コンピュータに、プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出機能と、前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出機能と、前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムに検査用の命令列を挿入するプローブ挿入機能を持たせる。
本発明が提供する一貫性破壊検出方法は、コンピュータが、並行実行するプログラムにおける一貫性破壊を検出する一貫性破壊検出方法である。当該一貫性破壊検出方法は、前記コンピュータが、プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出ステップと、前記コンピュータが、前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出ステップと、前記コンピュータが、前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムに検査用の命令列を挿入するプローブ挿入ステップを有する。
本発明によれば、一貫性破壊の障害検出を短い時間で行う一貫性破壊検出装置、及びコンピュータが一貫性破壊検出を行うためのプログラム、及びコンピュータが一貫性破壊の検出を行う方法が提供される。
実施形態1に係る一貫性破壊検出装置を表すブロック図である。 並行メソッド抽出部を表すブロック図である。 コールフローグラフ生成部を表すブロック図である。 更新系メソッド抽出部を表すブロック図である。 構造化制御フローグラフ生成部を表すブロック図である。 変数リストの構成を表す図である。 一貫性破壊検出装置による処理の流れの一例を表すフローチャートである。 並行メソッド抽出部による処理の流れの一例を表すフローチャートである。 コールフローグラフ生成部による処理の流れの一例を表すフローチャートである。 更新系メソッド抽出部による処理の流れの一例を表すフローチャートである。 構造化制御フローグラフ生成部による処理の流れの一例を表すフローチャートである。 更新変数分析部による処理全体の流れの一例を表すフローチャートである。 更新変数分析部による命令分析処理の流れの一例を表すフローチャートである。 実施形態2に係るコールフローグラフ生成部を表すブロック図である。 実施形態2に係るコールフローグラフ生成部による処理全体の流れの一例を表すフローチャートである。 実施例のプログラムに関するクラス階層グラフを示す図である。 実施例のプログラムにおいて、Counter#incを起点メソッドとするコールフローグラフを示す図である。 実施例のプログラムにおける構造化制御フローグラフを示す図である。 実施例における初期化時の変数リスト、及び実施例において変更された変数リストを示す図である。 実施例におけるスレッドアンセーフな並行メソッドと更新変数リストの組み合わせを示す図である。
以下、本発明の実施の形態について、図面を用いて説明する。尚、すべての図面において、同様な構成要素には同様の符号を付し、適宜説明を省略する。
なお、以下に示す説明において、各装置の各構成要素は、ハードウエア単位の構成ではなく、機能単位のブロックを示している。各装置の各構成要素は、任意のコンピュータのCPU、メモリ、メモリにロードされた本図の構成要素を実現するプログラム、そのプログラムを格納するハードディスクなどの記憶メディア、ネットワーク接続用インタフェースを中心にハードウエアとソフトウエアの任意の組合せによって実現される。そして、その実現方法、装置には様々な変形例がある。
[実施形態1]
<概要>
図1は、 本実施形態における一貫性破壊検出装置2000を、その使用環境と共に示す図である。図において、矢印は情報の流れを示す。
一貫性破壊検出装置2000は、並行メソッド抽出部2200を有する。並行メソッド抽出部2200は、プログラム10を取得する。プログラム10は、ソースコード、バイトコード、又はバイトコードに相当する実行媒体である。そして並行メソッド抽出部2200は、プログラム10の中から、実行時に並行に動作しうるメソッド(以下、並行メソッド)を抽出し、並行メソッドのリスト(以下、並行メソッドリスト)を生成する。
一貫性破壊検出装置2000は、更新系メソッド抽出部2400を有する。更新系メソッド抽出部2400は、プログラム10、及び並行メソッドリストを取得する。そして、更新系メソッド抽出部2400は、並行メソッドリストに含まれる並行メソッドの中から、スレッド間で共有される変数を更新するメソッドを、スレッドアンセーフな並行メソッドとして抽出する。また、更新系メソッド抽出部2400は、スレッド間で共有される変数であり、かつ、上記スレッドアンセーフな並行メソッドによって更新される変数を、更新変数として抽出し、更新変数のリスト(以下、更新変数リスト)を生成する。更新系メソッド抽出部2400は、「スレッドアンセーフな並行メソッド、そのメソッドに関する更新変数リスト」の組み合わせを抽出する。
一貫性破壊検出装置2000はさらに、プローブ挿入部2600を有する。プローブ挿入部2600は、「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせに基づき、プログラム10に対し、一貫性破壊検出用の命令列を挿入する。具体的には、プローブ挿入部2600は、上記スレッドアンセーフな並行メソッド内における、上記更新変数リストに含まれる更新変数を更新する命令の前、又は後ろに、上記一貫性破壊検出用の命令列を挿入する。以下、一貫性破壊障害検出用の命令列を、プローブと呼ぶ。そして、プローブ挿入部2600は、プローブを挿入したプローブ入りプログラム20を生成する。
以上のように、本実施形態における一貫性破壊検出装置2000は、並行メソッド抽出部2200、更新系メソッド抽出部2400、及びプローブ挿入部2600により、「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせを抽出する。そして、その組み合わせに基づき、プログラム10にプローブを挿入し、プローブ入りプログラム20を生成する。こうすることで、プログラム10のうち、一貫性破壊の原因となる可能性がある箇所にプローブを挿入する。プローブ入りプログラム20を実行すると、一貫性破壊が起こった場合に、その一貫性破壊を検出することができる。一貫性破壊検出装置2000は、プログラム10の中から、実行時に並行実行されうるメソッド(並行メソッド)を抽出し、抽出した並行メソッドに関してのみ一貫性破壊が起こるか否かを検証する。そのため、一貫性破壊検出装置2000は、プログラムの実行経路を網羅的に検査するモデル検査に比べ、一貫性破壊の検出にかかる時間を短くすることができる。さらに、一貫性破壊検出装置2000は、プローブ入りプログラム20において、プローブが挿入されている部分、つまりは、一貫性破壊の障害が起こりうる部分が実際に実行された場合のみ、一貫性破壊障害の検出が行われる。そのため、一貫性破壊検出装置2000は、一貫性破壊障害の誤検出を少なくすることができる。
以下、本実施形態の詳細を述べる。
<並行メソッド抽出部2200の構成詳細>
並行メソッド抽出部2200の構成は、例えば図2のブロック図に示す構成である。図2に示す並行メソッド抽出部2200は、並行API抽出部2220、コールフローグラフ生成部2240、及びコールフロートレース部2260を有する。
並行API抽出部2220は、プログラム10を取得する。そして、並行API抽出部2220は、プログラム10の中から、並行に実行されるメソッド列の起点となるメソッドを抽出し、起点メソッドとする。並行API抽出部2220が、起点メソッドを抽出する方法は様々である。並行API抽出部2220は例えば、プログラム10を記述するために提供されているスレッドライブラリを取得し、上記スレッドライブラリにおいて並行命令を開始するメソッドを特定する。例えば、Java(登録商標)におけるThread#runのオーバライドメソッドや、C言語におけるpthread_create関数に引数として与える関数である。そして、並行メソッド抽出部2200は、プログラム10の中から、特定した並行命令を開始するメソッドを割り出し、起点メソッドとする。その他にも例えば、起点メソッドになりうるメソッドの一覧を手動、もしくはファイル等を通じて入力して並行メソッド抽出部2200に与えてもよい。
プログラム10において、起点メソッドは複数あってもよい。その場合、起点メソッドごとに、並行メソッドリストを生成する。
コールフローグラフ生成部2240は、プログラム10、及び並行API抽出部2220が抽出した起点メソッドを取得する。そして、コールフローグラフ生成部2240は、上記起点メソッドを始点ノードとしたプログラム10のコールフローグラフ90を生成する。コールフローグラフ生成部2240の詳細については、後述する。
コールフロートレース部2260は、コールフローグラフ生成部2240が生成したコールフローグラフを取得する。そして、コールフロートレース部2260は、コールフローグラフに含まれるメソッドを並行メソッドとする並行メソッドリスト30を生成する。
このように、一貫性破壊検出装置2000は、並行メソッド抽出部2200によって、起点メソッドを抽出し、起点メソッドから到達可能なメソッドのコールフローグラフ90を生成する。こうすることで、以降の解析の対象を、起点メソッドから到達可能なメソッドに絞り込む。こうすることで、一貫性破壊の危険性のあるメソッドを効率的かつ自動的にリストアップすることができる。
<コールフローグラフ生成部2240の構成詳細>
コールフローグラフ生成部2240の構成は、例えば図3のブロック図で表される。コールフローグラフ生成部2240は、メソッド内呼び出し抽出部2244を有する。メソッド内呼び出し抽出部2244は、プログラム10及び起点メソッド80を取得する。さらに、メソッド内呼び出し抽出部2244は、プログラム10の中から、起点メソッド80から到達可能なメソッドを1つずつ選択する。以下、メソッド内呼び出し抽出部2244が選択したメソッドを選択メソッドと表記する。次に、メソッド内呼び出し抽出部2244は、上記選択メソッドごとに、選択メソッドの内部から呼び出されるメソッド(以下、呼び出し先メソッド)を抽出する。そして、メソッド内呼び出し抽出部2244は、上記選択メソッドごとに、「選択メソッド、呼び出し先メソッド」の組み合わせを示す呼び出し先メソッドリストを生成する。
コールフローグラフ生成部2240はさらに、グラフ生成部2246を有する。グラフ生成部2246は、呼び出し先メソッドリストに基づいて、コールフローグラフ90を生成する。具体的にはまず、グラフ生成部2246は、呼び出し先メソッドリストに基づき、始点ノードが選択メソッドであり、終端ノードが呼び出し先メソッドである部分グラフを生成する。そしてグラフ生成部2246は、生成した全ての部分グラフを、同じメソッドを示すノードを重ね合わせて連結することで、コールフローグラフ90を生成する。生成されたコールフローグラフ90は、始点ノードが起点メソッドであり、起点メソッドから到達しうるメソッド間のコールフローを示すコールフローグラフとなる。
<更新系メソッド抽出部2400の構成詳細>
更新系メソッド抽出部2400の構成は、例えば図4に示すブロック図で表される。図4に示す更新系メソッド抽出部2400は、メソッド取得部2420、構造化制御フローグラフ生成部2440、及び更新変数分析部2460を有する。
メソッド取得部2420は、並行メソッドリスト30を取得する。そして、メソッド取得部2420は、並行メソッドリスト30に示されている並行メソッドの中から1つを選択し、選択した並行メソッドの定義であるメソッド定義40を取得する。ここで、メソッドの定義とは、プログラム10において、そのメソッドを表す命令列を指す。例として、以下にtestというメソッドの定義を示す。
int test(int x){
int y = 2;
return x+y;
}
構造化制御フローグラフ生成部2440は、メソッド取得部2420が取得したメソッド定義40における制御の流れを解析し、その制御の流れを表す制御フローグラフに、メソッド定義40に含まれる各分岐命令の種類を示す分岐識別情報を付加した構造化制御フローグラフを生成する。
更新変数分析部2460は、構造化制御フローグラフ生成部2440が生成した構造化制御フローグラフを取得する。そして、更新変数分析部2460は、構造化制御フローグラフを解析し、メソッド取得部2420が選択した並行メソッド内の変数の中から、スレッド間で共有される可能性があり、かつ、更新される可能性がある変数を、更新変数として抽出する。更新変数分析部2460は、上記選択した並行メソッドにおいて、更新変数が1つ以上存在した場合、上記選択した並行メソッドをスレッドアンセーフな並行メソッド50とする。また、更新変数分析部2460は、抽出された更新変数のリストを生成し、更新変数リスト60とする。そして、更新変数分析部2460は、スレッドアンセーフな並行メソッド50と更新変数リスト60を対応づけて抽出する。
<構造化制御フローグラフ生成部2440の構成詳細>
構造化制御フローグラフ生成部2440の構成は、例えば図5に示すブロック図で表される。図5に示す構造化制御フローグラフ生成部2440は、初期制御フローグラフ生成部2442、ループ抽出部2444、条件分岐抽出部2446、及び構造化部2448を有する。
初期制御フローグラフ生成部2442は、メソッド定義40を取得する。そして、初期制御フローグラフ生成部2442は、メソッド定義40で表される命令の制御の流れを示す初期制御フローグラフを生成する。
ループ抽出部2444は、初期制御フローグラフを取得する。そして、ループ抽出部2444は、初期制御フローグラフからループ処理を抽出する。ループ処理とは、一定の条件を満たす間、又は一定の条件を満たさない間、繰り返し行われる命令列から構成される処理である。さらに、ループ抽出部2444は、上記ループ処理の継続又は終了を判定する命令(以下、ループ判定命令)をループリストに登録する。
条件分岐抽出部2446は、初期制御フローグラフ及びループリストを取得する。そして、条件分岐抽出部2446は、初期制御フローグラフから分岐命令を抽出し、抽出した分岐命令がループリストに含まれていなければ、その分岐命令を条件分岐命令として、条件分岐リストに登録する。
構造化部2448は、ループリスト及び条件分岐リストを参照しながら初期制御フローグラフを解析する。そして、構造化部2448は、初期制御フローグラフに含まれる各分岐命令に対し、ループ判定命令であるか、条件分岐命令であるかを示す分岐識別情報を付加した構造化制御フローグラフ70を生成する。
<更新変数分析部2460の詳細>
更新変数分析部2460は、構造化制御フローグラフ70を取得する。そして、更新変数分析部2460は、空の変数リストを生成する。変数リストは、変数の更新の有無を示す情報である更新情報、及び、その変数と同一のアドレスを参照している他の変数を示す情報である同一参照情報を有する。
変数リストの一例は、例えば図6に示す変数リスト200である。変数リスト200は、変数識別子210、更新情報220、及び参照先同一変数情報230を有する。例えば、図6に示す変数表200の1行目のレコードは、変数xは更新されていること、及び、変数xは変数aと同じアドレスを参照していることを示している。
更新変数分析部2460は、構造化制御フローグラフ70が示す命令ごとに、その命令が操作対象としている変数の更新の有無を調べる。変数が更新されていた場合、更新変数分析部2460は、その変数に関する変数リストのレコードの更新情報を「更新あり」とする。
また、更新変数分析部2460は、構造化制御フローグラフ70が示す命令ごとに、その命令によって、2つ以上の変数が同一のアドレスを参照するようになったか否かを調べる。上記命令によって2つ以上の変数が同一のアドレスを参照するようになった場合、命令分析部2462は、上記変数リストにおける上記各変数の同一参照情報に、同一のアドレスを参照するようになった他の変数を追加する。
更新変数分析部2460は、変数リストを参照し、更新情報が更新有りを示している変数を更新変数とし、更新変数リストに加える。また、更新変数分析部2460は、変数リストを参照し、更新情報が更新有りとなっている変数に関するレコードにおいて、同一参照情報に示されている変数も、更新変数リストに加える。
<プローブ挿入部2600の詳細>
プローブ挿入部2600は、プログラム10、及び「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせを取得する。そして、プログラム10のうち、一貫性破壊の可能性がある箇所に、プローブを挿入し、プローブ入りプログラム20を生成する。具体的には、プローブ挿入部2600は、プログラム10において、上記スレッドアンセーフな並行メソッド内にある、上記更新変数リストに含まれる更新変数を更新する命令の前又は後ろにプローブを挿入する。ここで、プローブを挿入する箇所は、更新変数を更新する命令の直前又は直後には限定されない。更新変数を更新する命令とプローブの間に、他の命令があってもよい。
プローブ挿入部2600が挿入するプローブは様々である。例えばプローブ挿入部2600は、スレッドアンセーフな並行メソッドにおいて、更新変数リストに示されている変数を更新する前の部分に、時刻を記録するプローブを挿入する。さらに、プローブ挿入部2600は、上記並行メソッドにおいて、上記変数を更新した後の部分に、変数更新前に記録した時刻の変更の有無を確認し、時刻が変更されていた場合はエラーを出力するプローブを挿入する。並行メソッドにおいて、変数更新前に記録した時刻が、変数更新後に変更されている場合、他のスレッドによって再度変数が更新されたことを意味する。したがって、上記プローブが挿入されたプローブ入りプログラム20を実行すると、一貫性破壊の障害が起こった場合は、上記プローブによってエラーが出力される。そのため、上記プローブ入りプログラム20を実行することで、一貫性破壊の障害を検出することができる。
<一貫性破壊検出装置2000による処理の流れ>
図7は、一貫性破壊検出装置2000がプログラム10に対してプローブを挿入する処理の全体的な流れの一例を表すフローチャートである。
ステップS102において、並行メソッド抽出部2200は、対象のプログラム10を取得する。
ステップS104において、並行メソッド抽出部2200は、取得したプログラム10を解析し、並行メソッドリス30トを生成する。
ステップS106において、更新系メソッド抽出部2400は、並行メソッドリスト30に含まれるメソッドの中から、「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせを抽出する。
ステップS108において、プローブ挿入部2600は、「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせに基づいてプログラム10へプローブを挿入し、プローブ入りプログラム20を生成する。
<並行メソッド抽出部2200による処理の流れ>
図8は、並行メソッド抽出部2200が、並行メソッドリストを作成する処理の流れの一例を表すフローチャートである。
ステップS202において、並行メソッド抽出部2200は、プログラム10を取得する。
ステップS204において、並行API抽出部2220は、プログラム10から、起点メソッド80を抽出する。
ステップS206において、コールフローグラフ生成部2240は、プログラム10に基づき、上記起点メソッド80を始点ノードとするコールフローグラフ90を生成する。
ステップS208において、コールフロートレース部2260は、上記コールフローグラフ90を辿り、コールフローグラフ90に含まれるメソッドを並行メソッドとする並行メソッドリスト30を生成する。
<コールフローグラフ生成部2240による処理の流れ>
図9は、コールフローグラフ生成部2240による処理の流れの一例を示すフローチャートである。
ステップS702において、コールフローグラフ生成部2240は、プログラム10を取得する。
ステップS704において、コールフローグラフ生成部2240は、起点メソッド80を取得する。
ステップS706において、コールフローグラフ生成部2240は、空の集合Sに起点メソッド80を加える。
ステップS708〜ステップS720は、集合Sにメソッドが含まれる間行うループ処理Aである。ステップS708において、コールフローグラフ生成部2240は、集合Sにメソッドが含まれるか否かをチェックする。集合Sにメソッドが含まれる場合、コールフローグラフ生成部2240は、集合Sに含まれるメソッドから1つを取り出し、ステップS710に進む。集合Sにメソッドが含まれない場合、コールフローグラフ生成部2240は、ステップS722に進む。
ステップS710において、コールフローグラフ生成部2240は、集合Sと同じ要素から成る集合Vを生成する。そして、集合Sを空にする。
ステップS712〜ステップS718は、集合Vに含まれる各メソッドiについて行うループ処理Bである。ステップS712において、コールフローグラフ生成部2240は、集合Vに含まれる全てのメソッドをループ処理Bの対象としたかをチェックする。集合Vの中にループ処理Bの対象としていないメソッドがある場合、その中から1つを選択してメソッドiとし、ステップS714に進む。一方、集合Vに含まれる全てのメソッドについてループ処理Bを終えている場合、ステップS720に進む。
ステップS714において、メソッド内呼び出し抽出部2244は、メソッドiを選択メソッドとして、呼び出し先メソッドリストを生成する。
ステップS716において、コールフローグラフ生成部2240は、メソッドiの各呼び出し先メソッドを、集合Sに加える。
ステップS718は、ループ処理Bの終端である。そのため、ステップS712に戻る。
ステップS720は、ループ処理Aの終端である。そのため、ステップS708に戻る。
ステップS722において、グラフ生成部2246は、呼び出し先メソッドリストに基づき、コールフローグラフ90を生成する。
<更新系メソッド抽出部2400による処理の流れ>
図10は、更新系メソッド抽出部2400による処理の流れの一例を示すフローチャートである。
ステップS302において、メソッド取得部2420は、並行メソッドリスト30を取得する。
ステップS304〜ステップS312は、並行メソッドリスト30に含まれる各並行メソッドについてそれぞれ行うループ処理Aである。まず、ステップS304において、メソッド取得部2420は、並行メソッドリスト30に含まれる全ての並行メソッドについてループ処理Aを行ったかをチェックする。まだループ処理Aの対象としていない並行メソッドがある場合、その中から1つを選択し、ステップS306に進む。一方、全ての並行メソッドについてループ処理Aを終えている場合は、ステップS314に進む。
ステップS306において、メソッド取得部2420は、上記選択した並行メソッドについて、メソッド定義40を取得する。
ステップS308において、構造化制御フローグラフ生成部2440は、上記メソッド定義40に基づいて、構造化制御フローグラフを生成する。
ステップS310において、更新変数分析部2460は、構造化制御フローグラフを解析する。そして、上記選択した並行メソッドについて、更新変数リスト60を生成する。ここで、変数の更新を行わない並行メソッドの場合は、例えば更新変数リスト60が空のリストとなる。
ステップS312は、ループ処理Aの終端である。そのため、ステップS304に戻る。
ステップS314において、更新変数分析部2460は、「スレッドアンセーフな並行メソッド、その並行メソッドに関する更新変数リスト60」の組み合わせを抽出する。
<構造化制御フローグラフ生成部2440による処理の流れ>
図11は、構造化制御フローグラフ生成部2440による処理の流れの一例を示すフローチャートである。
ステップS402において、初期制御フローグラフ生成部2442は、メソッド定義40を取得する。
ステップS404において、初期制御フローグラフ生成部2442は、メソッド定義40に基づき、初期制御フローグラフを生成する。
ステップS406において、ループ抽出部2444は、初期制御フローグラフを辿ってループ判定命令を抽出し、抽出したループ判定命令の一覧を示すループリストを生成する。
ステップS408において、条件分岐抽出部2446は、初期制御フローグラフを辿って分岐命令を抽出する。そして、抽出した分岐命令のうち、ループリストに含まれていない分岐命令を条件分岐命令として抽出し、抽出した条件分岐命令の一覧を示す条件分岐リストを生成する。
ステップS410において、構造化部2448は、初期制御フローグラフ、ループリスト、及び条件分岐リストに基づき、構造化制御フローグラフを生成する。
<更新変数分析部2460による処理の流れ>
図12は、更新変数分析部2460による更新変数分析処理の流れの一例を示すフローチャートである。
ステップS502において、更新変数分析部2460は、構造化制御フローグラフを取得する。
ステップS503において、更新変数分析部2460は、変数リスト、及び参照先同一変数リストを初期化する。
ステップS504〜ステップS528は、構造化制御フローグラフから読み込んでいないノードがある間行うループ処理Aである。ステップS504において、更新変数分析部2460は、ステップS502で取得した構造化制御フローグラフに、まだ読み込んでいないノードがあるか否かをチェックする。まだ読み込んでいないノードがある場合、更新変数分析部2460は、先頭のノードを読み込む。すでに全てのノードを読み込んでいる場合、更新変数分析部2460は、ステップS530に進む。
ステップS506において、更新変数分析部2460は、ステップS504で読み込んだノードが示す命令を分析し、変数リストを更新する。ステップS506における処理の詳細は後述する(図13参照)。
ステップS508において、更新変数分析部2460は、ステップS504で読み込んだノードに付加されている分岐識別情報によって、処理を分岐する。上記ノードに条件分岐命令を示す分岐識別情報が付加されている場合、ステップS510に進む。上記ノードにループ判定命令を示す分岐識別情報が付加されている場合、ステップS520に進む。上記ノードに分岐識別情報が付加されていない場合、ステップS528に進む。
ステップS510〜ステップS518は、上記ノードが示す命令を始点とする条件分岐の各分岐について行うループ処理Bである。ステップS510において、更新変数分析部2460は、全ての分岐についてループ処理Bを行ったか否かをチェックする。まだループ処理Bを行っていない分岐がある場合は、分岐を一つ選択し、ステップS512に進む。すでに全ての分岐についてループ処理Bを終えている場合は、ステップS528に進む。
ステップS512において、変数リスト、及び命令分析に用いる一時作業領域をコピーする。
ステップS514において、更新変数分析部2460は、ステップS502で取得した構造化制御フローグラフの内、ステップS510で選択した分岐の開始ノードから、上記分岐が終了する合流ノードまでの間の部分グラフを入力として、更新変数分析処理を再帰実行する。再帰実行する更新変数分析処理において、更新変数分析部2460は、上記部分グラフを構造化制御フローグラフとして取得する。また、再帰実行する更新変数分析処理において、更新変数分析部2460は、ステップS512でコピーした変数リスト及び一時作業領域を利用する。
ステップS516において、更新変数分析部2460は、ステップS514における処理で変更された変数リスト及び一時作業領域のコピーを、コピー元の変数リスト及び一時作業領域にマージする。
ステップS518は、ループ処理Bの終端である。そのため、ステップS510に戻る。
ステップS520〜ステップS526は、ステップS504で選択したノードにループ判定命令を示す分岐識別情報が付加されている場合に行うループ処理Cである。ステップS520は、ループ処理Cの開始処理である。
ステップS522において、更新変数分析部2460は、参照先同一変数リストに、変数リストの内容を追加する。具体的には、更新変数分析部2460は、変数リストの参照先同一変数情報において参照先が同一であると示されている変数を、参照先同一変数とし、参照先同一変数リストに加える。
ステップS524において、更新変数分析部2460は、ステップS502で取得した構造化制御フローグラフの内、ステップS504で読み込んだノードの次のノードから、ループ処理の終端ノードまでのノードで構成される部分グラフを入力として、更新変数分析処理を再帰実行する。再帰実行する更新変数分析処理において、更新変数分析部2460は、上記部分グラフを構造化制御フローグラフとして取得する。
ステップS526は、ループ処理Cの終端である。更新変数分析部2460は、現在の変数リスト及び参照先同一変数リストを、前回のループ処理Cの終了時における変数リスト又は参照先同一変数リストと比較する。更新変数分析部2460は、変数リスト又は参照先同一変数リストのいずれかが変更されていた場合は、さらにループ処理Cを行うため、ステップS520に戻る。一方、変数リスト及び参照先同一変数リストの双方が変更されていない場合、更新変数分析部2460は、ループ処理Cを終えてステップS528に進む。
ステップS528は、ループ処理Aの終端である。そのため、ステップS504に戻る。
ステップS530において、更新変数分析部2460は、更新変数リストを生成する。具体的にはまず、更新変数分析部2460は、空の更新変数リストを生成する。そして、更新変数分析部2460は、変数リストにおいて、更新情報が「更新有り」となっている変数を、更新変数リストに追加する。また、変数リストにおいて、更新情報が「更新有り」となっている変数に関する参照先同一変数情報が示している他の変数も、更新変数リストに加える。さらに、参照先同一変数リストにおいて、更新変数リストが示している変数と参照先が同一であると示されている変数も、更新変数リストに加える。
<命令分析処理の流れ>
図13は、更新変数分析部2460が図12のステップS504において行う命令分析処理の流れの一例を示すフローチャートである。
ステップS602において、更新変数分析部2460は、命令の種類を特定し、命令の種類によって以降の処理を分岐する。分析する命令がLoad系命令の場合、ステップS604に進む。ここで、Load系命令とは、変数の内容を一時作業領域にコピーする命令を指す。分析する命令がStore系命令の場合、ステップS606に進む。ここで、Store系命令とは、一時作業領域の内容を変数にコピーする命令を指す。分析する命令が更新系命令の場合、ステップS610に進む。更新系命令とは、変数の値を更新する命令を指す。分析する命令がメソッド呼び出しを行う命令の場合、ステップS614に進む。分析する命令が上記Load系命令、Store系命令、更新系命令、及びメソッド呼び出しを行う命令のいずれにも当てはまらない場合、ステップS620に進む。
上記一時作業領域は、例えばレジスタ、スタックなどである。本実施形態においては、スタックを一時作業領域とする場合を例に説明する。そのため、更新変数分析部2460は、分析用の一時作業領域として、スタックを用いる。以下、更新変数分析部2460が分析に用いるスタックを、分析用スタックと呼ぶ。
ステップS604は、分析する命令がLoad系命令の場合に行う処理である。ステップS604において、更新変数分析部2460は、Load系命令の対象としている変数の識別子を、分析用スタックにpushする。
ステップS606〜ステップS608は、分析する命令がStore系命令の場合に行う処理である。まず、ステップS606において、分析用スタックに格納されている変数の識別子をpopする。
ステップS608において、更新変数分析部2460は、変数リストを更新する。具体的には、ステップS606でpopした変数と、Store系命令が対象としている変数に関する参照先同一変数情報を更新し、お互いに参照先が同一であるとする。
ステップS610〜ステップS612は、分析する命令が更新系命令である場合の処理である。まずステップS610において、更新変数分析部2460は、命令の内容に従って分析用スタックを操作する。具体的には、更新変数分析部2460は、その命令を実行した際に、実行中のプログラムの一時作業領域であるスタックに適用される操作と同じ操作を、分析用スタックに対して行う。
ステップS612において、更新変数分析部2460は、上記更新系命令が更新対象としている変数について、変数リストの更新情報を更新し、「更新有り」とする。
ステップS614〜ステップS618は、分析する命令がメソッド呼び出しの場合の処理である。まずステップS614において、更新変数分析部2460は、ステップS610と同様に、命令の内容に従って分析用スタックを操作する。
ステップS616において、更新変数分析部2460は、呼び出すメソッドについて作成された更新変数リストを取得する。
ステップS618において、更新変数分析部2460は、変数リストが示す変数であり、かつ取得した上記更新変数リストに示されている変数に関し、変数リストの更新情報を更新有りに変更する
ステップS620は、分析する命令が上記Load系命令、Store系命令、更新系命令、及びメソッド呼び出しを行う命令のいずれにも当てはまらない場合の処理である。ステップS620において、更新変数分析部2460は、ステップS610と同様に、命令の内容に従って分析用スタックを操作する。
<作用・効果>
以上の構成により、本実施形態に係る一貫性破壊検出装置2000は、並行メソッド抽出部2200により、プログラム10の中から、実行時に並行に動作しうる並行メソッドを抽出し、並行メソッドリストを生成する。また、一貫性破壊検出装置2000は、更新系メソッド抽出部2400により、「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせを抽出する。そして、一貫性破壊検出装置2000は、プローブ挿入部2600により、「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせに基づき、プログラム10において、上記スレッドアンセーフな並行メソッド内にある、上記更新変数リストに含まれる更新変数を更新する命令の前又は後ろにプローブを挿入して、プローブ入りプログラム20を生成する。一貫性破壊検出装置2000を利用すると、プログラム10を実行した時に実際に通る実行経路においてのみ、一貫性破壊の障害の検出が行われる。したがって、一貫性破壊検出装置2000は、プログラムを網羅的に検査するモデル検査と比べ、短い時間で一貫性破壊の障害の検出を行うことができる。また、一貫性破壊検出装置2000を利用すると、一貫性破壊障害の誤検出を少なくすることができる。これは、プローブ入りプログラム20を実行して一貫性破壊を検出する場合、一貫性破壊の検出は、実際に一貫性破壊が起こった場合にのみ行われるためである。
[実施形態2]
<構成>
実施形態2に係る一貫性破壊検出装置2000は、クラス階層を持つプログラムに対して、一貫性破壊障害を検出するためのプローブを挿入する機能を有する。クラス階層を有するプログラムの例としては、Java(登録商標)やSmalltalk等のオブジェクト指向言語で記述されたプログラムがある。本実施形態における一貫性破壊検出装置2000は、コールフローグラフ生成部2240により、クラス階層を考慮したコールフローグラフ90を生成する。
図14は、実施形態2に係るコールフローグラフ生成部2240を表すブロック図である。図14において、図3に同符号の機能ブロックが示されている機能ブロックは、図3における同符号の機能ブロックと同じ機能を有する。そのため、それらの機能ブロックについては、適宜説明を省略する。
本実施形態におけるコールフローグラフ生成部2240は、さらにクラス階層抽出部2248及びオーバライドメソッド抽出部2250を有する。クラス階層抽出部2248は、プログラム10を取得する。そして、クラス階層抽出部2248は、プログラム10に含まれる各クラス間の階層関係を表すクラス階層グラフを生成する。
オーバライドメソッド抽出部2250は、メソッド内呼び出し抽出部2244が生成した呼び出し先メソッドリスト、及びクラス階層抽出部2248が生成したクラス階層グラフを参照し、呼び出し先メソッドリストに含まれる各呼び出し先メソッドのオーバライドメソッドを割り出す。そして、上記オーバライドメソッドを示すオーバライドメソッドリストを生成する。
本実施形態におけるグラフ生成部2246は、呼び出し先メソッドリスト及びオーバライドメソッドリストを参照し、コールフローグラフ90を生成する。具体的にはまず、グラフ生成部2246は、呼び出し先メソッドリストに基づき、始点ノードが選択メソッドであり、終端ノードが呼び出し先メソッド、及び各呼び出し先メソッドのオーバライドメソッドである部分グラフを生成する。そして、グラフ生成部2246は、各部分グラフを連結して、コールフローグラフ90を生成する。生成されたコールフローグラフ90は、始点ノードが起点メソッドであり、起点メソッドから到達しうるメソッド、及び各メソッドのオーバライドメソッド間のコールフローを示すコールフローグラフとなる。
<実施形態2におけるコールフローグラフ生成部2240による処理の流れ>
図15は、実施形態2におけるコールフローグラフ生成部2240による処理の流れの一例を示すフローチャートである。ここで、図15のフローチャートは、ステップS802、S804、及びS806を除き、図9のフローチャートと同じである。そのため、図9に含まれるステップについては、適宜説明を省略する。
ステップS802において、クラス階層抽出部2248は、クラス階層グラフを生成する。
ステップS804において、オーバライドメソッド抽出部2250は、ステップS714で生成された呼び出し先メソッドリストに含まれる各呼び出し先メソッドについて、オーバライドメソッドリストを生成する。
ステップS806において、グラフ生成部2246は、呼び出し先メソッドリスト及びオーバライドメソッドリストに基づいて、コールフローグラフ90を生成する。
<作用・効果>
以上の構成により、本実施形態に係る一貫性破壊検出装置2000は、クラス階層抽出部2248により、プログラム10におけるクラス間の階層構造を表すクラス階層グラフを生成する。また、一貫性破壊検出装置2000は、オーバライドメソッド抽出部2250により、呼び出し先メソッドリストが示すメソッドごとに、そのメソッドのオーバライドメソッドを示すオーバライドメソッドリストを生成する。そして、一貫性破壊検出装置2000は、グラフ生成部2246により、呼び出し先メソッドリスト及びオーバライドメソッドリストに基づいて、コールフローグラフ90を生成する。これにより、本実施形態におけるコールフローグラフ生成部2240が生成するコールフローグラフ90は、各メソッドから呼び出されうるメソッドとして、そのメソッドが内部から明示的に呼び出している呼び出し先メソッドだけでなく、呼び出し先メソッドのオーバライドメソッドも示す。こうすることで、クラス階層を有するプログラムについても、起点メソッドから到達しうる全てのメソッドを対象として、プローブを挿入することができる。
[実施例]
以下に、実施形態2に係る一貫性破壊検出装置2000の実施例を示す。なお、以下に示す実施例はあくまで例示である。上述した実施形態は、下記実施例によって何ら限定を受けない。
まず、次のJava(登録商標)プログラムのソースコードが与えられているとする。
public class ConcurrentMain implements Runnable {
private Thread t;
static Counter c = new Counter(0);
public static void main(String[] args) {
ConcurrentMain t1 = new ConcurrentMain();
ConcurrentMain t2 = new ConcurrentMain();
System.out.println("cnt=" + ConcurrentMain.c.getVal());
}
public ConcurrentMain() {
t = new Thread(this);
t.start();
}
@Override
public void run() {
ConcurrentMain.c.inc();
}
}
public class Counter {
public Counter(int cnt) {
this.cnt = cnt;
}
private int cnt;
void inc() { cnt++; }
int getVal() { return cnt; }
}
これをjavac等のコマンドでコンパイルしたバイトコードは、以下のとおりである。以下、このバイトコードをプログラム10とする。
Compiled from "ConcurrentMain.java"
public class ConcurrentMain implements java.lang.Runnable {
static Counter c;

static {};
Code:
0: new #14 // class Counter
3: dup
4: iconst_0
5: invokespecial #16 // Method Counter."<init>":(I)V
8: putstatic #20 // Field c:LCounter;
11: return

public static void main(java.lang.String[]);
Code:
0: new #1 // class ConcurrentMain
3: dup
4: invokespecial #26 // Method "<init>":()V
7: astore_1
8: new #1 // class ConcurrentMain
11: dup
12: invokespecial #26 // Method "<init>":()V
15: astore_2
16: getstatic #28 // Field java/lang/System.out:Ljava/io/PrintStream;
19: new #34 // class java/lang/StringBuilder
22: dup
23: ldc #36 // String cnt=
25: invokespecial #38 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
28: getstatic #20 // Field c:LCounter;
31: invokevirtual #41 // Method Counter.getVal:()I
34: invokevirtual #45 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
37: invokevirtual #49 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
40: invokevirtual #53 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
43: return

public ConcurrentMain();
Code:
0: aload_0
1: invokespecial #63 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #64 // class java/lang/Thread
8: dup
9: aload_0
10: invokespecial #66 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
13: putfield #69 // Field t:Ljava/lang/Thread;
16: aload_0
17: getfield #69 // Field t:Ljava/lang/Thread;
20: invokevirtual #71 // Method java/lang/Thread.start:()V
23: return

public void run();
Code:
0: getstatic #20 // Field c:LCounter;
3: invokevirtual #76 // Method Counter.inc:()V
6: return
}

Compiled from "Counter.java"
public class Counter {
public Counter(int);
Code:
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: aload_0
5: iload_1
6: putfield #13 // Field cnt:I
9: return

void inc();
Code:
0: aload_0
1: dup
2: getfield #13 // Field cnt:I
5: iconst_1
6: iadd
7: putfield #13 // Field cnt:I
10: return

int getVal();
Code:
0: aload_0
1: getfield #13 // Field cnt:I
4: ireturn
}
まず、並行メソッド抽出部2200は、対象のプログラム10を解析し、並行メソッドリストを生成する(図8のステップS104)。その具体的な動作として、まず、並行API抽出部2220は、プログラム10を取得し、起点メソッドをもとめる(図7のステップS204)。Java(登録商標)の場合、並行APIは、Runnable#runのオーバライドメソッドか、Thread#runのオーバライドメソッドである。そのため、ConcurrentMain#run が起点メソッドとなる。
そして、コールフローグラフ生成部2240は、プログラム10を取得し、コールフローグラフ90を生成する(図8のステップS206)。その具体的な処理として、クラス階層抽出部2248は、プログラム10を読み込み、クラス階層グラフを生成する(図15のステップS802)。その例として、図16に示すクラス階層グラフを生成する。そして、メソッド選択部2242は、起点メソッドから到達しうる全てのメソッドに関して、図15のステップS712〜ステップS718のループ処理Bを行う。その結果として、プログラム10もしくは、それをコンパイルしたバイトコードをもとに、起点メソッドConcurrentMain#runを起点とする図17に示すコールフローグラフ90を生成する。すなわち、ConcurrentMain#runと、ConcurrentMain#runから呼び出されるCounter#inc()をノードとし、ConcurrentMain#runからCounter#inc()への有向辺を持つコールフローグラフ90を生成する。
そして、コールフロートレース部2260は、起点メソッドであるConcurrentMain#runと、起点メソッドから上記コールフローグラフ90を辿って得られるメソッドであるCounter#incの2つを並行メソッドとする並行メソッドリスト30を生成する(図8のステップS208)。
そして、更新系メソッド抽出部2400は、上記並行メソッドの中で、スレッド間で共有される変数が更新されるメソッドとその変数のリスト、すなわち、スレッドアンセーフな並行メソッドと、更新変数リストとを求める(図10)。例えばJava(登録商標)の場合、スレッド間で共有される可能性のある変数は、static変数、this変数、及びメソッドの仮引数のうち、オブジェクトへのポインタであるものである。
メソッド取得部2420は、並行メソッドリスト30から並行メソッドを1つ読み込み、そのメソッド定義40を得る(図10のステップS304及びS306)。そして、更新系メソッド抽出部2400は、図10のステップS304〜S312までのループ処理Aを、並行メソッドリスト30に含まれる全てのメソッドに適用するまで繰り返す。以下、並行メソッドの一つであるCounter#incを例として説明する。
図10のループ処理Aの内部において、構造化制御フローグラフ生成部2440はまず、Counter#incのメソッド定義40を読み込み、図18に示す構造化制御フローグラフ70を生成する(図10のステップS304及びS306)。
次に、更新変数分析部2460は、構造化制御フローグラフ70を読み込み、更新変数リストを生成する(図10のステップS310)。
図10のステップS310は、図11に示す一連の処理で構成される。変数リストの例を、図19(a)に示す。更新変数分析部2460は、変数リストにおいて、Counter#incの引数がないため、thisの識別子である0に関して、更新情報を「無し」に設定し、参照先同一変数情報には、自身と同じである0を示す。また、参照先同一変数リストについては、例えばループの脱出分岐節のアドレスを記入する。ただし、例のCounter#incはループ処理を有しないので、参照先同一変数リストは空表である。
更新変数分析部2460は、以下に示すように構造化制御フローグラフ70を辿り、命令分析を行う。ここで、更新変数分析部2460は一時領域としてスタックを用いるとする。以下、このスタックを分析用スタックと表記する。また、更新変数分析部2460が各命令を分析した後の分析用スタックの状態を、図18の構造化制御フローグラフ70の右側に示す。
更新変数分析部2460はまず、構造化制御フローグラフ70の先頭ノードである「0:aload_0」を読み込む(図12のステップS504)。そして、更新変数分析部2460は、読み込んだ命令の種類を調べる(図12のステップS506、及び図13のステップS602)。
aload_0はload系命令なので、更新変数分析部2460は、分析用スタックSを「S0」とする。これは、分析用スタックSに0番目の局所変数 (Java(登録商標)の場合はthis)を積むことを意味する(図13のステップS604)。
そして、更新変数分析部2460は、上記命令によって条件分岐が行われるかを調べる(図12のステップS508)。上記命令は、条件分岐を行わない命令である。したがって、更新変数分析部2460は、図12のステップS528に進んだ後、ステップS504に戻る。
更新変数分析部2460は、構造化制御フローグラフ70における次のノード「1:dup」を読み込み、命令の種類を調べる。dupは、Load系命令、Store系命令、更新系命令、及びメソッド呼び出し命令のいずれにも該当しない。そこで更新変数分析部2460は、図13のステップS620に進む。更新変数分析部2460は、dupが行うスタック操作を、分析用スタックに適用する。具体的には、dupは、スタックの先頭要素をコピーし、スタックにpushする命令である。したがって、更新変数分析部2460は、分析用スタックSを、「S0」から、「S00」に変更する。さらに更新変数分析部2460は、上記命令によって条件分岐が行われるか調べる。dupは条件分岐を伴わない命令なので、再度図12のステップS504に戻る。
そして、更新変数分析部2460は、構造化制御フローグラフ70の次の節「2:getfield#13」を1つ読み込み、命令の種類を調べる。getfieldは、Load系命令であり、まず、スタックの先頭にあるオブジェクトをpopする。本例の場合、スタックの先頭に積まれているのはCounterオブジェクトである。さらに、getieldは、popしたオブジェクトのフィールドの内、#で指定したフィールドの値を、スタックにpushする。本例の場合は、Counterオブジェクトのcntフィールドを、スタックにpushする。Counter#cntは整数型なので、更新変数分析部2460は、分析用スタックSに対し、単純型を表すマーク「*」を積む。つまり、スタック「S 0 0」を、スタック「S0*」に更新する。さらに更新変数分析部2460は、上記命令によって条件分岐が行われるか調べる。getfieldは条件分岐を伴わない命令なので、再度図12のステップS504に戻る。
更新変数分析部2460は、構造化制御フローグラフ70の次のノード「5:iconst_1」を読み込み、命令の種類を調べる。iconst_1は、定数1をスタックにプッシュするLoad系命令である。そこで、更新変数分析部2460は、分析用スタックSを、「S0*」から、「S0**」に更新する。さらに更新変数分析部2460は、上記命令によって条件分岐が行われるか調べる。iconst_1は条件分岐を伴わない命令なので、再度図12のステップS504に戻る。
更新変数分析部2460は、構造化制御フローグラフ70の次のノード「6:iadd」を読み込み、命令の種類を調べる。iaddはスタック操作系命令で、2つのスタック上の変数をpopし、popした2つの変数の和をスタックに積む。そこで、更新変数分析部2460は、分析用スタックS「S0**」を、「S0*」に更新する。さらに更新変数分析部2460は、上記命令によって条件分岐が行われるか調べる。iaddは条件分岐を伴わない命令なので、再度図12のステップS504に戻る。
更新変数分析部2460は、構造化制御フローグラフ70の次のノード「7:putfield#13」を読み込み、命令の種類を調べる。putfieldは、スタック上のオブジェクト及び値の2つをpopし、popしたオブジェクトの指定したフィールドに、popした値を代入する更新系命令である。本例の場合、Counterクラスのオブジェクトと、上記iaddでスタックにpushした値の2つをpopし、Counterクラスのcntフィールドにpopした値を代入する。そこで、更新変数分析部2460は、分析用スタックSからオブジェクトと整数型をpopする(図13のステップS610)。具体的には、分析用スタックS「S0*」を、「S」に更新する。そして、更新変数分析部2460は、変数リストにおいて、putfieldが更新した変数である0(this)に関するレコードの更新情報を、「無し」から「有り」に更新する(図13のステップS612)。さらに更新変数分析部2460は、上記命令によって条件分岐が行われるか調べる。putfieldは条件分岐を伴わない命令なので、再度図12のステップS504に戻る。
さらに、更新変数分析部2460は、構造化制御フローグラフ70の次のノード「10:return」を読み込み、命令の種類を調べる。returnは、Load系命令、Store系命令、更新系命令、及びメソッド呼び出し命令のいずれにも該当しない。そこで更新変数分析部2460は、図13のステップS620に進み、分析用スタックを操作する。また、更新変数分析部2460は、上記命令によって条件分岐が行われるか調べる。returnは条件分岐を伴わない命令なので、再度図12のステップS504に戻る。
更新変数分析部2460は、構造化制御フローグラフ70に含まれる全ての命令について、分析を終えている。したがって、図12のステップS530に進む。そして、変数リストと参照先同一変数リストを併合して更新変数リストを生成する。本例の場合、参照先同一変数リストは変更されなかったため、更新変数リストは、変数リストと同じになる。
本例において、更新変数分析部2460による処理後の更新変数リストは、図19(b)に示す表となる。更新変数リストは、変数0(this)が更新されていることを示している。したがってthis、すなわちCounterオブジェクトが、更新変数となる。
以上の動作により、一貫性破壊検出装置2000は、Counter#incメソッドがスレッドアンセーフな並行メソッドであり、Counter#incメソッドによって更新される更新変数はCounter#thisであることを割り出した。同様に、一貫性破壊検出装置2000がその他のメソッドについても分析して出力した「スレッドアンセーフな並行メソッド、更新変数リスト」の組み合わせを、図20に示す。
プローブ挿入部2600は、Counter#incメソッドにプローブを挿入する(図7のステップS108)。以下に、プローブ挿入部2600がCounter#incに挿入するプローブの例を示す。
public class Counter extends java.lang.Object{
void inc();
Code:
0: aload_0
1: invokestatic #3; //Method Log.getUpdateTime:(Ljava/lang/Object;)J
4: lstore_1
5: aload_0
6: dup
7: getfield #2; //Field cnt:I
10: iconst_1
11: iadd
12: putfield #2; //Field cnt:I
15: aload_0
16: invokestatic #3; //Method Log.getUpdateTime:(Ljava/lang/Object;)J
19: lstore_3
20: aload_0
21: invokestatic #4; //Method Log.updateTime:(Ljava/lang/Object;)V
24: lload_1
25: lload_3
26: lcmp
27: ifeq 40
30: new #5; //class java/lang/RuntimeException
33: dup
34: ldc #6; //String Atomicity Error
36: invokespecial #7; //Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
39: athrow
40: goto 75
43: astore 5
45: aload_0
46: invokestatic #3; //Method Log.getUpdateTime:(Ljava/lang/Object;)J
49: lstore 6
51: aload_0
52: invokestatic #4; //Method Log.updateTime:(Ljava/lang/Object;)V
55: lload_1
56: lload 6
58: lcmp
59: ifeq 72
62: new #5; //class java/lang/RuntimeException
65: dup
66: ldc #6; //String Atomicity Error
68: invokespecial #7; //Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
71: athrow
72: aload 5
74: athrow
75: return
Exception table:
from to target type
5 15 43 any
43 45 43 any
}
アドレス0からアドレス4は、更新変数thisの更新時間を得るメソッドLog#getUpdateTimeを呼び出すプローブである。アドレス15からアドレス19は、再度更新変数thisの更新時間を得るメソッドLog#getUpdateTimeを呼び出すプローブである。アドレス20から21は、更新変数thisの更新時間を再設定するためのメソッドLog#updateTimeを呼び出すプローブである。アドレス24から39は、更新変数thisの変更時刻を比較し、不一致であれば、一貫性違反としてRuntimeExceptionをthrowするプローブである。アドレス43から49は、上記一貫性違反の例外をハンドルする例外ハンドラである。
上記プローブが挿入されたプローブ入りプログラム20を実行すると、スレッドアンセーフである並行メソッド(例:Counter#inc)が並行実行されたとき、上記プローブは、一貫性が破壊されたことを通知するRuntimeExeptionを発生させる。
以上、図面を参照して本発明の実施形態及び実施例について述べたが、これらは本発明の例示であり、上記以外の様々な構成を採用することもできる。
[付記]
(付記1)
プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出手段と、
前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出手段と、
前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムにおいて、該スレッドアンセーフな並行メソッド内にある、該更新変数を更新する命令の前又は後ろに、検査用の命令列を挿入するプローブ挿入手段を有する一貫性破壊検出装置。
(付記2)
前記並行メソッド抽出手段は、
前記プログラムの中から、並行に実行されるメソッド列の起点となるメソッドを検出し、起点メソッドとして抽出する並行API抽出手段と、
前記起点メソッドを起点としたコールフローグラフを生成するコールフローグラフ生成手段と、
前記コールフローグラフに含まれるメソッドを並行メソッドとして、並行メソッドリストを生成するコールフロートレース手段と、
を有する付記1記載の一貫性破壊検出装置。
(付記3)
前記更新系メソッド抽出手段は、
前記並行メソッドリストから前記並行メソッドを取得し、該並行メソッドの定義を取得するメソッド取得手段と、
前記メソッド取得手段により取得された前記並行メソッドの定義に基づいて、該並行メソッド内の制御フローを示す制御フローグラフに、該並行メソッドに含まれる各分岐命令の種類を示す分岐識別情報を付加した構造化制御フローグラフを生成する構造化制御フローグラフ生成手段と、
前記構造化制御フローグラフを解析し、前記並行メソッドの定義に含まれる変数のうち、前記構造化制御フローが示すいずれかの制御フローにおいて、スレッド間で共有され、かつ、更新される変数を、前記更新変数として抽出する更新変数分析手段と、
前記取得された並行メソッドと前記更新変数を対応づけて抽出する更新系メソッド出力手段と、
を有する付記1又は2記載の一貫性破壊検出装置。
(付記4)
前記更新変数分析手段は、
前記メソッド取得手段が取得した前記並行メソッドの定義に含まれる変数ごとに、変数の更新の有無を示す情報である更新情報、及び該変数と同一のアドレスを参照している他の変数を示す情報である参照先同一変数情報を記録する変数リストを生成し、
前記構造化制御フローグラフの始点から順に命令を1つずつ取得し、
取得された前記命令によって変数が更新された場合は、該変数に関する前記更新情報を更新有りとし、
取得された前記命令によって、変数と他の変数が同一のアドレスを参照するようになった場合は、該変数に関する前記参照先同一変数情報に、該他の変数を加え、
前記変数リストを参照し、前記更新情報において更新有りとされている前記変数、及び、前記参照先同一変数情報において該変数と参照するアドレスが同一であるとされている前記他の変数を前記更新変数とすることを特徴とする付記3記載の一貫性破壊検出装置。
(付記5)
前記構造化制御フローグラフ生成手段は、
前記並行メソッドの定義を取得し、該並行メソッド内の命令列の制御の流れを表す初期制御フローグラフを生成する初期制御フローグラフ生成手段と、
前記初期制御フローグラフに示される前記命令列の中から、ループ処理を継続するか否かの判定を行う命令をループ判定命令として抽出し、抽出された該ループ判定命令をループリストに登録するループ抽出手段と、
前記初期制御フローグラフに示される前記命令列の中から、分岐命令であり、かつ、ループ判定命令ではない命令を条件分岐命令として抽出し、抽出された該条件分岐命令を条件分岐リストに登録する条件分岐抽出手段と、
前記初期制御フローグラフ、前記ループリスト、及び前記条件分岐リストに基づいて、前記初期制御フローグラフに示される分岐命令ごとに、前記ループ判定命令と前記条件分岐命令のどちらであるかを示す情報を、分岐識別情報として付加して構造化制御フローグラフを生成する構造化手段と、
を有する付記4記載の一貫性破壊検出装置。
(付記6)
前記更新変数分析手段は、
前記構造化制御フローグラフから取り出された命令に、前記条件分岐命令を示す分岐識別情報が付加されている場合は、各条件分岐について、該構造化制御フローグラフの中から、該条件分岐命令の次の命令から条件分岐の終了までの命令を示す部分グラフを前記構造化制御フローグラフとして再帰実行し、
前記構造化制御フローグラフから取り出された命令に、前記ループ判定命令を示す分岐識別情報が付加されている場合は、前記変数リストが更新されなくなるまで、該ループ判定命令の次の命令からループ処理の終了までの命令を示す部分グラフを前記構造化制御フローグラフとした再帰実行を繰り返すことを特徴とする付記5記載の一貫性破壊検出装置。
(付記7)
前記更新変数分析手段は、作業領域としてスタックを有し、前記構造化制御フローグラフから取り出された命令の種類を調べ、
前記命令がLoad系命令である場合は、前記命令の内容に応じて前記スタックをpushし、
前記命令がStore系命令である場合は、前記命令の内容に応じて前記スタックをpopし、前記命令の対象となっている変数に関する変数表の参照先同一変数に、Store系命令の対象となっている別の変数を加え、
前記命令が更新系命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令によって更新される変数に関する変数リストにおいて、更新情報を更新ありに変更し、
前記命令がメソッドを起動する命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令が起動するメソッドについて生成された更新変数表を参照して、該更新変数表が更新変数として示している変数について、前記変数リストの更新情報を更新有りに変更することを特徴とする付記4乃至6いずれか一項に記載の一貫性破壊検出装置。
(付記8)
前記コールフローグラフ生成手段は、
前記プログラム及び前記起点メソッドを取得し、前記起点メソッドから到達可能なメソッドのそれぞれについて、該メソッドが呼び出すメソッドの一覧である呼び出し先メソッドリストを生成するメソッド内呼び出し抽出手段と、
前記プログラムの中から、クラス間の階層関係を表すクラス階層グラフを生成するクラス階層抽出手段と、
クラス階層グラフを参照し、前記呼び出し先メソッドリストに含まれるメソッドのそれぞれについて、該メソッドをオーバライドしたメソッドの一覧であるオーバライドメソッドリストを生成するオーバライドメソッド抽出手段と、
前記起点メソッドから到達可能な前記各メソッドについて、該メソッドの前記呼び出し先メソッドリスト及び該呼び出し先メソッドリストに関する前記オーバライドメソッドリストに基づいて、始点ノードが該メソッドであり、終端ノードが該メソッドリスト又は該オーバライドメソッドリストに含まれるメソッドである部分グラフを生成し、前記部分グラフを連結して、前記起点メソッドを始点ノードとするコールフローグラフを生成するグラフ生成手段と、
を有する付記2乃至7いずれか一項に記載の一貫性破壊検出装置。
(付記9)
コンピュータに、並行実行されるプログラムにおける一貫性破壊を検出する機能を持たせる一貫性破壊検出プログラムであって、
前記コンピュータに、
プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出機能と、
前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出機能と、
前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムにおいて、該スレッドアンセーフな並行メソッド内にある、該更新変数を更新する命令の前又は後ろに、検査用の命令列を挿入するプローブ挿入機能を持たせる一貫性破壊検出プログラム。
(付記10)
前記並行メソッド抽出機能は、
前記プログラムの中から、並行に実行されるメソッド列の起点となるメソッドを検出し、起点メソッドとして抽出する並行API抽出機能と、
前記起点メソッドを起点としたコールフローグラフを生成するコールフローグラフ生成機能と、
前記コールフローグラフに含まれるメソッドを並行メソッドとして、並行メソッドリストを生成するコールフロートレース機能と、
を有する付記9記載の一貫性破壊検出プログラム。
(付記11)
前記更新系メソッド抽出機能は、
前記並行メソッドリストから前記並行メソッドを取得し、該並行メソッドの定義を取得するメソッド取得機能と、
前記メソッド取得機能により取得された前記並行メソッドの定義に基づいて、該並行メソッド内の制御フローを示す制御フローグラフに、該並行メソッドに含まれる各分岐命令の種類を示す分岐識別情報を付加した構造化制御フローグラフを生成する構造化制御フローグラフ生成機能と、
前記構造化制御フローグラフを解析し、前記並行メソッドの定義に含まれる変数のうち、前記構造化制御フローが示すいずれかの制御フローにおいて、スレッド間で共有され、かつ、更新される変数を、前記更新変数として抽出する更新変数分析機能と、
前記取得された並行メソッドと前記更新変数を対応づけて抽出する更新系メソッド出力機能と、
を有する付記9又は10記載の一貫性破壊検出プログラム。
(付記12)
前記更新変数分析機能は、
前記メソッド取得機能が取得した前記並行メソッドの定義に含まれる変数ごとに、変数の更新の有無を示す情報である更新情報、及び該変数と同一のアドレスを参照している他の変数を示す情報である参照先同一変数情報を記録する変数リストを生成し、
前記構造化制御フローグラフの始点から順に命令を1つずつ取得し、
取得された前記命令によって変数が更新された場合は、該変数に関する前記更新情報を更新有りとし、
取得された前記命令によって、変数と他の変数が同一のアドレスを参照するようになった場合は、該変数に関する前記参照先同一変数情報に、該他の変数を加え、
前記変数リストを参照し、前記更新情報において更新有りとされている前記変数、及び、前記参照先同一変数情報において該変数と参照するアドレスが同一であるとされている前記他の変数を前記更新変数とすることを特徴とする付記11記載の一貫性破壊検出プログラム。
(付記13)
前記構造化制御フローグラフ生成機能は、
前記並行メソッドの定義を取得し、該並行メソッド内の命令列の制御の流れを表す初期制御フローグラフを生成する初期制御フローグラフ生成機能と、
前記初期制御フローグラフに示される前記命令列の中から、ループ処理を継続するか否かの判定を行う命令をループ判定命令として抽出し、抽出された該ループ判定命令をループリストに登録するループ抽出機能と、
前記初期制御フローグラフに示される前記命令列の中から、分岐命令であり、かつ、ループ判定命令ではない命令を条件分岐命令として抽出し、抽出された該条件分岐命令を条件分岐リストに登録する条件分岐抽出機能と、
前記初期制御フローグラフ、前記ループリスト、及び前記条件分岐リストに基づいて、前記初期制御フローグラフに示される分岐命令ごとに、前記ループ判定命令と前記条件分岐命令のどちらであるかを示す情報を、分岐識別情報として付加して構造化制御フローグラフを生成する構造化機能と、
を有する付記12記載の一貫性破壊検出プログラム。
(付記14)
前記更新変数分析機能は、
前記構造化制御フローグラフから取り出された命令に、前記条件分岐命令を示す分岐識別情報が付加されている場合は、各条件分岐について、該構造化制御フローグラフの中から、該条件分岐命令の次の命令から条件分岐の終了までの命令を示す部分グラフを前記構造化制御フローグラフとして再帰実行し、
前記構造化制御フローグラフから取り出された命令に、前記ループ判定命令を示す分岐識別情報が付加されている場合は、前記変数リストが更新されなくなるまで、該ループ判定命令の次の命令からループ処理の終了までの命令を示す部分グラフを前記構造化制御フローグラフとした再帰実行を繰り返すことを特徴とする付記13記載の一貫性破壊検出プログラム。
(付記15)
前記更新変数分析機能は、作業領域としてスタックを有し、前記構造化制御フローグラフから取り出された命令の種類を調べ、
前記命令がLoad系命令である場合は、前記命令の内容に応じて前記スタックをpushし、
前記命令がStore系命令である場合は、前記命令の内容に応じて前記スタックをpopし、前記命令の対象となっている変数に関する変数表の参照先同一変数に、Store系命令の対象となっている別の変数を加え、
前記命令が更新系命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令によって更新される変数に関する変数リストにおいて、更新情報を更新ありに変更し、
前記命令がメソッドを起動する命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令が起動するメソッドについて生成された更新変数表を参照して、該更新変数表が更新変数として示している変数について、前記変数リストの更新情報を更新有りに変更することを特徴とする付記11乃至14いずれか一項に記載の一貫性破壊検出プログラム。
(付記16)
前記コールフローグラフ生成機能は、
前記プログラム及び前記起点メソッドを取得し、前記起点メソッドから到達可能なメソッドのそれぞれについて、該メソッドが呼び出すメソッドの一覧である呼び出し先メソッドリストを生成するメソッド内呼び出し抽出機能と、
前記プログラムの中から、クラス間の階層関係を表すクラス階層グラフを生成するクラス階層抽出機能と、
クラス階層グラフを参照し、前記呼び出し先メソッドリストに含まれるメソッドのそれぞれについて、該メソッドをオーバライドしたメソッドの一覧であるオーバライドメソッドリストを生成するオーバライドメソッド抽出機能と、
前記起点メソッドから到達可能な前記各メソッドについて、該メソッドの前記呼び出し先メソッドリスト及び該呼び出し先メソッドリストに関する前記オーバライドメソッドリストに基づいて、始点ノードが該メソッドであり、終端ノードが該メソッドリスト又は該オーバライドメソッドリストに含まれるメソッドである部分グラフを生成し、前記部分グラフを連結して、前記起点メソッドを始点ノードとするコールフローグラフを生成するグラフ生成機能と、
を有する付記10乃至15いずれか一項に記載の一貫性破壊検出プログラム。
(付記17)
コンピュータが、並行実行するプログラムにおける一貫性破壊を検出する一貫性破壊検出方法であって、
前記コンピュータが、プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出ステップと、
前記コンピュータが、前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出ステップと、
前記コンピュータが、前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムにおいて、該スレッドアンセーフな並行メソッド内にある、該更新変数を更新する命令の前又は後ろに、検査用の命令列を挿入するプローブ挿入ステップを有する一貫性破壊検出方法。
(付記18)
前記並行メソッド抽出ステップは、
前記コンピュータが、前記プログラムの中から、並行に実行されるメソッド列の起点となるメソッドを検出し、起点メソッドとして抽出する並行API抽出ステップと、
前記コンピュータが、前記起点メソッドを起点としたコールフローグラフを生成するコールフローグラフ生成ステップと、
前記コンピュータが、前記コールフローグラフに含まれるメソッドを並行メソッドとして、並行メソッドリストを生成するコールフロートレースステップと、
を有する付記17記載の一貫性破壊検出方法。
(付記19)
前記更新系メソッド抽出ステップは、
前記コンピュータが、前記並行メソッドリストから前記並行メソッドを取得し、該並行メソッドの定義を取得するメソッド取得ステップと、
前記コンピュータが、前記メソッド取得機能により取得された前記並行メソッドの定義に基づいて、該並行メソッド内の制御フローを示す制御フローグラフに、該並行メソッドに含まれる各分岐命令の種類を示す分岐識別情報を付加した構造化制御フローグラフを生成する構造化制御フローグラフ生成ステップと、
前記コンピュータが、前記構造化制御フローグラフを解析し、前記並行メソッドの定義に含まれる変数のうち、前記構造化制御フローが示すいずれかの制御フローにおいて、スレッド間で共有され、かつ、更新される変数を、前記更新変数として抽出する更新変数分析ステップと、
前記コンピュータが、前記取得された並行メソッドと前記更新変数を対応づけて抽出する更新系メソッド出力ステップと、
を有する付記17又は18記載の一貫性破壊検出方法。
(付記20)
前記更新変数分析ステップは、前記コンピュータが、
前記メソッド取得機能が取得した前記並行メソッドの定義に含まれる変数ごとに、変数の更新の有無を示す情報である更新情報、及び該変数と同一のアドレスを参照している他の変数を示す情報である参照先同一変数情報を記録する変数リストを生成し、
前記構造化制御フローグラフの始点から順に命令を1つずつ取得し、
取得された前記命令によって変数が更新された場合は、該変数に関する前記更新情報を更新有りとし、
取得された前記命令によって、変数と他の変数が同一のアドレスを参照するようになった場合は、該変数に関する前記参照先同一変数情報に、該他の変数を加え、
前記変数リストを参照し、前記更新情報において更新有りとされている前記変数、及び、前記参照先同一変数情報において該変数と参照するアドレスが同一であるとされている前記他の変数を前記更新変数とすることを特徴とする付記19記載の一貫性破壊検出方法。
(付記21)
前記構造化制御フローグラフ生成ステップは、
前記コンピュータが、前記並行メソッドの定義を取得し、該並行メソッド内の命令列の制御の流れを表す初期制御フローグラフを生成する初期制御フローグラフ生成ステップと、
前記コンピュータが、前記初期制御フローグラフに示される前記命令列の中から、ループ処理を継続するか否かの判定を行う命令をループ判定命令として抽出し、抽出された該ループ判定命令をループリストに登録するループ抽出ステップと、
前記コンピュータが、前記初期制御フローグラフに示される前記命令列の中から、分岐命令であり、かつ、ループ判定命令ではない命令を条件分岐命令として抽出し、抽出された該条件分岐命令を条件分岐リストに登録する条件分岐抽出ステップと、
前記コンピュータが、前記初期制御フローグラフ、前記ループリスト、及び前記条件分岐リストに基づいて、前記初期制御フローグラフに示される分岐命令ごとに、前記ループ判定命令と前記条件分岐命令のどちらであるかを示す情報を、分岐識別情報として付加して構造化制御フローグラフを生成する構造化ステップと、
を有する付記20記載の一貫性破壊検出方法。
(付記22)
前記更新変数分析ステップは、
前記構造化制御フローグラフから取り出された命令に、前記条件分岐命令を示す分岐識別情報が付加されている場合は、各条件分岐について、該構造化制御フローグラフの中から、該条件分岐命令の次の命令から条件分岐の終了までの命令を示す部分グラフを前記構造化制御フローグラフとして再帰実行し、
前記構造化制御フローグラフから取り出された命令に、前記ループ判定命令を示す分岐識別情報が付加されている場合は、前記変数リストが更新されなくなるまで、該ループ判定命令の次の命令からループ処理の終了までの命令を示す部分グラフを前記構造化制御フローグラフとした再帰実行を繰り返すことを特徴とする付記21記載の一貫性破壊検出方法。
(付記23)
前記更新変数分析ステップは、前記コンピュータが、作業領域としてスタックを有し、前記構造化制御フローグラフから取り出された命令の種類を調べ、
前記命令がLoad系命令である場合は、前記命令の内容に応じて前記スタックをpushし、
前記命令がStore系命令である場合は、前記命令の内容に応じて前記スタックをpopし、前記命令の対象となっている変数に関する変数表の参照先同一変数に、Store系命令の対象となっている別の変数を加え、
前記命令が更新系命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令によって更新される変数に関する変数リストにおいて、更新情報を更新ありに変更し、
前記命令がメソッドを起動する命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令が起動するメソッドについて生成された更新変数表を参照して、該更新変数表が更新変数として示している変数について、前記変数リストの更新情報を更新有りに変更することを特徴とする付記19乃至22いずれか一項に記載の一貫性破壊検出方法。
(付記24)
前記コールフローグラフ生成ステップは、
前記コンピュータが、前記プログラム及び前記起点メソッドを取得し、前記起点メソッドから到達可能なメソッドのそれぞれについて、該メソッドが呼び出すメソッドの一覧である呼び出し先メソッドリストを生成するメソッド内呼び出し抽出ステップと、
前記コンピュータが、前記プログラムの中から、クラス間の階層関係を表すクラス階層グラフを生成するクラス階層抽出ステップと、
前記コンピュータが、クラス階層グラフを参照し、前記呼び出し先メソッドリストに含まれるメソッドのそれぞれについて、該メソッドをオーバライドしたメソッドの一覧であるオーバライドメソッドリストを生成するオーバライドメソッド抽出ステップと、
前記コンピュータが、前記起点メソッドから到達可能な前記各メソッドについて、該メソッドの前記呼び出し先メソッドリスト及び該呼び出し先メソッドリストに関する前記オーバライドメソッドリストに基づいて、始点ノードが該メソッドであり、終端ノードが該メソッドリスト又は該オーバライドメソッドリストに含まれるメソッドである部分グラフを生成し、前記部分グラフを連結して、前記起点メソッドを始点ノードとするコールフローグラフを生成するグラフ生成ステップと、
を有する付記18乃至23いずれか一項に記載の一貫性破壊検出プログラム。
10 プログラム
20 プローブ入りプログラム
30 並行メソッドリスト
40 メソッド定義
50 スレッドアンセーフな並行メソッド
60 更新変数リスト
70 構造化制御フローグラフ
80 起点メソッド
90 コールフローグラフ
200 変数リスト
210 変数識別子
220 更新情報
230 参照先同一変数情報
2000 一貫性破壊検出装置
2200 並行メソッド抽出部
2220 並行API抽出部
2240 コールフローグラフ生成部
2242 メソッド選択部
2244 メソッド内呼び出し抽出部
2246 グラフ生成部
2248 クラス階層抽出部
2250 オーバライドメソッド抽出部
2260 コールフロートレース部
2400 更新系メソッド抽出部
2420 メソッド取得部
2440 構造化制御フローグラフ生成部
2442 初期制御フローグラフ生成部
2444 ループ抽出部
2446 条件分岐抽出部
2448 構造化部
2460 更新変数分析部
2462 命令分析部
2600 プローブ挿入部

Claims (10)

  1. プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出手段と、
    前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出手段と、
    前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムにおいて、該スレッドアンセーフな並行メソッド内にある、該更新変数を更新する命令の前又は後ろに、検査用の命令列を挿入するプローブ挿入手段を有する一貫性破壊検出装置。
  2. 前記並行メソッド抽出手段は、
    前記プログラムの中から、並行に実行されるメソッド列の起点となるメソッドを検出し、起点メソッドとして抽出する並行API抽出手段と、
    前記起点メソッドを起点としたコールフローグラフを生成するコールフローグラフ生成手段と、
    前記コールフローグラフに含まれるメソッドを並行メソッドとして、並行メソッドリストを生成するコールフロートレース手段と、
    を有する請求項1記載の一貫性破壊検出装置。
  3. 前記更新系メソッド抽出手段は、
    前記並行メソッドリストから前記並行メソッドを取得し、該並行メソッドの定義を取得するメソッド取得手段と、
    前記メソッド取得手段により取得された前記並行メソッドの定義に基づいて、該並行メソッド内の制御フローを示す制御フローグラフに、該並行メソッドに含まれる各分岐命令の種類を示す分岐識別情報を付加した構造化制御フローグラフを生成する構造化制御フローグラフ生成手段と、
    前記構造化制御フローグラフを解析し、前記並行メソッドの定義に含まれる変数のうち、前記構造化制御フローが示すいずれかの制御フローにおいて、スレッド間で共有され、かつ、更新される変数を、前記更新変数として抽出する更新変数分析手段と、
    前記取得された並行メソッドと前記更新変数を対応づけて抽出する更新系メソッド出力手段と、
    を有する請求項1又は2記載の一貫性破壊検出装置。
  4. 前記更新変数分析手段は、
    前記メソッド取得手段が取得した前記並行メソッドの定義に含まれる変数ごとに、変数の更新の有無を示す情報である更新情報、及び該変数と同一のアドレスを参照している他の変数を示す情報である参照先同一変数情報を記録する変数リストを生成し、
    前記構造化制御フローグラフの始点から順に命令を1つずつ取得し、
    取得された前記命令によって変数が更新された場合は、該変数に関する前記更新情報を更新有りとし、
    取得された前記命令によって、変数と他の変数が同一のアドレスを参照するようになった場合は、該変数に関する前記参照先同一変数情報に、該他の変数を加え、
    前記変数リストを参照し、前記更新情報において更新有りとされている前記変数、及び、前記参照先同一変数情報において該変数と参照するアドレスが同一であるとされている前記他の変数を前記更新変数とすることを特徴とする請求項3記載の一貫性破壊検出装置。
  5. 前記構造化制御フローグラフ生成手段は、
    前記並行メソッドの定義を取得し、該並行メソッド内の命令列の制御の流れを表す初期制御フローグラフを生成する初期制御フローグラフ生成手段と、
    前記初期制御フローグラフに示される前記命令列の中から、ループ処理を継続するか否かの判定を行う命令をループ判定命令として抽出し、抽出された該ループ判定命令をループリストに登録するループ抽出手段と、
    前記初期制御フローグラフに示される前記命令列の中から、分岐命令であり、かつ、ループ判定命令ではない命令を条件分岐命令として抽出し、抽出された該条件分岐命令を条件分岐リストに登録する条件分岐抽出手段と、
    前記初期制御フローグラフ、前記ループリスト、及び前記条件分岐リストに基づいて、前記初期制御フローグラフに示される分岐命令ごとに、前記ループ判定命令と前記条件分岐命令のどちらであるかを示す情報を、分岐識別情報として付加して構造化制御フローグラフを生成する構造化手段と、
    を有する請求項4に記載の一貫性破壊検出装置。
  6. 前記更新変数分析手段は、
    前記構造化制御フローグラフから取り出された命令に、前記条件分岐命令を示す分岐識別情報が付加されている場合は、各条件分岐について、該構造化制御フローグラフの中から、該条件分岐命令の次の命令から条件分岐の終了までの命令を示す部分グラフを前記構造化制御フローグラフとして再帰実行し、
    前記構造化制御フローグラフから取り出された命令に、前記ループ判定命令を示す分岐識別情報が付加されている場合は、前記変数リストが更新されなくなるまで、該ループ判定命令の次の命令からループ処理の終了までの命令を示す部分グラフを前記構造化制御フローグラフとした再帰実行を繰り返すことを特徴とする請求項5記載の一貫性破壊検出装置。
  7. 前記更新変数分析手段は、作業領域としてスタックを有し、前記構造化制御フローグラフから取り出された命令の種類を調べ、
    前記命令がLoad系命令である場合は、前記命令の内容に応じて前記スタックをpushし、
    前記命令がStore系命令である場合は、前記命令の内容に応じて前記スタックをpopし、前記命令の対象となっている変数に関する変数表の参照先同一変数に、Store系命令の対象となっている別の変数を加え、
    前記命令が更新系命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令によって更新される変数に関する変数リストにおいて、更新情報を更新ありに変更し、
    前記命令がメソッドを起動する命令の場合は、前記命令の内容に応じて前記スタックを処理し、前記命令が起動するメソッドについて生成された更新変数表を参照して、該更新変数表が更新変数として示している変数について、前記変数リストの更新情報を更新有りに変更することを特徴とする請求項4乃至6いずれか一項に記載の一貫性破壊検出装置。
  8. 前記コールフローグラフ生成手段は、
    前記プログラム及び前記起点メソッドを取得し、前記起点メソッドから到達可能なメソッドのそれぞれについて、該メソッドが呼び出すメソッドの一覧である呼び出し先メソッドリストを生成するメソッド内呼び出し抽出手段と、
    前記プログラムの中から、クラス間の階層関係を表すクラス階層グラフを生成するクラス階層抽出手段と、
    クラス階層グラフを参照し、前記呼び出し先メソッドリストに含まれるメソッドのそれぞれについて、該メソッドをオーバライドしたメソッドの一覧であるオーバライドメソッドリストを生成するオーバライドメソッド抽出手段と、
    前記起点メソッドから到達可能な前記各メソッドについて、該メソッドの前記呼び出し先メソッドリスト及び該呼び出し先メソッドリストに関する前記オーバライドメソッドリストに基づいて、始点ノードが該メソッドであり、終端ノードが該メソッドリスト又は該オーバライドメソッドリストに含まれるメソッドである部分グラフを生成し、前記部分グラフを連結して、前記起点メソッドを始点ノードとするコールフローグラフを生成するグラフ生成手段と、
    を有する請求項2乃至7いずれか一項に記載の一貫性破壊検出装置。
  9. コンピュータに、並行実行されるプログラムにおける一貫性破壊を検出する機能を持たせる一貫性破壊検出プログラムであって、
    前記コンピュータに、
    プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出機能と、
    前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出機能と、
    前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムにおいて、該スレッドアンセーフな並行メソッド内にある、該更新変数を更新する命令の前又は後ろに、検査用の命令列を挿入するプローブ挿入機能を持たせる一貫性破壊検出プログラム。
  10. コンピュータが、並行実行するプログラムにおける一貫性破壊を検出する一貫性破壊検出方法であって、
    前記コンピュータが、プログラムを取得し、該プログラムの中から、並行に実行されうるメソッドである並行メソッドを抽出し、並行メソッドリストを生成する並行メソッド抽出ステップと、
    前記コンピュータが、前記プログラムと前記並行メソッドリストに基づいて、スレッド間で共有される変数を更新する並行メソッドであるスレッドアンセーフな並行メソッドと、前記スレッドアンセーフな並行メソッドが更新する変数である更新変数とを組み合わせて抽出する更新系メソッド抽出ステップと、
    前記コンピュータが、前記スレッドアンセーフな並行メソッドと前記更新変数の組み合わせに基づき、前記プログラムにおいて、該スレッドアンセーフな並行メソッド内にある、該更新変数を更新する命令の前又は後ろに、検査用の命令列を挿入するプローブ挿入ステップを有する一貫性破壊検出方法。
JP2012180236A 2012-08-15 2012-08-15 一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法 Pending JP2014038467A (ja)

Priority Applications (1)

Application Number Priority Date Filing Date Title
JP2012180236A JP2014038467A (ja) 2012-08-15 2012-08-15 一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
JP2012180236A JP2014038467A (ja) 2012-08-15 2012-08-15 一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法

Publications (1)

Publication Number Publication Date
JP2014038467A true JP2014038467A (ja) 2014-02-27

Family

ID=50286565

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2012180236A Pending JP2014038467A (ja) 2012-08-15 2012-08-15 一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法

Country Status (1)

Country Link
JP (1) JP2014038467A (ja)

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2018150504A1 (ja) 2017-02-16 2018-08-23 三菱電機株式会社 動作検証装置、動作検証方法および動作検証プログラム

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2018150504A1 (ja) 2017-02-16 2018-08-23 三菱電機株式会社 動作検証装置、動作検証方法および動作検証プログラム

Similar Documents

Publication Publication Date Title
JP5933762B2 (ja) コード網羅率決定方法およびシステム
US10423474B2 (en) Performing diagnostic tracing of an executing application to identify suspicious pointer values
CN106557413A (zh) 基于代码覆盖率获取测试用例的方法和设备
JP2003186708A (ja) アクセス権矛盾検出装置および解析ルール作成装置
Saltaformaggio et al. {DSCRETE}: Automatic rendering of forensic information from memory images via application logic reuse
US20050125776A1 (en) Determining the possibility of adverse effects arising from a code change
Urbina et al. Sigpath: A memory graph based approach for program data introspection and modification
US7539979B1 (en) Method and system for forcing context-switch during mid-access to non-atomic variables
CN111913878A (zh) 基于程序分析结果的字节码插桩方法、装置及存储介质
US9189372B2 (en) Trace coverage analysis
CN114328168A (zh) 异常检测方法、装置、计算机设备和存储介质
US8291389B2 (en) Automatically detecting non-modifying transforms when profiling source code
CN116578282A (zh) 代码生成方法、装置、电子设备及介质
JP2014038467A (ja) 一貫性破壊検出装置、一貫性破壊検出プログラム、及び一貫性破壊検出方法
US20170286072A1 (en) Custom class library generation method and apparatus
JP2008186378A (ja) 例外に対処するためのプログラム
Hermann et al. Getting to know you: Towards a capability model for java
CN113076084A (zh) 资源文件处理方法、装置、设备及存储介质
KR101583133B1 (ko) 스택 기반 소프트웨어 유사도 평가 방법 및 장치
CN111143229A (zh) 软件测试方法及装置、计算机设备及计算机可读存储介质
CN111367796A (zh) 应用程序调试方法及装置
KR102519639B1 (ko) 코드 점검 인터페이스 제공 방법, 그리고 이를 구현하기 위한 장치
CN113296834B (zh) 一种基于逆向工程的安卓闭源服务类型信息提取方法
Quante Online construction of dynamic object process graphs
JP5343840B2 (ja) プログラムの解析装置及び解析方法