2017-09-23 11 views
4

私のmanページ:libgcovフォークとexecフック

(ダブルカウントが発生しません)。また、「フォーク」のコールが検出され、正しく処理されます。

そして私は私の/usr/lib/gcc/x86_64-linux-gnu/5.4.0/libgcov.aシンボル__gcov_fork__gcov_execl、およびその他の__gcov_exec*変種が含まれています注意してください。これらの関数の定義をオンラインで調べると、データの重複や消失を避けるためにカバレッジ出力をダンプして消去するように見えます。

しかし、これは私のために動作していないようです:

gcov_test$ rm *.gcno *.gcda 
gcov_test$ cat gcov_test.c 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

int main(void) { 
    puts("Before loop"); 
    for (int i=0; i<5; ++i) 
     printf("i=%d\n", i); 
    puts("After loop"); 
    pid_t child1 = fork(); 
    if (child1<0) { 
     perror("fork 1"); 
     exit(1); 
    } else if (child1==0) { 
     printf("In child 1: %d\n", (int)getpid()); 
     execl("/bin/true", "/bin/true", (char*)NULL); 
     perror("execl"); 
     exit(1); 
    } 
    printf("Parent spawned child 1: %d\n", (int)child1); 
    pid_t child2 = fork(); 
    if (child2<0) 
    { 
     perror("fork 2"); 
     exit(1); 
    } else if (child2==0) { 
     printf("In child 2: %d\n", (int)getpid()); 
    } else { 
     printf("Parent spawned child 2: %d\n", (int)child2); 
     if (waitpid(child1, NULL, 0)<0) 
      perror("waitpid 1"); 
     if (waitpid(child2, NULL, 0)<0) 
      perror("waitpid 2"); 
     puts("Parent done"); 
    } 
    return 0; 
} 

gcov_test$ gcc --version 
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 
Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

gcov_test$ gcc -c -std=c11 -Wall --coverage gcov_test.c 
gcov_test$ gcc --coverage gcov_test.o -o gcov_test 
gcov_test$ ./gcov_test 
Before loop 
i=0 
i=1 
i=2 
i=3 
i=4 
After loop 
Parent spawned child 1: 31569 
Parent spawned child 2: 31570 
In child 2: 31570 
In child 1: 31569 
Parent done 
gcov_test$ gcov gcov_test.c 
File 'gcov_test.c' 
Lines executed:64.29% of 28 
Creating 'gcov_test.c.gcov' 

gcov_test$ cat gcov_test.c.gcov 
     -: 0:Source:gcov_test.c 
     -: 0:Graph:gcov_test.gcno 
     -: 0:Data:gcov_test.gcda 
     -: 0:Runs:2 
     -: 0:Programs:1 
     -: 1:#include <stdlib.h> 
     -: 2:#include <stdio.h> 
     -: 3:#include <unistd.h> 
     -: 4:#include <sys/types.h> 
     -: 5:#include <sys/wait.h> 
     -: 6: 
     2: 7:int main(void) { 
     2: 8: puts("Before loop"); 
     12: 9: for (int i=0; i<5; ++i) 
     10: 10:  printf("i=%d\n", i); 
     2: 11: puts("After loop"); 
     2: 12: pid_t child1 = fork(); 
     2: 13: if (child1<0) { 
    #####: 14:  perror("fork 1"); 
    #####: 15:  exit(1); 
     2: 16: } else if (child1==0) { 
    #####: 17:  printf("In child 1: %d\n", (int)getpid()); 
    #####: 18:  execl("/bin/true", "/bin/true", (char*)NULL); 
    #####: 19:  perror("execl"); 
    #####: 20:  exit(1); 
     -: 21: } 
     2: 22: printf("Parent spawned child 1: %d\n", (int)child1); 
     2: 23: pid_t child2 = fork(); 
     2: 24: if (child2<0) 
     -: 25: { 
    #####: 26:  perror("fork 2"); 
    #####: 27:  exit(1); 
     2: 28: } else if (child2==0) { 
     1: 29:  printf("In child 2: %d\n", (int)getpid()); 
     -: 30: } else { 
     1: 31:  printf("Parent spawned child 2: %d\n", (int)child2); 
     1: 32:  if (waitpid(child1, NULL, 0)<0) 
    #####: 33:   perror("waitpid 1"); 
     1: 34:  if (waitpid(child2, NULL, 0)<0) 
    #####: 35:   perror("waitpid 2"); 
     1: 36:  puts("Parent done"); 
     -: 37: } 
     2: 38: return 0; 
     -: 39:} 
     -: 40: 
gcov_test$ 

特に"In child 1"行が実行するので、「子1」プロセスは、ファイルへのカバレッジ結果を書いたことがないようですが、私には見えますが、カバーされているようには示されていない。そして、2番目の前のすべての行forkは2倍のカバレッジを報告しているようですので、マニュアルページが請求されているので、カバレッジ結果はforkを呼び出してリセットされていないようです。

これらのlibgcovフックを有効にするために何か必要なことはありますか?カバレッジ・モードでコンパイルするときに実際にsyscallを実際のフック名に置き換えるのではないでしょうか?

答えて

2

解決方法:c11gnu11に置き換えてください。

-std=c11は、純粋なC11(GNU拡張なし)を意味します。 -std=gnu11は、GNU拡張も有効にします。 -std=--coverageの間の接続を説明することはできません(おそらく-std=は組み込み関数の使用に影響し、__gcov_forkもその1つです)。標準をgnu11に変更するだけで、問題は解決しているようです。 29の実行回数が1になりました(GCC 5.4.0と最近のトランクリビジョンの両方で試しました)。

P.S.バグレポートを提出することをお勧めします。この動作が意図されていても、コンパイラは潜在的な問題について少なくとも警告する必要があります。

+0

修正: '__gcov_fork'は組み込み関数ではありません。 'exec *'と 'fork'はあります。 –

関連する問題