gcov − カバレッジテストツール |
gcov [−v│--version] [−h│--help] [−b│--branch-probabilities] [−c│--branch-counts] [−n│--no-output] [−l│--long-file-names] [−f│--function-summaries] [−o│--object-directory directory] sourcefile |
gcov は、カバレッジテストを行うプログラムです。 GCC といっしょに用いる と、あなたのプログラムをもっと効果的で高速に動くコードにするための解析 ができます。 gcov をプロファイリングツールとして使うと、プログラムを最 適化するにはどこを直すのが一番効果的かを見つけ出す事ができます。また、 gprof とともに用いると、コードのどの部分が実行時間をもっとも使っている のかを調べる事ができます。 プロファイリングツールを使って、あなたのコードの性能を解析することがで きます。 gcov や gprof のようなプロファイラを使うと、性能にかかわる以下 のような基礎的な統計情報が得られます。 |
• |
コードの各行が何回実行されるか。 |
||
• |
コードのどの部分が実際に実行されたのか。 |
||
• |
コードの各部分の実行にどれだけの時間がかかっているか。 |
コンパイルされたコードがどのように動くのかがわかれば、最適化すべきモ ジュールを見つけられます。 gcov を使えば、最適化のためにどこに力をいれ ればよいかを決める事ができます。 ソフトウェア開発者は、カバレッジテストをテストスイートといっしょに使う 事で、ソフトウェアがリリース可能な品質を持つことを確認できます。テスト スイートはプログラムが期待どおり動作する事を検証します。一方、カバレッ ジテストによって、テストスイートがプログラムをどれだけテストしているか を調べる事ができます。より良いテストとより良い最終製品を作るために、テ ストスイートにどんな種類のテストケースを追加すればよいかを決める事がで きます。 gcov を使う場合には最適化無しでコンパイルするべきです。なぜなら最適化に よって数行のコードが 1 つにまとめられてしまうと、実行時間の多くを消費し ている「ホットスポット」を探すのに必要な情報が十分集まらなくなってしま うかもしれないからです。さらに、 gcov は統計情報を行ごと (最小分析単位) に集めるので、各行に文を 1 つずつ書くプログラミングスタイルにすると、 もっとも役に立つ結果が得られます。ループや他の制御構文に展開される複雑 なマクロを使うと、マクロ呼び出しの 1 行にしか情報が出ませんから、統計情 報はあまり役に立たなくなってしまいます。もしそのマクロが関数のように振 る舞うものなら、それをインライン関数に置き換えるとこの問題を解決できま す。 gcov は sourcefile.gcov というログファイルを作ります。これには sourcefile.c というソースファイルのどの行が何回実行されたかが記録されて います。このログファイルを gprof といっしょに使えば、あなたのプログラム の性能をファインチューニングする助けになります。 gprof からは、 gcov の 出力といっしょに使える、タイミング情報が得られます。 gcov は、 GCC でコンパイルされたコードのみで動作します。他のプロファイ ルやテストカバレッジの仕組みとの互換はありません。 |
−h |
--help |
gcov の使いかたを標準出力に表示して、プログラムを終了します。それ 以外の処理はしません。 |
−v |
--version |
gcov のバージョン番号を標準出力に表示して、プログラムを終了しま す。それ以外の処理はしません。 |
−b |
--branch-probabilities |
分岐の回数を出力ファイルに書き出し、分岐のサマリを標準出力に表示し ます。このオプションにより、プログラム中でそれぞれの分岐がどのくら い起きたかを調べることができます。 |
−c |
--branch-counts |
分岐が成立した割合 (パーセント) の代わりに、分岐の成立した回数を出 力します。 |
−n |
--no-output |
gcov 出力ファイルを作りません。 |
−l |
--long-file-names |
インクルードされたソースファイルの名前として長いファイル名を使いま す。たとえば、ヘッダファイル x.h がコードを含んでいて、 a.c によっ てインクルードされる場合、 gcov を a.c に対して実行すると、出力 ファイルは x.h.gcov ではなく、 a.c.x.h.gcov になります。これは、 x.h が複数のファイルにインクルードされている場合に便利です。 |
−f |
--function-summaries |
ファイルレベルのサマリの他に、各関数についてのサマリも出力します。 |
−o directory |
--object-directory directory |
オブジェクトファイルのあるディレクトリを指定します。 gcov は、この ディレクトリで .bb, .bbg, .da ファイルを探します。 |
gcov を使うには、最初にまず GCC の 2 つの特別なオプション、 −fprofile-arcs, −ftest-coverage を指定して、プログラムをコンパイルしな ければなりません。これによってコンパイラは、 gcov が必要とする追加情報 (基本的にはプログラムのフローグラフ) を生成し、また gcov が必要とするプ ロファイル情報を生成するコードをオブジェクトファイルに含めます。これら の追加のファイルは、ソースコードのあるディレクトリに作られます。 プログラムを実行すると、プロファイル結果が生成されます。 −fprofile-arcs を指定してコンパイルしたソースファイル毎に、対応する .da ファイルがソー スディレクトリに作られます。 プログラムのソースファイル名を引数にして gcov を実行すると、コードの各 行に実行回数を示したソースリストを生成します。プログラム名を tmp.c とす ると、 gcov の基本機能は以下のようにして使います。 $ gcc -fprofile-arcs -ftest-coverage tmp.c $ a.out $ gcov tmp.c 87.50% of 8 source lines executed in file tmp.c Creating tmp.c.gcov. gcov の出力は tmp.c.gcov に格納されています。以下はそのサンプルです。 main() { 1 int i, total; 1 total = 0; 11 for (i = 0; i < 10; i++) 10 total += i; 1 if (total != 45) ###### printf ("Failure\n"); else 1 printf ("Success\n"); 1 } −b オプションを使うと、出力は次のようになります。 $ gcov -b tmp.c 87.50% of 8 source lines executed in file tmp.c 80.00% of 5 branches executed in file tmp.c 80.00% of 5 branches taken at least once in file tmp.c 50.00% of 2 calls executed in file tmp.c Creating tmp.c.gcov. 以下は、結果の tmp.c.gcov ファイルのサンプルです。 main() { 1 int i, total; 1 total = 0; 11 for (i = 0; i < 10; i++) branch 0 taken = 91% branch 1 taken = 100% branch 2 taken = 100% 10 total += i; 1 if (total != 45) branch 0 taken = 100% ###### printf ("Failure\n"); call 0 never executed branch 1 never executed else 1 printf ("Success\n"); call 0 returns = 100% 1 } 基本ブロック (basic block) について、基本ブロックの最終行の次に、基本ブ ロックを終わらせた分岐か関数呼び出しについての行を表示します。ある行で 終わる基本ブロックが複数ある場合、そのソース行に対して複数の分岐や関数 呼び出しが示される事があります。この場合、それらの分岐や関数呼び出しに は番号がふられます。その番号とソース上の要素とのマッピングは単純ではあ りませんが、もっとも小さい番号を持つ分岐や関数呼び出しが、ソース上で もっとも左にあるのが普通です。 分岐 (branch) について、一度でも実行された分岐は、分岐の成立した回数を 分岐の実行数で割った比率をパーセントで示します。一度も実行されなかった 分岐は ‘‘never executed’’ と表示します。 関数呼び出し (call) について、一度でも実行された関数呼び出しは、呼び出 しから戻った回数を呼び出した回数で割った比率をパーセントで示します。こ れは普通は 100% になりますが、 "exit" や "longjmp" を呼び出すために戻っ てこない事のある関数ではそれより少なくなるかもしれません。 実行回数は積算されます。もし .da ファイルを消さずにプログラムを再実行す ると、ソースの各行の実行回数は、以前の結果に加えられます。これにはいく つか役に立つ使い道を考えられます。たとえばテストスイートの一部として行 われる、プログラムの複数回の実行結果をまとめたり、長期間のより正確な情 報を得るためにプログラムを非常に大きな回数実行して結果をまとめたりする 事ができます。 .da ファイルのデータは、プログラムの終了直前に保存されます。 −fprofile-arcs を指定してコンパイルされた各ファイルに組み込まれているプ ロファイリングコードは、まず始めに既存の .da ファイルを読み込みます。も しその内容が実行プログラムと一致しなければ (基本ブロックの数が合わなけ れば) 、ファイルの内容は無視します。一致する場合には、新しい実行回数を 足し込んでから、データをファイルに書き出します。 gcov と GCC の最適化の関係 あなたのコードを gcov を使って最適化しようとするならば、最初にまず GCC の 2 つの特別なオプション −fprofile-arcs, −ftest-coverage を指定して、 プログラムをコンパイルしなければなりません。それに加えて GCC の他のどん なオプションも指定する事ができます。一方、プログラム中の全ての行が実行 される事を確認したい時には、最適化を指定してはいけません。一部のマシン では最適化によって複数の行が 1 つにまとめられてしまい、行の区別が無く なってしまう可能性があります。たとえば以下のようなコードがあるとします: if (a != b) c = 1; else c = 0; ある種のマシンではこのコードは 1 命令にコンパイルする事ができます。その 場合、各行に対応する命令コードが存在しないため、 gcov は行ごとの実行回 数を数える事ができません。したがってプログラムを最適化した時の gcov の 出力は以下のようになります。 100 if (a != b) 100 c = 1; 100 else 100 c = 0; この出力は、最適化によって結合されたこのコードブロックが 100 回実行され た事を示しています。 4 行からなるブロックが 1 命令にまとめられたのです から、これはある意味では正しいものです。しかしながら、結果が 0 になった 回数や 1 になった回数を、この出力から読み取る事はできません。 |
gpl(7), gfdl(7), fsf-funding(7), gcc(1) と gcc の Info エントリ |
Copyright (c) 1996, 1997, 1999, 2000, 2001 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being ‘‘ GNU General Public License’’ and ‘‘Funding Free Software’’, the Front-Cover texts being (a) (see below), and with the Back-Cover Texts being (b) (see below). A copy of the license is included in the gfdl(7) man page. (a) The FSF ’s Front-Cover Text is: A GNU Manual (b) The FSF ’s Back-Cover Text is: You have freedom to copy and modify this GNU Manual, like GNU software. Copies published by the Free Software Foundation raise funds for GNU development. |