(57)【要約】【課題】イベント同期方式で作成されたマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援装置、プログラミング支援方法、プログラミング支援プログラム、およびプログラミング支援プログラムを格納したコンピュータ読取可能な記録媒体を提供する。【解決手段】本発明に係るプログラミング支援装置１００の演算部２００は、解析対象の要求イベントを取得する解析対象取得部２１０と、解析対象の要求イベントに関するコールグラフ１３５を、記憶部２５０に格納されたソースコード１３１、イベント情報１３２、ルート関数情報１３３、送信関数情報１３４に基づいて作成するコールグラフ作成部２２０と、イベント送信情報付きコールグラフ１３６を作成するイベント送信情報付加部２３０と、イベント送信情報付きコールグラフ１３６から同期不具合の原因箇所を抽出する不具合抽出部２４０とを含む。【選択図】図５
2009223534.tif 000002
【特許請求の範囲】
【請求項１】
各タスクが他の前記タスクに処理の実行を指示するために送信する要求イベントおよび前記要求イベントを受信した前記タスクが前記処理の実行後に送信する受理イベントの送受信を利用したマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援装置であって、
前記マルチタスクプログラムに関する情報を格納する記憶手段を備え、
前記記憶手段は、前記要求イベントおよび前記受理イベントに関するイベント情報を格納し、
解析対象となる前記要求イベントを取得する取得手段と、
前記イベント情報に基づいて、前記解析対象となる要求イベントに関わる処理の流れを表わすコールグラフを作成するコールグラフ作成手段とをさらに備え、
前記コールグラフ作成手段は、
前記マルチタスクプログラムのコード中の制御コード、および、前記イベント情報に含まれる前記要求イベントまたは前記受理イベントを送信する命令コードに基づいて、前記コードを複数のブロックに分割する分割手段と、
前記制御コードおよび前記命令コードにより送信される前記要求イベントまたは前記受理イベントに基づいて、前記ブロック間の移行情報を生成する生成手段と、
前記移行情報に基づいて、前記解析対象となる要求イベントを含む前記ブロックを起点として、前記複数のブロックを接続し、前記コールグラフを作成する接続手段とを含む、プログラミング支援装置。
【請求項２】
前記記憶手段は、
前記要求イベントまたは前記受理イベントと、前記要求イベントまたは前記受理イベントを受信した前記タスクが実行するルート関数とを関連付けたルート関数情報をさらに格納し、
前記生成手段は、
前記イベント情報に基づいて、前記コード中から前記要求イベントを送信する前記命令コードを検出する送信命令検出部と、
前記ルート関数情報に基づいて、検出された前記命令コードにより送信される前記要求イベントに対応する前記ルート関数を検出する送信先検出部とを有し、
前記生成手段は、検出された前記命令コードを含む前記ブロックと、検出された前記ルート関数を含む前記ブロックとを接続する移行情報を生成する、請求項１に記載のプログラミング支援装置。
【請求項３】
前記送信先検出部は、前記イベント情報および前記ルート関数情報に基づいて、検出された前記命令コードにより送信される前記要求イベントに対応する前記受理イベントのルート関数を検出する、請求項２に記載のプログラミング支援装置。
【請求項４】
前記コールグラフに含まれる前記ブロックの接続箇所の各々に、各前記接続箇所以降の処理において前記解析対象となる前記要求イベントに対応する前記受理イベントが正しく送信されるかどうかを表わすイベント送信情報を付加し、イベント送信情報付きコールグラフを作成する付加手段をさらに備える、請求項１から３のいずれか１項に記載のプログラミング支援装置。
【請求項５】
前記イベント送信情報に基づいて、前記コードにおける前記同期不具合の原因となる前記接続箇所を抽出する不具合抽出手段と、
前記抽出された接続箇所を特定するための情報を表示する表示手段とをさらに備える、請求項４に記載のプログラミング支援装置。
【請求項６】
前記不具合抽出手段は、前記解析対象となる前記要求イベントに対応する前記受理イベントが正しく送信されないことを表わす前記イベント送信情報が付加された前記接続箇所のうち、最下層にある前記接続箇所を、前記同期不具合の原因となる前記接続箇所として抽出する、請求項５に記載のプログラミング支援装置。
【請求項７】
各タスクが他のタスクに処理の実行を指示するために送信する要求イベントおよび前記要求イベントを受信したタスクが前記処理の実行後に送信する受理イベントを含むイベントの送受信を利用したマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援方法であって、
解析対象となる前記要求イベントを取得するステップと、
前記マルチタスクプログラムのコード中の制御コード、および、前記要求イベントまたは前記受理イベントを送信する命令コードに基づいて、前記コードを複数のブロックに分割するステップと、
前記制御コードおよび前記命令コードにより送信される前記要求イベントまたは前記受理イベントに基づいて、前記ブロック間の移行情報を生成するステップと、
前記移行情報に基づいて、前記解析対象となる要求イベントを含む前記ブロックを起点として、前記複数のブロックを接続し、前記解析対象となる要求イベントに関わる処理の流れを表わすコールグラフを作成するステップとを備える、プログラミング支援方法。
【請求項８】
各タスクが他のタスクに処理の実行を指示するために送信する要求イベントおよび前記要求イベントを受信したタスクが前記処理の実行後に送信する受理イベントを含むイベントの送受信を利用したマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援プログラムであって、
解析対象となる前記要求イベントを取得するステップと、
前記マルチタスクプログラムのコード中の制御コード、および、前記要求イベントまたは前記受理イベントを送信する命令コードに基づいて、前記コードを複数のブロックに分割するステップと、
前記制御コードおよび前記命令コードにより送信される前記要求イベントまたは前記受理イベントに基づいて、前記ブロック間の移行情報を生成するステップと、
前記移行情報に基づいて、前記解析対象となる要求イベントを含む前記ブロックを起点として、前記複数のブロックを接続し、前記解析対象となる要求イベントに関わる処理の流れを表わすコールグラフを作成するステップとをコンピュータに実行させるためのプログラミング支援プログラム。
【請求項９】
請求項８に記載のプログラミング支援プログラムを格納したコンピュータ読取可能な記録媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
この発明は、作成されたプログラムが正しく動作するか評価するプログラミング支援技術に関し、特に、プログラムのイベント同期制御に関する不具合の原因の抽出を支援するプログラミング支援技術に関する。
【背景技術】
【０００２】
プログラム開発者がプログラムの開発を行う際には、通常、作成したプログラムに問題点がないかのテストを行なう。従来のテスト方法の１つに、ソースコードを静的に解析し、ソースコード上の問題箇所や、問題箇所を発見するためのテストを実施する条件といった、プログラム開発に有用な情報を抽出する方法がある。例えば、特許文献１（特開平７−２１９８１９号公報）には、ソースコードを静的に解析して、すべてのコードをテストで通過させるためのテスト条件を作成するために参考になる情報を抽出する方法が開示されている。より具体的には、ソースコードを複数の基本ブロックに分割し、基本ブロックまでの到達必要条件を求める方法が開示されている。
【０００３】
ところで、近年のコンピュータの多くは、マルチタスクＯＳで動作する。マルチタスクＯＳ上で動作するマルチタスクプログラムは、必要に応じて各タスク間で協調して処理が行なわれるように記述されている。例えば、タスクＡが第１の処理を実施した後に、その結果を利用してタスクＢが第２の処理を実施するように記述されている。
【０００４】
マルチタスクを実現するために、しばしば用いられるのが、イベントドリブン方式のプログラムである。イベントドリブン方式のプログラムでは、イベントの発生に応じて、処理が実行される。具体的には、各タスクは、他のタスクから処理の開始を要求するメッセージ（以下、要求イベントとよぶ）を受信すると、要求イベントの内容に合う処理を実行する。そして、処理を完了すると、処理を完了した旨のメッセージ（以下、受理イベントとよぶ）を他のタスクに送信する。各タスクは、常にイベントの到来を待っており、イベントが届くと、イベントに応じた処理を行い、処理を完了すると、再度、イベントの到来を待つ状態に戻る。このようなイベントのやり取りにより、各タスクは、協調して処理を進めることができる。
【０００５】
イベントドリブン方式で作成されたプログラムに従った処理の流れについて図１を用いて具体的に説明する。図１は、イベントドリブン方式で作成されたプログラムに含まれる２つのタスクが行なう処理について説明するための図である。
【０００６】
このプログラムは、タスク１１（文字αで表わす）と、タスク１２（文字βで表わす）とを含む。タスク１１は、他のタスクからのイベントやプログラム開始直後に送信されるイベントの受信に応じて、第１の処理１３を開始する。タスク１２は、要求イベントを待つ状態になっている。
【０００７】
タスク１１は、第１の処理１３を実施した後に、タスク１２へ第２の処理１５の実施を要求する要求イベント１４（REQ_TO_β_PROC_2）を送信し、送信した要求イベントに対応する受理イベントを待つ状態になる。
【０００８】
タスク１２は、要求イベント１４（REQ_TO_β_PROC_2）を受信すると、第２の処理１５を実施する。第２の処理１５の実施後、タスク１１からの要求イベント１４（REQ_TO_β_PROC_2）に対する処理の完了を通知する受理イベント１６（ACK_TO_α_PROC_2）を送信し、要求イベントを待つ状態に戻る。
【０００９】
タスク１１は、受理イベント１６（ACK_TO_α_PROC_2）を受信すると、第３の処理１７を実施する。
【００１０】
以上のように、イベントドリブン方式で作成したプログラムによれば、第１の処理１３から第３の処理１７までの処理が、協調して進行される。すなわち、これらの処理は、この順に行なわれ、同時に実行されることがない。
【００１１】
図１を用いて説明したプログラムのソースコードの一部を図２、図３に示す。図２は、タスク１１に相当するソースコードである。図３は、タスク１２に相当するソースコードである。これらのソースコード中において、task_start関数は、引数に指定されているタスクの処理を開始する関数である。send関数は、引数に指定されているイベントを送信する関数である。receive関数は、イベントが受信されると、引数に指定されている変数（図中の“msg”）に受信したイベントを代入する関数である。print関数は、引数に指定された値を表示するなど、引数に指定された値の出力処理を行なう関数である。ソースコードのその他の部分は、一般的なＣ言語の仕様に従って記述されている。
【００１２】
以下に、図Ｎのｍ行目を(N-m)と表わし、図２および図３に示したソースコードと、図１との対応関係を説明する。
【００１３】
まず、タスク１１の動作と図２のソースコードとの関係について説明する。(2-6)は、タスク１１に第１の処理１３の実行を指示する。(2-7)は、タスク１１に要求イベント１４（REQ_TO_β_PROC_2）の送信を指示する。(2-9)は、タスク１１に、要求イベント１４（REQ_TO_β_PROC_2）の送信後、イベントを受信するまで待つことを指示する。(2-10)は、タスク１１に、受信したイベントがACK_TO_α_PROC_2であるかの判定を指示する。
【００１４】
タスク１１が受理イベント１６（ACK_TO_α_PROC_2）を受信すると、(2-11)のbreakによって、イベントを待つループ処理(2-8)〜(2-13)が終了する。そして、(2-14)の指示により、タスク１１は、第３の処理１７を実行する。
【００１５】
タスク１２の動作と図３のソースコードとの関係は次のとおりである。(3-6)は、タスク１２に、イベントを受信するまで待つことを指示する。(3-7)および(3-8)の指示により、タスク１２は、イベントREQ_TO_β_PROC_2を受信したかどうかを判定する。要求イベント１４（REQ_TO_β_PROC_2）が受信されると、(3-9)により関数βreq2がコールされて(3-17)が実行される。(3-17)の実行が、タスク１２による第２の処理１５の実行に相当する。(3-18)が、タスク１２による受理イベント１６（ACK_TO_α_PROC_2）の送信に相当する。
【００１６】
特開平９−１８５５２８号公報には、このようなマルチタスクソフトウェアを実時間で動作させ、マルチタスクモニタにて動作中に送信されるイベントを監視し、各タスクに対するイベントと、そのイベントに対するレスポンスとのペア集合が、予め設定されたタスク間のインタフェイス仕様に違反していないかを検出する技術が開示されている。
【特許文献１】特開平７−２１９８１９号公報
【特許文献２】特開平９−１８５５２８号公報
【発明の開示】
【発明が解決しようとする課題】
【００１７】
ソースコードの静的な解析により、イベントドリブン方式のプログラムが正しく動作するかをテストするためには、まず、イベントドリブン方式のプログラムに特有の処理の流れを理解する必要がある。例えば、図２に示されるソースコードにおいては、５行目、６行目、と処理が逐次実行され、１０行目の条件分岐では、特定の条件によって１１行目が実行される場合と実行されない場合がある、といったことに加え、イベントの送受信によって処理の流れが図２の７行目から図３の９行目へ移行することを理解する必要がある。
【００１８】
さらに、協調的な処理を実現するために、イベントドリブン方式のプログラムに含まれる各タスクは、要求イベントを受信した時に、要求イベントに対応する処理を実行するとともに、受信した要求イベントに対応した受信イベントを、必ず１つだけ送信しなければならないという条件を満たさなければならないことにも注意する必要がある。
【００１９】
この条件が満たされていない場合、次のような問題が生じる。まず、イベントが送信されないというプログラムのミスがあると、イベントが送信されない部分で処理が停止してしまい、各タスクにて連続して処理が実施されない。また、正しくないイベントが送信されるというプログラムのミスがあると、期待している処理と並行して、予期しない処理が実行されてしまったりする。以下では、このような問題を、同期不具合と記すことにする。同期不具合は、条件分岐や繰り返し処理などの構造が折り重なった部分など、プログラム作成者の注意が及びにくい部分で発生しやすい。
【００２０】
特許文献１に記載の方法では、イベントの送受信による処理の流れを追跡できないため、イベントを受信した後にだけ実行される処理へ到達する処理経路を検出できない。したがって、同期不具合を検出できない。
【００２１】
また、特許文献２に記載の技術は、ソフトウェアを実際に実行させて、不具合の有無を検出するものである。検査前に、不具合が発生する可能性を知ることはできないため、発生する確率の低い不具合を検出することは困難である。
【００２２】
本発明は、上記のような問題を解決するためになされたものであって、イベント同期方式で作成されたマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援装置、プログラミング支援方法、プログラミング支援プログラム、およびプログラミング支援プログラムを格納したコンピュータ読取可能な記録媒体を提供することを課題とする。
【課題を解決するための手段】
【００２３】
１つの局面に係る本願発明は、各タスクが他のタスクに処理の実行を指示するために送信する要求イベントおよび要求イベントを受信したタスクが処理の実行後に送信する受理イベントの送受信を利用したマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援装置であって、マルチタスクプログラムに関する情報を格納する記憶手段を備え、記憶手段は、要求イベントおよび受理イベントに関するイベント情報を格納し、解析対象となる要求イベントを取得する取得手段と、イベント情報に基づいて、解析対象となる要求イベントに関わる処理の流れを表わすコールグラフを作成するコールグラフ作成手段とをさらに備え、コールグラフ作成手段は、マルチタスクプログラムのコード中の制御コード、および、イベント情報に含まれる要求イベントまたは受理イベントを送信する命令コードに基づいて、コードを複数のブロックに分割する分割手段と、制御コードおよび命令コードにより送信される要求イベントまたは受理イベントに基づいて、ブロック間の移行情報を生成する生成手段と、移行情報に基づいて、解析対象となる要求イベントを含むブロックを起点として、複数のブロックを接続し、コールグラフを作成する接続手段とを含む。
【００２４】
好ましくは、記憶手段は、要求イベントまたは受理イベントと、要求イベントまたは受理イベントを受信したタスクが実行するルート関数とを関連付けたルート関数情報をさらに格納し、生成手段は、イベント情報に基づいて、コード中から要求イベントを送信する命令コードを検出する送信命令検出部と、ルート関数情報に基づいて、検出された命令コードにより送信される要求イベントに対応するルート関数を検出する送信先検出部とを有し、生成手段は、検出された命令コードを含むブロックと、検出されたルート関数を含むブロックとを接続する移行情報を生成する。
【００２５】
さらに好ましくは、送信先検出部は、イベント情報およびルート関数情報に基づいて、検出された命令コードにより送信される要求イベントに対応する受理イベントのルート関数を検出する。
【００２６】
好ましくは、コールグラフに含まれるブロックの接続箇所の各々に、各接続箇所以降の処理において解析対象となる要求イベントに対応する受理イベントが正しく送信されるかどうかを表わすイベント送信情報を付加し、イベント送信情報付きコールグラフを作成する付加手段をさらに備える。
【００２７】
さらに好ましくは、イベント送信情報に基づいて、コードにおける同期不具合の原因となる接続箇所を抽出する不具合抽出手段と、抽出された接続箇所を特定するための情報を表示する表示手段とをさらに備える。
【００２８】
さらに好ましくは、不具合抽出手段は、解析対象となる要求イベントに対応する受理イベントが正しく送信されないことを表わすイベント送信情報が付加された接続箇所のうち、最下層にある接続箇所を、同期不具合の原因となる接続箇所として抽出する。
【００２９】
他の局面に係る本願発明は、各タスクが他のタスクに処理の実行を指示するために送信する要求イベントおよび要求イベントを受信したタスクが処理の実行後に送信する受理イベントを含むイベントの送受信を利用したマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援方法であって、解析対象となる要求イベントを取得するステップと、マルチタスクプログラムのコード中の制御コード、および、要求イベントまたは受理イベントを送信する命令コードに基づいて、コードを複数のブロックに分割するステップと、制御コードおよび命令コードにより送信される要求イベントまたは受理イベントに基づいて、ブロック間の移行情報を生成するステップと、移行情報に基づいて、解析対象となる要求イベントを含むブロックを起点として、複数のブロックを接続し、解析対象となる要求イベントに関わる処理の流れを表わすコールグラフを作成するステップとを備える。
【００３０】
さらに他の局面に係る本願発明は、各タスクが他のタスクに処理の実行を指示するために送信する要求イベントおよび要求イベントを受信したタスクが処理の実行後に送信する受理イベントを含むイベントの送受信を利用したマルチタスクプログラムにおける同期不具合の抽出を支援するプログラミング支援プログラムであって、解析対象となる要求イベントを取得するステップと、マルチタスクプログラムのコード中の制御コード、および、要求イベントまたは受理イベントを送信する命令コードに基づいて、コードを複数のブロックに分割するステップと、制御コードおよび命令コードにより送信される要求イベントまたは受理イベントに基づいて、ブロック間の移行情報を生成するステップと、移行情報に基づいて、解析対象となる要求イベントを含むブロックを起点として、複数のブロックを接続し、解析対象となる要求イベントに関わる処理の流れを表わすコールグラフを作成するステップとをコンピュータに実行させる。
【００３１】
さらに他の局面に係る本願発明は、上述のプログラミング支援プログラムを格納したコンピュータ読取可能な記録媒体である。
【発明の効果】
【００３２】
本発明によれば、プログラムのソースコードの解析にあたり、要求イベントおよび受理イベントを含むイベント情報を利用して、各タスクの行なう処理の流れを追跡する。したがって、イベントドリブン方式で作成されたプログラムを精度よく評価できる。
【発明を実施するための最良の形態】
【００３３】
以下、図面を参照しつつ、本発明の実施の形態について説明する。以下の説明では、同一の部分には同一の符号を付してある。それらの名称および機能も同じである。したがってそれらについての詳細な説明は繰り返さない。
【００３４】
（第１の実施の形態）
図４は、本発明に係るプログラミング支援装置１００の構成をブロック図形式で示す図である。以下、図４を参照して、本発明に係るプログラミング支援装置１００の構成について説明する。
【００３５】
プログラミング支援装置１００は、コンピュータ本体１０２と、表示装置としてのモニタ１０４と、入力装置としてのキーボード１１０およびマウス１１２とを備える。モニタ１０４、キーボード１１０、マウス１１２は、いずれも、バス１０５を介してコンピュータ本体１０２に接続される。コンピュータ本体１０２は、ＣＰＵ（Central Processing Unit）１２０と、ＲＯＭ（Read Only Memory）およびＲＡＭ（Random Access Memory）を含むメモリ１２２と、直接アクセスメモリ装置、たとえば、ハードディスク１３０と、フレキシブルディスク（Flexible Disk、以下「ＦＤ」と呼ぶ）ドライブ１０６と、光ディスクドライブ１０８と、外部とデータの授受を行なうための通信インターフェイス１２８とを含む。
【００３６】
ＦＤドライブ１０６は、ＦＤ１１６に情報を読み書きする。光ディスクドライブ１０８は、ＣＤ−ＲＯＭ（Compact Disc Read-Only Memory）１１８等の光ディスク上の情報を読み込む。
【００３７】
ハードディスク１３０は、解析対象となるプログラムのソースコードであるソースコード１３１と、イベント情報１３２と、ルート関数情報１３３と、送信関数情報１３４と、コールグラフ１３５と、イベント送信情報付きコールグラフ１３６と、不具合一覧１３７と、コールグラフを作成するためのプログラム１３８と、不具合を抽出するためのプログラム１３９とを格納する。イベント情報１３２は、要求イベントおよび受理イベント（以下、要求イベントと受理イベントを合わせて、イベントとよぶことがある）の記述コードを表わす。また、要求イベントと当該要求イベントに対して返されるべき受理イベントとの対応関係を表わす。ルート関数情報１３３は、イベントと、当該イベントを受信したときに実行される関数であるルート関数との対応関係を表わす。送信関数情報１３４は、ソースコード１３１に含まれる送信関数sendの送信イベントパラメータ位置を表わす。コールグラフ１３５は、解析対象となる要求イベントを起点として実行される処理の流れを表わすグラフである。イベント送信情報付きコールグラフ１３６は、コールグラフ１３５の各分岐点（以下、ノードとよぶ）に、各ノード以降の処理において、解析対象となる要求イベントに対応して、正しく受理イベントが送信されるかを表わすイベント送信情報を付加したものである。
【００３８】
演算処理装置として機能するＣＰＵ１２０は、メモリ１２２をワーキングメモリとして、上述した各プログラムに対応した処理を実行する。
【００３９】
上述の各プログラムは、ＣＰＵ１２０により実行されるソフトウェアである。一般的に、こうしたソフトウェアは、ＣＤ−ＲＯＭ１１８、ＦＤ１１６等の記憶媒体に格納されて流通し、光ディスクドライブ１０８またはＦＤドライブ１０６等により記憶媒体から読み取られてハードディスク１３０に一旦格納される。
【００４０】
また、上述のプログラムは、コンピュータ本体１０２がネットワークに接続されている場合には、ネットワーク上のサーバから読み出されるものであってもよい。このようなプログラムは、例えば、サーバから、一旦ハードディスク１３０にコピーされ、さらに、メモリ１２２中のＲＡＭに読み出されてＣＰＵ１２０により実行される。あるいは、ハードディスク１３０に格納することなくＲＡＭに直接ロードして実行される。逆に、プログラミング支援装置１００は、通信インターフェイス１２８を介して、各処理を、外部のコンピュータに実行させ、その結果をハードディスク１３０に格納させてもよい。
【００４１】
なお、ＣＤ−ＲＯＭ１１８は、コンピュータ本体に対してインストールされるプログラム等の情報を記録可能な媒体であれば、他の媒体、たとえば、ＤＶＤ−ＲＯＭ（Digital Versatile Disc）やメモリーカードなどでもよく、その場合は、コンピュータ本体１０２には、これらの媒体を読み取ることが可能なドライブ装置が設けられる。また、バス１０５には、カセット形式の磁気テープを着脱自在に装着してアクセスする磁気テープ装置が接続されていてもよい。
【００４２】
図４に示したコンピュータのハードウェア自体およびその動作原理は一般的なものである。したがって、本発明の機能を実現するにあたり本質的な部分は、ＦＤ１１６、ＣＤ−ＲＯＭ１１８、ハードディスク１３０等の記憶媒体に記憶されたソフトウェアである。
【００４３】
図５は、本発明に係るプログラミング支援装置１００の機能的構成を示すブロック図である。以下、図５を参照して、本発明に係るプログラミング支援装置１００の機能的構成について説明する。
【００４４】
プログラミング支援装置１００は、演算部２００と、記憶部２５０と、表示部２６０とを備える。図１のＣＰＵ１２０が演算部２００に、ハードディスク１３０が記憶部に、モニタ１０４が表示部２６０に、それぞれ相当する。
【００４５】
演算部２００は、解析対象取得部２１０と、コールグラフ作成部２２０と、イベント送信情報付加部２３０と、不具合抽出部２４０とを含む。以下、これらの各部の行なう処理について説明する。
【００４６】
解析対象取得部２１０は、ソースコード１３１を記憶部２５０から読み込む。また、記憶部２５０に格納されたイベント情報１３２を読み込み、解析対象となる要求イベントを取得する。また、イベント情報１３２に基づき、取得した要求イベントに対応する受理イベントを取得する。さらに、記憶部２５０に格納されたルート関数情報１３３を参照し、取得した要求イベントのルート関数を取得する。そして、取得した情報を、コールグラフ作成部２２０に送る。
【００４７】
コールグラフ作成部２２０は、ソースコード１３１と、イベント情報１３２と、ルート関数情報１３３と、送信関数情報１３４とに基づいて、解析対象の要求イベントに関わる処理の流れを表わすコールグラフ１３５を作成し、作成したコールグラフ１３５を記憶部２５０に格納する。コールグラフ１３５は、解析対象取得部２１０から渡されたルート関数からの処理において、どのような分岐制御構造やループ制御構造があり、どのような関数が呼び出され、どのイベントが送信されているかという情報を含む。
【００４８】
コールグラフ作成部２２０は、プログラム分割部２２２と、移行情報生成部２２４と、接続部２２６とを含む。
【００４９】
プログラム分割部２２２は、ソースコード１３１に含まれる制御構文またはイベントを送信する命令であるイベント送信関数を検出し、ソースコード１３１を複数のブロックに分割する。
【００５０】
移行情報生成部２２４は、ソースコード１３１、イベント情報１３２、ルート関数情報１３３、送信関数情報１３４を参照して、プログラムの分岐構造やループ構造、あるいは関数の呼び出し箇所を解析し、各ブロック間の移行に関する移行情報の生成を行なう。
【００５１】
接続部２２６は、移行情報に基づいて各ブロックを接続し、コールグラフを作成する。また、プログラムに要求イベントの送信命令が含まれる場合、送信命令に対応するルート関数を起点とするコールグラフを作成し、送信命令がある箇所に、対応するルート関数を起点とするコールグラフを接続したコールグラフを作成する。
【００５２】
イベント送信情報付加部２３０は、コールグラフ１３５の各ノードにイベント送信情報を付加したイベント送信情報付きコールグラフ１３６を作成し、作成したイベント送信情報付きコールグラフ１３６を記憶部２５０に格納する。イベント送信情報は、着目するノード以下の処理で、解析対象の要求イベントに対応して、正しく受理イベントを送信しているかを表わす。具体的には、イベント送信情報は、着目するノード以下の処理において、解析対象の要求イベントに対応する正しい受理イベントの送信回数が、０回、１回、２回以上のいずれであるのか、また、正しくない受理イベントが送信されているのかどうか、を表わす。これらのうち正しく受理イベントを送信しているといえるのは、正しいイベントを１回送信している場合のみである。その他の場合は、同期不具合が生じる可能性がある。
【００５３】
不具合抽出部２４０は、イベント送信情報付きコールグラフ１３６を参照し、同期不具合をもたらす原因となっている可能性のある箇所に関する情報を表わす不具合一覧１３７を作成する。あわせて不具合抽出部２４０は、プログラム開発者に分かりやすい形式で、不具合一覧１３７を表示部２６０に表示する。
【００５４】
ここからは、図６〜図９に示すプログラムを解析対象とした場合の、プログラミング支援装置１００の処理を説明する。
【００５５】
図６は、タスク６０１（文字Ａで表わす）、タスク６０２（文字Ｂで表わす）、タスク６０３（文字Ｃで表わす）を含むマルチタスクプログラムの動作を、タスク６０２の処理を中心として表わしたシーケンス図である。
【００５６】
タスク６０２は、要求イベント６０５（REQ_TO_B_PROC_X）を受信すると、処理６０６を実行する。
【００５７】
引き続いて、flagXという条件が満たされている場合には、図６に示す領域６０７注の処理を行なう。すなわち、タスク６０３に対して要求イベント６０８（REQ_TO_C_PROC_Y）を送信し、タスク６０３から要求イベント６０８に対応する受理イベントACK_TO_B_PROC_Yが送信されてくるのを待つ。タスク６０２は、受理イベント６１０（ACK_TO_B_PROC_Y）を受信すると、処理６１１および処理６１２を実行する。
【００５８】
一方、要求イベント６０５（REQ_TO_B_PROC_X）を受信した時点で、flagXという条件が満たされていない場合には、タスク６０３とのイベントのやり取りを行なうことなしに、処理６０６および処理６１２を実行する。
【００５９】
これらの処理を完了すると、タスク６０２は、受理イベント６１３（ACK_TO_B_PROC_Y）を返す。
【００６０】
タスク６０１は、プログラム開始時に送信される要求イベントを受信すると、処理６０４を行ない、タスク６０２に対して要求イベント６０５（REQ_TO_B_PROC_X）を送信する。そして、タスク６０２から要求イベント６０５に対応する受理イベントが送信されてくるのを待つ。タスク６０２は、要求イベント６０５に対応する受理イベントACK_TO_A_PROC_Xを受信すると、処理６１４を実行する。
【００６１】
タスク６０３は、要求イベントREQ_TO_C_PROC_Yを受信すると、処理６０９を実行し、タスク６０２に、受理イベント６１０（ACK_TO_B_PROC_Y）を送信する。
【００６２】
図７から図９は、図６のシーケンス図のタスク６０２の機能を実現することを意図して、イベントドリブン方式で作成されたソースコードの例である。ただし、これらのソースコードには、以下で説明するように、図６のとおりには動作しない不具合が含まれている。これらのソースコードを用いて、同期制御に関する不具合の原因の抽出について説明する。
【００６３】
図７は、タスク６０２のメイン関数のソースコードである。タスク６０２は、(7-6)の関数receiveに従い、イベントを受信する。受信したイベントが要求イベントREQ_TO_B_PROC_Xであった場合(7-8)は、(7-9)に従って関数B_ProcXを呼び出す。受理イベントACK_TO_B_PROC_Yであった場合(7-10)は、(7-11)に従って関数B_AckYを呼び出す。各々の処理終了後は、(7-5)のループによって、(7-6)以降の処理を繰り返す。
【００６４】
図８は、(7-9)により呼び出される関数B_ProcXのソースコードである。関数B_ProcXが実行されると、タスク６０２は、まず、(8-3)の関数sendに従い、受理イベントACK_TO_B_PROC_Yを送信する。次に、(8-4)でflagXが満たされているかを判断し、判断結果が偽であれば(8-6)、(8-7)の関数sendに従い、受理イベントACK_TO_A_PROC_Xを送信する。(8-4)の判断結果が真、すなわち、flagXが満たされている場合には、(8-5)の関数sendに従い、REQ_TO_C_PROC_Yを送信する。
【００６５】
図９は、(7-11)から呼び出される関数B_AckYのソースコードである。関数B_AckYは、ループ構造を有する。つまり、関数B_AckYが実行されると、(9-3)により、条件loopFlagが満たされている間、タスク６０２は、以下の処理を実行する。まず、(9-4)によりflagYが満たされているか判断し、判断結果が真であれば、(9-5)の関数sendに従い、受理イベントACK_TO_A_PROC_Xを送信する。判断結果が偽であれば、何もしない。
【００６６】
図６から図９を用いて説明したプログラムの送信関数情報を、図１０に示す。図１０の送信関数情報１００１によれば、イベントを送信する関数の名前はsendであり、この関数により送信されるイベントは、この関数の第１パラメータに指定されることが分かる。なお、送信関数が複数ある場合、送信関数情報は、すべての送信関数についての情報を含む。
【００６７】
図６から図９を用いて説明したプログラムのルート関数情報を、図１１に示す。ルート関数とは、イベントを受信すると実行される関数のことであり、イベントＸを受信すると実行される関数を、「Ｘのルート関数」と記すことにする。本説明では、ルート関数情報１１０１で示されるように、イベントREQ_TO_B_PROC_Xのルート関数は、B_ProcXであり、ルート関数情報１１０２で示されるように、イベントACK_TO_A_PROC_Yのルート関数は、B_AckYであるとする。なお、ルート関数情報には、イベントと、そのイベントを受信した時に実行される関数の情報すべてが含まれる。図１１では、同期不具合をタスクＢに関して説明するために必要な情報のみを示しており、実際にはタスクＡやタスクＣに関する情報も含まれる。
【００６８】
また、図６から図９を用いて説明したプログラムのイベント情報は、図１２に示すものであるとする。つまり、イベント情報１２０１で示されるように、要求イベントREQ_TO_B_PROC_Xに受理イベントACK_TO_A_PROC_Xが対応し、イベント情報１２０２で示されるように、要求イベントREQ_TO_C_PROC_Yに受理イベントACK_TO_B_PROC_Yが対応するものとする。なお、イベント情報には、要求イベントに対応して送信されるべき受理イベントの対応関係がすべて含まれる。図１２では、同期不具合をタスクＢに関して説明するために必要な情報のみを示しており、実際にはタスクＡやタスクＣに関する情報も含まれる。
【００６９】
上記のイベント情報によれば、図６から図９を用いて説明したプログラムは、同期不具合を含んでいることが分かる。
【００７０】
まず、関数B_ProcXによれば、タスク６０２は、受理イベントACK_TO_B_PROC_Yを送信する。ところが、これは、要求イベントREQ_TO_B_PROC_Xに対する正しい受理イベントではない。つまり、この行において、正しくない受理イベントを送信するという同期不具合が生じる。
【００７１】
また、関数B_ProcXによれば、タスク６０２は、flagXが満たされていない場合には、正しい受理イベントACK_TO_A_PROC_Xを１回送信するものの、flagXが満たされている場合には、REQ_TO_C_PROC_Yをタスク６０３に送信するのみであり、プログラムの実行中に正しい受理イベントACK_TO_A_PROC_Xを送信しない可能性がある。
【００７２】
さらに、関数B_AckYも同期不具合の原因となる。関数B_AckYによれば、タスク６０２は、flagYが満たされている場合、正しい受理イベントACK_TO_A_PROC_Xを送信するが、関数B_AckYはループ構造を有するため、受理イベントを２回以上送信する可能性がある。また、flagYが満たされていない場合、タスク６０２は受理イベントACK_TO_A_PROC_Xを送信しないため、関数B_AckYは、受理イベントを送信しないという同期不具合を引き起こす危険性も有する。
【００７３】
プログラミング支援装置１００は、以下の方法で、このプログラムに含まれるルート関数を起点とするコールグラフを作成する。
【００７４】
解析対象取得部２１０は、イベント情報１３２から、１つの要求イベントを選択して、取得する。また、その要求イベントに対応する受理イベントを取得する。この説明では、要求イベントREQ_TO_B_PROC_Xと受理イベントACK_TO_A_PROC_Xの組を取得するものとする。さらに、また、解析対象取得部２１０は、ルート関数情報１３３を参照し、選択された要求イベントのルート関数を取得する。ルート関数情報１１０１から分かるように、解析対象取得部２１０は、REQ_TO_B_PROC_Xのルート関数B_ProcXを取得する。
【００７５】
コールグラフ作成部２２０は、解析対象取得部２１０が取得したルート関数B_ProcXを起点としたコールグラフ１３５を作成する。コールグラフは、プログラムに基づいて行なわれる処理の流れをグラフ構造で表わしたものである。本実施の形態においては、ソースコードを、一連の処理のかたまりであるブロックに分割し、ブロック間の処理の流れを追跡し、コールグラフを作成する。
【００７６】
コールグラフ作成部２２０に含まれるプログラム分割部２２２は、制御構文およびイベントの送信命令とに着目して、これらの点でソースコードを分割する。制御構文には、例えば、ソースコード中の分岐制御命令、ループ制御命令、関数呼び出し命令が含まれる。以下、分割点を「ノード」と呼ぶことにする。ノードは、コールグラフにおける分岐点に相当する。
【００７７】
例えば、図８に示したソースコードは、説明に不要なコードをほとんど含んでいないため、ほぼ１行ごとに分割される。ただし、図８の３行目「send(ACK_TO_B_PROC_Y);」の前に、分割とは関係ない「a = 1」といったコード行がある場合、この行と「send(ACK_TO_B_PROC_Y);」の２行は分割されずに１つのブロックにまとめられる。このような分割は、コンパイラでも使用される一般的なものであるが、イベントの送信命令にも着目してプログラムを分割する点に、本発明の特徴がある。
【００７８】
コールグラフ作成部２２０に含まれる移行情報生成部２２４は、各ブロック間の移行に関する移行情報を取得する。本実施の形態における移行情報生成部２２４は、図１３に示すように、送信命令検出部２２４ａ、送信先検出部２２４ｂ、移行情報生成部２２４ｃを有し、以下のように移行情報を取得する。
【００７９】
送信命令検出部２２４ａは、送信関数情報１３４を参照して、ソースコード中のイベントの送信関数を検出し、ノードが、イベントの送信命令であるかどうか判定する。
【００８０】
ブロックに含まれるノードが、イベントの送信命令である場合には、送信命令検出部２２４ａは、イベント情報１３２を参照して、送信されるイベントが、要求イベントであるかどうか判断する。
【００８１】
送信先検出部２２４ｂは、ブロックに含まれるノードが、イベント送信命令でない制御構文である場合には、制御構文の内容に従って、接続先のブロックを決定する。
【００８２】
ノードが要求イベントの送信命令である場合、送信先検出部２２４ｂは、検出された送信関数が送信する要求イベントに対応する関数を含むブロックを接続先として決定する。すなわち、移行情報生成部２２４ｃは、イベント情報１３２を参照して、検出された送信関数が送信する要求イベントに対応する受理イベントを取得する。次に、この受理イベントのルート関数をルート関数情報１３３から取得し、取得したルート関数を接続先として決定する。ノードが要求イベントでないイベント、すなわち受理イベントの送信命令である場合、このイベントを起点とするコールグラフの作成は行わない。
【００８３】
移行情報生成部２２４ｃは、イベント送信命令以外の制御構文のノードを含むブロックと、送信先検出部２２４ｂが決定した接続先のブロックとを接続する移行情報を生成する。また、検出された要求イベント送信箇所と、上記の方法で送信先検出部２２４ｂが取得するルート関数とを接続する移行情報を生成する。
【００８４】
接続部２２６は、移行情報に基づいて、解析対象となる要求イベントを含むブロックを起点として、各ブロックを接続し、コールグラフを作成する。コールグラフのうち、要求イベントを送信する送信命令の接続先のルート関数を起点とする部分については、接続先のルート関数を起点とするコールグラフが、すでに求められており、記憶部２５０に記憶されている場合は、記憶されているコールグラフを呼び出して、利用することもできる。ただし、この部分についても、他の箇所と同様、移行情報に基づいて、各ブロックを接続することで作成してもよい。
【００８５】
上述の処理により作成される、B_ProcXを起点とするコールグラフは図１４のようになる。図１４に示すように、このコールグラフは、起点のルート関数B_ProcXを表す関数ノード１４０１から始まり、分岐制御構造と関数呼び出しで次第に枝分かれしたノードへ接続される木構造を持つ。
【００８６】
図８に示した関数B_ProcXのソースコードによれば、関数B_ProcXの最上位の構造は、(8-3)のイベントACK_TO_B_PROC_Yの送信と、(8-4)のifによる分岐である。関数B_ProcXの関数ノード１４０１から、送信ノード１４０２と分岐ノード１４０５へ接続するグラフでこの分岐を表す。送信ノード１４０２は、送信関数がある行番号３と、送信命令により送信されるイベントを保持する。なお、送信されるイベントの情報は、送信関数情報１３４を参照することで、取得できる。図１０の関数情報によれば、関数sendはイベント送信を行う関数であり、その第１引数が送信するイベントであるので、イベントACK_TO_B_PROC_Yが送信されることが分かる。
【００８７】
以下、新たに追加されたノードから、順次下位構造に関してグラフを作成していく。分岐ノード１４０５は、(8-4)のifによる二分岐なので、２つの分岐先ノード、すなわち、分岐先ノード１４０６、分岐先ノード１４０８に接続される。分岐先ノード１４０６および分岐先ノード１４０８は、分岐先の先頭行番号である５と７を、それぞれ保持する。
【００８８】
(8-4)のifの条件が真であった時、ソースコードによれば、イベントREQ_TO_C_PROC_Yが送信されるので、これを分岐先ノード１４０６に接続する形で、送信ノード１４０７として作成する。送信ノード１４０７は、送信するイベントREQ_TO_C_PROC_Yの情報と、行番号である５とを保持する。
【００８９】
(8-4)のifの条件が偽であった時、イベントACK_TO_A_PROC_Xが送信されるので、これを分岐先ノード１４０８に接続する形で、送信ノード１４０９として作成する。送信ノードは、送信するイベントACK_TO_A_PROC_Xの情報と行番号である７を保持する。
【００９０】
送信ノード１４０７は、要求イベントREQ_TO_C_PROC_Yを送信するものなので、要求イベントREQ_TO_C_PROC_Yに対応する受理イベントを、イベント情報１３２から取得する。図１２によれば、この受理イベントはACK_TO_B_PROC_Yである。また、ルート関数情報１３３を参照して、この受理イベントACK_TO_B_PROC_Yのルート関数を取得する。図１１によれば、この関数はB_AckYである。取得されたルート関数B_AckYを表わす関数ノード１４１０が作成される。関数ノード１４１０は、コールグラフ作成の要因となった送信ノード１４０７に接続される。
【００９１】
さらに、関数B_AckYを起点の関数ノード１４１０とするコールグラフが作成される。図９に示した関数B_AckYのソースコードによれば、関数B_AckYの最上位の構造は、(9-3)のループ構造である。コールグラフでは、関数B_AckYの関数ノード１４１０からループノード１４１１へ接続するグラフでこれを表す。ループノード１４１１は、ループ制御を行っている行番号３を保持する。
【００９２】
以下、新たに追加されたノードから、順次下位構造に関してグラフを作成していく。(9-3)のループ構造の中には、(9-4)のifによる分岐があり、これをループノード１４１１に接続される分岐ノード１４１４で表わす。
【００９３】
分岐ノード１４１４は、(9-4)のifによる二分岐なので、２つの分岐先ノード；分岐先ノード１４１５および分岐先ノード１４１７に接続される。一方の分岐先ノード１４１５には、分岐先の先頭行番号である５を保持する。もう一方の分岐先は存在しないので、分岐際ノード１４１７は、分岐元のifの行番号４に、存在しないことを示すために−１を乗じた行番号−４を保持する。
【００９４】
(9-4)のifの条件が真であった時、イベントACK_TO_A_PROC_Xが送信されるので、これを分岐先ノード１４１５に接続する形で、送信ノード１４１６として作成する。送信ノードは、送信するイベントACK_TO_A_PROC_Xの情報と、行番号である５とを保持する。
【００９５】
このように作成されたコールグラフを参照することにより、利用者は、プログラムが正しく作成されているか、すなわち、プログラムに含まれる各要求イベントについて、対応して送信されるべき受理イベントが、常にただ一度だけ送信されるかを容易に検証することができる。
【００９６】
なお、以上では、図１２の１つ目のイベント情報１２０１に着目し、このイベントに関するコールグラフの作成について説明したが、他のイベント情報についても、同様にコールグラフを作成することができる。また、解析対象取得部２１０が、各イベント情報を順次、取得することで、すべてのイベントに関して、コールグラフを作成する構成であってもよい。
【００９７】
さらに、本実施の形態に係るプログラミング支援装置１００は、イベント送信情報付加部２３０により、作成されたコールグラフ１３５にイベント送信情報を付加したイベント送信情報付きコールグラフ１３６を作成することができる。以下、イベント送信情報付加部２３０の行なう処理について説明する。
【００９８】
イベント送信情報付加部２３０は、起点となるノードから遠いノードから、イベント送信情報を付加していく。例えば、起点のノードから深さ優先探索（ｄｅｐｔｈ−ｆｉｒｓｔ  ｓｅａｒｃｈ，  ＤＦＳ）を行ない、ノードからバックトラックする時に、各ノードへイベント送信情報を付加していく。
【００９９】
ＤＦＳは、グラフの各ノードを順次処理する際などに使用する一般的なアルゴリズムである。例えば、図１４において、上を優先した（つまり、探索候補のノードが複数の場合、図１４の上にあるノードを先に探索する）ＤＦＳを行なうと、以下の順にノードの探索が行われる。
【０１００】
1401,1402←(1401),1405,1406,1407,1410,1411,1414,1415,1416←(1415)←(1414),1417←(1414)←(1411)←(1410)←(1407)←(1406)←(1405),1408,1409←(1408)←(1405)←(1401)←(終了)
ここで、ノードの右の「←」は、当該ノードの下に接続されるノードがないために、１つ上のノードへバックトラックすることを表わす。また、「←」の右の（＊）はノード＊へバックトラックすることを表わす。以下の手順で、「←」の左側にあるノードについてイベント情報が作成される。
【０１０１】
図１５を用いて、どのようなイベント送信情報が生成されるかを具体的に説明する。図１５は、図１４で示すコールグラフにイベント送信情報を付加したイベント送信情報付きコールグラフである。
【０１０２】
まず、最後に探索される送信ノード１４０９は、正しい受理イベントを１回送信する。また、送信ノード１４０９のバックトラック先の分岐先ノード１４０８の下には、送信ノード１４０９以外のノードは接続されていない。したがって、分岐先ノード１４０８には、イベント送信情報１５０１が付加される。図１５に示した表は、対象ノード以下の処理において、正しいイベントが送信されない場合、正しいイベントが１回送信される場合、正しいイベントが２回以上送信される場合、注目している要求イベント（ここでは、REQ_TO_B_PROC_X）に対応しない不正な受理イベントが送信される場合のそれぞれについて、可能性のあるものを○、可能性のないものを×と表現している。
【０１０３】
次に知りたいのは分岐先ノード１４０８のバックトラック先の分岐ノード１４０５のイベント送信情報である。しかし、分岐ノード１４０５には、分岐先ノード１４０８の他に、分岐先ノード１４０６が接続されているため、まだ、分岐ノード１４０５のイベント送信情報を求めることはできない。
【０１０４】
このようにバックトラック先のノードの下に、まだイベント送信情報を求めていないノードが接続されている場合、イベント送信情報が求められていないノードのうち、探索順序が最も遅いノードについて、イベント送信情報を求める。したがって、本実施例では、分岐先ノード１４１７についてのイベント送信情報を求める。分岐先ノード１４１７では、イベントの送信を行っていないので、分岐先ノード１４１７にはイベント送信情報１５０２が付加される。
【０１０５】
分岐先ノード１４１７のバックトラック先である分岐ノード１４１４には、分岐先ノード１４１７の他に、分岐先ノード１４１５が接続されている。したがって、次に、送信ノード１４１６のイベント送信情報を求める。送信ノード１４１６は、正しい受理イベントACK_TO_A_PROC_Xを送信し、その他のイベントは送信しないので、正しい受理イベントを1回送信する場合がある。また、送信ノード１４１６のバックトラック先の分岐先ノード１４１５には、送信ノード１４１６以外のノードは接続されていない。したがって、分岐先ノード１４１５にはイベント送信情報１５０３が付加される。
【０１０６】
次に、分岐先ノード１４１５のバックトラック先の分岐ノード１４１４について、イベント送信情報を求める。分岐ノード１４１４に接続されているノードのすべてに対し、イベント送信情報が求められているため、イベント送信情報を求めることができる。分岐ノード１４１４には、その下に接続されたノードのイベント送信情報を総合したイベント送信情報が付加される。すなわち、分岐条件によってイベント送信情報１５０２のように振舞う場合と、イベント送信情報１５０３のように振舞う場合があるので、分岐ノード１４１４には、イベント送信情報１５０４が付加される。
【０１０７】
次に、分岐ノード１４１４のバックトラック先のループノード１４１１に、その直接の下位のノードである分岐ノード１４１４のイベント送信情報を総合したイベント送信情報を付加する。分岐ノード１４１４は、ループ構造により０回以上実施されるため、ループノード１４１１には、イベント送信情報１５０５が付加される。
【０１０８】
次に、ループノード１４１１のバックトラック先の関数ノード１４１０に、その直接の下位のノードであるループノード１４１１のイベント送信情報を総合したイベント送信情報を付加する。すなわち、ループノード１４１１が１回実施される可能性があるので、関数ノード１４１０には、ループノード１４１１のイベント送信情報１５０５と同じイベント送信情報１５０６が付加される。
【０１０９】
次に、関数ノード１４１０のバックトラック先の送信ノード１４０７には、関数ノード１４１０のイベント送信情報１５０６と同じイベント送信情報を付加する。送信ノード１４０７にて要求イベントREQ_TO_C_PROC_Yが送信されると、そのルート関数が実行されるので、この要求イベントREQ_TO_C_PROC_Yの送信はそのルート関数B_AckYの実行と等価であるからである。また、その下に送信ノード１４０７のみが接続されている分岐先ノード１４０６に付加されるイベント送信情報も、関数ノード１４１０のイベント送信情報と同じとなる。すなわち、分岐先ノード１４０６には、イベント送信情報１５０７が付加される。
【０１１０】
以下、同様の手順で、残りのノードにもイベント送信情報が付加される。分岐ノード１４０５には、その直接の下位の分岐先ノード１４０６および分岐先ノード１４０８のイベント送信情報を総合したイベント送信情報を付加する。分岐条件によってイベント送信情報１５０７のように振舞う場合と、イベント送信情報１５０１のように振舞う場合があるので、分岐ノード１４０５には、イベント送信情報１５０８が付加される。関数ノード１４０１には、その直接の下位のノードである送信ノード１４０２と分岐ノード１４０５のイベント送信情報を総合したイベント送信情報を付加する。送信ノード１４０２と、分岐ノード１４０５はいずれも１回ずつ実施される可能性があるので、送信ノード１４０２によって不正なイベントが送信される場合があることを考慮して、関数ノード１４０１には、イベント送信情報１５０９が付加される。
【０１１１】
不具合抽出部２４０は、以上のように作成されるイベント送信情報付きコールグラフ１３６に基づいて、イベント同期不具合を抽出し、抽出したイベント同期不具合を、不具合一覧１３７へ出力していく。このとき、抽出したイベント同期不具合の性質、あるいは、イベント同期不具合を引き起こす原因となっているプログラム上の箇所も出力する。この構成により、ソフトウェア開発者が、不具合一覧１３７を参照してプログラムの問題を修正することが容易になる。
【０１１２】
不具合抽出部２４０がイベント同期不具合の抽出を行なう手順について、図１５に示したイベント送信情報付きコールグラフを例として説明する。
【０１１３】
不具合抽出部２４０は、イベント送信情報付きコールグラフの木構造の根のノード、すなわち、最初のルート関数B_ProcXの関数ノード１４０１から順に、イベント送信情報を参照していく。
【０１１４】
関数ノード１４０１に付加されているイベント送信情報１５０９によると、この関数ノード１４０１以降の処理では、要求イベントREQ_TO_B_PROC_Xに対応する正しい受理イベントが０回送信される場合と１回送信される場合と２回以上送信される場合と、要求イベントREQ_TO_B_PROC_Xに対応しない不正な受理イベントを送信している場合のすべてが起き得る。このうち、正しい受理イベントの送信回数が０回と２回以上の場合、および不正なイベントを送信する場合は、イベント同期不具合となる。このように不具合の原因が２種類以上ある場合には、不具合の詳細を調べるために、コールグラフを下位へたどっていく。
【０１１５】
関数ノード１４０１の直下の送信ノード１４０２は、不正な受理イベントを送信する。したがって、このノードをイベント同期不具合の原因として抽出する。この送信ノードは、関数B_ProcXの関数ノード１４０１の下位に位置する。また、この送信ノードによるイベントは、図８で示した通り、関数B_ProcXのソースコードの行番号３に対応する。また、送信するイベントは、ACK_TO_B_PROC_Yであるという情報も分かる。表示部２６０は、これらの情報を含む図１６のような画面を表示する。図１６は、不正な受理イベントを送信するイベント同期不具合に関する情報を表わす画面の一例である。
【０１１６】
関数ノード１４０１のもうひとつの直下のノードである分岐ノード１４０５に付加されているイベント送信情報１５０８によると、分岐ノード１４０５以降の処理では、正しい受理イベントが、０回送信される場合と１回送信される場合と２回以上送信される場合が存在する。よって、不具合抽出部２４０は、さらに下位のノードについて不具合の抽出処理を進めていく。
【０１１７】
分岐ノード１４０５には、分岐先ノード１４０６と分岐先ノード１４０８とが接続されている。このうち、分岐先ノード１４０８に付加されているイベント送信情報１５０１によると、分岐先ノード１４０８以降の処理においては、正しい受理イベントが１回のみ送信される。つまり、このノード以降にはイベント同期不具合の要因となるものは存在しない。よって、不具合抽出部２４０は、このノード以降のコールグラフをたどる処理は行わない。一方、分岐先ノード１４０６に付加されているイベント送信情報１５０７によると、分岐先ノード１４０８以降の処理においては、正しい受理イベントが、０回送信される場合と１回送信される場合と２回以上送信される場合が存在するので、さらに下位のノードをたどる。
【０１１８】
分岐先ノード１４０６の下位にある関数ノード１４１０に付加されているイベント送信情報１５０６によると、関数ノード１４１０以降の処理においては、正しい受理イベントが、０回送信される場合と１回送信される場合と２回以上送信される場合が存在するので、さらに下位のノードをたどる。
【０１１９】
関数ノード１４１０の下位にあるループノード１４１１に付加されているイベント送信情報１５０５によると、ループノード１４１１以降の処理においては、正しい受理イベントが、０回送信される場合と１回送信される場合と２回以上送信される場合が存在するので、さらに下位のノードをたどる。
【０１２０】
ループノード１４１１の下位にある分岐ノード１４１４に付加されているイベント送信情報１５０４によると、正しい受理イベントが、０回送信される場合と１回送信される場合が存在する。２回以上送信される場合は無くなっているので、上位のループノード１４１１が、正しい受理イベントを２回以上送信する可能性の要因となっていることが分かる。しかし、まだ問題の位置は判明しておらず、０回送信される問題も存在するため、さらに下位のノードをたどる。
【０１２１】
分岐先ノード１４１５に付加されているイベント送信情報１５０３は、正しい受理イベントが１回送信される可能性のみを示している。分岐先ノード１４０８のイベント送信情報１５０１は、正しい受理イベントが１回送信される可能性のみを示すものであるため、分岐先ノード１４０８以降の処理には、イベント同期不具合の要因は存在しないと判定していた。しかし、ここのケースでは上位にループノード１４１１が存在するため、この分岐先ノード１４１５での１回の送信がイベント同期不具合の要因となる。よって、不具合箇所の抽出処理を続ける。まだ問題の位置は判明していないため、さらに下位へたどる。
【０１２２】
なお、このように正しい受理イベントが１回送信される可能性を示すイベント送信情報が付されたノードに対し、適切な処理を行なうため、各ノードには、ループの下位にあるかどうかを示す情報が与えられているものとする。あるいは、ノードを巡回する際に、ループ内にあるかどうかのフラグを管理することで、適切な処理を実現してもよい。
【０１２３】
分岐先ノード１４１５の下位にある送信ノード１４１６は、正しい受理イベントを送信している。これが前記ループノード１４１１で正しい受理イベントを２回以上送信される可能性があるという問題の要因なので、これをイベント同期不具合の原因として抽出する。この送信ノードは、関数B_AckYの関数ノード１４１０の下位に位置し、また、ループノード１４１１の下位に位置する。さらに、この送信ノードに対応する命令は、図９に示した関数B_AckYの行番号５に対応する。さらに、関数ノード１４１０は送信ノード１４０７に接続しており、送信ノード１４０７はその上位の分岐先ノード１４０６を経由して、関数ノード１４０１の下位に位置していることも分かる。表示部２６０は、これらの情報を含む図１７のような画面を表示する。図１７は、受理イベントを２回以上送信するイベント同期不具合に関する情報を表わす画面の一例である。
【０１２４】
分岐先ノード１４１７に付加されているイベント送信情報１５０２によると、分岐先ノード１４１７では、正しい受理イベントは１回も送信されない。したがって、分岐先ノード１４１７は、分岐先ノード１４１５とは異なり、ループノード１４１１が受理イベントを２回以上送信する問題の要因ではない。しかし、分岐先ノード１４１７は、受理イベントを送信しない問題の要因となっているため、これをイベント同期不具合の原因として抽出する。この分岐先ノード１４１７は、関数B_AckYの関数ノード１４１０の下位に位置する。また、この送信ノードの行番号は−４である。さらに、関数ノード１４１０は、送信ノード１４０７に接続しており、送信ノード１４０７はその上位の分岐先ノード１４０６を経由して関数ノード１４０１の下位に位置している。表示部２６０は、これらの情報を含む図１８のような画面を表示する。図１８は、受理イベントを送信しないイベント同期不具合に関する情報を表わす画面の一例である。
【０１２５】
以上の図１６から図１８のような画面をプログラム作成者が参照することで、イベント同期不具合の内容を容易に判断し、修正することができる。
【０１２６】
なお、本発明により作成されるコールグラフは、図１４を用いて説明したものに限られるわけではなく、利用者がプログラムによる処理の流れが正しいかを判別できるための情報を含んでいればよい。例えば、特許文献１に記載のプログラム評価データのような形式であってもよい。特許文献１の方法に、上記本発明特有の手段を追加した方法によれば、イベントの送受信を経由している場合に対応したプログラム評価データを作成することができる。
【０１２７】
（第２の実施の形態）
第１の実施の形態で説明したように、本発明により作成されるコールグラフは、イベントの送受信によるタスク間の遷移についても表現する能力がある。
【０１２８】
ところで、第１の実施の形態においては、タスク間の遷移の追跡のため、以下の手段を採っていた。すなわち、送信命令検出部２２４ａは、イベント情報１３２および送信関数情報１３４を参照して、要求イベントを送信している箇所を検出し、また、この要求イベントに対応する受理イベントをイベント情報１３２から取得する。さらに、この受理イベントのルート関数をルート関数情報１３３から取得する。移行情報生成部２２４ｃは、これら取得した情報と検出した要求イベント送信箇所から移行情報を生成する。この手段では、注目するタスク以外のタスクが正常に動作することを仮定している。
【０１２９】
これに対し、他のタスクが正常に動作することを仮定しないで、他のタスクを含めた処理を追跡し、その追跡結果を表わすコールグラフを作成することもできる。この方法によれば、他のタスクも含めたプログラム全体の動作が正しいかどうかを調べることができる。本実施の形態では、以下の手法により、このようなコールグラフを作成する。
【０１３０】
本実施の形態に係るプログラミング支援装置の構成は、第１の実施の形態で説明したものとほぼ同様であるが、移行情報生成部２２４の行なう処理が異なる。本実施の形態に係る移行情報生成部２２４は、以下のように移行情報を生成する。
【０１３１】
移行情報生成部２２４に含まれる送信命令検出部２２４ａは、イベント情報１３２および送信関数情報１３４を参照し、ソースコード１３１の中から要求イベントを送信している箇所を検出する。この点は第１の実施の形態と同様である。
【０１３２】
送信先検出部２２４ｂは、検出された箇所により送信される要求イベントのルート関数をルート関数情報１３３から取得する。この点が、第１の実施の形態と異なる。
【０１３３】
移行情報生成部２２４ｃは、要求イベント送信箇所が検出された場合、要求イベント送信箇所と、上記の方法で送信先検出部２２４ｂが取得するルート関数とを接続する移行情報を生成する。
【０１３４】
この後の手続きは、実施の形態と同じで、接続部２２６は、コールグラフ上の検出された要求イベント送信箇所のノードへ、取得されたルート関数を起点とするコールグラフを接続する。
【０１３５】
以上のようにすることで、イベントの送受信を経由している場合でも、処理の流れをコールグラフとして表現することができる。すなわち、ソースコード上の処理ブロックの接続関係を表現することができる。
【０１３６】
なお、第１の実施の形態と同様、コールグラフは、図１４を用いて説明したものに限られるわけではなく、利用者がプログラムによる処理の流れが正しいかを判別できるための情報を含んでいればよい。例えば、特許文献１の方法に上記本発明特有の手段を追加した方法により作成できるプログラム評価データを上記のコールグラフの代わりに利用してもよい。
【０１３７】
最後に、本発明に係るプログラミング支援装置１００の演算部２００が行なう処理について、図１９を参照して、まとめておく。図１９は、演算部２００が行なう処理の流れを表わすフローチャートである。
【０１３８】
まず、演算部２００は、ステップＳ１０１において、記憶部２５０に格納されたイベント情報１３２およびルート関数情報１３３に基づいて、解析対象となる要求イベントと、解析対象となる要求イベントに対応する受理イベントおよびルート関数を取得する。
【０１３９】
次に、演算部２００は、ステップＳ１０３において、ソースコード１３１を、制御構文およびイベント送信関数の位置で分割し、複数のブロックを生成する。
【０１４０】
続いて、演算部２００は、ステップＳ１０５において、ブロック間の移行情報を生成する。生成される移行情報については、すでに説明したとおりである。第１の実施の形態と、第２の実施の形態とでは、要求イベントの送信関数を含むブロックの接続先が異なる。
【０１４１】
演算部２００は、ステップＳ１０７において、生成された接続情報に基づいて、ブロック同士を接続し、コールグラフ１３５を作成する。
【０１４２】
次に、演算部２００は、ステップＳ１０９において、コールグラフ１３５の各ノードにイベント送信情報が付加されたイベント送信情報付きコールグラフ１３６を作成する。
【０１４３】
次に、演算部２００は、ステップＳ１１１において、イベント情報付きコールグラフ１３６に基づいて、イベント同期不具合の原因となっている箇所を抽出する。
【０１４４】
最後に、演算部２００は、ステップＳ１１３において、イベント同期不具合の原因箇所を表示部２６０に表示させる。さらに、発生しているイベント同期不具合の種類を表示させてもよい。
【０１４５】
今回開示された実施の形態はすべての点で例示であって制限的なものではないと考えられるべきである。本発明の範囲は上記した説明ではなくて特許請求の範囲によって示され、特許請求の範囲と均等の意味および範囲内でのすべての変更が含まれることが意図される。
【図面の簡単な説明】
【０１４６】
【図１】イベントドリブン方式で作成されたプログラムに含まれる２つのタスクが行なう処理について説明するための図である。
【図２】タスク１１に相当するソースコードである。
【図３】タスク１２に相当するソースコードである。
【図４】プログラミング支援装置１００の構成をブロック図形式で示す図である。
【図５】プログラミング支援装置１００の機能的構成を示すブロック図である。
【図６】タスク６０１、タスク６０２、タスク６０３を含むマルチタスクプログラムの動作を、タスク６０２の処理を中心として表わしたシーケンス図である。
【図７】タスク６０２のメイン関数のソースコードである。
【図８】関数B_ProcXのソースコードである。
【図９】関数B_AckYのソースコードである。
【図１０】プログラムの送信関数を示す図である。
【図１１】プログラムのルート関数情報を示す図である。
【図１２】プログラムのイベント情報を示す図である。
【図１３】移行情報生成部２２４の構成を説明するための図である。
【図１４】B_ProcXを起点とするコールグラフである。
【図１５】図１４で示すコールグラフにイベント送信情報を付加したイベント送信情報付きコールグラフである。
【図１６】不正な受理イベントを送信するイベント同期不具合に関する情報を表わす画面の一例である。
【図１７】受理イベントを２回以上送信するイベント同期不具合に関する情報を表わす画面の一例である。
【図１８】受理イベントを送信しないイベント同期不具合に関する情報を表わす画面の一例である。
【図１９】演算部２００が行なう処理の流れを表わすフローチャートである。
【符号の説明】
【０１４７】
１１  タスク、１２  タスク、１３  第１の処理、１４  要求イベント、１５  第２の処理、１６  受理イベント、１７  第３の処理、１００  プログラミング支援装置、１０２  コンピュータ本体、１０４  モニタ、１０５  バス、１０６  ＦＤドライブ、１０８  光ディスクドライブ、１１０  キーボード、１１２  マウス、１２０  ＣＰＵ、１２２  メモリ、１２８  通信インターフェイス、１３０  ハードディスク、１３１  ソースコード、１３２  イベント情報、１３３  ルート関数情報、１３４  送信関数情報、１３５  コールグラフ、１３６  イベント送信情報付きコールグラフ、１３７  不具合一覧、１３８  コールグラフを作成するためのプログラム、１３９  不具合を抽出するためのプログラム、２００  演算部、２１０  解析対象取得部、２２０  コールグラフ作成部、２２２  プログラム分割部、２２４  移行情報取得部、２２４ａ  送信命令検出部、２２４ｂ  送信先検出部、２２４ｃ  移行情報生成部、２２６  接続部、２３０  イベント送信情報付加部、２４０  不具合抽出部、２５０  記憶部、２６０  表示部、６０１〜６０３  タスク、６０４，６０６，６０９，６１１，６１２，６１４  処理、６０５，６０８  要求イベント、６０７  領域、６０８，６１３  受理イベント、１００１  送信関数情報、１１０１，１１０２  ルート関数情報、１２０１，１２０２  イベント情報、１４０１  関数ノード、１４０２  送信ノード、１４０５  分岐ノード、１４０６  分岐先ノード、１４０７  送信ノード、１４０８  分岐先ノード、１４０９  送信ノード、１４１０  関数ノード、１４１１  ループノード、１４１４  分岐ノード、１４１５  分岐先ノード
１４１６  送信ノード、１４１７  分岐先ノード、１５０１〜１５０９  イベント送信情報。
【図１】
2009223534.tif 000003
【図２】
2009223534.tif 000004
【図３】
2009223534.tif 000005
【図４】
2009223534.tif 000006
【図５】
2009223534.tif 000007
【図６】
2009223534.tif 000008
【図７】
2009223534.tif 000009
【図８】
2009223534.tif 000010
【図９】
2009223534.tif 000011
【図１０】
2009223534.tif 000012
【図１１】
2009223534.tif 000013
【図１２】
2009223534.tif 000014
【図１３】
2009223534.tif 000015
【図１４】
2009223534.tif 000016
【図１５】
2009223534.tif 000017
【図１６】
2009223534.tif 000018
【図１７】
2009223534.tif 000019
【図１８】
2009223534.tif 000020
【図１９】
2009223534.tif 000021