JP2018073223A - 解析プログラム、解析方法、および解析装置 - Google Patents

解析プログラム、解析方法、および解析装置 Download PDF

Info

Publication number
JP2018073223A
JP2018073223A JP2016214024A JP2016214024A JP2018073223A JP 2018073223 A JP2018073223 A JP 2018073223A JP 2016214024 A JP2016214024 A JP 2016214024A JP 2016214024 A JP2016214024 A JP 2016214024A JP 2018073223 A JP2018073223 A JP 2018073223A
Authority
JP
Japan
Prior art keywords
node
analysis
nodes
reachable
unit
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
JP2016214024A
Other languages
English (en)
Inventor
圭佑 堀田
Keisuke Hotta
圭佑 堀田
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.)
Fujitsu Ltd
Original Assignee
Fujitsu Ltd
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 Fujitsu Ltd filed Critical Fujitsu Ltd
Priority to JP2016214024A priority Critical patent/JP2018073223A/ja
Publication of JP2018073223A publication Critical patent/JP2018073223A/ja
Pending legal-status Critical Current

Links

Images

Landscapes

  • Stored Programmes (AREA)

Abstract

【課題】コールグラフを用いた解析時間を短縮する。【解決手段】解析装置10は、解析対象プログラム1内の処理の複数の手続きを複数のノードで表し、手続き間の複数の呼び出し関係を複数のエッジで表したコールグラフ2を記憶する。解析装置10は、コールグラフ2に基づいて、複数のノードそれぞれについて、複数のエッジを呼び出し元から呼び出し先へ辿ることで自ノードへ到達可能な他ノードの数を示す到達可能ノード数を取得する。次に解析装置10は、複数のノードそれぞれを、到達可能ノード数に基づいた順番で解析対象ノードとして選定する。そして解析装置10は、コールグラフ2に基づいて選定された解析対象ノードに関する解析を行い、解析対象ノードに関連する情報を取得する。【選択図】図1

Description

