내 매뉴얼 페이지libgcov 포크와 간부 후크 <code>--coverage</code> 옵션에 대한 GCC의 주장
또한 "포크"전화가 감지되고 올바르게 처리 (이중 계산이 일어나지 않을 것입니다).
는 그리고 내 /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"
라인이 실행 된 이후, 파일에의 적용 결과를 썼다 없지만, 포함 된대로 표시되지 않습니다. 그리고 두 번째 전에 모든 라인은 fork
이중 커버리지를보고하는 것으로 보입니다. 따라서 man 페이지가 주장 된대로 fork
을 호출 할 때 커버리지 결과가 리셋되지 않았습니다.
libgcov 후크를 사용하려면 어떻게해야합니까? 나는 실제 syscalls를 실제 훅 이름으로 대체하기로되어 있지 않다. 단지 커버리지 모드에서 컴파일 할 때이다.
수정 :'__gcov_fork'는 기본 제공 함수가 아닙니다. 'exec *'와'fork'가 있습니다. –