(57)【要約】【課題】  限られたシステムリソースの環境であっても診断データをデバイス上でリアルタイムに集め、障害原因の診断を可能とする。【解決手段】  アプリケーション（ＡＰ）からの関数コールに対して関数の開始時刻とアドレスを含む関数履歴を記録する入口トレース関数と、関数が終了する場合に関数の終了時刻とアドレスを含む関数履歴を記録する出口トレース関数を用いる。それぞれの関数の冒頭に、関数の実行後に戻るべきアドレスをスタックに一時記憶する命令と、入口トレース関数を呼び出して実行する命令を加えておく。ＡＰから関数コールがあると、関数の開始時に入口トレース関数を呼び出して関数履歴を取得してリターンレジスタに前記出口トレース関数の呼び出しを設定し、関数に戻って関数本体の内容を実行し、関数の終了時に出口トレース関数を呼び出して関数履歴を取得した後、スタックに一時記憶したアドレスを基にＡＰに戻る。【選択図】図１
2008059402.tif 000002
【特許請求の範囲】
【請求項１】
アプリケーション（オペレーティングシステムやデバイスドライバなどを含むあらゆるプログラムを意味する）と関数を備えたリアルタイムソフトウェアシステムに対して、
前記アプリケーションから前記関数が呼び出しを受けた場合に前記関数の開始時刻とアドレスを含む関数履歴を記録する入口トレース関数と、前記関数が終了する場合に前記関数の終了時刻とアドレスを含む関数履歴を記録する出口トレース関数とを備え、
それぞれの前記関数の冒頭に、前記アプリケーションから呼び出された際に前記関数の実行後に戻るべきアドレスをスタックに一時記憶する命令と、前記入口トレース関数を呼び出して実行する命令を加え、
前記アプリケーションから前記関数が呼び出されると、前記関数の開始時に前記入口トレース関数を呼び出して前記関数履歴を取得し、前記関数に戻って前記関数本体の内容を実行し、前記関数の終了時に前記出口トレース関数を呼び出して前記関数履歴を取得しその関数履歴となるトレースデータをサイクリックバッファーに保存した後、前記スタックに一時記憶した前記アドレスを手掛かりとして前記アプリケーションに戻ることにより、前記関数履歴のトレース（ファンクショントレース）を実行することを特徴とする利用者システムのリアルタイム診断システム。
【請求項２】
前記アプリケーションから前記関数を呼び出すアドレスをaddr1、前記関数処理から戻るアドレスをaddr2、前記関数の最初の命令のアドレスをaddr3とし、
前記関数の冒頭に加える命令が、前記アドレスaddr2をスタックに一時記憶するアセンブリ命令と前記入口トレース関数を呼び出すアセンブリ命令であり、
前記入口トレース関数が前記関数開始履歴の取得後に、リターンレジスタに前記出口トレース関数の呼び出しを設定する命令と、前記関数のアドレスaddr3に戻る命令とを備え、
前記関数が最後に前記リターンレジスタに設定されている前記出口トレース関数をプログラムカウンタに入れる命令を備え、
前記出口トレース関数が前記関数終了履歴の取得後に、前記スタックに一時記憶されている前記アドレスaddr2をプログラムカウンタに入れる命令を備え、
前記アプリケーションの前記アドレスaddr1から前記関数の呼び出し実行、前記関数の開始時に前記入口トレース関数の実行、前記アドレスaddr3に戻って前記関数の実行、前記関数の終了時に前記出口トレース関数の実行を経て、前記アプリケーションのアドレスaddr2に戻ることにより前記ファンクショントレースを実行することを特徴とする、請求項１に記載のリアルタイム診断システム。
【請求項３】
前記入口トレース関数が、リターンレジスタにある前記アドレスaddr3をスタックに保存せしめる命令と、前記関数開始時のレジスタの内容をスタックに保存せしめる命令と、前記関数の開始時刻とアドレスを記録する命令と、前記スタックから前記レジスタの内容をリストアする命令と、前記リターンレジスタに前記出口トレース関数の関数呼び出しを設定する命令と、前記アドレスaddr3を前記プログラムカウンタに入れて前記関数に戻る命令を備え、
前記出口トレース関数が、前記関数終了時のレジスタ（R0からR3まで）の内容をスタックに保存せしめる命令と、前記関数の終了時刻とアドレスを記録する命令と、前記スタックから前記レジスタの内容をリストアする命令と、前記スタックからアドレスaddr2を取得してプログラムカウンタに入れる命令を備えたことを特徴とする請求項２に記載のリアルタイム診断システム。
【請求項４】
前記入口トレース関数の、前記関数開始時のレジスタの内容のスタック保存命令が、引数が入っている最初の４つのレジスタ（R0からR3まで）のデータを一時的にスタックに保存する命令であり、
前記出口トレース関数の、前記関数終了時のレジスタの内容のスタック保存命令が、前記関数のリターン値が入っているR0を含める最初の４つのレジスタ（R0からR3まで）のデータを一時的にスタックに保存する命令である請求項３に記載のリアルタイム診断システム。
【請求項５】
前記入口トレース関数と、前記出口トレース関数を、ダイナミックライブラリにて提供する請求項１から４のいずれかに記載のリアルタイム診断システム。
【請求項６】
それぞれの前記関数に対する前記ファンクショントレース用のリアルタイム診断ソフトウェアの実装にあたり、
前記リアルタイム診断ソフトウェアの実装ツールを用意し、
前記アプリケーションおよび前記関数に対してオリジナルに準備されているそれぞれのビルドツールの名前を前記リアルタイム診断ソフトウェア実装ツールのコマンドの名前に変更するとともに、
前記リアルタイム診断ソフトウェア実装ツールのそれぞれのツールの名前を前記オリジナルのビルドツールの名前にそれぞれ変更し、
前記オリジナルのビルドツールの名前にてビルド実行コマンドを実行することにより、前記関数に前記ファンクショントレース用のリアルタイム診断ソフトウェアを自動的に実装せしめたことを特徴とする請求項１から５のいずれかに記載のリアルタイム診断システム。
【請求項７】
それぞれの前記関数をノードとし、それらの呼び出し関係をグラフ化したベクターグラフにおいて、
ある上流ノードから下流ノードへのルートが一意に定まる場合、前記上流ノードおよび前記下流ノードに対しては前記ファンクショントレース用のリアルタイム診断ソフトウェアを実装せしめ、当該一意に定まるルート上にある２つ以上の中間ノードに対しては前記ファンクショントレース用の入口トレース関数と出口トレース関数の実装を省略する請求項６に記載のリアルタイム診断システム。
【請求項８】
前記入口トレース関数が、前記関数の開始時刻と前記アドレスの記録に加えて前記関数の引数の値の記録を含む関数（入口ロジカルトレース関数）であり、
前記出口トレース関数が、前記関数の終了時刻と前記アドレスの記録に加えて前記関数の返り値の記録を含む関数（出口ロジカルトレース関数）であり、
前記関数の引数と返し値のトレースを実行する請求項１から７のいずれかに記載のリアルタイム診断システム。
【請求項９】
前記アプリケーションにおいてメモリの割り付けが関与するオペレーションが開始された場合に、前記オペレーション処理を前記関数呼び出しの処理と同様に扱い、
前記入口トレース関数が、前記オペレーションの開始時刻と前記アドレスの記録に加えて前記オペレーション開始時における前記メモリの使用量の記録を含む関数（入口メモリトレース関数）であり、
前記出口トレース関数が、前記オペレーションの終了時刻と前記アドレスの記録に加えて前記オペレーション終了時における前記メモリの使用量の記録を含む関数（出口メモリトレース関数）であり、
前オペレーション開始時における前記メモリの使用量と前記オペレーション終了時における前記メモリの使用量の差分からメモリリークの検出を実行する請求項１から７のいずれかに記載のリアルタイム診断システム。
【請求項１０】
前記アプリケーションにおける処理時間の計測対象となるオペレーション処理を、前記関数呼び出しの処理と同様に扱い、
前記入口トレース関数が、前記オペレーションの開始時刻と前記アドレスの記録を含む関数（入口オペレーショントレース関数）であり、
前記出口トレース関数が、前記オペレーションの終了時刻と前記アドレスの記録を含む関数（出口オペレーショントレース関数）であり、
前記オペレーションの前記開始時刻と前記終了時刻の差分から前記オペレーション処理にかかった時間を計測するストップウォッチ機能を実行する請求項１から７のいずれかに記載のリアルタイム診断システム。
【請求項１１】
前記リアルタイムソフトウェアシステムがワイヤレスモバイルシステム、組み込み型のキャリアサーバシステムまたはネットワークデバイスのいずれかである請求項１から１０のいずれかに記載のリアルタイム診断システム。
【請求項１２】
アプリケーションと関数を備えたリアルタイムソフトウェアシステムに対して、
前記アプリケーションから前記関数が呼び出しを受けた場合に前記関数の開始時刻とアドレスを含む関数履歴を記録する入口トレース関数と、前記関数の終了時刻とアドレスを含む関数履歴を記録する出口トレース関数とを用い、
それぞれの前記関数の冒頭に、前記アプリケーションから呼び出された際に前記関数の実行後に戻るべきアドレスをスタックに一時記憶する命令と、前記入口トレース関数を呼び出して実行する命令を加え、
前記アプリケーションから前記関数が呼び出されると、前記関数の開始時に前記入口トレース関数を呼び出して前記関数履歴を取得してサイクリックバッファーに保存してリターンレジスタに前記関数の終了時に前記出口トレース関数の呼び出しを設定し、前記関数に戻って前記関数本体の内容を実行し、前記関数の終了時に前記出口トレース関数を呼び出して前記関数履歴を取得してサイクリックバッファーに保存した後、前記スタックに一時記憶した前記アドレスを手掛かりとして前記アプリケーションに戻ることにより、前記関数履歴のトレース（ファンクショントレース）を実行することを特徴とする利用者システムのリアルタイム診断方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、リアルタイムソフトウェアシステムに組み込んで、システムの障害診断に適用されるリアルタイム診断システムおよびリアルタイム診断方法に関する。特に、不具合に関連した生の診断データ収集のオーバーヘッドを従来の操作の中で無視できるレベル（例えば１０％以下）まで押さえ、デバイス上でリアルタイムに障害診断ができるリアルタイム診断システムおよびリアルタイム診断方法に関する。
【背景技術】
【０００２】
携帯電話などのワイヤレスデバイスの普及が進むにつれ、単なる通話機能だけではなく、いわゆる電子電話帳機能、電子メール通信機能、スケジュール機能、写真撮影機能、着信メロディ機能、テレビジョン画像の受信機能など多種多様な機能が搭載されている。その一方、携帯電話などのワイヤレスデバイスはシステムリソースが限られているため、これら機能を駆使する結果、携帯電話に障害が発生することも多い。
携帯電話などのワイヤレスデバイス上で発生する障害には、様々なレベルがあり、一時的に不安定になる程度の障害のレベルから、復旧のためにメーカーへの持ち込みが必要となる障害のレベルまである。障害の発生をリアルタイムに検知するために障害検知機能を組み込むことが望まれている。
【０００３】
障害検知機能のために携帯電話の通常機能のリアルタイム性に影響を与えるようではユーザーの利便性に影響が及ぶ。そのため、携帯電話の通常機能のリアルタイム性への影響を最小限としつつ障害検知を行なうリアルタイム診断システムが求められている。
【０００４】
ソフトウェアの不具合を診断するために、最も有効になるデータは関数の呼び出し履歴をトレースしたファンクショントレースデータである。
従来のソフトウェア障害検知手法においてファンクショントレースを実行する技術としては特許文献１などに記載されたものが知られていた。当該デバッグ処理方法はリアルタイムを想定したものではなくコンパイルオプションを用いてファンクショントレース用の関数を挿入してデバッグ手法としてコマンドの実行履歴や関数の呼び出し履歴を記録し、ソフトウェアの障害が検知されれば、これらコマンド実行履歴や関数の呼び出し履歴にアクセスし、初期状態に戻してから再び履歴に沿った操作を行い、エラーが起こった直前のコマンドを実行する前の状態を再現するものであった。
【０００５】
【特許文献１】特開平８−２４９２１５号公報
【特許文献２】特開平９−１７９７５３号公報
【発明の開示】
【発明が解決しようとする課題】
【０００６】
上記特許文献１、２などは特定の関数をプログラムや関数に挿入して、プログラムの動作管理情報や関数のスタック情報を収集するものである。管理関数はコンパイルオプションによって埋め込まれる。ファンクショントレースの場合は、ファンクショントレースを実行するためファンクショントレース用の関数がコンパイルのオプションにより組み込まれる。コンパイルのオプションによってファンクショントレース用の関数を挿入する手法は、関数の入口と出口の２箇所にファンクショントレース用の関数の呼び出しを入れる。
【０００７】
しかし、コンパイルオプションを使った従来の方式では、システムにかける負荷が非常に大きいため、リアルタイムに適用できる完全なファンクショントレースを実装することが不可能である。コンパイルオプションを使って、ファンクショントレース用の関数を挿入した場合は、各関数に少なくとも８つの命令を挿入し、ＡＲＭモードの場合に大抵40バイトのコードを追加することが必要となり、例えば10万個の関数を有するソフトウェアシステムでは4MB分のコードが増えることとなる。また、実行時間に関して、例えば200MHzのプロセッサを搭載したシステム上で挿入したファンクショントレース関数を実行するには20マイクロセカンド以上が必要となってしまい、システムパフォーマンスが3倍から5倍遅くなってしまう。
【０００８】
また、ソフトウェア障害診断としてロジカルエラーの診断が重要であるところ、ソフトウェア上のロジカルエラーを診断するためには関数の引数と返し値は重要なデータとなる。しかし、関数の引数と返し値を記録すること（関数の引数と返し値のトレース）は、上記のコンパイルのオプションを用いたファンクショントレース手法で関数の引数と返し値を取得することができず、また、上記のファンクショントレース同様にデータ量が多くシステムのパフォーマンスに影響するので従来技術ではリアルタイム診断に適用できる適当な手法がなかった。
【０００９】
また、ソフトウェア障害の原因としてメモリリークが挙げられるが、潜在的なメモリリークはよく発生し得る問題である。このメモリリークが発生するとシステムが不安定になったり、アプリケーションが起動できなくなったりする致命的な障害が起きる恐れがある。しかし、従来技術にはリアルタイムシステムにおいて、アプリケーションのどの個所でどの位の量のメモリが何故漏れたかを確実に検出する有効的な方法はなかった。
【００１０】
また、携帯電話などのモバイルシステムの障害診断では、すべてのオペレーションに対してパフォーマンスを測定して評価する必要があるが、多くのオペレーションが短いので従来の計測方法では正確に測ることが困難である。また、オペレーションのレスポンスが遅い場合にそのレスポンスが遅くなる原因を特定するための情報を取得するのが困難であった。
【００１１】
そこで、本発明は、ワイヤレスデバイスなど限られたシステムリソースの環境において、不具合に関連した生の診断データをデバイス上でリアルタイムに集め、その障害が発生した原因の診断を可能とするリアルタイム診断システムおよびリアルタイム診断方法を提供することを目的とする。
【課題を解決するための手段】
【００１２】
上記目的を達成するため、本発明のリアルタイム診断システムは、以下のファンクショントレース手法を用いる。本発明においてファンクショントレースとは、関数の開始と終了の履歴を記録する機能をいい、ファンクショントレース手法とは、この履歴を記録する関数（ファンクショントレース関数）を挿入することを言い、従来のコンパイルオプションを用いた手法と異なり、関数の入口と出口に２つのファンクショントレース用関数を挿入するのでなく、関数の入口だけに関数の開始履歴を記録する入口トレース関数の呼び出しを挿入し、この挿入した入口トレース関数の中で出口トレース関数の呼び出しを設定する。
【００１３】
本発明のリアルタイム診断システムは、アプリケーションと関数を備えたリアルタイムソフトウェアシステムに対して、
前記アプリケーションから前記関数が呼び出しを受けた場合に前記関数の開始時刻とアドレスを含む関数履歴を記録する入口トレース関数と、前記関数が終了する場合に前記関数の終了時刻とアドレスを含む関数履歴を記録する出口トレース関数とを備え、
それぞれの前記関数の冒頭に、前記アプリケーションから呼び出された際に前記関数の実行後に戻るべきアドレスをスタックに一時記憶する命令（str lr, [sp, #4]！）と、前記入口トレース関数を呼び出して実行する命令（bl __mv_functrace_enter）を加え、
前記アプリケーションから前記関数が呼び出されると、前記関数の開始時に前記入口トレース関数を呼び出して前記関数履歴を取得し、前記関数に戻って前記関数本体の内容を実行し、前記関数の終了時に前記出口トレース関数を呼び出して前記関数履歴を取得した後、前記スタックに一時記憶した前記アドレスを手掛かりとして前記アプリケーションに戻ることにより、前記関数履歴のトレース（ファンクショントレース）を実行することを特徴とする。
【００１４】
上記構成により、本発明におけるファンクショントレースは、コンパイルオプションを使用せず、前記アセンブリレベルで２つの命令（アセンブリコード）を各関数の冒頭に挿入して実行せしめることにより、例えば200MHzのプロセッサを搭載するシステムならば2マイクロセカンド以内で関数履歴のトレースを実行でき、システムのリアルタイム動作に影響しない水準でソフトウェア障害解析に重要なデータを取得することができる。
【００１５】
上記構成の本発明のリアルタイム診断システムのより具体的な構成は、前記アプリケーションから前記関数を呼び出すアドレスをaddr1、前記関数処理から戻るアドレスをaddr2、前記関数の最初の命令のアドレスをaddr3とし、
前記関数の冒頭に加える命令が、前記アドレスaddr2をスタックに一時記憶するアセンブリ命令（str lr, [sp, #4]！）と前記入口トレース関数を呼び出すアセンブリ命令（bl __mv_functrace_enter）であり、
前記入口トレース関数が前記関数履歴の取得後に、リターンレジスタに前記出口トレース関数の呼び出しを設定する命令（ldr lr, =__mv_functrace_exit）と、前記関数のアドレスaddr3に戻る命令とを備え、
前記関数が実行の最後に前記リターンレジスタに設定されている前記出口トレース関数をプログラムカウンタに入れる仕組みを備え、
前記出口トレース関数が前記関数履歴の取得後に、前記スタックに一時記憶されている前記アドレスaddr2をプログラムカウンタに入れる命令（ldr pc, [sp, #-4]）を備え、
前記アプリケーションの前記アドレスaddr1から前記関数の呼び出し実行、前記関数の開始時に前記入口トレース関数の実行、前記アドレスaddr3に戻って前記関数の実行、前記関数の終了時に前記仕組みによって前記出口トレース関数の実行を経て、前記アプリケーションのアドレスaddr2に戻ることにより前記ファンクショントレースを実行することを特徴とする。
【００１６】
上記構成により、アドレスaddr1における関数の呼び出しに対して、入口トレース関数のみを関数の入口に挿入して関数の呼び出し・実行の入口（開始時）と出口（終了時）に関数履歴を取得しつつ、関数実行後に戻るべきアドレスaddr2に戻って来ることができる。
【００１７】
ここで、前記入口トレース関数は以下の構成とする。つまり、前記リターンレジスタにあるアドレスaddr3をスタックに保存せしめる命令（str lr, [sp, #-4]!）と、前記関数開始時の最初の４つのレジスタの内容をスタックに保存せしめる命令（stmfd sp!, {r0, r1, r2, r3}）と、前記関数の開始時刻とアドレスを記録する関数の呼び出しと、前記スタックから前記レジスタの内容をリストアする命令（ldmfd sp!, {r0, r1, r2, r3}）と、前記リターンレジスタに前記出口トレース関数の関数呼び出しを設定する命令（ldr lr, =__mv_functrace_exit）と、前記アドレスaddr3を前記プログラムカウンタに入れて前記関数に戻る命令（ldr pc, [sp, #0]）を備える。
【００１８】
また同様に、前記出口トレース関数は以下の構成とする。つまり、前記関数終了時の最初の４つのレジスタの内容をスタックに保存せしめる命令（stmfd sp!, {r0, r1, r2, r3}）と、前記関数の終了時刻とアドレスを記録する関数の呼び出しと、前記スタックから前記最初の４つのレジスタの内容をリストアする命令（ldmfd sp!, {r0, r1, r2, r3}）と、前記スタックからアドレスaddr2を取得してプログラムカウンタに入れる命令（ldr pc, [sp, #-20]）を備える。
【００１９】
モバイルシステムなどでは関数履歴のデータは、保存するバッファーがあまり膨大にならないようにサイクリックバッファーを用いれば少ないバッファー容量で関数履歴を効果的に記録・保存することができる。このバッファーに記録するデータが一杯になったら、古いデータから上書きしていく。なお、関数履歴のデータに含める関数のアドレスは、マップファイル等を用いて読みやすい関数の名前に変更することができる。
【００２０】
なお、上記のファンクショントレースに用いる入口トレース関数と出口トレース関数はダイナミックライブラリにて提供することができる。
【００２１】
なお、上記のファンクショントレース実装当たって、実装される関数が数十万個に及ぶ場合もあるため、既存のモバイルシステム用のソフトウェアを書き換えて本発明のリアルタイム診断システムを構築するためには手直し作業は数日間を必要とする膨大な手数がかかる。そこで、ファンクショントレース実装作業は自動化することが好ましい。
【００２２】
そこで、前記リアルタイム診断ソフトウェアの実装ツールを用意し、
前記アプリケーションおよび前記関数に対してオリジナルに準備されているそれぞれのビルドツールの名前を前記リアルタイム診断ソフトウェア実装ツールのコマンドの名前に変更するとともに、
前記リアルタイム診断ソフトウェア実装ツールのそれぞれのツールの名前を前記オリジナルのビルドツールの名前にそれぞれ変更し、
前記オリジナルのビルドツールの名前にてビルド実行コマンドを実行することにより、前記関数に前記ファンクショントレース用のリアルタイム診断ソフトウェアを自動的に実装せしめる。
上記構成により、ファンクショントレース実装作業は完全に自動化することができる。
【００２３】
本発明のリアルタイム診断システムではすべての関数にファンクショントレース手法を適用するのが基本であるが、関数の呼び出し関係に注目すれば、一部の関数については必ずしも個別にファンクショントレース手法を適用しなくても、以下のように関数呼び出し関係の上流および下流の関数に適用したファンクショントレースによって必要な関数履歴を得ることができる。
つまり、それぞれの前記関数をノードとし、それらの呼び出し関係をグラフ化したベクターグラフにおいて、ある上流ノードから下流ノードへのルートが一意に定まる場合、前記上流ノードおよび前記下流ノードに対しては前記ファンクショントレース用のリアルタイム診断ソフトウェアを実装せしめ、当該一意に定まるルート上にある中間ノードに対しては前記ファンクショントレースの実装を省略することができる。本発明ではこの実装省略手法をファンクショントレースに対するサンプリング実装手法と呼ぶ。
【００２４】
上記構成により、ファンクショントレースを入れなくても関数の呼び出しルートが分かる関数が選定され、ファンクショントレースを入れる関数を例えば全体の30%程度に抑えることができ、すべての関数にファンクショントレースを入れた時と比べてリアルタイムシステムに与えるオーバーヘッドを３分の１に削減することができる。
【００２５】
次に、本発明のリアルタイム診断システムは、上記のファンクショントレースを基本として、種々の応用を展開していくことができる。
【００２６】
第１の応用は、ロジカルエラーをトレースするもので、前記入口トレース関数が、前記関数の開始時刻と前記アドレスの記録に加えて前記関数の引数の値の記録を含む関数（入口ロジカルトレース関数）であり、前記出口トレース関数が、前記関数の終了時刻と前記アドレスの記録に加えて前記関数の返り値の記録を含む関数（出口ロジカルトレース関数）であり、前記関数の引数と返し値のトレースを実行するものである。
上記構成によれば、ロジカルエラーを診断するための関数の引数と返り値をトレースすることが可能である。
【００２７】
第２の応用は、メモリリークをトレースするもので、前記アプリケーションにおいてメモリの割り付けが関与するオペレーションが開始された場合に、前記オペレーション処理を前記関数呼び出しの処理と同様に扱い、前記入口トレース関数が、前記オペレーションの開始時刻と前記アドレスの記録に加えて前記オペレーション開始時における前記メモリの使用量の記録を含む関数（入口メモリトレース関数）であり、前記出口トレース関数が、前記オペレーションの終了時刻と前記アドレスの記録に加えて前記オペレーション終了時における前記メモリの使用量の記録を含む関数（出口メモリトレース関数）であり、前オペレーション開始時における前記メモリの使用量と前記オペレーション終了時における前記メモリの使用量の差分からメモリリークの検出を実行するものである。
上記構成により、アプリケーションのオペレーションの前後においてメモリ使用量を検知し、潜在的なメモリリークを検出することができる。
【００２８】
第３の応用は、オペレーション処理の時間を計測するストップウォッチ機能を実現するもので、前記アプリケーションにおける処理時間の計測対象となるオペレーション処理を、前記関数呼び出しの処理と同様に扱い、前記入口トレース関数が、前記オペレーションの開始時刻と前記アドレスの記録を含む関数（入口オペレーショントレース関数）であり、前記出口トレース関数が、前記オペレーションの終了時刻と前記アドレスの記録を含む関数（出口オペレーショントレース関数）であり、前記オペレーションの前記開始時刻と前記終了時刻の差分から前記オペレーション処理にかかった時間を計測するストップウォッチ機能を実行するものである。
上記構成により、リアルタイムシステムにおける細かいオペレーションのパフォーマンスを測定することができ、測定した結果をレスポンスが遅い障害の診断に用いることができる。
【発明の効果】
【００２９】
本発明によれば、コンパイルオプションを使用せずにリアルタイムソフトウェアシステムにリアルタイム性に影響しないファンクショントレースを実装することと、このファンクショントレースによってシステムに不具合が発生した時に不具合を診断するための必要な関数の呼び出し履歴データを漏れなく記録することができる。
【００３０】
本発明によれば、本発明におけるファンクショントレースは、アセンブリレベルで２つのアセンブリコードを各関数の冒頭に挿入して実行せしめることにより、従来のコンパイルオプションを用いる手法の８つ以上のアセンブリコードより元のシステムコードに追加するコードを４分の１で済むことができ、また例えば200MHzのプロセッサを搭載するシステムならば、従来のコンパイルオプションで実装したファンクショントレースに必要となる関数履歴のトレース時間20マイクロセカンドより、その10分の1である2マイクロセカンド以内で関数履歴のトレースを実行でき、システムのリアルタイム動作に影響しない水準でソフトウェア障害解析に重要なデータを取得することができる。
【００３１】
本発明によれば、ファンクショントレースによってシステムのフリーズ診断、ロジカルトレースによってシステムのロジカルエラー分析、メモリトレースによって潜在的なメモリリーク検出、ストップウォッチによってシステムの細かいパフォーマンス測定と遅いレスポンスの原因特定などの障害診断をシステムリソースが小さいワイヤレスデバイスなどであってもシステムのリアルタイム性への影響を最小化して実現することができる。
【発明を実施するための最良の形態】
【００３２】
以下、本発明を実施するための最良の形態について実施例により具体的に説明する。本発明はこれらの実施例に限定されるものではない。なお、本発明はリアルタイムソフトウェアシステムのアプリケーションの中での実施例に限定されるものでなく、デバイスドライバとカネールから、ライブラリ、ミドウェアとアプリケーションまで実施することができる。
なお、以下の説明において、ワイヤレスデバイスは携帯電話に限定されることはないが、以下の説明では携帯電話を想定して説明する。
【実施例１】
【００３３】
本発明のリアルタイム診断システムは、ファンクショントレースを基本とする。本発明におけるファンクショントレースとは、関数の呼び出し履歴（開始と終了時の時刻、関数のアドレス、引数と返し値）を記録することであり、ファンクショントレース手法の実現は、トレースされる関数へのリターンアドレスを一旦スタックに保存して関数の開始履歴（開始時の時刻、関数のアドレスと関数の引数）を記録するための入口トレース関数を呼び出しにかかる関数の先頭に挿入して、挿入した入口トレース関数の中で関数の終了履歴（終了時の時刻、関数のアドレス、関数の引数と返し値）を記録する出口トレース関数を呼び出してスタックに保存しているトレースされた関数へのリターンアドレスを取得して呼び出された場所へ戻られるようにすることにより実現する。
【００３４】
本発明におけるファンクショントレース手法は、コンパイルオプションを使用せず、アセンブリレベルで二つのアセンブリコード（ARM方式の場合に８バイト、THUMB方式の場合に４バイト）を各関数に挿入することにより実装できる。アセンブリコードの一方は、アプリケーションから関数を呼び出して関数実行後に戻るべきアドレスを設定するために用いられ、アセンブリコードの他方は、関数の開始履歴を記録する入口トレース関数の呼び出しに用いられる。
【００３５】
図１は、本発明のリアルタイム診断システムに適するファンクショントレースの実施形態を示した図であり、本発明のファンクショントレースを関数の呼び出しの流れに従って実施することを示している。一方、図２は、本発明のファンクショントレースの実施を自動化するツールの実装処理を示している。
【００３６】
図１に示すように、この例は、アプリケーション実行中に、関数user_func1をファンクションコールにより呼び出し、関数user_func1の実行後、アプリケーションに戻ってその実行を継続してゆく流れとなっている。この従来の流れではリアルタイムで障害診断に必要な関数履歴を得ることになっていない。
一方、図１（ｂ）に示す本発明のリアルタイム診断システムでは、入口トレース関数（mv_functrace_enter）と、出口トレース関数（mv_functrace_exit）を備え、関数user_func1の冒頭部分に２つのアセンブリコード“str lr, [sp, #4]!”と“bl__mv_functrace_enter”が挿入されている。
【００３７】
入口トレース関数（__mv_functrace_enter）とは、アプリケーションから関数（関数user_func1など）が呼び出しを受けた場合に関数の開始時刻とアドレスを含む関数履歴を記録する関数である。
出口トレース関数（__mv_functrace_exit）とは、関数（関数user_func1など）が終了する場合に関数の終了時刻とアドレスを含む関数履歴を記録する関数である。この出口トレース関数は、従来のコンパイルオプションを用いた手法のように直接にトレースされる関数に挿入されるのでなく、入口トレース関数の中でリターンレジスタを用いる仕組みによってトレースされる関数が終了する時に呼び出される。
関数user_func1の冒頭部分に加えられたアセンブリコードとは、アプリケーションから呼び出された際に関数の実行後に戻るべきアドレスをスタックに一時記憶するアセンブリ命令と、入口トレース関数を呼び出して実行するアセンブリ命令である。
【００３８】
以下、アプリケーションから関数user_func1を呼び出すアドレスをaddr1、関数user_func1の処理から戻るアドレスをaddr2、関数user_func1の最初の命令のアドレスをaddr3として処理の流れを追って説明する。
【００３９】
関数user_func1の冒頭に加える命令が、アドレスaddr2をスタックに一時記憶するアセンブリ命令と入口トレース関数を呼び出すアセンブリ命令となっており、アプリケーションから関数user_func1が呼び出されると、関数user_func1の開始時に入口トレース関数を呼び出して関数履歴を取得し、関数user_func1に戻って関数user_func1本体の内容を実行し、関数user_func1の終了時に出口トレース関数を呼び出して関数履歴を取得した後、スタックに一時記憶したアドレスaddr2を手掛かりとしてアプリケーションに戻ることにより、関数履歴のトレース（ファンクショントレース）を実行する。
【００４０】
前者のアセンブリコード“str lr, [sp, #4]!”は、ファンクショントレース関数を実行してから元の場所に戻るために関数user_func1が呼び出された直後のアドレスaddr2を一旦スタックに保存する命令となっている。このスタックにアドレスaddr2を一時保存しておく仕組みは本発明における重要な手法の一つであり、後述するように、出口トレース関数の終了時点にスタックから読み出してプログラムカウンタに書き込むことによりアプリケーションのアドレスaddr2に戻ることが可能となる。
後者のアセンブリコード“bl __mv_functrace_enter”は、関数user_func1から入口トレース関数“__mv_functrace_enter”を呼び出すアセンブリ命令である。
【００４１】
入口トレース関数“__mv_functrace_enter”では、まずリターンレジスタLRにある挿入した二つのアセンブリの直後になるアドレスaddr3をスタックに保存する。そして、引数が入っている最初の４つのレジスタR0、R1、R2とR3を一時スタックに保存してから関数の入口（関数開始時点）で履歴を記録する作業を行う。保存されたレジスタR0、R1、R2とR3をスタックから戻して、リターンレジスタLRに関数の出口で履歴を記録するための出口トレース関数“__mv_functrace_exit”のアドレスを設定する。最後にスタックに保存されたアドレスaddr3をレジスタPCに入れて、トレースされる関数の最初の命令へ実行を移行する。関数の実行が終るとリターンレジスタLRに出口トレース関数へのアドレスが入っているために実行はこの出口トレース関数へ移行する。このリターンレジスタLRを用いて出口トレース関数を呼び出す仕組みは、本発明における重要な手法のもう一つである。
【００４２】
ファンクショントレースの動作を鳥瞰すると次のステップになる。
【００４３】
（１）アプリケーションから関数user_func1を呼び出する命令“bl user_func1”を実行して関数user_func1へ飛び、挿入した二つの命令の一つ目である“str lr, [sp, #4]!”を実行する。
【００４４】
（２）挿入した二つ目の命令である“bl __mv_functrace_enter”を実行してファンクション関数__mv_functrace_enterへ飛び、関数の入口（開始時点）で関数を呼び出す時刻と関数user_func1のアドレスを関数履歴として記録する。
【００４５】
（３）関数user_func1に戻るためのアドレスaddr3をレジスタPCに設定したので、user_func1の最初の命令へ実行を移行し、関数user_func1の元のコードをすべて実行する。
【００４６】
（４）入口トレース関数__mv_functrace_enterの処理中でレジストLRに出口トレース関数mv_functrace_exitのアドレスを設定しているために、関数user_func1の実行が終った後に当該リターンレジスタに設定されている出口トレース関数のアドレスをプログラムカウンタに入れ、関数__mv_functrace_exitへ実行を移行し、関数の出口（終了時点）での履歴となる関数を終了する時刻と関数のアドレスを記録する。
【００４７】
（５）__mv_functrace_exitの最後に、スタックに保存している元のアプリケーションへ戻るためのアドレスaddr2をレジスタPCに入れ、user_func1を呼び出した直後の命令へ実行を移行する。
【００４８】
つまり、アプリケーションのアドレスaddr1から関数の呼び出し実行、関数の開始時に入口トレース関数の実行、アドレスaddr3に戻って関数の実行、関数の終了時に出口トレース関数の実行を経て、アプリケーションのアドレスaddr2に戻ることによりファンクショントレースを実行するものとなっている。
【００４９】
なお、ファンクショントレース関数“__mv_functrace_enter”と“__mv_functrace_exit”は、ダイナミックライブラリで提供される。
上記構成によれば、ファンクショントレース関数はその実行時間が例えば200MHzのプロセッサを搭載するシステム上では2マイクロセカンド以内となり、システム全体の動作に影響しない水準とすることができる。
【００５０】
次に、上記のファンクショントレースの自動的実装について述べる。
上記ファンクショントレースの実装を自動化することは重要である。モバイルシステムのような比較的規模の小さいシステムであっても実装される関数は数十万個となることが想定され、ビルド用makefileの数も数百から数千になることが想定される。数多くのmakefileを手作業で行なうと数日間を要することとなる。そこで実装作業を自動化する必要がある。
【００５１】
本発明におけるファンクショントレースを自動的に実装する手法を図２に示す。手作業による実装に代え、ファンクショントレースを実装するためのツールを用意し、この実装ツールはすべての元のビルドコマンドラインを吸収してファンクショントレースに必要な作業を行い、最後に元のビルド作業を継続させる。
【００５２】
この実装手法は次のステップになる。
【００５３】
（１）元のビルドツールであるarm-linux-gcc、arm-linux-g++、arm-linux-ld、arm-linux-arの名前をmv-arm-linux-gcc、mv-arm-linux-g++、mv-arm-linux-ld、mv-arm-linux-arにそれぞれ変更する。
【００５４】
（２）ファンクショントレースの実装ツールであるmv_make_gcc、mv_make_g++、mv_make_ld、mv_make_arの名前を元のビルドツールarm-linux-gcc、arm-linux-g++、arm-linux-ldにそれぞれ変更する。
【００５５】
（３）ファンクショントレース実装に必要な設定ファイルmv_make.cfgを指定する環境変数MV_MAKE_CFGに設定する。
【００５６】
（４）従来通りターゲットをビルドするためのコマンド、例えばmake buildを実行してすべての必要な関数にファンクショントレースを自動的に実装する。
【００５７】
上記のように、ファンクショントレースを実装する際には、ファンクショントレース実装ツールが元のビルドツールの名前になっているので、まず従来通りに実行したビルドコマンドをファンクショントレース実装ツールに渡して以下のように分析を行い、ファンクショントレースを実装する。
コマンドラインにあるファイルに関してファンクショントレースが必要でない場合はコマンドを直接にGNUツールに渡す。
【００５８】
ファンクショントレースが必要である場合はコマンドの違いにより次のようにケース分類する。
【００５９】
もしコマンドがarである場合には、オブジェクトにファンクショントレースが既に挿入されていれば、weakで設定したファンクショントレース関数を入れたダミーのオブジェクトを作り、GUNのar (mv-arm-linux-ar)を実行する。
【００６０】
もしコマンドがldである場合にはオブジェクトにファンクショントレースが既に挿入されていればファンクショントレース用ライブラリをコマンドラインにリンクオプションを追加してGNU ld (mv-arm-linux-ld)を実行する。
【００６１】
もし、コマンドがgxxである場合にはGNU gxx (mv-arm-linux-gxx)によってソースコードのアセンブリを生成して必要に応じて関数にファンクショントレース用の二つのアセンブリを挿入し、コマンドラインに元のソースファイルを生成したアセンブリファイルに変更してアセンブリをコンパイルする新しいコマンドラインをGNU gxxに渡して実行する。
【００６２】
すべてのプロジェクトビルドが完了するまで以上の作業を繰り返す。最後にファンクショントレース実装ログを記録する。
上記実装手法によればファンクショントレース実装作業は完全に自動化することができる。
【実施例２】
【００６３】
本発明のリアルタイム診断システムではすべての関数にファンクショントレース手法を適用するのが基本であるが、関数の呼び出し関係に注目すれば、一部の関数については必ずしも個別にファンクショントレースを適用しなくても、関数呼び出し関係の上流および下流の関数に適用したファンクショントレースから必要な関数履歴を得ることができる。
実施例２はファンクショントレースに対する実装省略手法を説明する。ここではサンプリング実装手法と呼ぶ。
【００６４】
サンプリング実装手法では、それぞれの関数をノードとし、それらの呼び出し関係をグラフ化したベクターグラフにおいて、ある上流ノードから下流ノードへのルートが一意に定まる場合、上流ノードおよび下流ノードに対してはファンクショントレースを実装し、当該一意に定まるルート上にある中間ノードに対してはファンクショントレース実装を省略するものである。
中間ノードではファンクショントレースを入れなくても関数の呼び出しルートが分かるので省略しても良く、ファンクショントレースを挿入する関数を例えば全体の30%程度に抑えることができる。
【００６５】
図３は、関数の呼び出し関係を示すベクターグラフとサンプリングアルゴリズムによりファンクショントレースの実装が省略されうる中間ノードの選択の原理を説明する図である。
【００６６】
［セットアップ］
ＧＳをベクターグラフの集合とし、その中にあるグラフがバイナリファイルと対応するものとする。ＧはＧＳの中にあるエレメント即ち一つのベクターグラフとする。ｕは、サンプリング実施関数SAMPLING_VERTEXのパラメータであり、ベクターグラフの中にあるノードである。各ノードであるｕには、以下のパラメータが有する。
【００６７】
color[u]
color[u]はノードのカラーを表し、GRAYで初期化される。カラーの値は３種類がある。GRAYは、アルゴリズムによってベクターグラフの全体を処理（traverse）する中で通っていなくfunctraceを入れるかどうまた分からない状態を表す。WHITEは通ったノードにfunctraceが必要としないことを表す。BLACKはノードを通りかけ、functraceが必要とする処理を済んだことを表す。
【００６８】
name[u]
name[u]は、ベクターグラフにノードを表し、例えばname[1]="1"   name[2]="2"がノード“1”と“2”を表現する。
【００６９】
gap[u]
gap[u]は、あるノードとそのノードに属するすべての子供ノードにfunctraceが必要としない集合を現す。
【００７０】
sons[u]
sons[u]はノードのすべての子供ノードを表す。例えば、図３には次の子供集合、sons[5]={7，8，10，11，12}，sons[4]={6，9，10}がある。
【００７１】
extern[u]
extern[u]は、ベクターグラフ間の関数呼び出しを表し、次の二つの値TRUEとFALSEを有する。
TRUE：あるノードからベクターグラフ外の関数を呼び出している。例えば図３にあるノード３はそのノードである。
FALSE ：ノードから外部関数を呼び出していない。
【００７２】
extern_invoked[u]
extern_invoked[u]は外部関数から呼び出されていることを表し、次の二つの値TRUEとFALSEを有する。
TRUE：外部から呼び出されている。例えば図３にあるノード14はそのノードである。
FALSE：外部からよびだされていない。
【００７３】
is_top[u]
is_top[u]は、誰にも呼び出されないノードを表し、例えば、図３にあるノード“１３”“１”“２”がこの種類のノードであり、次の二つの値TRUEとFALSEを有する。
TRUE：このノードがベクターグラフの中で誰にも呼び出されていない。
FALSE：このノードが少なくとも一つの関数に呼び出されている。
【００７４】
図４にSAMPLING_VERTEX(u)のアルゴリズムの例を示す。
以下に、図４に示したSAMPLING_VERTEX(u)のアルゴリズムの実行例を示す。
【００７５】
MAX_FUNCTRACE_GAPを2に設定する。
次の状況から
is_top[1]=TRUE, is_top[2]=TRUE,  is_top[13]=TRUE
extern[3]=TRUE
extern_invoked[14]=TRUE
【００７６】
ノード1,2,3,13,14はfunctraceを入れることになる。すべての集合は次のようになる。
Gap[16]={}
Gap[17]={}
Gap[15]={16, 17}   functraceを入れる。
Gap[9]={} 
Gap[10]={}
Gap[6]={9,10}  functraceを入れる。
Gap[7]={10}  functraceを入れる。
Gap[11]={}
Gap[12]={}
Gap[8]={11,12} functraceを入れる。
Gap[4]={}  注意：ノードの子供ノード6にfunctraceを入れたためにGap[6]はGap[4]に合併しない。
Gap[5]={}  同上
Gap[2]={4,5}   functraceを入れる。
【００７７】
図５は上記のアルゴリズムの実行結果を示す図である。
図５に示すように、黒く塗られたノードはファンクショントレースが実装され、白く塗られたノードはファンクショントレースの実装が省略される。ノード間にスキップする数であるMAX_FUNCTRACE_GAPを2に設定した場合にfunctraceの数が半分に減らすことができた。
【００７８】
もしこのMAX_FUNCTRACE_GAPを４に設定するとファンクショントレースを実装するノードの数をさらに減らすことができる。
上流と下流のノードの間に数個のノードをスキップしても、関数の呼び出しルートを分かる。例えば、ノード2とノード6の間にノード4にファンクショントレースを挿入していないが、関数の呼び出しルートはノード２、４、６であることを間違いなく再現することができる。
【実施例３】
【００７９】
本発明のリアルタイム診断システムは、実施例１で説明したファンクショントレース手法を基本として、種々の応用が可能である。
実施例３では第１の応用として、ロジカルエラーをトレースするものを説明する。
【００８０】
実施例３のリアルタイム診断システムでは、ファンクショントレース手法を用いて、ファンクショントレース関数の中で呼び出された関数の引数を関数の入口（関数開始時点）で記録し、返し値を出口（関数終了時点）で記録する。この関数の引数と返し値は、関数の呼び出し履歴を一緒に記録するが、記録データを保存するバッファーが膨大に要求されないように最初の４つの引数のみ（20バイト分）を記録する。リアルタイムシステムには、４つの引数を持つ関数が全体の90%を占めるので効率的なものとすることができる。また、最初の４つの引数は、実施例１に示したようにレジスタにあるためにファンクショントレース実行の過程で同時に記録することができ、余分のオーバーヘッドが発生しない。
【００８１】
図６は実施例３のロジカルエラーを診断するためのロジトレース手法を実施した例を示した図である。
関数の引数と返し値トレースは次のステップになる。
【００８２】
（１）アプリケーションの中で関数func_1を呼び出してfunc_1へ移行する。
（２）functrace手法によってfunc_1の先頭にファンクショントレースの入口トレース関数mv_ft_enterを挿入してあるために、実行はこのmv_ft_enterへ移行する。
（３）関数mv_ft_enterの中では、ファンクショントレースのデータ（関数の呼び出し時刻と関数のアドレス）とR0からR3までのレジスタにある関数の引数を保存する。
（４）そして、実行はmv_ft_enterを呼び出したfunc_1へ戻る。
（５）func_1の中で元のfunc_1のコードを実行してから出口トレース関数mv_ft_exitへ実行を移行する。
（６）mv_ft_exitの中では、レジスタR0にある関数func_1の返し値を記録する。
（７）関数func_1の呼び出された場所の後に実行を移行する。
すべての関数の引数と返し値は、ファンクショントレースと共に（１）から（７）までの作業を繰り返して記録される。また、記録場所もファンクショントレースと同じバッファーである。
【００８３】
上記のように、実施例１で示したファンクショントレース手法をベースとしながら入口（関数開始時）における４つの引数のトレースと、出口（関数終了時）における返り値のトレースを実行する。
【実施例４】
【００８４】
実施例４では第２の応用として、メモリリークをトレースするものを説明する。
アプリケーションにおいてメモリの割り付けが関与するオペレーションが開始された場合に、オペレーション処理を関数呼び出しの処理と同様に扱い、ファンクショントレースの手法を応用しつつ、潜在的なメモリリークを検出する。
【００８５】
本手法は、潜在的なメモリリークが、繰り返し動作の中で割り付けられたメモリの開放漏れによって発生するものであると推定し、すべての操作の入口関数にファンクショントレース手法を用いて入口メモリトレース関数および出口メモリトレース関数を挿入して動作前と動作後のメモリ使用量を取得してその差を求め、同じ動作が繰り返された時にこの差が直線的に増加するのであれば、メモリがこの動作の中で漏れたことと断定し、漏れた場所と具体的な漏れたメモリの量を特定する。
【００８６】
入口メモリトレース関数は、オペレーションの開始時刻とアドレスの記録に加えてオペレーション開始時におけるメモリの使用量の記録を含む関数であり、出口トレース関数は、オペレーションの終了時刻とアドレスの記録に加えてオペレーション終了時におけるメモリの使用量の記録を含む関数であり、オペレーション開始時におけるメモリの使用量とオペレーション終了時におけるメモリの使用量の差分からメモリリークの検出を実行する。
【００８７】
図７は実施例４の潜在的なメモリリークを検出するためのメモリトレース手法を実施した例を示した図である。
【００８８】
（１）アプリケーションの中である操作に関連する関数、例えばOperation_1を呼び出した時に実行をその関数へ移行する。
（２）Operation_1関数の中では、最初にメモリトレース関数mv_mm_enterを呼び出す。
（３）mv_mm_enterでは、その時点（動作が始まる前）でのメモリ使用量を取得してメモリトレースデータとしてバッファーに保存する。
（４）mv_mm_enterを呼び出したOperation_1関数のコードへ実行を移行し、Operation_1関数にあるすべての元のコードを実行し、動作をすべて完了させる。
（５）Operation_1関数のExitでファンクショントレース手法によって設定されたメモリトレース関数mv_mm_exitへ実行を移行する。
（６）mv_mm_exitでは、Operation_1関数の出口（関数終了時点）で呼び出されるために動作のすべてが完了してあり、この時点でメモリ使用量を取得する。
（７）Operation_1関数が呼び出された場所の直後に戻る。
よって、特定な動作で漏れたメモリは、Operation_1関数の入口で取得したメモリ使用量と出口で取得したメモリ使用量の差を求めることによって検出される。
【００８９】
この手法は、潜在的なメモリ漏れを検出するために対象となるすべての動作の入口関数リストをファームウェアをビルドする前に予めに用意する必要がある。記録場所はファンクショントレースと分けた別のバッファーである。
【００９０】
なお上記実装では、関数呼び出しの入口と出口の２箇所においてメモリ使用量を取得して差分を得る方法であったが、２回分の操作をまとめて差分を算出することでもメモリリークを検出することは可能である。Operation_1関数の入口で１回取得して、次回のOperation_1関数の出口で１回取得しておき、２回の動作間におけるメモリ使用量の差を求めることによって漏れたメモリを検出することも機能的には可能であり、メモリ使用量の取得回数が少なくて済むので負荷を低減させることができる。
【００９１】
上記構成により、アプリケーションのオペレーションの前後においてメモリ使用量を検知し、潜在的なメモリリークを検出することができる。
【実施例５】
【００９２】
実施例５では第３の応用として、アプリケーションの処理時間を正確に計測することができるストップウォッチ機能を説明する。
アプリケーションにおける処理時間の計測対象となるオペレーション処理を、関数呼び出しの処理と同様に扱ってタイムスタンプを取り、関数開始時刻と終了時刻の差から処理時間を求めるものである。
【００９３】
本発明における処理ごとのパフォーマンス測定ストップウォッチ手法は、リアルタイムシステムにおいて、あらゆるオペレーションで実際にかかった時間をファンクショントレースのタイムスタンプデータによって表示する（例えばマイクロセカンド単位で表示する）ものであり、遅いレスポンスに対してどこで遅くなったかを関数レベルで示すことができる。
本手法は、ファンクショントレース手法を用いてパフォーマンスを測定する対象となるオペレーションの入口関数にファンクショントレース関数をストップウォッチとして入れ、実行した際にその関数開始時刻のタイムスタンプとその関数終了時刻のタイムスタンプを取得することによりオペレーションの時間を測定するストップウォッチを実現する。
【００９４】
このストップウォッチ手法は、図８に示しているように次のステップによってリアルタイムシステムにおける細かいオペレーションのパフォーマンスを測定し、測定した結果を分析するためのデータを提供する。
図８は実施例５のストップウォッチ手法を実施した例を示した図である。
【００９５】
（１）アプリケーションの中である操作の入口関数例えばOperation_1を呼び出した時に実行をその関数へ移行する。
（２）Operation_1関数の中では、最初にファンクショントレース関数mv_ft_enterを呼び出す。
（３）mv_ft_enterでは、その時点（動作が始まる直前）でのタイムスタンプを取得してバッファーに記録する。
（４）mv_ft_enterを呼び出したOperation_1関数のコードへ実行を移行し、Operation_1関数にあるすべての元のコードを実行し、動作をすべて完了させる。
（５）Operation_1関数の出口でファンクショントレース手法によって設定されたファンクショントレース関数mv_ft_exitへ実行を移行する。
（６）mv_ft_exitでは、Operation_1関数の出口（終了直前）で呼び出されるために動作のすべてが完了してあり、この時点でのタイムスタンプを取得してバッファーに記録する。
（７）Operation_1関数が呼び出された場所の直後に戻る。
計測が必要な操作に関するストップウォッチ機能は、ファンクショントレースと共に（１）から（７）までの作業を繰り返して記録される。また、記録場所もファンクショントレースと同じバッファーである。
【００９６】
なお、上記ストップウォッチ手法を実現するには、前提として、ファームウェアをビルドする前にパフォーマンスを測定する対象となるすべてのオペレーションの入口関数リストをメーカ側から予め提供してもらう必要がある。
上記構成により、リアルタイムシステムにおける細かいオペレーションのパフォーマンスを測定することができ、測定した結果を障害の診断に用いることができる。
【００９７】
以上、本発明のリアルタイム診断システムの好ましい実施形態を図示して説明してきたが、本発明の技術的範囲を逸脱することなく種々の変更が可能であることは理解されるであろう。
【産業上の利用可能性】
【００９８】
本発明は、携帯電話などのワイヤレスデバイス、キャリア用の各種の組込み型サーバ、ルータなどの各種ネットワークデバイス、カーナビデバイス、ゲーム端末、テレビなどのセットボックス、インテリジェント家電製品、ロボット、工作機械装置など多様なシステムに広く適用することができる。
【図面の簡単な説明】
【００９９】
【図１】本発明のリアルタイム診断システムに適するファンクショントレースの実施形態を示した図
【図２】本発明におけるファンクショントレースを自動的に実装する手法を示した図
【図３】関数の呼び出し関係を示すベクターグラフとサンプリングアルゴリズムによりファンクショントレースの実装が省略されうる中間ノードの選択の原理を説明する図
【図４】SAMPLING_VERTEX(u)のアルゴリズムの実施例を示す図
【図５】SAMPLING_VERTEX(u)のアルゴリズムの実行結果を示す図
【図６】実施例３のロジカルエラーを診断するためのロジトレース手法を実施した例を示した図
【図７】実施例４の潜在的なメモリリークを検出するためのメモリトレース手法を実施した例を示した図
【図８】実施例５のストップウォッチ手法を実施した例を示した図
【図１】
2008059402.tif 000003
【図２】
2008059402.tif 000004
【図３】
2008059402.tif 000005
【図４】
2008059402.tif 000006
【図５】
2008059402.tif 000007
【図６】
2008059402.tif 000008
【図７】
2008059402.tif 000009
【図８】
2008059402.tif 000010