本発明は、解析プログラム、解析方法、および解析装置に関する。
ソフトウェアの開発において、作成されているプログラムのソースコードの解析を行うことがある。ソースコード解析では、例えばコールグラフが用いられる。コールグラフは、コンピュータプログラムのサブルーチン同士の呼び出し関係を表現した有向グラフである。コールグラフのノードが、処理の手続きを表現し、エッジが手続き間の呼び出しを示す。
コールグラフを用いて解析を行うコンピュータは、コールグラフ内のあるノードの情報を得る場合、そのノードから呼び出し先を辿ることで到達可能な他のすべてのノードの情報を取得する。なお、解析の過程で、解析対象のノードからの新たな呼び出し先のノードの存在が判明することがある。この場合、コンピュータは、呼び出し関係を呼び出し元から呼び出し先に辿ることで解析対象のノードに到達可能なノードについては、すでに解析済であっても再度解析を行うこととなる。また、コールグラフには閉路が存在し得る。閉路が存在する場合、コンピュータは、コールグラフ内の一部のノードについては何度も繰り返し解析することで、正しい情報を得ることができる。
コールグラフを用いた解析技術としては、例えばシステムプロセスのソースコードを構文解析するリバースエンジニアリングによって出力された物理モデルのコールグラフなどから論理モデルのユースケースを抽出するシステム分析方法が開示されている。
特開2012−108607号公報
コールグラフのノード数が増加すると、ノード間の呼び出し関係が複雑化し、個々のノードの解析回数も増加する。そのため、コールグラフに含まれるノード数の増加に伴い、解析するノードの延べ数が著しく増大する。その結果、コールグラフを用いた解析には多大な時間がかかる。
1つの側面では、本発明は、コールグラフを用いた解析時間を短縮することを目的とする。
1つの案では、以下の処理をコンピュータに実行させる解析プログラムが提供される。
コンピュータは、解析対象プログラム内の処理の複数の手続きを複数のノードで表し、手続き間の複数の呼び出し関係を複数のエッジで表したコールグラフに基づいて、複数のノードそれぞれについて、複数のエッジを呼び出し元から呼び出し先へ辿ることで自ノードへ到達可能な他ノードの数を示す到達可能ノード数を取得する。次にコンピュータは、複数のノードそれぞれを、到達可能ノード数に基づいた順番で解析対象ノードとして選定する。そしてコンピュータは、コールグラフに基づいて選定された解析対象ノードに関する解析を行い、解析対象ノードに関連する情報を取得する。
1態様によれば、コールグラフを用いた解析時間を短縮することができる。
第1の実施の形態に係る解析装置の機能構成例を示す図である。 第2の実施の形態に用いるコンピュータのハードウェアの一構成例を示す図である。 ソースコードに示されるメソッド間の呼び出し関係の一例を示す図である。 コールグラフの一例を示す図である。 ノード間の“情報”の伝搬を説明する図である。 解析順による解析回数の違いを示す図である。 概算到達可能ノード数の算出例を示す図である。 プログラム解析機能の構成例を示す図である。 メモリ内に設けられた記憶機能の一例を示す図である。 プログラム解析処理の手順を示すフローチャートである。 ノード選定処理の手順の一例を示すフローチャートである。 要解析ノード選定処理の手順の一例を示すフローチャートである。 安定性判定処理の手順の一例を示すフローチャートである。 コールグラフ構築処理の手順の一例を示すフローチャートである。 ノード解析処理の手順の一例を示すフローチャートの前半である。 ノード解析処理の手順の一例を示すフローチャートの後半である。 再解析通知処理の手順の一例を示すフローチャートである。 ノード更新処理の手順の一例を示すフローチャートである。 未解析ノード登録処理の手順の一例を示すフローチャートである。 要解析ノード登録処理の手順の一例を示すフローチャートである。 解析結果出力処理の手順の一例を示すフローチャートである。 ソースコードから生成されるコールグラフの一例を示す図である。 各格納部内の情報の遷移の例を示す図である。 初期状態から2周目までのコールグラフの構築・探索状況の一例を示す図である。 3周目と4周目のコールグラフの構築・探索状況の一例を示す図である。 5周目と6周目のコールグラフの構築・探索状況の一例を示す図である。 7周目と8周目のコールグラフの構築・探索状況の一例を示す図である。 9周目と10周目のコールグラフの構築・探索状況の一例を示す図である。 11周目と12周目のコールグラフの構築・探索状況の一例を示す図である。 13周目と14周目のコールグラフの構築・探索状況の一例を示す図である。 15周目と16周目のコールグラフの構築・探索状況の一例を示す図である。 17周目のコールグラフの構築・探索状況の一例を示す図である。 解析画面例を示す図である。 第2の実施の形態におけるノード選定方式と未解析優先方式との総計算時間の比較結果を示す図である。
以下、本実施の形態について図面を参照して説明する。なお各実施の形態は、矛盾のない範囲で複数の実施の形態を組み合わせて実施することができる。
〔第1の実施の形態〕
図1は、第1の実施の形態に係る解析装置の機能構成例を示す図である。解析装置10は、記憶部11と処理部12とを有している。記憶部11は、例えば解析装置10が有するメモリまたはストレージ装置である。処理部12は、例えば解析装置10が有するプロセッサである。
記憶部11は、解析対象プログラム1とコールグラフ2とを記憶する。解析対象プログラム1は、例えば高級言語で記述されたソースコードである。コールグラフ2は、解析対象プログラム1内の処理の複数の手続きを複数のノードで表し、手続き間の複数の呼び出し関係を複数のエッジで表した有向グラフである。処理の手続きは、例えば関数やメソッドである。
処理部12は、コールグラフ2に基づいて、複数のノードそれぞれについて、複数のエッジを呼び出し元から呼び出し先へ辿ることで自ノードへ到達可能な他ノードの数を示す到達可能ノード数を取得する。例えば処理部12は、複数のノードそれぞれに対応付けて、自ノードへ到達可能な他ノードのノード識別子が登録された到達可能ノード集合を設けておく。そして処理部12は、複数のノードそれぞれの到達可能ノード集合に登録されたノード識別子の数を、複数のノードそれぞれの到達可能ノード数として取得する。
なお、各ノードの到達可能ノード集合は、例えばそのノードに対してエッジで直接接続された隣接ノードの情報を調査して判明する範囲での到達可能ノードのノードIDを含んでいるものでよい。この場合、到達可能ノード集合に基づいて得られる到達可能ノード数は概算値となる。到達可能ノード数を概算値でよいものとすることで、到達可能ノードの探索処理負荷が軽減される。
到達可能ノード数を取得後、処理部12は、複数のノードそれぞれを、到達可能ノード数に基づいた順番で解析対象ノードとして選定する。例えば処理部12は、到達可能ノード数が多いノードほど優先的に解析対象ノードとして選定する。例えば処理部12は、解析対象ノードを選定する指標が、到達可能ノード数を含めて複数あるとき、到達可能ノード数以外の指標に差異がないノード間において、到達可能ノード数が多いノードを先に解析対象ノードとして選定する。
解析対象ノードを選定後、処理部12は、コールグラフ2に基づいて、選定された解析対象ノードに関する解析を行い、解析対象ノードに関連する情報を取得する。例えば処理部12は、取得した情報を、解析対象ノードに関連付けて保持する。また処理部12は、解析対象ノードから複数のエッジを辿ることで到達可能な新たな呼び出し先ノードが検出されると、新たな呼び出し先ノードの到達可能ノード集合に、解析対象ノードの到達可能ノード集合に含まれるノード識別子を追加する。
このように、到達可能ノード数が多いノードを優先的に解析することで、情報が変更されたときの影響範囲が広いノードを先に解析することができる。その結果、呼び出し先のノードの情報が変更されることにより再解析を行うこととなるノードの発生確率を低くすることができ、解析するノードの延べ数が抑制される。その結果、解析時間が短縮される。
なお、処理部12は、コールグラフ2内の各ノードの状態を判定し、その状態に応じて解析対象ノードを選定することもできる。例えば処理部12は、複数のノードのうち、一度も解析を行っていないノードの状態を未解析状態と判定する。また処理部12は、少なくとも1度解析が行われ、自ノードの最後の解析後に、自ノードにエッジで接続された隣接ノードの情報が更新されたノードの状態を要解析状態と判定する。そして処理部12は、解析対象ノードの選定において、未解析状態のノードを、要解析状態のノードよりも先に解析対象ノードとして選定する。このように、未解析状態のノードを優先的に解析することで、情報が変更される可能性が高いノードほど先に解析され、再解析の発生回数を抑止することができる。
また処理部12は、ノードの状態の判定において、複数のノードのうち、未解析状態と要解析状態とのいずれでもないノードを解析済状態と判定することもできる。このとき処理部12は、解析対象ノードの選定において、要解析状態のノードのうち、自ノードからの直接の呼び出し先のノードのすべてが解析済状態であるノードを、情報が安定的であると判定する。そして処理部12は、情報が安定的な要解析状態のノードを、情報が安定的でない要解析状態のノードよりも先に解析対象ノードとして選定する。これにより、情報が変更される可能性が高いノードほど先に解析され、再解析の発生回数を抑止することができる。
さらに、処理部12は、コールグラフ2の構築と、コールグラフ2を用いた解析とを並行して実施することもできる。この場合、処理部12は、解析対象プログラム1に基づいて、選定された解析対象ノードに対応する手続きから呼び出される他の手続きの有無を解析する。そして処理部12は、呼び出し先の手続きに対応するノードがコールグラフ2内に存在しないとき、呼び出し先の手続きに対応するノードをコールグラフ2に追加する。ノードを追加したとき、処理部12は、追加したノードを、呼び出し元のノードからエッジで接続する。
処理部12は、未解析ノードかどうか、安定ノードかどうか、および到達可能ノード数の内の1つ以上を組み合わせて、解析対象ノードを選定することができる。図1の例では、以下のような手順で解析処理を行っている。
処理部12は、まず、すべてのノードの状態が解析済かどうかを判定する(ステップS11)。すべてのノードの状態が解析済であれば、解析処理は終了する。解析済の状態になっていないノードが少なくとも1つ存在すれば、処理部12は、未解析ノードがあるか否かを判定する(ステップS12)。未解析ノードがある場合、処理部12は、到達可能ノード数が最大の未解析ノードのうちの1つを、解析対象ノードとして選定する(ステップS13)。
未解析ノードがない場合、処理は、安定ノード(呼び出し先がすべて解析済の要解析ノード)があるか否かを判定する(ステップS14)。安定ノードがある場合、処理部12は、到達可能ノード数が最大の安定ノードのうちの1つを、解析対象ノードとして選定する(ステップS15)。安定ノードがない場合、処理部12は、到達可能ノード数が最大の要解析ノードのうちの1つを、解析対象ノードとして選定する(ステップS16)。
解析対象ノードを選定後、処理部12は、選定した解析対象ノードを解析する(ステップS17)。処理部12は、解析によって解析対象ノードに関する情報を取得する。例えば解析対象ノードからエッジを呼び出し先方向に辿って到達可能なノードのリスト(呼び出し先ノード集合)や、エッジを呼び出し先方向に辿って解析対象ノードに到達可能なノードのリスト(到達可能ノード集合)が、情報として取得される。解析を行うと、処理部12は、解析対象ノードの状態を解析済に変更する。
解析後、処理部12は、解析によって解析対象ノードの情報が変化したか否かを判定する(ステップS18)。例えば処理部12は、解析対象ノードからの呼び出し先のノード(エッジを呼び出し先方向に辿って到達可能なノード)が変化した場合、情報が変化したものと判定する。情報が変化した場合、処理部12は、解析対象ノードの呼び出しを行う呼び出し元ノードの状態を要解析に変更する(ステップS19)。
そして処理部12は、解析対象ノードから直接呼び出される呼び出し先ノードの到達可能ノードを更新する(ステップS20)。例えば処理部12は、解析対象ノードの到達可能ノード集合に含まれるノード識別子を、直接の呼び出し先のノードの到達可能ノードの集合に追加する。その後、処理部12は、処理をステップS11に進め、すべてのノードが解析済状態になるまで、上記の処理を繰り返す。
このような処理により、未解析ノード優先、安定ノード優先、および到達可能ノード数が大きいノード優先を組み合わせて、適切な解析対象ノードの選定を行うことができる。例えば図1に示したコールグラフ2であれば、未解析状態のノード「D」とノード「G」が存在し、ノード「D」の到達可能ノード数は「2」であり、ノード「G」の到達可能ノード数は「1」である。そこで、到達可能ノード数が最大の未解析ノードであるノード「D」が、次の解析対象ノードとして選定される。このような選定を繰り返すことで、解析時間を大幅に短縮することができる。
〔第2の実施の形態〕
次に第2の実施の形態について説明する。
図2は、第2の実施の形態に用いるコンピュータのハードウェアの一構成例を示す図である。コンピュータ100は、プロセッサ101によって装置全体が制御されている。プロセッサ101には、バス109を介してメモリ102と複数の周辺機器が接続されている。プロセッサ101は、マルチプロセッサであってもよい。プロセッサ101は、例えばCPU(Central Processing Unit)、MPU(Micro Processing Unit)、またはDSP(Digital Signal Processor)である。プロセッサ101がプログラムを実行することで実現する機能の少なくとも一部を、ASIC(Application Specific Integrated Circuit)、PLD(Programmable Logic Device)などの電子回路で実現してもよい。
メモリ102は、コンピュータ100の主記憶装置として使用される。メモリ102には、プロセッサ101に実行させるOS(Operating System)のプログラムやアプリケーションプログラムの少なくとも一部が一時的に格納される。また、メモリ102には、プロセッサ101による処理に必要な各種データが格納される。メモリ102としては、例えばRAM(Random Access Memory)などの揮発性の半導体記憶装置が使用される。
バス109に接続されている周辺機器としては、ストレージ装置103、グラフィック処理装置104、入力インタフェース105、光学ドライブ装置106、機器接続インタフェース107およびネットワークインタフェース108がある。
ストレージ装置103は、内蔵した記録媒体に対して、電気的または磁気的にデータの書き込みおよび読み出しを行う。ストレージ装置103は、コンピュータの補助記憶装置として使用される。ストレージ装置103には、OSのプログラム、アプリケーションプログラム、および各種データが格納される。なお、ストレージ装置103としては、例えばHDD(Hard Disk Drive)やSSD(Solid State Drive)を使用することができる。
グラフィック処理装置104には、モニタ21が接続されている。グラフィック処理装置104は、プロセッサ101からの命令に従って、画像をモニタ21の画面に表示させる。モニタ21としては、CRT(Cathode Ray Tube)を用いた表示装置や液晶表示装置などがある。
入力インタフェース105には、キーボード22とマウス23とが接続されている。入力インタフェース105は、キーボード22やマウス23から送られてくる信号をプロセッサ101に送信する。なお、マウス23は、ポインティングデバイスの一例であり、他のポインティングデバイスを使用することもできる。他のポインティングデバイスとしては、タッチパネル、タブレット、タッチパッド、トラックボールなどがある。
光学ドライブ装置106は、レーザ光などを利用して、光ディスク24に記録されたデータの読み取りを行う。光ディスク24は、光の反射によって読み取り可能なようにデータが記録された可搬型の記録媒体である。光ディスク24には、DVD(Digital Versatile Disc)、DVD−RAM、CD−ROM(Compact Disc Read Only Memory)、CD−R(Recordable)/RW(ReWritable)などがある。
機器接続インタフェース107は、コンピュータ100に周辺機器を接続するための通信インタフェースである。例えば機器接続インタフェース107には、メモリ装置25やメモリリーダライタ26を接続することができる。メモリ装置25は、機器接続インタフェース107との通信機能を搭載した記録媒体である。メモリリーダライタ26は、メモリカード27へのデータの書き込み、またはメモリカード27からのデータの読み出しを行う装置である。メモリカード27は、カード型の記録媒体である。
ネットワークインタフェース108は、ネットワーク20に接続されている。ネットワークインタフェース108は、ネットワーク20を介して、他のコンピュータまたは通信機器との間でデータの送受信を行う。
以上のようなハードウェア構成によって、第2の実施の形態の処理機能を実現することができる。なお、第1の実施の形態に示した装置も、図2に示したコンピュータ100と同様のハードウェアにより実現することができる。
コンピュータ100は、例えばコンピュータ読み取り可能な記録媒体に記録されたプログラムを実行することにより、第2の実施の形態の処理機能を実現する。コンピュータ100に実行させる処理内容を記述したプログラムは、様々な記録媒体に記録しておくことができる。例えば、コンピュータ100に実行させるプログラムをストレージ装置103に格納しておくことができる。プロセッサ101は、ストレージ装置103内のプログラムの少なくとも一部をメモリ102にロードし、プログラムを実行する。またコンピュータ100に実行させるプログラムを、光ディスク24、メモリ装置25、メモリカード27などの可搬型記録媒体に記録しておくこともできる。可搬型記録媒体に格納されたプログラムは、例えばプロセッサ101からの制御により、ストレージ装置103にインストールされた後、実行可能となる。またプロセッサ101が、可搬型記録媒体から直接プログラムを読み出して実行することもできる。
コンピュータ100は、ソースコードに基づいて、ソースコード内のメソッド間の呼び出し関係を示すコールグラフを生成する。そしてコンピュータ100は、生成したコールグラフを利用して、ソースコードに示されるプログラムを解析する。プログラムの解析では、例えばオブジェクトの状態変化、オブジェクトへの依存の検出などが行われる。
以下、ソースコードがオブジェクト指向のプログラミング言語で記述されている場合を想定し、ソースコードから生成されるコールグラフについて説明する。
図3は、ソースコードに示されるメソッド間の呼び出し関係の一例を示す図である。ソースコードには、例えば複数のクラス31〜33が定義されている。クラス31〜33内には、メソッドを呼び出す記述が含まれる。メソッドでは、他のメソッドを呼び出し、呼び出した先のメソッドの実行結果を利用して、呼び出し元のメソッドを実行することができる。例えばクラス31内に示されるメソッド「m1」から、クラス32内に示されるメソッド「m2」が呼び出されている。このようなメソッド間の呼び出し関係があることで、図3の例では、「m1()」を呼び出すと、「A.b,A.c,B.s,C.x」の値が変わる可能性がある。また「m1()」の実行結果(返り値)は「A.i」の値に依存する。
このようにメソッドを介して、各クラスが影響を及ぼし合っている。例えば、オブジェクトの状態変化やオブジェクトへの依存を検出したい場合、メソッド間の呼び出し関係を解析することとなる。すなわち、メソッド間の呼び出し関係の解析は、プログラム理解支援やレビュー強化に活用できると期待できる。ただし、あるメソッドの解析結果が別のメソッドに波及し得るため、同じメソッドを複数回解析することとなり、プログラムの解析に時間がかかる。
あるメソッドの解析結果の影響が、どのメソッドに波及するのかを調査するのに、コールグラフが用いられる。
図4は、コールグラフの一例を示す図である。コールグラフ40は、ソースコード34内に示されている手続きを示すモジュール(メソッドや関数など)を示すノード41と、モジュール間の呼び出し関係を示すエッジ42を含んでいる。
コールグラフ40は、データ表記40a上は、「コールグラフG=(V,E)」と表される。Vは ノード(メソッドや関数)の集合であり、データ表示上は「V={m1,m2,m3}」と表される。Eはエッジ(呼び出し関係)の集合(E⊆V×V)であり、データ表記上は「E={(m1,m1),(m1,m2),(m1,m3),(m2,m3),(m3,m2)」と表される。
なお、第2の実施の形態におけるコールグラフ40のエッジ42には、オーバーライド関係を表すエッジを含むものとする。オーバーライドとは、スーパークラスで定義されたメソッドをサブクラスで定義しなおし、動作を上書きすることである。オーバーライド関係を表すエッジは、オーバーライドされる側からする側への矢印で表される。コールグラフ40にオーバーライドを示すエッジを含めることで、オーバーライドを含めた解析を行うことができる。
ここで、ソースコード解析において、コールグラフを構築・探索して、例えばあるノードの情報を取得する場合を考える。以下、ノードの情報を“情報”と表し、他の一般的な情報と区別する。
コールグラフ「G=(V,E)」の分析により取得する“情報”としては、例えば、ステップ数、出現する変数などがある。図3の例であれば、「m1()」について「変更する変数」の“情報”を取得すると、「A.b,A.c,B.s,C.x」という結果が得られる。また「m1()」について「依存する変数」の“情報”を取得すると、「A.i」という結果が得られる。
ここで、取得対象の“情報”に示される値の数は、有限であるものとする。“情報”に示される値の数が有限であることで、探索問題の停止性を保証される。
コールグラフを用いた探索において、1つのノードを複数回解析することとなる原因の1つは、あるノードから別のノードへ「“情報”」が伝搬し得る点である。
図5は、ノード間の“情報”の伝搬を説明する図である。図5の例において、ソースコード35を解析して、ノード「m2」のステップ数を得たいものとする。ソースコード35では、メソッド「m2」がメソッド「m1」を呼び出している。そのためコールグラフ43において、ノード「m2」からノード「m1」へのエッジが存在する(i.e.(m2,m1)∈E)。
この場合、コンピュータ100は、ノード「m1」のステップ数もノード「m2」のステップ数に計上する。すなわち、ノード「m1」からノード「m2」に“情報”の伝搬が発生している。逆にノード「m2」からノード「m1」への“情報”の伝搬はないものとして取り扱う。呼び出し元のノードから呼び出し先のノードへの“情報”伝搬が存在し得る問題も考えられるが、第2の実施の形態では、解析の対象外とする。
なおコンピュータ100は、コールグラフの構築と探索を同時並行的に実施することができる。初期状態では、いくつかのノード(起点)の存在だけが明らかになっているものとする。存在が明らかとなっている各ノードを解析することで、そのノードの1つ先のノードの存在が判明する。
このようなコールグラフの構築並びに探索を同時並行的に行うコールグラフ構築・探索問題では、ノード数の増加に伴い解析されるノードの述べ数が著しく増大する。ここで、「次にどのノードを解析するか」を選定する方式を工夫することで、ノードの解析回数を抑制し、結果的に所要時間が短縮されると期待できる。
以下図6を参照して、ノードの選定順と解析回数との関係について説明する。
図6は、解析順による解析回数の違いを示す図である。解析順の善し悪しを分かりやすくするため、極めて単純なコールグラフ44を考える。コールグラフ44では、N(Nは1以上の整数)個のノードを有する。コールグラフ44の各ノードは、左側のノードから呼び出され、右側のノードを呼び出す。左端のノードが起点であり、右端のノードが末尾である。
このようなコールグラフ44の生成元となるソースコードを解析する場合、最適な解析順は、起点のノードから順に呼び出し先を辿りながら解析を進めていき、末尾のノードに到達したら、1つずつ呼び出し元に戻ってくるという順番である。このような順番でノードを選定して解析を行うと、末尾のノードのみ1度の解析で済み、それ以外は2度解析を行うことから、解析回数は「N+(N−1)=2N−1」となる。これは、オーダ表記で「O(N)」と表される。
他方、最悪な解析順は、逐次起点に戻りながら解析するという順番である。このような順番でノードを選定して解析を行うと、解析回数は「1+2+3+・・・+N=N(N+1)/2」となる。これはオーダ表記で「O(N2)」と表される。
このように、解析対象とするノードの選定順が異なれば、ノードを解析する回数も異なる。このことから、適切な順番でノードを選定すれば、解析回数を削減できることが理解できる。
従来のノードの選定方式としては、例えば、条件を満たすノードの中から解析するノードをランダムに選定する手法(ランダム方式)がある。ランダム方式では、無駄な解析が多く、処理に要する時間が著しく大きい。そこで、未解析のノードがあればその中から、なければそれ以外のノードから解析するノードをランダムに選定する手法(未解析優先方式)が考えられる。未解析優先方式は、ランダム方式よりは無駄な解析が抑制されるが、処理に要する時間は依然として大きい。
このように、従来のノード選定方式では、ノードの解析回数の削減効果が不十分である。そこで、ランダム方式や未解析優先方式より適切なノード選定方式について検討する。
適切なノード選定方式は、不要な解析の回数を抑え、合計処理時間の削減につなげることができるノード選定方式である。なお、このノード選定方式を用いて得られる結果が、従来のノード選定方式と同一であることが前提となる。
また、第2の実施の形態では、ノードの解析回数を最小にするノード選定方式ではなく、適切と思われるノードを、少ない計算量で選定できるノード選定方式を採用する。すなわち、コンピュータ100は、適切なノードの選定を、なるべく簡単な処理で実現する。これは、より複雑な選定処理を行えば、より適切なノードを選定できる可能性があるが、選定処理に要するオーバーヘッドが大きくなり、全体の処理時間の短縮効果が薄れるためである。
複雑な処理で最もいいものを選ぶのではなく、簡単な処理でよさそうなものを選ぶために、第2の実施の形態では、以下の3つの指標を利用する。
1.ノードの状態(未解析なのか要解析なのか)
2.ノードに到達可能なノードの数
3.ノードが安定であるか否か
以下、3つの指標について詳細に説明する。
[指標1(ノードの状態)について]
指標1のノードの状態とは、解析対象となるノードが取り得る状態であり、未解析状態と要解析状態とがある。未解析状態のノードは、そのノードの存在は判明しているが、一度も解析していないノードである。未解析状態のノードからの呼び出し先に、他のノードが存在するか否かは未知である。
要解析状態のノードは、そのノードを一度以上解析したが、そこから先の“情報”の変化に伴い再解析を要するノードである。要解析状態のノードからの呼び出し先のノードは既知である。
第2の実施の形態では、コールグラフ構築・探索問題では、コールグラフの構築と探索を同時に行う。そのため、一部しか判明していないサブグラフ内の探索を優先して、サブグラフ内の“情報”を確定させても、後でグラフの全体像が明らかになったときにその“情報”に変化が生じる可能性がある。そこでコールグラフの構築処理を優先的に行った方が、ノードの解析回数を削減できる。そこでコンピュータ100は、要解析状態のノードよりも未解析状態のノードを先に選定し、解析を行う。
[指標2(ノードに到達可能なノードの数)について]
あるノードの到達可能ノード数は、コールグラフのエッジの向きに沿って辿ったとき、そのノードに辿りつくことができるノードの数である。到達可能ノード数は、自分自身を除いて数えられる。到達可能ノード数が大きいほど自身の“情報”が変化したときに影響を受けるノードが多い。そこでコンピュータ100は、到達可能ノード数が多いノードほど、解析対象として優先的に選定する。
ただし、コールグラフの規模が大きくなると、到達可能ノード数の算出に時間がかかる場合がある。そこで第2の実施の形態では、到達可能ノード数の概算値(概算到達可能ノード数)を用いる。
図7は、概算到達可能ノード数の算出例を示す図である。図7の例では、ノード45を解析することで、ノード45からノード46へのエッジ47が生成されたものとする。このとき、ノード45に到達可能なすべてのノードは、ノード46にも到達可能であるため、ノード46の概算到達可能ノード数が更新される。同様にノード46に到達可能なすべてのノードは、ノード46から呼び出される他のノードにも到達可能である。しかし、概算到達可能ノード数の計算では、ノード46から呼び出される他のノードの概算到達可能ノード数は更新されない。正確な到達可能ノード数を用いた方がより適切なノードを選定できる可能性はあるが、正確な到達可能ノード数の計算時間を勘案し、第2の実施の形態では、概算到達可能ノード数を用いる。
[指標3(ノードが安定であるか否か)について]
安定であるノードとは、そのノードから辿ることができるノードの状態が解析済状態となっているノードである。このようなノードは、そのノードから先では“情報”の変化が起きることがない、すなわち“情報”が安定している。安定したノードを解析すれば、以降そのノードを再解析する状況は生じない。
ノードの安定性の判別の際、あるノードが安定か否かを正確に判別するためには、そのノードから辿ることができるすべてのノードの状態を検査することとなる。しかしコールグラフが大規模になると、対象のすべてのノードの状態を検査するのは処理負荷が過大となる。そこで、第2の実施の形態では、安定性判別対象のノードからの直接の呼び出し先のノードの状態がすべて解析済ならば、安定性判別対象のノードは安定であると定義する。すなわち、コンピュータ100は、安定性判別対象のノードに隣接したノードの“情報”のみから、おおよその安定性を判別する。これにより、判定に要する処理時間を抑えることができる。
以上説明した3つの指標を用いてノードを選定することで、プログラム解析時に、適切なノード選定を効率的に行うことができる。
次に、コンピュータ100における、コールグラフ構築・探索を含むプログラム解析機能について説明する。
図8は、プログラム解析機能の構成例を示す図である。コンピュータ100は、記憶機能として、ソースコード格納部111、コールグラフ格納部112、未解析ノード格納部113、要解析ノード格納部114、およびノード詳細情報格納部115を有する。
ソースコード格納部111は、図3などに示したような、複数のメソッドの呼び出し関係を有するソースコードを記憶する。ソースコード格納部111は、例えばメモリ102またはストレージ装置103を用いて実現される。
コールグラフ格納部112、未解析ノード格納部113、要解析ノード格納部114、およびノード詳細情報格納部115は、例えばプログラム解析時にメモリ102内に設けられる記憶領域によって実現される記憶機能である。
図9は、メモリ内に設けられた記憶機能の一例を示す図である。コールグラフ格納部112には、ノードの集合(Nodes)とエッジの集合(Edges)とが格納される。ノードの集合には、存在が確認できた手続きを示すモジュール(メソッドや関数など)に対応するノードの識別子が含まれる。エッジの集合には、手続き間の呼び出し関係に対応するエッジが含まれる。各エッジは、呼び出し元のノードの識別子と呼び出し先のノードの識別子との対で表される。
未解析ノード格納部113には、未解析状態のノード(未解析ノード)の識別子が、そのノードへの到達可能ノード数別で格納される。
要解析ノード格納部114には、要解析状態のノード(要解析ノード)の識別子が、そのノードへの到達可能ノード数別で格納される。
ノード詳細情報格納部115には、ノードごとに、そのノードへの到達可能ノードの識別子の集合と、呼び出し先ノードの識別子の集合とが格納される。
図9の例では、コールグラフ格納部112、未解析ノード格納部113、要解析ノード格納部114、およびノード詳細情報格納部115を、メモリ102が有するものとしているが、これらのうちの少なくとも一部を、ストレージ装置103内に設けてもよい。また各格納部で格納するデータの一部をストレージ装置103に格納することもできる。
図8の説明に戻る。コンピュータ100は、処理機能として、解析制御部121、ノード選定部122、安定性判定部123、コールグラフ構築部124、ノード解析部125、再解析通知部126、ノード更新部127、未解析ノード登録部128、要解析ノード登録部129、および解析結果出力部130を有する。
解析制御部121は、プログラム解析全体を制御する。ノード選定部122は、コールグラフから解析対象のノードを選定する。安定性判定部123は、ノードの安定性を判定する。コールグラフ構築部124は、ソースコードに基づいてコールグラフを構築する。ノード解析部125は、ノードに対応するモジュールを解析する。再解析通知部126は、解析済となったノードのうち再度解析するノードを、要解析ノード登録部129に通知する。ノード更新部127は、各ノードの詳細情報を更新する。未解析ノード登録部128は、未解析ノードを未解析ノード格納部113に登録する。要解析ノード登録部129は、再度解析する要解析ノードを、要解析ノード格納部114に登録する。解析結果出力部130は、解析結果を出力する。
なお、図8に示した各要素間を接続する線は通信経路の一部を示すものであり、図示した通信経路以外の通信経路も設定可能である。また、図8に示した各要素の機能は、例えば、その要素に対応するプログラムモジュールをコンピュータに実行させることで実現することができる。
次に、コンピュータ100が実行する処理について、具体的に説明する。
図10は、プログラム解析処理の手順を示すフローチャートである。プログラム解析処理は、解析の起点となるノードの集合を含む解析要求の入力に応じて実行開始される。またプログラム解析処理の結果として、コールグラフ「G=(V,E)」とノードの“情報”「Info(v)(v∈V)」とが出力される。以下、図10に示す処理をステップ番号に沿って説明する。
[ステップS101]解析制御部121は、ノード選定部122を用いて、解析対象ノードを選定する。例えば解析制御部121は、ノード選定部122に対して、解析対象ノードの選定要求を送信する。するとノード選定部122により解析対象ノードが選定される。ノード選定部122は選定した解析対象ノードの識別子を出力する。解析対象ノードが存在しない場合、ノード選定部122は「NULL」を出力する。解析制御部121は、ノード選定部122から、選定されたノードの識別子を取得する。
[ステップS102]解析制御部121は、解析対象ノードがあるか否かを判断する。例えば解析制御部121は、ノード選定部122の出力が「NULL」以外であれば、解析対象ノードがあると判断する。解析対象ノードがある場合、解析制御部121は、処理をステップS104に進める。解析対象ノードがない場合、解析制御部121は、処理をステップS103に進める。
[ステップS103]解析制御部121は、解析結果出力部130を用いて解析の結果を出力する。例えば解析制御部121は、解析結果出力部130に対して、解析結果の出力要求を送信する。すると解析結果出力部130は、例えばノード詳細情報格納部115から解析結果データを取得して、解析結果をモニタ21に出力する。
[ステップS104]解析制御部121は、選定された解析対象ノードが未解析ノードか否かを判断する。例えば解析制御部121は、未解析ノード格納部113を参照し、解析対象ノードの識別子が未解析ノード格納部113に格納されている場合、未解析ノードであると判断する。解析制御部121は、未解析ノードであれば、処理をステップS105に進める。また解析制御部121は、未解析ノードでなければ、処理をステップS106に進める。
[ステップS105]解析制御部121は、コールグラフ構築部124を用いて、解析対象ノードからの呼び出し先ノードをコールグラフ格納部112に登録する。例えば解析制御部121は、コールグラフ構築部124に、解析対象ノードの識別子を含むコールグラフ登録要求を送信する。コールグラフ登録要求に応じてコールグラフ構築部124で未解析ノードが解析され、呼び出し先ノードがコールグラフ格納部112に登録される。
[ステップS106]解析制御部121は、ノード解析部125を用いてノードの解析を実施する。例えば解析制御部121は、ノード解析部125に、解析対象ノードの識別子を含むノード解析要求を送信する。するとノード解析部125により、解析対象ノードに付与される“情報”(ノード詳細情報への登録内容)や、“情報”の変化の有無が解析される。
[ステップS107]解析制御部121は、ノード解析部125の解析結果に基づいて、解析前後で解析対象ノード(v)の呼び出し先ノード(Info(v))が変化したか否かを判断する。呼び出し先ノードが変化した場合、解析制御部121は、処理をステップS108に進める。呼び出し先ノードが変化していない場合、解析制御部121は、処理をステップS109に進める。
[ステップS108]解析制御部121は、再解析通知部126を用いて、解析対象ノードの呼び出し元ノードの状態を、要解析状態に変更する。例えば解析制御部121は、再解析通知部126に、解析対象ノードの識別子を含む再解析設定要求を送信する。すると、再解析通知部126により、解析対象ノードの呼び出し元ノードの状態が、要解析状態に変更される。
[ステップS109]解析制御部121は、ノード更新部127を用いて、解析対象ノードの呼び出し先ノードの到達可能ノード集合を更新する。例えば解析制御部121は、ノード更新部127に対して、解析対象ノードの識別子を含むノード更新要求を送信する。するとノード更新部127により、ノード詳細情報格納部115における解析対象ノードの呼び出し先ノードの到達可能ノード集合が更新される。その後、解析制御部121は、処理をステップS101に進める。
このようにして、解析制御部121の制御のもと、コールグラフ構築・探索を伴うプログラム解析が実行され、解析結果を得ることができる。
次に、解析制御部121からの要求に応じて実行される処理について詳細に説明する。まず、ノード選定部122によるノード選定処理について説明する。
図11は、ノード選定処理の手順の一例を示すフローチャートである。ノード選定部122は、解析制御部121からの解析対象ノードの選定要求に応じてノード選定処理を開始する。ノード選定部122は、ノード選定処理に当たり、到達可能ノード別に分類された未解析ノード群と要解析ノード群とを、それぞれ未解析ノード格納部113と要解析ノード格納部114とから取得する。ノード選定部122は、ノード選定処理の結果、次に解析すべきノード(解析対象ノード)の識別子を出力する。以下、図11に示す処理をステップ番号に沿って説明する。
[ステップS121]ノード選定部122は、未解析ノード格納部113内に未解析ノードがあるか否かを判断する。例えばノード選定部122は、未解析ノード格納部113内のいずれかの到達可能ノード数に対応する未解析ノードの集合が空集合でなければ、未解析ノードがあると判断する。ノード選定部122は、未解析ノードがある場合、処理をステップS122に進める。またノード選定部122は、未解析ノードがない場合、処理をステップS125に進める。
[ステップS122]ノード選定部122は、未解析ノード格納部113から、到達可能ノード数が最大のノードを1つ選定する。
[ステップS123]ノード選定部122は、未解析ノード格納部113から、選定したノードの識別子を削除する。
[ステップS124]ノード選定部122は、選定したノードの識別子を、解析対象ノードの識別子として出力する。その後、ノード選定処理が終了する。
[ステップS125]ノード選定部122は、要解析ノード格納部114に要解析ノードがあるか否かを判断する。例えばノード選定部122は、要解析ノード格納部114内のいずれかの到達可能ノード数に対応する要解析ノードの集合が空集合でなければ、要解析ノードがあると判断する。ノード選定部122は、要解析ノードがある場合、処理をステップS127に進める。またノード選定部122は、要解析ノードがない場合、処理をステップS126に進める。
[ステップS126]ノード選定部122は、ノード選定結果として「NULL」を出力する。その後、ノード選定処理が終了する。
[ステップS127]ノード選定部122は、要解析ノード選定処理を実行する。要解析ノード選定処理において、要解析ノードのうちの1つが解析対象ノードとして選定され、その解析対象ノードの識別子が出力される。
図12は、要解析ノード選定処理の手順の一例を示すフローチャートである。以下、図12に示す処理をステップ番号に沿って説明する。
[ステップS131]ノード選定部122は、要解析ノード格納部114から、到達可能ノード数が最大のノードを1つ仮選定する。
[ステップS132]ノード選定部122は、安定性判定部123を用いて、仮選定したノードが安定ノードか否かを判断する。例えばノード選定部122は、安定性判定部123に対して、仮選定したノード(安定性判定対象ノード)の識別子を含む安定性判定要求を送信する。安定性判定要求に応じて、安定性判定部123により、安定性対象ノードが安定か否かが判定される。安定性判定部123は、安定であると判定した場合「TRUE」を出力し、安定ではないと判定した場合「FALSE」を出力する。ノード選定部122は、安定性判定部123の出力値に基づいて、仮選定したノードが安定か否かを判断できる。ノード選定部122は、仮選定したノードが安定であれば、処理をステップS133に進める。またノード選定部122は、仮選定したノードが安定でなければ、処理をステップS134に進める。
[ステップS133]ノード選定部122は、仮選定したノードを出力ノードとして選定する。その後、ノード選定部122は処理をステップS141に進める。
[ステップS134]ノード選定部122は、要解析ノード格納部114内の仮選定したノードの識別子に対して、検査済みとマークする。このマークは、要解析ノード選定処理内でのみ使用される局所的なフラグである。その後、ノード選定部122は、仮選定したノードの識別子をメモリ102に退避する。
[ステップS135]ノード選定部122は、要解析ノード格納部114内に未検査の要解析ノードがあるか否かを判断する。ノード選定部122は、未検査の要解析ノードがあれば、処理をステップS137に進める。またノード選定部122は、未検査の要解析ノードがなければ、処理をステップS136に進める。
[ステップS136]ノード選定部122は、メモリ102に退避していた識別子に対応するノードを、出力ノードとして選定する。その後、ノード選定部122は、処理をステップS141に進める。
[ステップS137]ノード選定部122は、要解析ノード格納部114から、到達可能ノード数が最大のノードのうち、未検査のノードを1つ仮選定する。未検査のノードとは、ノードの識別子に検査済みのマークが付与されていないノードである。
[ステップS138]ノード選定部122は、安定性判定部123を用いて、仮選定したノードが安定ノードか否かを判断する。ノード選定部122は、仮選定したノードが安定であれば、処理をステップS140に進める。またノード選定部122は、仮選定したノードが安定でなければ、処理をステップS139に進める。
[ステップS139]ノード選定部122は、要解析ノード格納部114内の仮選定したノードの識別子に対して、検査済みとマークする。その後、ノード選定部122は、処理をステップS135に進める。
[ステップS140]ノード選定部122は、仮選定したノードを出力ノードとして選定する。その後、ノード選定部122は処理をステップS141に進める。
[ステップS141]ノード選定部122は、要解析ノード格納部114から、出力ノードとして選定したノードの識別子を削除する。
[ステップS142]ノード選定部122は、出力ノードとして選定したノードの識別子を、解析対象ノードの識別子として出力する。その後、要解析ノード選定処理が終了する。
図11、図12に示した処理によって、要解析ノードよりも未解析ノードが、解析対象ノードとして優先的に選定される。また未解析ノード同士では、到達可能ノード数が大きいノード程、解析対象ノードとして優先的に選定される。未解析ノード同士では、安定ノードのうち到達可能ノード数が最も大きいノードが、解析対象ノードとして優先的に選定される。未解析ノード内に安定ノードがなければ、未解析ノードのうち到達可能ノード数が最も大きいノードが、解析対象ノードとして優先的に選定される。
次に安定性判定部123による安定性判定処理について詳細に説明する。
図13は、安定性判定処理の手順の一例を示すフローチャートである。安定性判定部123は、安定性判定対象ノードの識別子を含む安定性判定要求に応じて安定性判定処理を開始する。安定性判定処理の結果、安定性判定対象ノードが安定か否かを示す値を出力する。以下、図13に示す処理をステップ番号に沿って説明する。
[ステップS151]安定性判定部123は、コールグラフ格納部112から、安定性判定対象ノードの呼び出し先ノードの識別子をすべて取得する。
[ステップS152]安定性判定部123は、取得した識別子で示されるノードに、未検査の呼び出し先ノードがあるか否かを判断する。未検査のノードとは、ノードの識別子に検査済みのマークが付与されていないノードである。取得したノードの識別子に付与される検査済みのマークは、安定性判定処理の中でのみ使われる局所的なフラグである。安定性判定部123は、未検査の呼び出し先ノードがあれば、処理をステップS154に進める。また安定性判定部123は、未検査の呼び出し先ノードがなければ、処理をステップS153に進める。
[ステップS153]安定性判定部123は、安定性判定対象ノードが安定であることを示す情報「TRUE」を出力し、安定性判定処理を終了する。
[ステップS154]安定性判定部123は、ステップS151で取得した識別子で示されるノードの中から未検査の呼び出し先ノードを1つ選定し、そのノードの識別子に検査済みとマークする。
[ステップS155]安定性判定部123は、選定したノードの状態が解析済か否かを判断する。例えば安定性判定部123は、選定したノードの識別子が、要解析ノード格納部114に登録されていない場合、そのノードは解析済であると判断する。安定性判定部123は、解析済であれば、処理をステップS152に進める。安定性判定部123は、解析済でなければ、処理をステップS156に進める。
[ステップS156]安定性判定部123は、安定性判定対象ノードが安定でないことを示す情報「FALSE」を出力し、安定性判定処理を終了する。
このような安定性判定処理により、安定性判定対象ノードの呼び出し先ノードが、すべて解析済状態であれば、安定性判定対象ノードは安定であると判断される。安定性判定対象ノードの呼び出し先ノードのうち、解析済でない状態のノードが少なくとも1つでもあれば、安定性判定対象ノードは安定でないと判断される。
次に、コールグラフ構築部124によるコールグラフ構築処理について詳細に説明する。
図14は、コールグラフ構築処理の手順の一例を示すフローチャートである。コールグラフ構築部124は、未解析の解析対象ノードの識別子を含むコールグラフ登録要求に応じてコールグラフ構築処理を開始する。コールグラフ構築部124は、コールグラフ構築処理の結果、呼び出し先ノードの集合および呼び出しエッジの集合を出力する。出力した値は、コールグラフ格納部112に登録される。以下、図14に示す処理をステップ番号に沿って説明する。
[ステップS161]コールグラフ構築部124は、解析対象ノードを分析し、呼び出し先ノードをすべて特定する。例えばコールグラフ構築部124は、ソースコード格納部111から、ソースコード内の解析対象ノードに対応するモジュールを取得する。そしてコールグラフ構築部124は、取得したモジュール内の記述を解析し、他のメソッドまたは関数を呼び出す命令に基づいて、呼び出し先のノードを特定する。
[ステップS162]コールグラフ構築部124は、未処理の呼び出し先ノードがあるか否かを判断する。未処理のノードとは、ノードの識別子に検査済みのマークが付与されていないノードである。取得したノードの識別子に付与される検査済みのマークは、コールグラフ構築処理の中でのみ使われる局所的なフラグである。コールグラフ構築部124は、未処理の呼び出し先ノードがある場合、処理をステップS163に進める。またコールグラフ構築部124は、未処理の呼び出し先ノードがない場合、コールグラフ構築処理を終了する。
[ステップS163]コールグラフ構築部124は、未処理の呼び出し先ノードを1つ選定し、そのノードの識別子に処理済みとマークする。
[ステップS164]コールグラフ構築部124は、コールグラフ格納部112を参照し、選定したノードがコールグラフに登録済みか否かを判断する。コールグラフ構築部124は、選定したノードが登録済みであれば、処理をステップS166に進める。またコールグラフ構築部124は、選定したノードが未登録であれば、処理をステップS165に進める。
[ステップS165]コールグラフ構築部124は、選定したノードをコールグラフ格納部165に登録する。
[ステップS166]コールグラフ構築部124は、解析対象ノードと選定したノードとを結ぶエッジを作成し、コールグラフ格納部112に登録する。その後、コールグラフ構築部124は、処理をステップS162に進める。
このようにして、未解析のノードを解析する際に、コールグラフの構築処理が行われる。
次に、ノード解析部125によるノード解析処理について詳細に説明する。
図15は、ノード解析処理の手順の一例を示すフローチャートの前半である。ノード解析部125は、解析対象ノードの識別子を含むノード解析要求に応じて、ノード解析処理を開始する。ノード解析部125は、ノード解析処理の結果、解析対象ノードに付与される“情報”と、その“情報”が解析前後で変化したか否かを示す値とを出力する。以下、図15に示す処理をステップ番号に沿って説明する。
[ステップS171]ノード解析部125は、ノード詳細情報格納部115から、解析対象ノードの呼び出し先ノード(Info(v))を取得し、取得した呼び出し先ノード(Info(v))をメモリ102に退避する。
[ステップS172]ノード解析部125は、解析対象ノードを分析し、解析対象ノードから得られる呼び出し先ノード(Info(v))を特定する。
[ステップS173]ノード解析部125は、コールグラフ格納部112から、呼び出し先ノードをすべて取得する。
[ステップS174]ノード解析部125は、未処理の呼び出し先ノードがあるか否かを判断する。未処理の呼び出し先ノードとは、ノードの識別子に検査済みのマークが付与されていない呼び出し先ノードである。取得したノードの識別子に付与される検査済みのマークは、ノード解析処理の中でのみ使われる局所的なフラグである。ノード解析部125は、未処理の呼び出し先ノードがある場合、処理をステップS175に進める。またノード解析部125は、未処理の呼び出し先ノードがない場合、処理をステップS181(図16参照)に進める。
[ステップS175]ノード解析部125は、未処理の呼び出し先ノードを1つ選定し、そのノードの識別子に処理済みとマークする。
[ステップS176]ノード解析部125は、選定したノードの呼び出し先ノード(Info(v))をノード詳細情報格納部176から取得する。
[ステップS177]ノード解析部125は、選定したノードの呼び出し先ノード(Info(v))を、解析対象ノードの呼び出し先ノード(Info(v))として付与する。例えばノード解析部125は、選定したノードの呼び出し先ノード(Info(v))のうち、解析対象ノードの呼び出し先ノード(Info(v))に含まれていないノードの識別子を特定する。そしてノード解析部125は、特定したノードの識別子を、解析対象ノードの呼び出し先ノード(Info(v))のリストに追加する。その後、ノード解析部125は、処理をステップS174に進める。
図16は、ノード解析処理の手順の一例を示すフローチャートの後半である。以下、図16に示す処理をステップ番号に沿って説明する。
[ステップS181]ノード解析部125は、解析対象ノードの呼び出し先ノード(Info(v))を、ノード詳細情報格納部115に格納する。
[ステップS182]ノード解析部125は、解析対象ノードの呼び出し先ノード(Info(v))を、メモリ102に退避しておいた呼び出し先ノード(Info(v))と比較する。
[ステップS183]ノード解析部125は、解析前後で解析対象ノードの呼び出し先ノード(Info(v))が変化したか否かを判断する。ノード解析部125は、変化がある場合、処理をステップS184に進める。またノード解析部125は、変化がない場合、処理をステップS185に進める。
[ステップS184]ノード解析部125は、“情報”が解析前後で変化したか否かを示す値として、変化したことを示す「TRUE」を出力する。その後、ノード解析部125は、処理をステップS186に進める。
[ステップS185]ノード解析部125は、“情報”が解析前後で変化したか否かを示す値として、変化していないことを示す「FALSE」を出力する。
[ステップS186]ノード解析部125は、解析対象ノードの状態を解析済に設定する。例えばノード解析部125は、未解析ノード格納部113または要解析ノード格納部114から、管理対象ノードの識別子を削除する。その後、ノード解析部125は、ノード解析処理を終了する。
このようにして、解析対象ノードが解析され、解析対象ノードの呼び出し先ノードが更新されるとともに、処理結果として、解析前後での呼び出し先ノードの変化の有無が出力される。
次に、再解析通知部126による再解析通知処理について詳細に説明する。
図17は、再解析通知処理の手順の一例を示すフローチャートである。再解析通知部126は、解析対象ノードの識別子を含む再解析設定要求に応じて再解析通知処理を開始する。再解析通知部126は、再解析通知処理の結果、呼び出し元ノードの状態を要解析状態へ変更すると共に、ノード詳細情報格納部115へ到達可能ノードを登録する。以下、図17に示す処理をステップ番号に沿って説明する。
[ステップS191]再解析通知部126は、コールグラフ格納部112から、解析対象ノードの呼び出し元ノードの識別子をすべて取得する。
[ステップS192]再解析通知部126は、未処理の呼び出し元ノードがあるか否かを判断する。未処理の呼び出し元ノードとは、ノードの識別子に検査済みのマークが付与されていない呼び出し元ノードである。取得したノードの識別子に付与される検査済みのマークは、再解析通知処理の中でのみ使われる局所的なフラグである。再解析通知部126は、未処理の呼び出し元ノードがある場合、処理をステップS193に進める。また再解析通知部126は、未処理の呼び出し元ノードがない場合、再解析通知処理を終了する。
[ステップS193]再解析通知部126は、未処理の呼び出し元ノードを1つ選定し、そのノードの識別子に処理済みとマークする。
[ステップS194]再解析通知部126は、選定したノードの状態が未解析であるか否かを判断する。例えば再解析通知部126は、選定したノードの識別子が未解析ノード格納部113に格納されている場合、状態が未解析であると判断する。再解析通知部126は、状態が未解析の場合、処理をステップS192に進める。また再解析通知部126は、状態が未解析でなければ、処理をステップS195に進める。
[ステップS195]再解析通知部126は、選定したノードの状態を要解析に設定する。
[ステップS196]再解析通知部126は、要解析ノード登録部129を用いて、選定したノードを要解析ノード格納部114へ登録する。その後、再解析通知部126は、処理をステップS192に進める。
このようにして、再度解析するべきノードの状態を、要解析に設定することができる。
次に、ノード更新部127によるノード更新処理について詳細に説明する。
図18は、ノード更新処理の手順の一例を示すフローチャートである。ノード更新部127は、解析対象ノードの識別子を含むノード更新要求に応じてノード更新処理を開始する。ノード更新部127は、ノード更新処理の結果、呼び出し先ノードの到達可能ノード集合を更新する。
[ステップS201]ノード更新部127は、コールグラフ格納部112から、解析対象ノードの呼び出し先ノードをすべて取得する。
[ステップS202]ノード更新部127は、未処理の呼び出し先ノードがあるか否かを判断する。未処理の呼び出し先ノードとは、ノードの識別子に検査済みのマークが付与されていない呼び出し先ノードである。取得したノードの識別子に付与される検査済みのマークは、ノード更新処理の中でのみ使われる局所的なフラグである。ノード更新部127は、未処理の呼び出し先ノードがあれば、処理をステップS203に進める。またノード更新部127は、未処理の呼び出し先ノードがなければ、ノード更新処理を終了する。
[ステップS203]ノード更新部127は、未処理の呼び出し先ノードを1つ選定し、そのノードの識別子に処理済みとマークする。
[ステップS204]ノード更新部127は、選定したノードの到達可能ノード集合と解析対象ノードの到達可能ノード集合とを、ノード詳細情報格納部115から取得する。
[ステップS205]ノード更新部127は、選定したノードの到達可能ノード集合に、解析対象ノードと、解析対象ノードの到達可能ノード集合のすべての要素とを追加する。
[ステップS206]ノード更新部127は、選定したノードの到達可能ノード集合を、ノード詳細情報格納部115に登録する。
[ステップS207]ノード更新部127は、選定したノードの状態を判断する。ノード更新部127は、選定したノードが解析済の状態であれば、処理をステップS202に進める。ノード更新部127は、選定したノードが要解析の状態であれば、処理をステップS208に進める。ノード更新部127は、選定したノードが未解析の状態であれば、処理をステップS209に進める。
[ステップS208]ノード更新部127は、要解析ノード登録部129を用い、選定したノードを要解析ノード格納部114へ登録する。例えばノード更新部127は、選定したノード(登録対象ノード)の識別子を含む要解析ノード登録要求を、要解析ノード登録部129に送信する。その後、ノード更新部127は処理をステップS202に進める。
[ステップS209]ノード更新部127は、未解析ノード登録部128を用い、選定したノードを未解析ノード格納部113へ登録する。例えばノード更新部127は、選定したノード(登録対象ノード)の識別子を含む未解析ノード登録要求を、未解析ノード登録部128に送信する。その後、ノード更新部127は処理をステップS202に進める。
次に、未解析ノード登録部128による未解析ノード登録処理について詳細に説明する。
図19は、未解析ノード登録処理の手順の一例を示すフローチャートである。未解析ノード登録部128は、登録対象ノードの識別子を含む未解析ノード登録要求に応じて未解析ノード登録処理を開始する。未解析ノード登録部128は、未解析ノード登録処理の結果、登録対象ノードを未解析ノード格納部113へ登録する。以下、図19に示す処理をステップ番号に沿って説明する。
[ステップS221]未解析ノード登録部128は、ノード詳細情報格納部115から登録対象ノードの到達可能ノード集合を取得し、その要素数を計数する。
[ステップS222]未解析ノード登録部128は、登録対象ノードが未解析ノード格納部113に登録済みか否かを判断する。例えば未解析ノード登録部128は、未解析ノード格納部113を参照し、登録対象ノードの識別子が、到達可能ノード数別の未解析ノード集合のいずれかに含まれている場合、登録済みであると判断する。未解析ノード登録部128は、登録対象ノードが登録済みであれば、処理をステップS223に進める。また未解析ノード登録部128は、登録対象ノードが未登録であれば、処理をステップS224に進める。
[ステップS223]未解析ノード登録部128は、未解析ノード格納部113から、登録対象ノードを削除する。
[ステップS224]未解析ノード登録部128は、未解析ノード格納部113から、ステップS221で計数した要素数(到達可能ノード数)に対応する未解析ノード集合を取得する。
[ステップS225]未解析ノード登録部128は、取得した未解析ノード集合に登録対象ノードの識別子を要素として追加し、その未解析ノード集合を、未解析ノード格納部113内の元の位置に書き戻す。その後、未解析ノード登録部128は、未解析ノード登録処理を終了する。
次に、要解析ノード登録部129による要解析ノード登録処理の手順について詳細に説明する。
図20は、要解析ノード登録処理の手順の一例を示すフローチャートである。要解析ノード登録部129は、登録対象ノードの識別子を含む要解析ノード登録要求に応じて要解析ノード登録処理を開始する。要解析ノード登録部129は、要解析ノード登録処理の結果、登録対象ノードを要解析ノード格納部114へ登録する。以下、図20に示す処理をステップ番号に沿って説明する。
[ステップS231]要解析ノード登録部129は、ノード詳細情報格納部115から登録対象ノードの到達可能ノード集合を取得し、その要素数を計数する。
[ステップS232]要解析ノード登録部129は、登録対象ノードが要解析ノード格納部114に登録済みか否かを判断する。例えば要解析ノード登録部129は、要解析ノード格納部114を参照し、登録対象ノードの識別子が、到達可能ノード数別の要解析ノード集合のいずれかに含まれている場合、登録済みであると判断する。要解析ノード登録部129は、登録対象ノードが登録済みであれば、処理をステップS233に進める。また要解析ノード登録部129は、登録対象ノードが未登録であれば、処理をステップS234に進める。
[ステップS233]要解析ノード登録部129は、要解析ノード格納部114から、登録対象ノードを削除する。
[ステップS234]要解析ノード登録部129は、要解析ノード格納部114から、ステップS231で計数した要素数(到達可能ノード数)に対応する要解析ノード集合を取得する。
[ステップS235]要解析ノード登録部129は、取得した要解析ノード集合に登録対象ノードの識別子を要素として登録し、その要解析ノード集合を、要解析ノード格納部114内の元の位置に書き戻す。その後、要解析ノード登録部129は、要解析ノード登録処理を終了する。
次に、解析結果出力部130による解析結果出力処理について詳細に説明する。
図21は、解析結果出力処理の手順の一例を示すフローチャートである。解析結果出力部130は、解析結果の出力要求に応じて解析結果出力処理を開始する。解析結果出力部130は、解析結果出力処理の結果、ソースコードの解析結果をモニタ21に表示する。以下、解析結果出力処理をステップ番号に沿って説明する。
[ステップS241]解析結果出力部130は、コールグラフ格納部112内のコールグラフに基づいて、解析対象のソースコード中のすべてのメソッドを一覧表示する。
[ステップS242]解析結果出力部130は、利用者からの、1つのメソッドの選定入力を受け付ける。
[ステップS243]解析結果出力部130は、利用者が何らかのメソッドを選定したか否かを判断する。解析結果出力部130は、選定入力が行われた場合、処理をステップS244に進める。解析結果出力部130は、選定入力が行われなかった場合、解析結果出力処理を終了する。選定入力が行われなかった場合とは、例えばメソッドが選定されずにメソッド一覧画面が閉じられた場合である。
[ステップS244]解析結果出力部130は、ノード詳細情報格納部115から、選定されたメソッドの“情報”を取得し、取得した“情報”をモニタ21に表示する。
[ステップS245]解析結果出力部130は、選定されたメソッドの“情報”を基に、そのメソッドに関連する別のメソッドを特定し、その一覧と詳細情報をモニタ21に表示する。その後、解析結果出力部130は、処理をステップS242に進める。
以上のようにして、コールグラフを用いたソースコードの解析を効率的に行うことができる。以下、コールグラフを用いた解析を、具体例を用いて説明する。
図22は、ソースコードから生成されるコールグラフの一例を示す図である。図22に示すコールグラフ50は、8個のノードを有している。各ノードの識別子を「A」〜「H」とする。ここで、コールグラフ50が生成されるようなソースコードを、ノード「A」とノード「B」とを起点として解析する場合を想定する。
プログラム解析処理を開始直後は、各格納部には初期状態が設定され、ノードが1つずつ解析される。ノードが解析されるごとに、各格納部の内容が更新される。
図23は、各格納部内の情報の遷移の例を示す図である。初期状態では、起点ノードのみが判明している。すなわちコールグラフ格納部112内に、起点となるノード「A」、「B」が設定されている。ノード「A」、「B」は未解析状態であり、呼び出し関係が不明である。呼び出し関係が不明の場合、ノード「A」、「B」の到達可能ノード数は「0」となる。そこで、未解析ノード格納部113の到達可能ノード数「0」の未解析ノード集合に、ノード「A」、「B」が登録されている。
初期状態では、ノード「A」とノード「B」とは、ノード選定処理における優劣がない。この場合、ノード選定部122は、次に解析するノードとしてノード「A」とノード「B」とのどちらを選定してもよい。図23の例では、ノード「A」が先に選定され、解析されたものとする。
ノード「A」を解析することで、ノード「C」とノード「G」との存在が判明する。すなわち、ノード「A」に対応するメソッドの解析により、そのメソッド内でノード「C」に対応するメソッドの呼び出しと、ノード「G」に対応するメソッドの呼び出しとが行われていることが判明する。その結果、コールグラフ格納部112には、ノード「C」、「G」が追加されると共に、エッジ(A,C)、(A,G)が追加される。
新たに追加されたノード「C」、「G」は未解析状態であるが、それぞれの到達可能ノードとしてノード「A」が存在していることが分かっている。そこで、未解析ノード格納部113の到達可能ノード数「1」の未解析ノード集合に、ノード「C」、「G」が登録されている。なおノード「A」は解析されたことで解析済状態となり、未解析ノード格納部113から削除されている。
またノード「A」の解析により、ノード詳細情報格納部115も更新されている。例えば、ノード「C」の到達可能ノードとしてノード「A」が設定されている。またノード「G」の到達可能ノードとしてノード「A」が設定されている。さらにノード「A」の呼び出し先ノードとしてノード「C」と「G」が設定されている。
このようにノードが解析されるごとに、各格納部内の登録内容が更新される。更新された登録内容に基づいて、次に解析するノードを適切に選定することができる。例えば図23の例では、未解析状態のノードのうち、ノード「C」と「G」は到達可能ノード数が「1」であるが、ノード「B」は到達可能ノード数が「0」である。そこでノード選定部122は、ノード「C」と「G」のどちらかを、次に解析するノードとして選定する。
このような解析対象のノードの選定と、ノードの解析結果に応じた登録内容の更新とを交互に繰り返すことで、コールグラフが生成されていくと共に、ノード詳細情報格納部115に各ノードの詳細情報が格納されていく。そしてすべてのノードが解析済状態になったときにノード詳細情報格納部115に登録されている“情報”が、解析結果となる。
以下、図24〜図32を参照して、コールグラフの構築・探索の様子を具体的に説明する。以下の説明では、図10に示したステップS101〜S109の1回ずつの処理を1周とし、繰り返し処理の進捗状況を、何周目の処理なのかで表すこととする。また図24〜図32では、未解析状態のノードを網掛けの円で示し、要解析のノードを黒塗りの円で示し、解析済のノードを白抜きの円で示す。さらに図24〜図32では、各ノードの近くに、そのノードの到達可能ノード(Reachable)と呼び出し先ノード(Info)とを示す。
図24は、初期状態から2周目までのコールグラフの構築・探索状況の一例を示す図である。初期状態では、起点ノードであるノード「A」とノード「B」とがコールグラフに示されている。最初の解析対象ノードとしてノード「A」とノード「B」とのいずれも選定可能であるが、図24の例ではノード「A」が選定され、1周目の解析が実行されたものとする。
1周目(ノード「A」の解析)の処理後、コールグラフにはノード「C」とノード「G」とが追加されると共に、これらのノードへのノード「A」からのエッジが追加されている。ノード「A」の呼び出し先ノードには、ノード「C」とノード「G」とが追加されている。ノード「C」の到達可能ノードには、ノード「A」が追加されている。ノード「G」の到達可能ノードには、ノード「A」が追加されている。ノード「A」は、状態が未解析から解析済に変更されている。
次の解析対象ノードは、未解析ノードのうち、到達可能ノード数が最大のノードの中から選ばれる。図24の例では、ノード「C」とノード「G」の到達可能ノード数が「1」で最大であり、この2つのノードのいずれかを選定可能である。ここで、ノード「C」が選定され、2周目の解析が実行されたものとする。
2周目(ノード「C」の解析)の処理後、コールグラフにはノード「D」が追加されると共に、これらのノードへのノード「C」からのエッジが追加されている。ノード「C」の呼び出し先ノードには、ノード「D」が追加されている。ノード「D」の到達可能ノードには、ノード「D」の呼び出しを行うノード「C」に加え、ノード「C」の到達可能ノードに設定されているノード「A」が追加されている。ノード「C」は、状態が未解析から解析済に変更されている。ノード「C」を解析した結果、ノード「C」の持つ“情報”に変化が生じたため、ノード「A」の状態が解析済から要解析に変更されている。
次の解析対象ノードは、未解析ノードのうち、到達可能ノード数が最大のノードの中から選ばれる。図24の例では、ノード「D」の到達可能ノード数が「2」で最大であるため、ノード「D」が選定され、3周目の解析が実行される。
図25は、3周目と4周目のコールグラフの構築・探索状況の一例を示す図である。3周目(ノード「D」の解析)の処理後、コールグラフにはノード「E」とノード「F」が追加されると共に、これらのノードへのノード「D」からのエッジが追加されている。ノード「D」の呼び出し先ノードには、ノード「E」とノード「F」が追加されている。ノード「E」の到達可能ノードには、ノード「F」の呼び出しを行うノード「D」に加え、ノード「D」の到達可能ノードに設定されているノード「A」とノード「C」が追加されている。ノード「F」の到達可能ノードには、ノード「F」の呼び出しを行うノード「D」に加え、ノード「D」の到達可能ノードに設定されているノード「A」とノード「C」が追加されている。ノード「D」は、状態が未解析から解析済に変更されている。ノード「D」を解析した結果、ノード「D」の持つ“情報”に変化が生じたため、ノード「C」の状態が解析済から要解析に変更されている。
次の解析対象ノードは、未解析ノードのうち、到達可能ノード数が最大のノードの中から選ばれる。図25の例では、ノード「E」とノード「F」の到達可能ノード数が「3」で最大であり、この2つのノードのいずれかを選定可能である。ここで、ノード「E」が選定され、4周目の解析が実行されたものとする。
4周目(ノード「E」の解析)の処理後、コールグラフにはノード「E」からノード「C」へのエッジが追加されている。ノード「E」の呼び出し先ノードには、ノード「E」が直接呼び出すノード「C」に加え、ノード「C」の呼び出し先ノードに設定されているノード「D」が追加されている。ノード「C」の到達可能ノードには、ノード「C」の呼び出しを行うノード「E」に加え、ノード「E」の到達可能ノードに設定されているノード「D」が追加されている。ノード「E」は、状態が未解析から解析済に変更されている。ノード「E」を解析した結果、ノード「E」の持つ“情報”に変化が生じたため、ノード「D」の状態が解析済から要解析に変更されている。
なお4周目では、ノード「C」の到達可能ノードにノード「D」とノード「E」が追加されたため、到達可能ノードの設定を正確に行うのであれば、ノード「D」やノード「F」についても、到達可能ノードにノード「D」とノード「E」が追加されることとなる。ただし、到達可能ノードの設定を正確に行おうとすると、コールグラフの規模が大きくなったとき、呼び出し関係の追跡範囲が膨大となり、処理負荷が大きくなりすぎる。そこで第2の実施の形態では、コンピュータ100は概略的に到達可能ノードの設定を行っている。すなわち、解析対象ノードに隣接するノードしか到達可能ノードの更新を行わない。これにより、到達可能ノードの設定処理を効率化でき、コールグラフの構築・探索処理の効率化が図れる。
次の解析対象ノードは、未解析ノードのうち、到達可能ノード数が最大のノードの中から選ばれる。図25の例では、ノード「F」の到達可能ノード数が「3」で最大であるため、ノード「F」が選定され、5周目の解析が実行される。
図26は、5周目と6周目のコールグラフの構築・探索状況の一例を示す図である。5周目(ノード「F」の解析)の処理後、コールグラフに変更はない。また各ノードの“情報”も変更されていない。ノード「F」は、状態が未解析から解析済に変更されている。
次の解析対象ノードは、未解析ノードのうち、到達可能ノード数が最大のノードの中から選ばれる。図26の例では、ノード「G」の到達可能ノード数が「1」で最大であるため、ノード「G」が選定され、6周目の解析が実行される。
6周目(ノード「G」の解析)の処理後、コールグラフにはノード「H」が追加されると共に、ノード「G」からノード「H」へのエッジが追加されている。ノード「G」の呼び出し先ノードには、ノード「H」が追加されている。ノード「H」の到達可能ノードには、ノード「H」の呼び出しを行うノード「G」に加え、ノード「G」の到達可能ノードに設定されているノード「A」が追加されている。ノード「G」は、状態が未解析から解析済に変更されている。
次の解析対象ノードは、未解析ノードのうち、到達可能ノード数が最大のノードの中から選ばれる。図26の例では、ノード「H」の到達可能ノード数が「2」で最大であるため、ノード「H」が選定され、7周目の解析が実行される。
図27は、7周目と8周目のコールグラフの構築・探索状況の一例を示す図である。7周目(ノード「H」の解析)の処理後、コールグラフにはノード「H」からノード「E」へのエッジが追加されている。ノード「H」の呼び出し先ノードには、ノード「H」から直接呼び出すノード「E」に加え、ノード「E」の呼び出し先ノードに設定されているノード「C」とノード「D」が追加されている。ノード「E」の到達可能ノードには、ノード「E」の呼び出しを行うノード「H」に加え、ノード「H」の到達可能ノードに設定されているノード「G」が追加されている。ノード「H」は、状態が未解析から解析済に変更されている。
次の解析対象ノードは、未解析ノードのうち、到達可能ノード数が最大のノードの中から選ばれる。図27の例では、未解析ノードがノード「B」のみであるため、ノード「B」が選定され、8周目の解析が実行される。
8周目(ノード「B」の解析)の処理後、コールグラフにはノード「B」からノード「D」へのエッジが追加されている。ノード「B」の呼び出し先ノードには、ノード「B」から直接呼び出すノード「D」に加え、ノード「D」の呼び出し先ノードに設定されているノード「E」とノード「F」が追加されている。ノード「D」の到達可能ノードには、ノード「B」が追加されている。ノード「B」は、状態が未解析から解析済に変更されている。
以上の処理により、未解析状態のノードがなくなっている。従って、呼び出し関係で辿ることができるすべてのノードがコールグラフに含まれており、コールグラフは完成している。また要解析ノードの中に安定ノードはない。そこで、次の解析対象ノードは、要解析ノードの中から選ばれる。図27の例では、要解析ノードのうち、ノード「D」の呼び出し先ノードはノード「E」とノード「F」であり、これらのノードはいずれも解析済である。またノード「G」の呼び出し先ノードはノード「H」のみであり、このノード「H」は解析済である。従って、ノード「D」とノード「G」は共に安定ノードになっている。ノード「D」の到達可能ノード数は「3」であり、ノード「G」の到達可能ノード数は「1」である。そこで、安定ノードのうち到達可能ノード数が最大であるノード「D」が、次の解析対象ノードとして選定され、9周目の処理が実行される。
図28は、9周目と10周目のコールグラフの構築・探索状況の一例を示す図である。9周目(ノード「D」の解析)の処理後、ノード「D」の呼び出し先ノードには、ノード「H」の呼び出し先であるノード「E」の呼び出し先ノードに設定されているノード「C」が追加されている。ノード「E」の到達可能ノードには、ノード「E」の呼び出しを行うノード「D」の到達可能ノードに設定されているノード「B」が追加されている。ノード「F」の到達可能ノードには、ノード「F」の呼び出しを行うノード「D」の到達可能ノードに設定されているノード「B」が追加されている。ノード「D」は、状態が要解析から解析済に変更されている。
9周目の処理が終わったとき、要解析ノードであるノード「C」の呼び出し先ノードはノード「D」のみであり、このノード「D」は解析済である。従って、ノード「C」は安定ノードになっている。ノード「C」の到達可能ノード数は「3」であり、以前より安定ノードとなっているノード「G」の到達可能ノード数「1」よりも多い。そこで、安定ノードのうち到達可能ノード数が最大であるノード「C」が、次の解析対象ノードとして選定され、10周目の処理が実行される。
10周目(ノード「C」の解析)の処理後、ノード「C」の呼び出し先ノードには、ノード「C」の呼び出し先であるノード「D」の呼び出し先ノードに設定されているノード「C」、ノード「E」、およびノード「F」が追加されている。ノード「D」の到達可能ノードには、ノード「D」の呼び出しを行うノード「C」の到達可能ノードに設定されているノード「E」が追加されている。ノード「C」は、状態が要解析から解析済に変更されている。ノード「E」は、呼び出し先であるノード「C」の“情報”が変更されたため、状態が解析済から要解析に変更されている。
10周目の処理が終わったとき、要解析ノードであるノード「E」の直接の呼び出し先ノードはノード「C」のみであり、このノード「C」は解析済である。従って、ノード「E」は安定ノードになっている。ノード「E」の到達可能ノード数は「6」であり、以前より安定ノードとなっているノード「G」の到達可能ノード数「1」よりも多い。そこで、安定ノードのうち到達可能ノード数が最大であるノード「E」が、次の解析対象ノードとして選定され、11周目の処理が実行される。
図29は、11周目と12周目のコールグラフの構築・探索状況の一例を示す図である。11周目(ノード「E」の解析)の処理後、ノード「E」の呼び出し先ノードには、ノード「E」の呼び出し先であるノード「C」の呼び出し先ノードに設定されているノード「E」とノード「F」が追加されている。ノード「C」の到達可能ノードには、ノード「C」の呼び出しを行うノード「E」の到達可能ノードに設定されているノード「B」、ノード「G」、およびノード「H」が追加されている。ノード「E」は、状態が要解析から解析済に変更されている。ノード「D」とノード「H」は、呼び出し先であるノード「E」の“情報”が変更されたため、状態が解析済から要解析に変更されている。
11周目の処理が終わったとき、要解析ノードであるノード「D」の直接の呼び出し先ノードはノード「E」とノード「F」であり、これらのノードは共に解析済である。また要解析ノードであるノード「H」の呼び出し先ノードはノード「E」のみであり、このノード「E」は解析済である。従って、ノード「D」とノード「H」は安定ノードになっている。ノード「D」の到達可能ノード数は「4」であり、ノード「H」の到達可能ノード数は「2」である。そこで、安定ノードのうち到達可能ノード数が最大であるノード「D」が、次の解析対象ノードとして選定され、12周目の処理が実行される。
12周目(ノード「D」の解析)の処理後、ノード「D」の呼び出し先ノードには、ノード「D」の呼び出し先であるノード「E」の呼び出し先ノードに設定されているノード「D」が追加されている。ノード「F」の到達可能ノードには、ノード「F」の呼び出しを行うノード「D」の到達可能ノードに設定されているノード「E」が追加されている。ノード「D」は、状態が要解析から解析済に変更されている。
12周目の処理が終わったとき、要解析ノードであるノード「B」の直接の呼び出し先ノードはノード「D」のみであり、このノード「D」は解析済である。要解析ノードであるノード「C」の呼び出し先ノードはノード「D」のみであり、このノード「D」は解析済である。従って、ノード「B」とノード「C」は安定ノードになっている。ノード「H」は以前より安定ノードである。これらの安定ノードのうち、到達可能ノード数が最も多いのはノード「C」である。そこで、安定ノードのうち到達可能ノード数が最大であるノード「C」が、次の解析対象ノードとして選定され、13周目の処理が実行される。
図30は、13周目と14周目のコールグラフの構築・探索状況の一例を示す図である。13周目(ノード「C」の解析)の処理後、ノード「D」の到達可能ノードには、ノード「D」の呼び出しを行うノード「C」の到達可能ノードに設定されているノード「G」とノード「H」が追加されている。ノード「C」は、状態が要解析から解析済に変更されている。
13周目の処理が終わったとき、要解析ノードのうちノード「B」とノード「H」が安定ノードである。これらの安定ノードのうち、到達可能ノード数が最も多いのはノード「H」である。そこで、安定ノードのうち到達可能ノード数が最大であるノード「H」が、次の解析対象ノードとして選定され、14周目の処理が実行される。
14周目(ノード「H」の解析)の処理後、ノード「H」の呼び出し先ノードには、ノード「H」の呼び出し先であるノード「E」の呼び出し先ノードに設定されているノード「F」が追加されている。ノード「H」は、状態が要解析から解析済に変更されている。
14周目の処理が終わったとき、要解析ノードのうちノード「B」とノード「G」が安定ノードである。これらの安定ノードのうち、到達可能ノード数が最も多いのはノード「G」である。そこで、安定ノードのうち到達可能ノード数が最大であるノード「G」が、次の解析対象ノードとして選定され、15周目の処理が実行される。
図31は、15周目と16周目のコールグラフの構築・探索状況の一例を示す図である。15周目(ノード「G」の解析)の処理後、ノード「G」の呼び出し先ノードには、ノード「G」の呼び出し先であるノード「H」の呼び出し先ノードに設定されているノード「C」、ノード「D」、ノード「E」、およびノード「F」が追加されている。ノード「G」は、状態が要解析から解析済に変更されている。
15周目の処理が終わったとき、要解析ノードのうちノード「A」とノード「B」が安定ノードである。これらの安定ノードの到達可能ノード数は共に「0」である。従って、ノード「A」とノード「B」のいずれのノードも、次の解析対象ノードとして選定可能である。図31の例では、次の解析対象ノードとしてノード「A」が選定され、16周目の処理が実行されたものとする。
16周目(ノード「A」の解析)の処理後、ノード「A」の呼び出し先ノードには、ノード「A」の呼び出し先であるノード「C」またはノード「G」の呼び出し先ノードに設定されているノードが追加される。追加されたノードは、ノード「D」、ノード「E」、ノード「F」、およびノード「H」である。ノード「A」は、状態が要解析から解析済に変更されている。
16周目の処理が終わったとき、要解析ノードはノード「B」のみである。そこで、次の解析対象ノードとしてノード「B」が選定され、17周目の処理が実行される。
図32は、17周目のコールグラフの構築・探索状況の一例を示す図である。17周目(ノード「B」の解析)の処理後、ノード「B」の呼び出し先ノードには、ノード「B」の呼び出し先であるノード「D」の呼び出し先ノードに設定されているノード「C」が追加されている。ノード「B」は、状態が要解析から解析済に変更されている。
17周目の処理が終わったとき、すべてのノードが解析済の状態になっている。したがって、コールグラフの構築・探索処理は終了となり、解析結果が出力される。解析結果は、例えばモニタ21に表示される。
図33は、解析画面例を示す図である。図33の例では、あるメソッドに修正を加え、そのメソッドがある変数の値を書き換える可能性が生じた場合を想定している。このような場合、メソッドに修正を加えた利用者は、書き換えられる可能性がある変数に依存するメソッドがどれかを知りたい。そこでコンピュータ100を用いて、コールグラフを用いた影響波及分析が行われる。
例えば利用者が解析制御部121の起動をコンピュータ100に指示すると、図33に示すような解析画面60が表示される。利用者は、解析対象のソースコード名を、ソースコード入力部61に入力する。その後、利用者が解析ボタン62を押下すると、解析制御部121の制御の下、ソースコードが解析される。解析が終わると、メソッド一覧表示部63に、ソースコードに含まれているすべてのメソッドが表示される。利用者がメソッド一覧表示部63からメソッドを選定すると、選定されたメソッドによって影響を受けるすべてのメソッドが、影響メソッド表示部64に表示される。
またメソッド一覧表示部63で選定されたメソッドの内容(プログラムコード)が、影響元メソッド表示部65に表示される。影響メソッド表示部64で選定されたメソッドの内容(プログラムコード)が、影響先メソッド表示部66に表示される。
第2の実施の形態では、コールグラフを解析する際に、解析対象ノードを適切な順番で選定しているため、効率的に解析が実行される。そのため、解析ボタン62が押下されてから、短時間でメソッド一覧表示部63にメソッド一覧が表示される。そしてメソッド一覧表示部63からメソッドが選定されると、即座に、影響メソッド表示部64に影響を受けるメソッドが表示される。
以上説明したように、第2の実施の形態によれば、ソースコードを効率的に解析することができる。以下、第2の実施の形態による方式でノード選定を行ったときの解析時間を、他の方式でノード選定を行ったときの解析時間との比較結果を示す。他の方式は、ランダム方式と未解析優先方式である。ランダム方式は、次の解析対象ノードをランダムに選定する方式である。未解析優先方式は、未解析のノードを優先的に、次の解析対象ノードとして選定する方式である。
ここで、コールグラフのノード数をN(Nは1以上の整数)とする。またコールグラフ中の各メソッドの長さ(行数)の平均をm(mは正の実数)とする。
またコールグラフ構築・探索問題の計算量は、「(S+M)×P」で表すことができる。ここでSはノードの選定処理にかかる時間である。Mは1つのノードの解析に要する時間である。Pはノードの解析回数である。各選定方式の計算量をオーダ表記で表すと、以下のようになる。
[第2の実施の形態におけるノード選定方式の計算量]
まずノード選定の計算時間を考察する。最悪の場合、1つのノードを選定するためにすべてのノードを検査することになる。そのため、ノード選定の計算時間Sは、O(N)となる。ノードの処理時間は方式に依存せず、O(m)である。最悪時のノード解析回数Pは、あるノードの到達可能ノードとしてr個(rは1以上の整数)のノードがあるとしても、他の方式のような無駄な解析が発生せず、計算量はO(N)となる。従って、総計算量は、以下の通りである。
・S=O(N)
・M=O(m)
・P=O(N)
・総計算量=O(N2+mN)
[ランダム方式の計算量]
ノードの選定はランダムなので、ノード選定の計算時間Sは、O(1)である。1つのノードの処理時間Mは、ノード選定方式に依存せず、O(m)である。r個のノードの存在がわかっている時点での最悪時のノード解析回数Pは、「1+2+,…,+r=r(r+1)/2」と計算できる。これはオーダ表記ではO(r2)となる。1≦r≦Nを満たすそれぞれのrについてO(r2)なので、「12+22+,…,+N2=N(N+1)(2N+1)/6」となる。オーダ表記ではO(r3)となる。従って、総計算量は、以下の通りである。
・S=O(1)
・M=O(m)
・P=O(N3
・総計算量=O(mN3
[未解析優先方式の計算量]
ノード選定とノード処理時間は上述のランダム方式と同じである。最悪時のノード解析回数は、N個のノードの存在が判明してからの解析回数が「1+2+,…,+N=N(N+1)/2」となる。オーダ表記ではO(N2)となる。従って、総計算量は、以下の通りである。
・S=O(1)
・M=O(m)
・P=O(N2
・総計算量=O(mN2
コンピュータ100で解析することとなるようなプログラムは、ソースコードが大規模である。するとノード数Nとメソッドの長さの平均mも大きくなりがちとなる。ノード数Nが増加すると、ランダム方式ではNの3乗のオーダで処理が増加するが、第2の実施の形態ではNの2乗のオーダで済んでいる。また未解析優先方式では、メソッドの平均長さmがNの2乗に掛け合わされており、メソッドの長さが長くなったときの、処理量の増加が、第2の実施の形態に比べて大きい。すなわち、第2の実施の形態に示したノード選定方式が最も計算量が少なくて済むことが分かる。
図34は、第2の実施の形態におけるノード選定方式と未解析優先方式との総計算時間の比較結果を示す図である。図34の例では、コールグラフのノード数が、5ノード、10ノード、20ノード、50ノード、100ノード、200ノード、500ノード、および1000ノードの場合における解析時間をグラフで示している。各グラフ内の左側が第2の実施の形態におけるノード選定方式(Optomized)であり、右側が未解析優先方式(UnresolveFirst)である。各ノード数における解析を複数回実行し、解析時間の平均値を太線による横棒で示している。また平均値からの標準偏差σの範囲を矩形で示し、2σの範囲を細線による横棒で示している。
図34に示すように、コールグラフの規模が大きくなると、第2の実施の形態におけるノード選定方式による処理効率の方が、明らかに未解析優先方式よりも解析時間が短くなっている。
以上説明したように、第2の実施の形態によれば、到達可能ノード数が多いノードを優先的に解析するようにしたことで、ノードの情報が変更されたときの影響範囲が広いノードを優先的に解析することができる。すなわち他のノードに与える影響が大きいノードほど先に解析することで、ノードの繰り返し解析回数を削減し、解析時間を短縮することができる。
なお第2の実施の形態では、到達可能ノード数として、正確な値ではなく概算値が用いられる。これにより到達可能ノード数の算出時間を短縮することができ、処理の効率化が図れる。
さらに第2の実施の形態では、要解析状態のノードの中に安定ノードがある場合には、安定ノードが優先的に解析される。安定ノードは、呼び出し先ノードの情報が今後変更される可能性が低く、残り1回の解析で済む可能性が高い。安定ノードを優先的に解析することで、情報が未確定のノードを早期に減らすことができる。情報が未確定のノード数が少なくなれば、適切な解析対象ノードを選定することも容易となる。
要解析状態のノードが安定ノードかどうかの判断についても、概略的に求められている。すなわち、判断対象のノードから直接呼び出されるノードがすべて解析済状態であれば、判断対象のノードは安定ノードと判断される。これにより、安定ノードかどうかの判定を効率的に行うことができる。すなわち安定ノードかどうかの判定を行うことによる処理の増加が最小限に抑えられている。
以上、実施の形態を例示したが、実施の形態で示した各部の構成は同様の機能を有する他のものに置換することができる。また、他の任意の構成物や工程が付加されてもよい。さらに、前述した実施の形態のうちの任意の2以上の構成(特徴)を組み合わせたものであってもよい。
1 解析対象プログラム
2 コールグラフ
10 解析装置
11 記憶部
12 処理部

Claims (8)

  1. コンピュータに、
    解析対象プログラム内の処理の複数の手続きを複数のノードで表し、手続き間の複数の呼び出し関係を複数のエッジで表したコールグラフに基づいて、前記複数のノードそれぞれについて、前記複数のエッジを呼び出し元から呼び出し先へ辿ることで自ノードへ到達可能な他ノードの数を示す到達可能ノード数を取得し、
    前記複数のノードそれぞれを、前記到達可能ノード数に基づいた順番で解析対象ノードとして選定し、
    前記コールグラフに基づいて選定された前記解析対象ノードに関する解析を行い、前記解析対象ノードに関連する情報を取得する、
    処理を実行させる解析プログラム。
  2. 前記解析対象ノードの選定では、前記到達可能ノード数が多いノードほど優先的に解析対象ノードとして選定する、
    請求項1記載の解析プログラム。
  3. 前記複数のノードそれぞれに対応付けて、自ノードへ到達可能な他ノードのノード識別子が登録された到達可能ノード集合が設けられており、
    前記到達可能ノード数の取得では、前記複数のノードそれぞれの前記到達可能ノード集合に登録された前記ノード識別子の数を、前記複数のノードそれぞれの前記到達可能ノード数として取得し、
    前記コンピュータに、さらに、
    前記解析対象ノードの解析により、前記解析対象ノードから前記複数のエッジを辿ることで到達可能な新たな呼び出し先ノードが検出されるごとに、前記新たな呼び出し先ノードの前記到達可能ノード集合に、前記解析対象ノードの前記到達可能ノード集合に含まれる前記ノード識別子を追加する、
    請求項1または2記載の解析プログラム。
  4. 前記コンピュータに、さらに、
    前記複数のノードのうち、一度も解析を行っていないノードの状態を未解析状態と判定し、少なくとも1度解析が行われ、最後の解析後に、自ノードの直接の呼び出し先ノードの情報が更新されたノードの状態を要解析状態と判定する処理を実行させ、
    前記解析対象ノードの選定では、前記未解析状態のノードを、前記要解析状態のノードよりも先に前記解析対象ノードとして選定する、
    請求項1ないし3のいずれかに記載の解析プログラム。
  5. 前記状態の判定では、前記複数のノードのうち、前記未解析状態と前記要解析状態とのいずれでもないノードを解析済状態と判定し、
    前記解析対象ノードの選定では、前記要解析状態のノードのうち、自ノードからの直接の呼び出し先ノードのすべてが前記解析済状態であるノードを、情報が安定的であると判定し、情報が安定的な前記要解析状態のノードを、情報が安定的でない前記要解析状態のノードよりも先に前記解析対象ノードとして選定する、
    請求項4記載の解析プログラム。
  6. 前記コンピュータに、さらに、
    前記解析対象プログラムに基づいて、選定された前記解析対象ノードに対応する手続きから呼び出される他の手続きの有無を解析し、前記他の手続きに対応するノードが前記コールグラフ内に存在しないとき、前記他の手続きに対応するノードを前記コールグラフに追加する、
    処理を実行させる請求項1ないし5のいずれかに記載の解析プログラム。
  7. コンピュータが、
    解析対象プログラム内の処理の複数の手続きを複数のノードで表し、手続き間の複数の呼び出し関係を複数のエッジで表したコールグラフに基づいて、前記複数のノードそれぞれについて、前記複数のエッジを呼び出し元から呼び出し先へ辿ることで自ノードへ到達可能な他ノードの数を示す到達可能ノード数を取得し、
    前記複数のノードそれぞれを、前記到達可能ノード数に基づいた順番で解析対象ノードとして選定し、
    前記コールグラフに基づいて選定された前記解析対象ノードに関する解析を行い、前記解析対象ノードに関連する情報を取得する、
    解析方法。
  8. 解析対象プログラムと、前記解析対象プログラム内の処理の複数の手続きを複数のノードで表し、手続き間の複数の呼び出し関係を複数のエッジで表したコールグラフとを記憶する記憶部と、
    前記コールグラフに基づいて、前記複数のノードそれぞれについて、前記複数のエッジを呼び出し元から呼び出し先へ辿ることで自ノードへ到達可能な他ノードの数を示す到達可能ノード数を取得し、前記複数のノードそれぞれを、前記到達可能ノード数に基づいた順番で解析対象ノードとして選定し、前記コールグラフに基づいて選定された前記解析対象ノードに関する解析を行い、前記解析対象ノードに関連する情報を取得する処理部と、
    を有する解析装置。
JP2016214024A 2016-11-01 2016-11-01 解析プログラム、解析方法、および解析装置 Pending JP2018073223A (ja)

Priority Applications (1)

Application Number Priority Date Filing Date Title
JP2016214024A JP2018073223A (ja) 2016-11-01 2016-11-01 解析プログラム、解析方法、および解析装置

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
JP2016214024A JP2018073223A (ja) 2016-11-01 2016-11-01 解析プログラム、解析方法、および解析装置

Publications (1)

Publication Number Publication Date
JP2018073223A true JP2018073223A (ja) 2018-05-10

Family

ID=62114025

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2016214024A Pending JP2018073223A (ja) 2016-11-01 2016-11-01 解析プログラム、解析方法、および解析装置

Country Status (1)

Country Link
JP (1) JP2018073223A (ja)

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN112585547A (zh) * 2019-03-13 2021-03-30 欧姆龙株式会社 分析装置、分析方法以及分析程序
JPWO2021084581A1 (ja) * 2019-10-28 2021-05-06
CN114895196A (zh) * 2022-07-13 2022-08-12 深圳市威特利电源有限公司 一种基于人工智能的新能源电池故障诊断方法

Cited By (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN112585547A (zh) * 2019-03-13 2021-03-30 欧姆龙株式会社 分析装置、分析方法以及分析程序
CN112585547B (zh) * 2019-03-13 2024-02-06 欧姆龙株式会社 分析装置、分析方法以及记录介质
JPWO2021084581A1 (ja) * 2019-10-28 2021-05-06
WO2021084581A1 (ja) * 2019-10-28 2021-05-06 日本電信電話株式会社 テスト情報抽出装置、テスト情報抽出方法及びプログラム
JP7322964B2 (ja) 2019-10-28 2023-08-08 日本電信電話株式会社 テスト情報抽出装置、テスト情報抽出方法及びプログラム
US11886328B2 (en) 2019-10-28 2024-01-30 Nippon Telegraph And Telephone Corporation Test information extraction apparatus, test information extraction method and program
CN114895196A (zh) * 2022-07-13 2022-08-12 深圳市威特利电源有限公司 一种基于人工智能的新能源电池故障诊断方法
CN114895196B (zh) * 2022-07-13 2022-10-25 深圳市威特利电源有限公司 一种基于人工智能的新能源电池故障诊断方法

Similar Documents

Publication Publication Date Title
KR102154757B1 (ko) 콜경로 파인더
US9836389B2 (en) Test data generation utilizing analytics
US9563849B2 (en) Behavioral rules discovery for intelligent computing environment administration
US9779158B2 (en) Method, apparatus, and computer-readable medium for optimized data subsetting
US9454466B2 (en) Explaining partially illegal combinations in combinatorial models
US20160070633A1 (en) Memory leak analysis by usage trends correlation
US20180322200A1 (en) Analytics based on pipes programming model
US20110307507A1 (en) Identifying entries and exits of strongly connected components
JP2010002370A (ja) パターン抽出プログラム、方法及び装置
CN111124926A (zh) 模糊测试方法、装置、电子设备及存储介质
CN112783786B (zh) 测试案例的生成方法、装置、设备、介质和程序产品
CN112035359A (zh) 程序测试方法、装置、电子设备及存储介质
CN114116065B (zh) 获取拓扑图数据对象的方法、装置、及电子设备
JP2018073223A (ja) 解析プログラム、解析方法、および解析装置
US20210405980A1 (en) Long method autofix engine
US8713509B2 (en) Circuit design approximation
US10157049B2 (en) Static analysis with input reduction
JP2004178270A (ja) 有向グラフ解析方法、解析装置及びそのプログラム
CN114500290A (zh) 云平台网关节点探测拓扑生成的方法、装置、设备及介质
CN115796228B (zh) 算子融合方法、装置、设备以及存储介质
CN117873907B (zh) 控件元素测试方法、装置及存储介质
CN113836291B (zh) 数据处理方法、装置、设备和存储介质
CN114048147B (zh) 测试用例生成方法、装置、存储介质和电子设备
CN112286800B (zh) 一种功能测试点辅助分析方法与系统
US20220318386A1 (en) Generation of a causality tree representation of threat analysis report data