.\" $FreeBSD$ .\" Automatically generated by Pod::Man version 1.15 .\" Wed Feb 5 03:13:55 2003 .\" .\" Standard preamble: .\" ====================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Ip \" List item .br .ie \\n(.$>=3 .ne \\$3 .el .ne 3 .IP "\\$1" \\$2 .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used .\" to do unbreakable dashes and therefore won't be available. \*(C` and .\" \*(C' expand to `' in nroff, nothing in troff, for use with C<> .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr .\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and .\" index entries marked with X<> in POD. Of course, you'll have to process .\" the output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it .\" makes way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. .bd B 3 . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ====================================================================== .\" .IX Title "GCOV 1" .TH GCOV 1 "gcc-3.2.2" "2003-02-05" "GNU" .UC .SH "名称" gcov \- カバレッジテストツール .SH "書式" .IX Header "書式" gcov [\fB\-v\fR|\fB\*(--version\fR] [\fB\-h\fR|\fB\*(--help\fR] [\fB\-b\fR|\fB\*(--branch-probabilities\fR] [\fB\-c\fR|\fB\*(--branch-counts\fR] [\fB\-n\fR|\fB\*(--no-output\fR] [\fB\-l\fR|\fB\*(--long-file-names\fR] [\fB\-f\fR|\fB\*(--function-summaries\fR] [\fB\-o\fR|\fB\*(--object-directory\fR \fIdirectory\fR] \fIsourcefile\fR .SH "解説" .IX Header "解説" \&\fBgcov\fR は、カバレッジテストを行うプログラムです。 \s-1GCC\s0 といっしょに用いると、あなたのプログラムを もっと効果的で高速に動くコードにするための解析ができます。 \fBgcov\fR をプロファイリングツールとして使うと、 プログラムを最適化するには どこを直すのが一番効果的かを見つけ出す事ができます。 また、 \&\fBgprof\fR とともに用いると、 コードのどの部分が実行時間をもっとも使っているのかを 調べる事ができます。 .PP プロファイリングツールを使って、あなたのコードの性能を 解析することができます。 \fBgcov\fR や \fBgprof\fR のようなプロファイラを使うと、 性能にかかわる以下のような基礎的な統計情報が得られます。 .Ip "\(bu" 4 コードの各行が何回実行されるか。 .Ip "\(bu" 4 コードのどの部分が実際に実行されたのか。 .Ip "\(bu" 4 コードの各部分の実行にどれだけの時間がかかっているか。 .PP コンパイルされたコードがどのように動くのかがわかれば、 最適化すべきモジュールを見つけられます。 \&\fBgcov\fR を使えば、最適化のためにどこに力をいれればよいかを 決める事ができます。 .PP ソフトウェア開発者は、 カバレッジテストをテストスイートといっしょに使う事で、 ソフトウェアがリリース可能な品質を持つことを確認できます。 テストスイートはプログラムが期待どおり動作する事を検証します。 一方、カバレッジテストによって、テストスイートがプログラム をどれだけテストしているかを調べる事ができます。 より良いテストとより良い最終製品を作るために、 テストスイートにどんな種類のテストケースを追加すればよいかを 決める事ができます。 .PP \&\fBgcov\fR を使う場合には最適化無しでコンパイルするべきです。 なぜなら最適化によって数行のコードが 1 つにまとめられてしまうと、 実行時間の多くを消費している「ホットスポット」を探すのに 必要な情報が十分集まらなくなってしまうかもしれないからです。 さらに、 \fBgcov\fR は統計情報を行ごと (最小分析単位) に集めるので、 各行に文を 1 つずつ書くプログラミングスタイルにすると、 もっとも役に立つ結果が得られます。 ループや他の制御構文に展開される複雑なマクロを使うと、 マクロ呼び出しの 1 行にしか情報が出ませんから、 統計情報はあまり役に立たなくなってしまいます。 もしそのマクロが関数のように振る舞うものなら、 それをインライン関数に置き換えるとこの問題を解決できます。 .PP \&\fBgcov\fR は \fI\fIsourcefile\fI.gcov\fR というログファイルを作ります。 これには \fI\fIsourcefile\fI.c\fR というソースファイルのどの行が 何回実行されたかが記録されています。 このログファイルを \fBgprof\fR といっしょに使えば、 あなたのプログラムの性能をファインチューニングする助けになります。 \fBgprof\fR からは、 \&\fBgcov\fR の出力といっしょに使える、 タイミング情報が得られます。 .PP \&\fBgcov\fR は、 \s-1GCC\s0 でコンパイルされたコードのみで動作します。 他のプロファイルやテストカバレッジの仕組みとの互換はありません。 .SH "オプション" .IX Header "オプション" .Ip "\fB\-h\fR" 4 .IX Item "-h" .PD 0 .Ip "\fB\*(--help\fR" 4 .IX Item "help" .PD \fBgcov\fR の使いかたを標準出力に表示して、 プログラムを終了します。 それ以外の処理はしません。 .Ip "\fB\-v\fR" 4 .IX Item "-v" .PD 0 .Ip "\fB\*(--version\fR" 4 .IX Item "version" .PD \fBgcov\fR のバージョン番号を標準出力に表示して、 プログラムを終了します。 それ以外の処理はしません。 .Ip "\fB\-b\fR" 4 .IX Item "-b" .PD 0 .Ip "\fB\*(--branch-probabilities\fR" 4 .IX Item "branch-probabilities" .PD 分岐の回数を出力ファイルに書き出し、分岐のサマリを標準出力に表示します。 このオプションにより、プログラム中でそれぞれの分岐がどのくらい起きたかを 調べることができます。 .Ip "\fB\-c\fR" 4 .IX Item "-c" .PD 0 .Ip "\fB\*(--branch-counts\fR" 4 .IX Item "branch-counts" .PD 分岐が成立した割合 (パーセント) の代わりに、分岐の成立した回数を出力します。 .Ip "\fB\-n\fR" 4 .IX Item "-n" .PD 0 .Ip "\fB\*(--no-output\fR" 4 .IX Item "no-output" .PD \fBgcov\fR 出力ファイルを作りません。 .Ip "\fB\-l\fR" 4 .IX Item "-l" .PD 0 .Ip "\fB\*(--long-file-names\fR" 4 .IX Item "long-file-names" .PD インクルードされたソースファイルの名前として長いファイル名を使います。 たとえば、ヘッダファイル \fIx.h\fR がコードを含んでいて、 \&\fIa.c\fR によってインクルードされる場合、 \fBgcov\fR を \fIa.c\fR に対して実行すると、 出力ファイルは \fIx.h.gcov\fR ではなく、 \fIa.c.x.h.gcov\fR になります。 これは、 \fIx.h\fR が複数のファイルにインクルードされている場合に便利です。 .Ip "\fB\-f\fR" 4 .IX Item "-f" .PD 0 .Ip "\fB\*(--function-summaries\fR" 4 .IX Item "function-summaries" .PD ファイルレベルのサマリの他に、各関数についてのサマリも出力します。 .Ip "\fB\-o\fR \fIdirectory\fR" 4 .IX Item "-o directory" .PD 0 .Ip "\fB\*(--object-directory\fR \fIdirectory\fR" 4 .IX Item "object-directory directory" .PD オブジェクトファイルのあるディレクトリを指定します。 \fBgcov\fR は、このディレクトリで \fI.bb\fR, \&\fI.bbg\fR, \fI.da\fR ファイルを探します。 .PP \fBgcov\fR を使うには、最初にまず \s-1GCC\s0 の 2 つの特別なオプション、 \&\fB\-fprofile-arcs, \-ftest-coverage\fR を指定して、 プログラムをコンパイルしなければなりません。 これによってコンパイラは、 gcov が必要とする追加情報 (基本的にはプログラムのフローグラフ) を生成し、 また gcov が必要とするプロファイル情報を生成するコードを オブジェクトファイルに含めます。 これらの追加のファイルは、ソースコードのあるディレクトリに作られます。 .PP プログラムを実行すると、プロファイル結果が生成されます。 \fB\-fprofile-arcs\fR を指定してコンパイルしたソースファイル毎に、 対応する \fI.da\fR ファイルがソースディレクトリに作られます。 .PP プログラムのソースファイル名を引数にして \fBgcov\fR を実行すると、 コードの各行に実行回数を示したソースリストを生成します。 プログラム名を \fItmp.c\fR とすると、 \fBgcov\fR の基本機能は以下のようにして使います。 .PP .Vb 5 \& $ 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. .Ve \fBgcov\fR の出力は \fItmp.c.gcov\fR に格納されています。 以下はそのサンプルです。 .PP .Vb 3 \& main() \& { \& 1 int i, total; .Ve .Vb 1 \& 1 total = 0; .Ve .Vb 2 \& 11 for (i = 0; i < 10; i++) \& 10 total += i; .Ve .Vb 5 \& 1 if (total != 45) \& ###### printf ("Failure\en"); \& else \& 1 printf ("Success\en"); \& 1 } .Ve \fB\-b\fR オプションを使うと、出力は次のようになります。 .PP .Vb 6 \& $ 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. .Ve 以下は、結果の \fItmp.c.gcov\fR ファイルのサンプルです。 .PP .Vb 3 \& main() \& { \& 1 int i, total; .Ve .Vb 1 \& 1 total = 0; .Ve .Vb 5 \& 11 for (i = 0; i < 10; i++) \& branch 0 taken = 91% \& branch 1 taken = 100% \& branch 2 taken = 100% \& 10 total += i; .Ve .Vb 9 \& 1 if (total != 45) \& branch 0 taken = 100% \& ###### printf ("Failure\en"); \& call 0 never executed \& branch 1 never executed \& else \& 1 printf ("Success\en"); \& call 0 returns = 100% \& 1 } .Ve 基本ブロック (basic block) について、 基本ブロックの最終行の次に、基本ブロックを終わらせた 分岐か関数呼び出しについての行を表示します。 ある行で終わる基本ブロックが複数ある場合、 そのソース行に対して複数の分岐や関数呼び出しが示される事があります。 この場合、それらの分岐や関数呼び出しには番号がふられます。 その番号とソース上の要素とのマッピングは単純ではありませんが、 もっとも小さい番号を持つ分岐や関数呼び出しが、 ソース上でもっとも左にあるのが普通です。 .PP 分岐 (branch) について、 一度でも実行された分岐は、 分岐の成立した回数を分岐の実行数で割った比率をパーセントで示します。 一度も実行されなかった分岐は ``never executed'' と表示します。 .PP 関数呼び出し (call) について、 一度でも実行された関数呼び出しは、 呼び出しから戻った回数を呼び出した回数で割った比率をパーセントで示します。 これは普通は 100% になりますが、 \f(CW\*(C`exit\*(C'\fR や \f(CW\*(C`longjmp\*(C'\fR を呼び出すために 戻ってこない事のある関数ではそれより少なくなるかもしれません。 .PP 実行回数は積算されます。 もし \fI.da\fR ファイルを消さずにプログラムを再実行すると、 ソースの各行の実行回数は、以前の結果に加えられます。 これにはいくつか役に立つ使い道を考えられます。 たとえばテストスイートの一部として行われる、 プログラムの複数回の実行結果をまとめたり、 長期間のより正確な情報を得るためにプログラムを非常に大きな回数実行して 結果をまとめたりする事ができます。 .PP \fI\&.da\fR ファイルのデータは、プログラムの終了直前に保存されます。 \fB\-fprofile-arcs\fR を指定してコンパイルされた各ファイルに 組み込まれているプロファイリングコードは、 まず始めに既存の \fI.da\fR ファイルを読み込みます。 もしその内容が実行プログラムと一致しなければ (基本ブロックの数が 合わなければ) 、ファイルの内容は無視します。 一致する場合には、 新しい実行回数を足し込んでから、データをファイルに書き出します。 .Sh "\fBgcov\fP と \s-1GCC\s0 の最適化の関係" .IX Subsection "gcov と GCC の最適化の関係" あなたのコードを \fBgcov\fR を使って最適化しようとするならば、 最初にまず \s-1GCC\s0 の 2 つの 特別なオプション \&\fB\-fprofile-arcs, \-ftest-coverage\fR を指定して、 プログラムをコンパイルしなければなりません。 それに加えて \s-1GCC\s0 の他のどんなオプションも指定する事ができます。 一方、プログラム中の全ての行が実行される事を確認したい時には、 最適化を指定してはいけません。 一部のマシンでは最適化によって複数の行が 1 つにまとめられてしまい、 行の区別が無くなってしまう可能性があります。 たとえば以下のようなコードがあるとします: .PP .Vb 4 \& if (a != b) \& c = 1; \& else \& c = 0; .Ve ある種のマシンではこのコードは 1 命令にコンパイルする事ができます。 その場合、各行に対応する命令コードが存在しないため、 \fBgcov\fR は行ごとの実行回数を数える事ができません。 したがってプログラムを最適化した時の \fBgcov\fR の出力は 以下のようになります。 .PP .Vb 4 \& 100 if (a != b) \& 100 c = 1; \& 100 else \& 100 c = 0; .Ve この出力は、最適化によって結合されたこのコードブロックが 100 回 実行された事を示しています。 4 行からなるブロックが 1 命令にまとめられたのですから、 これはある意味では正しいものです。 しかしながら、結果が 0 になった回数や 1 になった回数を、 この出力から読み取る事はできません。 .SH "関連項目" .IX Header "関連項目" \&\fIgpl\fR\|(7), \fIgfdl\fR\|(7), \fIfsf-funding\fR\|(7), \fIgcc\fR\|(1) と \fIgcc\fR の Info エントリ .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright (c) 1996, 1997, 1999, 2000, 2001 Free Software Foundation, Inc. .PP Permission is granted to copy, distribute and/or modify this document under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being ``\s-1GNU\s0 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 \fIgfdl\fR\|(7) man page. .PP (a) The \s-1FSF\s0's Front-Cover Text is: .PP .Vb 1 \& A GNU Manual .Ve (b) The \s-1FSF\s0's Back-Cover Text is: .PP .Vb 3 \& 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. .Ve