空想犬猫記

※当日記では、犬も猫も空想も扱っておりません。(旧・エト記)

gcov

GDBハンドブック
買ったまま放置してあった「GDBハンドブック」に目を通す。商用Unix上でのデバッグ作業で,このcross platformなデバッガには普段からとてもお世話になっている。ぜひとも机の片隅に置いておこうと思って買ってあったものだ。
この本のAppendixに紹介されていたgcovなるカバレッジツールを使ってみる。僕の中では「カバレッジツールは高い」というイメージがあったが,なんとGCC上で使えるものが存在していたらしいのだ。
使い方はgprofなんかと同じで,簡単非常に簡単,

  1. GCCでビルドする際に-ftest-coverage -fprofile-arcsオプションを付ける。
  2. 通常通り実行する。
  3. ソースコードと同じディレクトリに集計ファイルが出来る(Tigerのgcc 4.0.1だと .gcda,.gcnoという拡張子のファイルが作成されている)。
  4. gcov -b hoge.cを実行するとhoge.c.gcovファイルが作成される。.gcovは既にhuman-readableなレポートになっている。

というかんじ。試しに以下のようなコード(cover.c)で実験してみた。

#include 

static void called( int i )
{
    printf( "I'm called with i = %d?n", i );
}

static void not_called(void)
{
    printf( "I'm alone.?n" );
}

int main(void)
{
    for ( int i=0; i<10; ++i ) {
        called( i );
        if ( i > 10 ) {
            printf( "I'm also alone.?n" );
        }
    }
    return 0;
}

実行例は以下の通り。
>

[yoda]~/tmp> gcc -ftest-coverage -fprofile-arcs -O0 cover.c
(出力略)
[yoda]~/tmp> ./a.out
(出力略)
[yoda]~/tmp> ls -l cover.*
-rw-r--r-- 1 jun jun 330 Nov 28 01:09 cover.c
-rw-r--r-- 1 jun jun 248 Nov 28 01:11 cover.gcda
-rw-r--r-- 1 jun jun 900 Nov 28 01:11 cover.gcno
[yoda]~/tmp> gcov -b covoer.c
File 'cover.c'
Lines executed:70.00% of 10
Branches executed:100.00% of 4
Taken at least once:75.00% of 4
Calls executed:50.00% of 4
cover.c:creating 'cover.c.gcov'
[yoda]~/tmp> cat cover.c.gcov
-: 0:Source:cover.c
-: 0:Graph:cover.gcno
-: 0:Data:cover.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include
-: 2:
-: 3:static void called( int i )
function called called 10 returned 100% blocks executed 100%
10: 4:{
10: 5: printf( "I'm called at i = %d?n", i );
call 0 returned 100%
-: 6:}
-: 7:
-: 8:static void not_called(void)
function not_called called 0 returned 0% blocks executed 0%
#####: 9:{
#####: 10: printf( "I'm alone.?n" );
call 0 never executed
-: 11:}
-: 12:
-: 13:int main(void)
function main called 1 returned 100% blocks executed 86%
1: 14:{
11: 15: for ( int i=0; i<10; ++i ) {
branch 0 taken 91%
branch 1 taken 9% (fallthrough)
10: 16: called( i );
call 0 returned 100%
10: 17: if ( i > 10 ) {
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 18: printf( "I'm also alone.?n" );
call 0 never executed
-: 19: }
-: 20: }
1: 21: return 0;
-: 22:}