(19)【発行国】日本国特許庁(JP)
(12)【公報種別】公開特許公報(A)
(11)【公開番号】P2022157976
(43)【公開日】2022-10-14
(54)【発明の名称】分析プログラム、分析装置、分析方法
(51)【国際特許分類】
G06F 11/36 20060101AFI20221006BHJP
【FI】
G06F11/36 104
【審査請求】未請求
【請求項の数】8
【出願形態】OL
(21)【出願番号】P 2021062545
(22)【出願日】2021-04-01
(71)【出願人】
【識別番号】000005223
【氏名又は名称】富士通株式会社
(74)【代理人】
【識別番号】100087480
【弁理士】
【氏名又は名称】片山 修平
(72)【発明者】
【氏名】堀田 圭佑
【テーマコード(参考)】
5B042
【Fターム(参考)】
5B042HH08
5B042HH39
5B042NN09
(57)【要約】
【課題】潜在バグを修正する修正プログラムを絞り込むのに有用な分析プログラム、分析装置、及び分析方法を提供すること。
【解決手段】第1及び第2のソースプログラムの各々を表現するグラフであって、実行時に問題を起こす第1及び第2の要素の各々に対応した第1及び第2のノードを有する第1及び第2のグラフを生成し、第1のグラフと第2のグラフに共通に含まれる複数のエッジのうち、第1のノードから測った距離と、第2のノードから測った距離とが等しい複数の第1のエッジを特定し、
複数の第1のエッジの各々に対し、第2のノードからの距離が近くなるほど大きくなる重みを算出し、第1のエッジの個数と重みとに基づいて、第1のソースプログラムと第2のソースプログラムとの類似度を算出する、
処理をコンピュータに実行させるための分析プログラムによる。
【選択図】
図11
【特許請求の範囲】
【請求項1】
第1のソースプログラムを表現するグラフであって、該第1のソースプログラムの実行時に問題を起こす該第1のソースプログラムの第1の要素に対応した第1のノードを有する第1のグラフを生成し、
第2のソースプログラムを表現するグラフであって、該第2のソースプログラムの実行時に問題を起こす該第2のソースプログラムの第2の要素に対応した第2のノードを有する第2のグラフを生成し、
前記第1のグラフと前記第2のグラフに共通に含まれる複数のエッジのうち、前記第1のノードから測った距離と、前記第2のノードから測った距離とが等しい複数の第1のエッジを特定し、
複数の前記第1のエッジの各々に対し、前記第2のノードからの距離が近くなるほど大きくなる重みを算出し、
前記第1のエッジの個数と前記重みとに基づいて、前記第1のソースプログラムと前記第2のソースプログラムとの類似度を算出する、
処理をコンピュータに実行させるための分析プログラム。
【請求項2】
前記類似度は、前記第1のエッジの個数と前記重みの少なくとも一方が大きくなるほど大きくなることを特徴とする請求項1に記載の分析プログラム。
【請求項3】
前記第1の要素は、前記第1のソースプログラムに含まれる文であり、
前記第2の要素は、前記第2のソースプログラムに含まれる文であることを特徴とする請求項1に記載の分析プログラム。
【請求項4】
前記第1のグラフは、前記第1のソースプログラムの全体を表す第1のルートノードを有するグラフであり、
前記第2のグラフは、前記第2のソースプログラムの全体を表す第2のルートノードを有するグラフであり、
前記第1のグラフに含まれる複数のノードのうち、前記第1のノードを起点として子ノードから親ノードの順に辿って前記第1のルートノードに至る第1の経路にないノードを削除し、
前記第2のグラフに含まれる複数のノードのうち、前記第2のノードを起点として子ノードから親ノードの順に辿って前記第2のルートノードに至る第2の経路にないノードを削除する、
処理を前記コンピュータに更に実行させるための請求項1に記載の分析プログラム。
【請求項5】
前記第1のグラフと前記第2のグラフの各々は、抽象構文木又はプログラム依存グラフを含むことを特徴とする請求項1に記載の分析プログラム。
【請求項6】
内容が相互に異なる複数の前記第1のソースプログラムごとに前記類似度を算出し、
前記類似度が高い前記第1のソースプログラムから順に、該第1のソースプログラムにおける前記第1の問題を修正した修正プログラムを提示する、
処理を前記コンピュータに更に実行させるための請求項1に記載の分析プログラム。
【請求項7】
第1のソースプログラムを表現するグラフであって、該第1のソースプログラムの実行時に問題を起こす該第1のソースプログラムの第1の要素に対応した第1のノードを有する第1のグラフと、第2のソースプログラムを表現するグラフであって、該第2のソースプログラムの実行時に問題を起こす該第2のソースプログラムの第2の要素に対応した第2のノードを有する第2のグラフとを生成する生成部と、
前記第1のグラフと前記第2のグラフに共通に含まれる複数のエッジのうち、前記第1のノードから測った距離と、前記第2のノードから測った距離とが等しい複数の第1のエッジを特定する特定部と、
複数の前記第1のエッジの各々に対し、前記第2のノードからの距離が近くなるほど大きくなる重みを算出する重み算出部と、
前記第1のエッジの個数と前記重みとに基づいて、前記第1のソースプログラムと前記第2のソースプログラムとの類似度を算出する類似度算出部と、
を有することを特徴とする分析装置。
【請求項8】
コンピュータが、
第1のソースプログラムを表現するグラフであって、該第1のソースプログラムの実行時に問題を起こす該第1のソースプログラムの第1の要素に対応した第1のノードを有する第1のグラフを生成し、
第2のソースプログラムを表現するグラフであって、該第2のソースプログラムの実行時に問題を起こす該第2のソースプログラムの第2の要素に対応した第2のノードを有する第2のグラフを生成し、
前記第1のグラフと前記第2のグラフに共通に含まれる複数のエッジのうち、前記第1のノードから測った距離と、前記第2のノードから測った距離とが等しい複数の第1のエッジを特定し、
複数の前記第1のエッジの各々に対し、前記第2のノードからの距離が近くなるほど大きくなる重みを算出し、
前記第1のエッジの個数と前記重みとに基づいて、前記第1のソースプログラムと前記第2のソースプログラムとの類似度を算出する、
処理を実行することを特徴とする分析方法。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、分析プログラム、分析装置、分析方法に関する。
【背景技術】
【0002】
プログラムの中には、不具合が表面化せずに潜んだままの潜在バグが含まれることがある。潜在バグは、プログラムのソースコードを解析する静的解析ツールを用いることで検出することができる。また、静的解析ツールの中には、検出した潜在バグを解消する修正プログラムを提示するものもある。
【0003】
しかしながら、静的解析ツールが一つの潜在バグに対して多数の修正プログラムを提示することがあり、それらのうちで適切な修正プログラムを特定するのは容易ではない。
【先行技術文献】
【特許文献】
【0004】
【特許文献1】特開2010-79447号公報
【特許文献2】特開2019-21037号公報
【非特許文献】
【0005】
【非特許文献1】増田ら、「二つの木の最大共通部分グラフを求めるアルゴリズム」、電子情報通信学会論文誌A、Vol. J77-A、No.3、pp.460-470、1994
【発明の概要】
【発明が解決しようとする課題】
【0006】
一側面によれば、潜在バグを修正する修正プログラムを絞り込むのに有用な分析プログラム、分析装置、及び分析方法を提供することを目的とする。
【課題を解決するための手段】
【0007】
一側面によれば、第1のソースプログラムを表現するグラフであって、該第1のソースプログラムの実行時に問題を起こす該第1のソースプログラムの第1の要素に対応した第1のノードを有する第1のグラフを生成し、第2のソースプログラムを表現するグラフであって、該第2のソースプログラムの実行時に問題を起こす該第2のソースプログラムの第2の要素に対応した第2のノードを有する第2のグラフを生成し、前記第1のグラフと前記第2のグラフに共通に含まれる複数のエッジのうち、前記第1のノードから測った距離と、前記第2のノードから測った距離とが等しい複数の第1のエッジを特定し、複数の前記第1のエッジの各々に対し、前記第2のノードからの距離が近くなるほど大きくなる重みを算出し、前記第1のエッジの個数と前記重みとに基づいて、前記第1のソースプログラムと前記第2のソースプログラムとの類似度を算出する処理をコンピュータに実行させるための分析プログラムが提供される。
【発明の効果】
【0008】
一側面によれば、潜在バグを修正する修正プログラムを絞り込むのに有用な分析プログラム、分析装置、及び分析方法を提供することができる。
【図面の簡単な説明】
【0009】
【
図1】
図1(a)、(b)は、JAVA(登録商標)で記述されたソースプログラムの潜在バグについて示す模式図である。
【
図2】
図2(a)、(b)は、静的解析ツールを実行しているコンピュータの処理について説明するための模式図である。
【
図3】
図3(a)は、潜在バグの修正ロジックの一例を示す模式図であり、
図3(b)は、修正ロジックとは相性が良くない第2のソースプログラムと、その第2のソースプログラムに当該修正ロジックを適用して得られた修正プログラムの模式図である。
【
図4】
図4は、本実施形態の基礎となる事項について示す模式図である。
【
図5】
図5は、本実施形態に係る分析装置が行う処理の模式図である。
【
図6】
図6は、類似度の算出方法について示す模式図(その1)である。
【
図7】
図7は、類似度の算出方法について示す模式図(その2)である。
【
図8】
図8は、類似度の算出方法について示す模式図(その3)である。
【
図9】
図9(a)、(b)は、類似度の算出方法について示す模式図(その4)である。
【
図10】
図10(a)、(b)は、類似度の算出方法について示す模式図(その5)である。
【
図11】
図11は、類似度の算出方法について示す模式図(その5)である。
【
図12】
図12は、
図11の各グラフを用いた場合の第1のソースプログラムと第2のソースプログラムとの類似度の計算例を示す図である。
【
図13】
図13は、各グラフに含まれるエッジの重みを各ノードからの距離が近くなるほど大きくすることで得られる効果について説明するための模式図である。
【
図14】
図14は、本実施形態に係る分析装置の機能構成図である。
【
図17】
図17は、修正プログラムの提示例について示す模式図である。
【
図18】
図18は、本実施形態に係る分析方法のフローチャートである。
【
図20】
図20は、本実施形態に係る分析装置のハードウェア構成図である。
【発明を実施するための形態】
【0010】
本実施形態の説明に先立ち、本願発明者が検討した事項について説明する。
【0011】
図1(a)、(b)は、JAVA(登録商標)で記述されたソースプログラムの潜在バグについて示す模式図である。
【0012】
このうち、
図1(a)における文「name == arg.name」は、文字列「name」と文字列「arg.name」とが等しいかを判定する処理を意図して開発者が記述した文である。
【0013】
しかし、JAVA(登録商標)の仕様では、この記述では文字列「name」と文字列「arg.name」の各々のメモリ内での格納場所が等しいかが判定されてしまう。よって、文「name == arg.name」は潜在バグとなる。この潜在バグの種類を以下では「STR_EQ」と呼ぶ。
【0014】
一方、
図1(b)における文「str += s;」は、文字列「str」に文字列「s」を連結する処理を意図して開発者が記述した文である。この記述によれば、開発者の意図したように文字列「str」に文字列「s」が連結される。
【0015】
しかし、forループの中に文「str += s;」が記述されていることで、ループの回数が増えると処理に時間がかかるという問題が生じる。よって、文「str += s;」は潜在バグとなる。この潜在バグの種類を以下では「SBSC」と呼ぶ。
【0016】
このように、潜在バグは、開発者の意図とは異なる処理が実行されるという問題(
図1(a))や、開発者の意図通りに処理されるがプログラムのパフォーマンスが低下する問題(
図1(a))の原因となるプログラム中の要素を指す。
【0017】
潜在バグが含まれているプログラムは実行時に問題を引き起こす。これを避けるため、開発者は、プログラムの開発段階で静的解析ツールを用いてプログラムを検査することがある。
【0018】
静的解析ツールは、ソースプログラムに潜在バグが存在するかを検査し、潜在バグが見つかったときにそれを修正するための修正プログラムを提示するためのプログラムである。
【0019】
図2(a)、(b)は、静的解析ツールを実行しているコンピュータの処理について説明するための模式図である。
【0020】
コンピュータ1は、静的解析ツールを実行するPC(Personal Computer)や仮想マシン等である。
【0021】
まず、
図2(a)に示すように、コンピュータ1は、リポジトリ2からソースプログラムの修正事例3を取得する。
【0022】
リポジトリ2は、コンピュータ1とネットワークで接続されたストレージ装置である。
【0023】
また、修正事例3は、潜在バグが潜む第1のソースプログラム4と、その潜在バグの修正箇所5とを対応付けた事例である。この例では、修正箇所5における記号「-」が修正前の文を示し、記号「+」が修正後の文を示す。コンピュータ1は、前述の「STR_EQ」や「SBSC」等の潜在バグの種類ごとに複数の修正事例3をリポジトリ2から収集する。
【0024】
次いで、コンピュータ1は、「STR_EQ」の潜在バグの複数の修正事例3に基づいて、当該潜在バグを修正する修正ロジック6を生成する。修正ロジック6は、潜在バグのある文の修正手順を示す情報である。例えば、記号「-」で示される文を記号「+」で示される文に修正する手順が修正ロジック6となる。修正ロジック6の個数は特に限定されず、「STR_EQ」という一つの潜在バグに対してコンピュータ1が複数の修正ロジック6を生成することもある。
【0025】
これと同様にして、コンピュータ1は、「SBSC」の潜在バグを修正するための修正ロジック6を生成する。
【0026】
次いで、
図2(b)に示すように、コンピュータ1は、開発段階の第2のソースプログラム8を取得する。第2のソースプログラム8には、例えば「STR_EQ」の潜在バグ8aが含まれているものとする。
【0027】
この場合、コンピュータ1は、第2のソースプログラム8を1文ごと検査することにより、第2のソースプログラム8に潜在バグ8aが含まれているかを判定する。
【0028】
そして、潜在バグ8aが含まれている場合、コンピュータ1は、「STR_EQ」の潜在バグ8aに対応した複数の修正ロジック6を特定する。
【0029】
次いで、コンピュータ1は、第2のソースプログラム8に複数の修正ロジック6の各々を適用した複数の修正プログラム9を提示する。
【0030】
以上により、静的解析ツールを実行しているコンピュータが行う基本的な処理を終える。
【0031】
これによれば、コンピュータ1は、潜在バグ8aがある一つの第2のソースプログラム8に対して複数の修正プログラム9を提示する。その修正プログラム9の個数が数十から数百の場合、開発者は、修正プログラム9で実際に潜在バグ8aが解消されているかを多数の修正プログラム9を実行することで確かめる必要があり、プログラムの開発効率が低下する。
【0032】
これを避けるには、コンピュータ1が、「STR_EQ」に対応する全ての修正ロジック6のうちで、分析対象の第2のソースプログラム8に適した一部の修正ロジック6を採用すればよい。しかし、修正ロジック6とその適用先の第2のソースプログラム8との間には相性があり、修正ロジック6の中には第2のソースプログラム8の潜在バグ8aを解消しきれないものある。これについて
図3(a)を参照しながら説明する。
【0033】
図3(a)は、潜在バグの修正ロジック6の一例を示す模式図である。
【0034】
第1のソースプログラム4は、変数「p」が「null」ではないときにprint文を実行することを意図したプログラムである。しかし、この例では開発者がif文の中に誤って文「p == null」を記述したことにより、変数「p」が「null」のときにprint文が実行されてしまう。よって、文「p == null」は潜在バグ4aである。
【0035】
修正ロジック6は、文「p == null」を文「p != null」と修正することによりこの潜在バグを修正するロジックである。
【0036】
図3(b)は、この修正ロジック6とは相性が良くない第2のソースプログラム8と、その第2のソースプログラム8に当該修正ロジック6を適用して得られた修正プログラム9の模式図である。
【0037】
第2のソースプログラム8は、変数「s」が「null」ではないときに変数「this.score」の値を増分「s.calc()」だけインクリメントすることを意図したプログラムである。
【0038】
しかし、この例では開発者が二つのif文のうちの最初のif文に文「s == null」を誤って記述したことにより、変数「s」が「null」のときに変数「this.score」の値がインクリメントされてしまう。よって、この第2のソースプログラム8の潜在バグ8aは文「s == null」である。
【0039】
修正プログラム9は、この第2のソースプログラム8に対して
図3(a)の修正ロジック6を適用したプログラムである。
【0040】
この例では、修正ロジック6は、修正プログラム9における二つのif文のうちの最後のif文の中の文9aに適用されているため、潜在バグ8aは解消されていない。よって、修正ロジック6で第2のソースプログラム8の潜在バグ8aを修正することはできず、修正ロジック6と第2のソースプログラム8とは相性が悪い。
【0041】
プログラム開発の効率化のために多数の修正ロジック6のうちで第2のソースプログラム8に適した一部を採用するには、多数の修正ロジック6から第2のソースプログラム8と相性の悪いものを排除すればよい。しかし、修正ロジック6と第2のソースプログラム8との相性の良し悪しを判定するのは容易ではない。以下、本実施形態について説明する。
【0042】
(本実施形態)
図4は、本実施形態の基礎となる事項について示す模式図である。なお、
図4において、
図1~
図3で説明したのと同じ要素にはこれらの図におけるのと同じ符号を付し、以下ではその説明を省略する。
【0043】
本実施形態では、修正ロジック6の生成に使用した第1のソースプログラム4と、分析対象の第2のソースプログラム8との類似性に着目する。これらが類似していると、第1のソースプログラム4の潜在バグ4aが解消されたのと同様に、修正ロジック6により第2のソースプログラム8の潜在バグ8aも解消されると考えられる。特に、各潜在バグ4a、8aの近くで各ソースプログラム4、8が類似していると、修正ロジック6により第2のソースプログラム8の潜在バグ8aが解消される可能性が高い。そこで、本実施形態では、以下のようにして二つのソースプログラムが潜在バグの近くで類似しているかを判定する。
【0044】
図5は、本実施形態に係る分析装置20が行う処理の模式図である。
【0045】
分析装置20は、PCや仮想マシン等のコンピュータであって、複数の第1のソースプログラム4と第2のソースプログラム8とを取得する。前述のように、第1のソースプログラム4は、修正ロジック6の生成に使用したプログラムである。一例として、第1のソースプログラム4には潜在バグ4aが含まれており、当該潜在バグ4aが修正ロジック6で修正される。なお、潜在バグ4aは、第1のソースプログラム4の実行時に問題を起こす第1の要素の一例である。
【0046】
また、第2のソースプログラム8は、潜在バグ8aがあるかを分析する対象のプログラムである。その潜在バグ8aは、第2のソースプログラム8の実行時に問題を起こす第2の要素の一例である。
【0047】
次いで、分析装置20は、第2のソースプログラム8に潜在バグ8aが存在するかを検査し、潜在バグ8aが存在する場合に複数の第1のソースプログラム4の各々と第2のソースプログラム8との類似度を算出する。
【0048】
次に、その類似度の算出方法について説明する。
【0049】
図6~
図11は、類似度の算出方法について示す模式図である。まず、
図6に示すように、分析装置20は、第1のソースプログラム4を表現する第1のグラフG
1として抽象構文木を生成する。この第1のグラフG
1の第1のルートノード31aは、第1のソースプログラム4の全体を表すノードである。また、第1のグラフG
1の各ノードは第1のソースプログラム4の各々の要素を示す。要素は特に限定されないが、この例では第1のソースプログラム4の文を要素として採用する。例えば、「Package Declaration」のノードは、第1のソースプログラム4が使用するパッケージを宣言する文を示す。
【0050】
そして、第1のグラフG1のエッジは、各ノードが表す文同士の依存関係を示す。ここでは、ある文が他の文の内部に記述されているとき、当該文は他の文に依存すると呼ぶ。例えば、「If statement」と「Return Statement」の各々の文に対応したノード間のエッジは、文「If statement」の内部に文「Return Statement」が記述されていることを示す。また、以下では依存元の文に対応したノードを子ノードと呼び、依存先の文に対応したノードを親ノードと呼ぶ。上記の例では、文「If statement」に対応したノードが親ノードであり、文「Return Statement」に対応したノードが子ノードである。
【0051】
なお、分析装置20は、抽象構文木に代えてプログラム依存グラフを第1のグラフG1として生成してもよい。
【0052】
次に、
図7に示すように、分析装置20は、第1のグラフG
1に、意味的な情報を示す有向エッジ31xを追加する。
【0053】
有向エッジ31xは、抽象構文木では表現できない文同士の意味的な繋がりをしめすエッジである。例えば、文「Expression Statement」から文「Field Declaration」に向かう有向エッジ31xは、文「Expression Statement」の内部で使用する変数が、文「Field Declaration」において定義されていることを示す。なお、有向エッジ31xに付された文字列「decl」は、当該有向エッジ31xが示す文の意味的な繋がりが変数の定義であることを示す。
【0054】
次に、
図8に示すように、分析装置20は、第1のグラフG
1に含まれる複数のノードのうちで、第1のソースプログラム4の潜在バグ4aに対応した第1のノード31bを特定する。ここでは、文「Expression」が潜在バグ4aであり、この文「Expression」に対応したノードが第1のノード31bであるとする。
【0055】
そして、分析装置20は、第1のソースプログラム4の要素のうちで潜在バグ4aとの関りが薄い要素に対応したノードを削除する。この例では、第1のノード31bを起点として子ノードから親ノードの順に辿って第1のルートノード31aに至る第1の経路P1、P2にないノードを削除する。例えば、第1のノード31bの親ノードである文「If Statement」に対応したノードは経路P1にあるため削除されずに残る。同様に、文「Field Declaration」に対応したノードは、有向エッジ31xで一部が形成される経路P2にあるため、削除されずに残る。
【0056】
一方、文「If Statement」に対応したノードの子ノードである文「Return Statement」に対応したノードは経路P1にないため削除される。
【0057】
これ以降の処理について
図9~
図11を参照して説明する。
【0058】
図9(a)は、
図6~
図8で生成した第1のグラフG
1を簡略化した図である。
図9(a)とこれ以降の図では各ノードを「A」、「B」、「C」、…等の文字で識別する。また、第1のルートノード31aは「A」のノードであり、潜在バグ4aに対応した第1のノード31bは「B」のノードであるとする。
【0059】
分析装置20は、分析対象の第2のソースプログラム8に対しても
図6~
図8の処理を行うことにより第2のグラフを生成する。
【0060】
図9(b)は、分析装置20が生成した第2のソースプログラム8を表現する第2のグラフG
2の模式図である。
【0061】
第1のグラフG1と同様に、第2のグラフG2の第2のルートノード32aは、第2のソースプログラム8の全体を表すノードである。また、第2のグラフG2の各ノードは、第2のソースプログラム8の要素である個々の文を示す。更に、第2のグラフG2の第2のノード32bは、第2のソースプログラム8の潜在バグ8aに対応したノードである。
【0062】
次に、
図10(a)の表内に示すように、分析装置20は、第1のグラフG
1に含まれるエッジを列挙する。この例では、各エッジを、その両端にある親ノードと子ノードとで識別する。例えば、「A-B」は、親ノードが「A」のノードであり、かつ子ノードが「B」のノードであるエッジを示す。
【0063】
更に、本実施形態では、分析装置20は、各々のエッジについて、第1のノード31bから測った距離を算出する。第1のノード31bとエッジとの距離は、当該エッジから第1のノード31bに至るまでに辿るエッジの本数である。但し、エッジの本数を計数する際、第1のノード31bとの距離の計測対象となるエッジ自身は除く。例えば、エッジ「A-B」は、自エッジ以外のエッジを辿らなくても第1のノード31bに辿り着けるため、エッジ「A-B」と第1のノード31bとの距離は「0」である。
【0064】
一方、エッジ「D-F」は、第1のノード31bに辿り着くために自エッジ以外の一つのエッジ「B-D」を通る必要がある。よって、エッジ「D-F」と第1のノード31bとの距離は「1」である。
【0065】
更に、この例では、分析装置20はエッジの本数も計数する。例えば、エッジ「B-C」は、第1のグラフG1に二本含まれているため、その本数は「2」となる。
【0066】
次に、
図10(b)の表内に示すように、分析装置20は、第2のグラフG
2に対しても
図10(a)と同様にしてエッジを抽出する。更に、分析装置20は、第2のノード32bから測った各エッジの距離と、各エッジの本数とを算出する。
【0067】
次いで、
図11に示すように、分析装置20は、各グラフG
1、G
2に共通に含まれる複数のエッジのうち、第1のノード31bから測った距離と、第2のノード32bから測った距離とが等しい第1のエッジ33を特定する。
【0068】
図11では、特定した第1のエッジ33を実線で示すと共に、当該第1のエッジ33に対応する表の行にハッチングをかけてある。また、特定されなかったエッジは点線で示してある。
【0069】
例えば、エッジ「A-B」は、第1のグラフG1と第2のグラフG2の両方に共通に含まれており、かつ、第1のノード31bから測った距離と第2のノード32bから測った距離がいずれも「0」で等しい。よって、エッジ「A-B」は、第1のエッジ33として特定される。
【0070】
一方、エッジ「B-E」について考える。エッジ「B-E」は、第1のグラフG1と第2のグラフG2の両方に共通に含まれている。しかし、第1のグラフG1においては第1のノード31bから測ったエッジ「B-E」の距離は「0」である。これに対し、第2のグラフG2においては第2のノード32bから測ったエッジ「B-E」の距離は「3」である。よって、エッジ「B-E」は、第1のノード31bから測った距離と第2のノード32bから測った距離とが異なるため、第1のエッジ33として特定されない。
【0071】
なお、エッジ「B-C」は各グラフG
1、G
2に共通に含まれ、かつ第1のノード31bから測った距離と第2のノード32bから測った距離がいずれも「0」で等しい。但し、エッジ「B-E」は、第1のグラフG
1には2本含まれるのに対し、第2のグラフG
2には3本含まれる。この場合、分析装置20は、第1のグラフG
1と第2のグラフG
2の両方に共通に含まれる2本のエッジ「B-E」を第1のエッジ33として特定する。
図11において第2のグラフG
2の表でエッジ「B-E」の行にかけられた薄いハッチングは、このように3本のうちの2本のみが第1のエッジ33として特定されることを示す。
【0072】
次に、分析装置20は、次の式(1)に従って、第1のソースプログラム4と第2のソースプログラム8の類似度Sim(G1, G2)を算出する。
【0073】
【数1】
なお、式(1)におけるeは各グラフG
1、G
2のエッジを示す。また、f(e)は、エッジeの個数を示す。そして、W
eは、分析装置20がエッジeに付与する重みである。本実施形態では、各ソースプログラム4、8に含まれる要素のうちで潜在バグ4a、8aに近い要素を類似度の計算に際して重視することで、潜在バグ4a、8aに近い部分で各ソースプログラム4、8が類似してるかを判定する。そのため、この例では、分析装置20が、第1のグラフG
1に含まれる複数のエッジeの重みW
eを、第1のノード31bからの距離が近くなるほど大きくする。同様に、分析装置20は、第2のグラフG
2に含まれる複数のエッジeの重みW
eを、第2のノード32bからの距離が近くなるほど大きくする。
【0074】
一例として、Weは以下の式(2)で定義される。
【0075】
【数2】
但し、n
eは、第1のグラフG
1のエッジeについては第1のノード31bとの距離であり、第2のグラフG
2のエッジeについては第2のノード32bとの距離である。
【0076】
また、式(1)の分子は、第1のエッジ33の重みWeと個数f(e)との積の2倍である。これによれば、類似度Simは、第1のエッジ33の個数f(e)と重みWeの少なくとも一方が大きくなるほど大きくなる。これにより、潜在バグ4a、8aに近い部分で各ソースプログラム4、8が類似してるほど類似度Simを大きくすることができる。
【0077】
図12は、
図11の各グラフG
1、G
2を用いた場合の第1のソースプログラム4と第2のソースプログラム8との類似度の計算例を示す図である。
【0078】
図12に示すように、この例では類似度は約0.7339となる。一方、全てのエッジに対して式(1)の重みW
eを「1」とすると類似度は約0.5455となり、上記の結果よりも類似度が低下する。これにより、重みW
eを加味して類似度を算出することにより、実際に潜在バグ4a、8aに近い部分で各ソースプログラム4、8が類似してるほど類似度Simを大きくなることが明らかとなった。
【0079】
図13は、各グラフG
1、G
2に含まれるエッジeの重みW
eを、式(2)のように各ノード31b、32bからの距離が近くなるほど大きくすることで得られる効果について説明するための模式図である。
【0080】
図13に示すように、各グラフG
1、G
2に共通に含まれる第1のエッジ33であるエッジ「D-B」は、他の第1のエッジ33と比べて第1のノード31bや第2のノード32bから離れている。よって、エッジ「D-B」の重みW
eは小さくなり、エッジ「D-B」が類似度Simに与える影響は小さい。
【0081】
一方、第1のエッジ33の他の例であるエッジ「A-B」は、エッジ「D-B」とくらべて第1のノード31bや第2のノード32bに近い。よって、エッジ「A-B」の重みWeは大きくなり、エッジ「A-B」が類似度Simに与える影響は大きい。
【0082】
このように、本実施形態では、二つのソースプログラム4、8が、潜在バグ4a、8aに近い部分で類似しているかを類似度Simに反映させることができる。
【0083】
しかも、本実施形態では、
図8のように第1のグラフG
1において経路P1、P2上にないノードを削除した状態で分析装置20が式(1)の類似度Simを算出する。第1のグラフG
1において経路P1、P2上にないノードは潜在バグ8aとの関連が薄いノードである。第2のグラフG
2についても同様である。そのため、このようにノードを削除してから類似度Simを算出することで、潜在バグ4a、8aと関連が薄い各ソースプログラム4、8の要素が類似度Simに与える影響を排除できる。
【0084】
なお、
図8のように不要なノードを削除せずに、各グラフG
1、G
2の最大共通部分グラフの大きさを基にして類似度を算出する方法もある。しかし、最大共通部分グラフを特定する問題はNP困難であることが知られている。これでは、最大共通部分グラフを特定するのに要する時間が複数の修正プログラム9を試行するのに要する時間よりも長くなってしまい、効率的にプログラム開発をすることができない。
【0085】
一方、
図8のように不要なノードを削除してから類似度Simを算出する場合では、第1のエッジ33の本数Nに対してO(N)の計算量で済み、効率的にプログラム開発をすることができる。
【0086】
また、本実施形態のようにグラフG1、G2を生成してから類似度Simを算出するのではなく、分析装置20が各ソースプログラム4、8をテキストベースで比較して両者の類似度を算出することも考えられる。テキストベースの類似度は、例えば、分析装置20が各ソースプログラム4、8に対して字句解析を行い、両者に共通に出現する単語を計数することで算出し得る。しかしながら、テキストベースでは各ソースプログラム4、8は異なっていても、各ソースプログラム4、8が構造的に類似していたり意味的に類似していたりすることがある。よって、各ソースプログラム4、8の構造や意味を考慮して類似度を算出するには、本実施形態のように各ソースプログラム4、8を表すG1、G2を生成するのが好ましい。
【0087】
次に、本実施形態に係る分析装置20の機能構成について説明する。
【0088】
図14は、本実施形態に係る分析装置20の機能構成図である。
図14に示すように、分析装置20は、通信部41、表示部42、記憶部43、及び制御部44を備える。
【0089】
このうち、通信部41は、インターネットやLAN(Local Area Network)等のネットワークに分析装置20を接続するためのインターフェースである。また、表示部42は、液晶ディスプレイ等の表示デバイスである。そして、記憶部43は、複数の第1のソースプログラム4、分析対象の第2のソースプログラム8、及び複数の修正プログラム9等の各種の情報を記憶する。
【0090】
一方、制御部44は、分析装置20の各部を制御する処理部である。一例として、制御部44は、取得部51、グラフ生成部52、削除部53、エッジ特定部54、重み算出部55、類似度算出部56、及び提示部57を備える。
【0091】
このうち、取得部51は、通信部41を介して各ソースプログラム4、8、修正ロジック6、第1の潜在バグ位置情報61、及び第2の潜在バグ位置情報62を取得する処理部である。
【0092】
このうち、第1の潜在バグ位置情報61は、複数の第1のソースプログラム4の各々の潜在バグ4aの位置情報として、各第1のソースプログラム4において潜在バグ4aが位置する行番号を格納した情報である。また、第2の潜在バグ位置情報62は、第2のソースプログラム8の潜在バグ8aの位置情報として、第2のソースプログラム8において潜在バグ8aが位置する行番号を格納した情報である。
【0093】
例えば、取得部51は、各ソースプログラム4、8に対して静的解析ツールを実行したコンピュータから各潜在バグ位置情報61、62と修正ロジック6とを取得し、それらを記憶部43に格納する。また、この例では、複数の修正ロジック6の各々を生成するのに要する内容が相異なる複数の第1のソースプログラム4を取得部51が取得する。なお、制御部44自身が静的解析ツールを実行して各潜在バグ位置情報61、62と修正ロジック6とを記憶部43に格納してもよい。
【0094】
グラフ生成部52は、複数の第1のソースプログラム4の各々を表現する複数の第1のグラフG1と、分析対象の第2のソースプログラム8を表現する第2のグラフG2とを生成する処理部である。更に、グラフ生成部52は、各グラフG1、G2の各々の構造を示すグラフ構造情報63を生成し、そのグラフ構造情報63を記憶部43に格納する。
【0095】
図15は、グラフ構造情報63の模式図である。
図15に示すように、グラフ構造情報63は、ノードテーブル63aとエッジテーブル63bとを有する。
【0096】
このうち、ノードテーブル63aは、各グラフG1、G2のノードの情報が格納されたテーブルであって、「ID」、「ソースID」、「ノード種別」、「行番号」、及び「テキスト」の各属性を有する。
【0097】
このうち、属性「ID」は、ノードテーブル63aの各レコードを一意に識別する識別子である。また、属性「ソースID」は、複数の第1のソースプログラム4と分析対象の第2のソースプログラム8の各々を一意に識別する識別子である。
【0098】
属性「ノード種別」は、ノードに対応した文の機能を示す文字列である。例えば、文の機能がメソッド呼び出しの場合には、「ノード種別」には「MethodInvocation」が格納される。
【0099】
属性「行番号」は、ノードに対応した文の行番号である。そして、属性「テキスト」は、当該文の内容である。
【0100】
一方、エッジテーブル63bは、各グラフG1、G2のエッジの情報が格納されたテーブルであって、「ID」、「ソースID」、「親ノードID」、「子ノードID」、及び「エッジ種別」の各属性を有する。
【0101】
このうち、属性「ID」は、エッジテーブル63bの各レコードを一意に識別する識別子である。また、属性「ソースID」は、ノードテーブル63aの属性「ソースID」と同じである。
【0102】
そして、属性「親ノードID」はエッジの親ノードを識別する識別子であり、属性「子ノードID」はエッジの子ノードを識別する識別子である。
【0103】
属性「エッジ種別」は、エッジによって定義される文の意味的な繋がりを示す文字列である。例えば、
図7のようにエッジが変数の定義を示す場合、属性「エッジ種別」には文字列「decl」が格納される。
【0104】
再び
図14を参照する。削除部53は、
図8に示したように、第1のグラフG
1に含まれる複数のノードのうち、第1のノード31bを起点として子ノードから親ノードの順に辿って第1のルートノード31aに至る第1の経路にないノードを削除する。同様に、削除部53は、第2のグラフG
2に含まれる複数のノードのうち、第2のノード32bを起点として子ノードから親ノードの順に辿って第2のルートノード32aに至る第2の経路にないノードを削除する。
【0105】
また、削除部53は、このようにノードを削除した後の各グラフG
1、G
2に係る剪定後グラフ構造情報64を生成し、それを記憶部43に格納する。なお、剪定後グラフ構造情報64のフォーマットは、
図15のグラフ構造情報と同一なので、ここではその説明を省略する。
【0106】
エッジ特定部54は、削除部53がノードを削除した後の各グラフG1、G2に共通に含まれる複数の第1のエッジ33を特定する処理部である。前述のように、第1のエッジ33は、第1のグラフG1と第2のグラフG2の各々に共通に含まれる複数のエッジのうち、第1のノード31bから測った距離と、第2のノード32bから測った距離とが等しいエッジである。
【0107】
また、エッジ特定部54は、複数の第1のエッジ33に係るエッジ情報65を生成し、そのエッジ情報65を記憶部43に格納する。
【0108】
図16は、エッジ情報65の模式図である。
図16に示すように、エッジ情報65は、「ID」、「ソースID」、「エッジID」、「親ノード種別」、「子ノード種別」、及び「距離」の各属性を対応付けたテーブルである。
【0109】
このうち、「ID」と「ソースID」は、グラフ構造情報63(
図15参照)におけるのと同様である。また、「エッジID」は、複数の第1のエッジ33の各々を一意に識別する識別子である。
【0110】
「親ノード種別」と「子ノード種別」は、それぞれ第1のエッジ33の親ノードと子ノードの各々に対応した文の機能を示す文字列であり、グラフ構造情報63(
図15参照)における「ノード種別」と同一である。
【0111】
再び
図14を参照する。重み算出部55は、前述の式(2)に従って複数の第1のエッジ33の各々の重みW
eを算出する処理部である。
【0112】
また、類似度算出部56は、前述の式(1)に従って、第1のソースプログラム4と第2のソースプログラム8との類似度Sim(G1, G2)を、複数の第1のソースプログラム4ごとに算出する処理部である。
【0113】
提示部57は、複数の第1のソースプログラム4の各々に対応した複数の修正ロジック6で第2のソースプログラム8を修正した複数の修正プログラム8を生成し、それを記憶部43に格納する。
【0114】
更に、提示部57は、類似度Simが高い第1のソースプログラム4から順に、当該1のソースプログラム4に対応した修正ロジック6が適用された修正プログラム9を提示する。一例として、提示部57は、修正プログラム9を表示する指示を表示部42に対して通知することにより、開発者に修正プログラム9を提示する。
【0115】
図17は、修正プログラム9の提示例について示す模式図である。
図17に示すように、この例では提示部57が類似度Simの高い順に二つの修正プログラム9を提示する。各々の修正プログラム9には、修正前の潜在バグ8aと、潜在バグ8aを修正した後の文9aとが示される。
【0116】
次に、本実施形態に係る分析方法について説明する。
【0117】
図18は、本実施形態に係る分析方法のフローチャートである。まず、取得部51が、各ソースプログラム4、8、修正ロジック6、第1の潜在バグ位置情報61、及び第2の潜在バグ位置情報62を取得し、これらを記憶部43に格納する(ステップS10)。
【0118】
次に、グラフ生成部52が、複数の第1のソースプログラム4の各々を表現する複数の第1のグラフG1を生成する(ステップS11)。更に、グラフ生成部52は、複数の第1のグラフG1の各々の構造を示すグラフ構造情報63を生成してそれを記憶部43に格納する。
【0119】
次いで、グラフ生成部52が、分析対象の第2のソースプログラム8を表現する第2のグラフG2を生成する(ステップS12)。また、グラフ生成部52は、グラフ構造情報63のレコードに、第2のグラフG2の構造を示す情報を追加する。
【0120】
続いて、削除部53が、各グラフG
1、G
2から不要なノードを削除する剪定処理を行う(ステップS13)。この剪定処理は、
図8に示したように、各グラフG
1、G
2のノードのうちで各ソースプログラム4、8の潜在バグ4a、8aと関連性が薄いノードを削除することで、各グラフG
1、G
2を剪定する処理である。この剪定処理の詳細については後述する。
【0121】
次いで、エッジ特定部54が、不要なノードを削除した後の各グラフG1、G2に共通に含まれる複数の第1のエッジ33を特定する(ステップS14)。また、エッジ特定部54は、複数の第1のエッジ33に係るエッジ情報65を生成してそれを記憶部43に格納する。
【0122】
次に、重み算出部55が、前述の式(2)に従って複数の第1のエッジ33の各々の重みWeを算出する(ステップS15)。
【0123】
続いて、類似度算出部56が、前述の式(1)に従って第1のソースプログラム4と第2のソースプログラム8との類似度Simを複数の第1のソースプログラム4ごとに算出する(ステップS16)。
【0124】
次いで、提示部57が、類似度Simが高い第1のソースプログラム4から順に、当該1のソースプログラム4に対応した修正ロジック6で第2のソースプログラム8を修正した修正プログラム9を提示する(ステップS17)。
【0125】
以上により、本実施形態に係る分析方法の基本的な処理を終える。
【0126】
次に、ステップS13の剪定処理について説明する。
【0127】
図19は、剪定処理のフローチャートである。まず、削除部53が、第1のグラフG
1において、第1のノード31bを起点として子ノードから親ノードの順に辿って第1のルートノード31aに至る全ての経路を列挙する(ステップS20)。
図8の例では、削除部53は、全ての経路として第1の経路P1、P2を列挙する。
【0128】
次に、削除部53が、第1のグラフG1のエッジのうちで、ステップS20で列挙した経路に含まれている全てのエッジを列挙する(ステップS21)。
【0129】
続いて、削除部53が、ステップS21で列挙したエッジの親ノードと子ノードとを列挙し、それ以外の第1のグラフG1のノードを削除する(ステップS22)。
【0130】
次いで、削除部53が、ステップS21で列挙したエッジと、ステップS22で列挙したノードに係る情報を剪定後グラフ構造情報64に格納する(ステップS23)。
【0131】
以上により剪定処理の基本的な処理を終える。なお、削除部53は、第2のグラフG2に対する剪定処理もこれと同様に行う。
【0132】
上記した本実施形態によれば、類似度算出部56が、重みWeと第1のエッジ33の個数とを含む式(1)に基づいて、第1のソースプログラム4と第2のソースプログラム8との類似度Simを算出する(ステップS16)。これによれば、潜在バグ4a、8aに近い部分で各グラフG1、G2が似ているほど各ソースプログラム4、8の類似度Simが増大する。そして、第2のソースプログラム8との類似度Simが高く相性の良い第1のソースプログラム4に対する修正ロジック6を第2のソースプログラム8に適用した修正プログラム9で潜在バグ8aが解消できる可能性が高まる。これにより、複数の修正プログラム9のうちで、潜在バグ8aが解消できる可能性が高いプログラムを絞り込むことができる。
【0133】
しかも、ステップS13においてグラフを剪定してから類似度算出部56が各ソースプログラム4、8の類似度を算出するため、潜在バグ4a、8aと関連が薄い各ソースプログラム4、8の要素が類似度Simに与える影響を排除できる。
【0134】
(ハードウェア構成)
次に、本実施形態に係る分析装置20のハードウェア構成について説明する。
【0135】
図20は、本実施形態に係る分析装置20のハードウェア構成図である。
【0136】
図20に示すように、分析装置20は、記憶装置20a、メモリ20b、プロセッサ20c、通信インターフェース20d、表示装置20e、及び媒体読取装置20gを有する。これらの各部は、バス20iにより相互に接続される。
【0137】
このうち、記憶装置20aは、Hard Disk Drive (HDD)やSolid State Drive (SSD)等の不揮発性のストレージであって、本実施形態に係る分析プログラム100を記憶する。
【0138】
なお、分析プログラム100をコンピュータが読み取り可能な記録媒体20hに記録し、媒体読取装置20gを介してプロセッサ20cにその分析プログラム100を読み取らせるようにしてもよい。
【0139】
そのような記録媒体20hとしては、例えばCompact Disc - Read Only Memory (CD-ROM)、Digital Versatile Disc (DVD)、及びUniversal Serial Bus (USB )メモリ等の物理的な可搬型記録媒体がある。また、フラッシュメモリ等の半導体メモリやハードディスクドライブを記録媒体20hとして使用してもよい。これらの記録媒体20hは、物理的な形態を持たない搬送波のような一時的な媒体ではない。
【0140】
更に、公衆回線、インターネット、及びLocal Area Network (LAN)等に接続された装置に分析プログラム100を記憶させてもよい。その場合は、プロセッサ20cがその分析プログラム100を読み出して実行すればよい。
【0141】
一方、メモリ20bは、Dynamic Random Access Memory (DRAM)等のようにデータを一時的に記憶するハードウェアであって、その上に分析プログラム100が展開される。
【0142】
プロセッサ20cは、分析装置20の各部を制御するCentral Processing Unit (CPU)やGraphical Processing Unit (GPU)等のハードウェアである。また、プロセッサ20cは、メモリ20bと協働して分析プログラム100を実行する。
【0143】
このようにメモリ20bとプロセッサ20cとが協働して分析プログラム100を実行することにより、分析装置20の制御部44(
図14参照)が実現される。その制御部44には、取得部51、グラフ生成部52、削除部53、エッジ特定部54、重み算出部55、類似度算出部56、及び提示部57が含まれる。
【0144】
また、記憶部43(
図14参照)は、記憶装置20aとメモリ20bとにより実現される。
【0145】
更に、通信インターフェース20dは、分析装置20をLANやインターネット等のネットワークに接続するためのNetwork Interface Card (NIC)等のハードウェアである。その通信インターフェース20dにより通信部41(
図14参照)が実現される。
【0146】
そして、表示装置20eは、
図17のように修正プログラム9を表示するための液晶ディスプレイやタッチパネル等のハードウェアである。その表示装置20eにより表示部42(
図14参照)が実現される。
【0147】
媒体読取装置20gは、記録媒体20hを読み取るためのCDドライブ、DVDドライブ、及びUSBインターフェース等のハードウェアである。
【符号の説明】
【0148】
1…コンピュータ、2…リポジトリ、4…第1のソースプログラム、4a…潜在バグ、5…修正箇所、6…修正ロジック、8…第2のソースプログラム、8a…潜在バグ、9…修正プログラム、9a…文、20…分析装置、31a…第1のルートノード、31b…第1のノード、31x…有向エッジ、32a…第2のルートノード、32b…第2のノード、33…第1のエッジ、41…通信部、42…表示部、43…記憶部、44…制御部、51…取得部、52…グラフ生成部、53…削除部、54…エッジ特定部、55…重み算出部、56…類似度算出部、57…提示部、61…第1の潜在バグ位置情報、62…第2の潜在バグ位置情報、63…グラフ構造情報、63a…ノードテーブル、63b…エッジテーブル、64…剪定後グラフ構造情報、65…エッジ情報。