Libgcov fork and exec hooks

My man page for gcc requires the option --coverage:

Fork calls were also detected and correctly processed (double counting will not happen).

And I notice that my / usr / lib / gcc / x 86_64-linux-gnu / 5.4.0 / libgcov.a contains characters __gcov_fork, __gcov_execland other options __gcov_exec*. Looking at the definitions of these functions on the Internet, it looks like they will upload and clear exit information to avoid duplication or data loss.

But for me this does not work:

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$ 

, "child 1" , , , "In child 1" , . fork, , , , -, reset fork, man-.

- , , libgcov? syscalls , , ?

+4
1

: c11 gnu11.

-std=c11 C11 ( GNU). -std=gnu11 GNU. -std= --coverage (, -std= , __gcov_fork - ), gnu11 , .. 17 29 , 1. ( GCC 5.4.0, ).

P.S. . , .

+2

Source: https://habr.com/ru/post/1686268/


All Articles