llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.92k stars 11.53k forks source link

[Coverage] Code Coverage count twice when function is weak symbol #97143

Open zhangtianhao6 opened 2 months ago

zhangtianhao6 commented 2 months ago

clang version

clang version 19.0.0git (https://github.com/llvm/llvm-project.git cf9eeb67e553137c979dca50bbf912acea8889a5)
Target: aarch64-target-linux-gnu
Thread model: posix
InstalledDir: /home/zth/llvm_latest/install/bin
Found candidate GCC installation: /usr/lib/gcc/aarch64-linux-gnu/10.3.1
Selected GCC installation: /usr/lib/gcc/aarch64-linux-gnu/10.3.1
Candidate multilib: .;@m64
Selected multilib: .;@m64

t.c

#include<stdio.h>

extern void test();
__attribute__((weak,noinline)) void printf_1(){
        printf("t printf_1\n");
}

int main(){
        int a = 1;
        while(a != 5){
                printf_1();
                a++;
        }
        test();
        return 0;
}

test.c

#include<stdio.h>

__attribute__((weak,noinline)) void printf_1(){
        printf("test printf_1\n");
}

void test(){
        int a = 1;
        while(a != 5){
                printf_1();
                a++;
        }
}

Refer to SourceBasedCodeCoverage guide to get code coverage https://clang.llvm.org/docs/SourceBasedCodeCoverage.html

Step 1: Compile with coverage enabled. clang -fprofile-instr-generate -fcoverage-mapping t.c test.c -o foo Step 2: Run the program LLVM_PROFILE_FILE="foo.profraw" ./foo Step 3: Show foo.profraw llvm-profdata show --all-functions --counts foo.profraw

Counters:
  printf_1:
    Hash: 0x0000000000000000
    Counters: 1
    Function count: 8
    Block counts: []
  main:
    Hash: 0x00000000000a0458
    Counters: 2
    Function count: 1
    Block counts: [4]
  printf_1:
    Hash: 0x0000000000000000
    Counters: 1
    Function count: 8
    Block counts: []
  test:
    Hash: 0x0000000000002811
    Counters: 2
    Function count: 1
    Block counts: [4]
Instrumentation level: Front-end
Functions shown: 4
Total functions: 4
Maximum function count: 8
Maximum internal block count: 4

Step 4: Index the raw profile llvm-profdata merge -sparse foo.profraw -o foo.profdata Step 5:Show foo.profdata

Counters:
  test:
    Hash: 0x0000000000002811
    Counters: 2
    Function count: 1
    Block counts: [4]
  main:
    Hash: 0x00000000000a0458
    Counters: 2
    Function count: 1
    Block counts: [4]
  printf_1:
    Hash: 0x0000000000000000
    Counters: 1
    Function count: 16
    Block counts: []
Instrumentation level: Front-end
Functions shown: 3
Total functions: 3
Maximum function count: 16
Maximum internal block count: 4

Step 6: Create a line-oriented coverage report. llvm-cov show ./foo -instr-profile=foo.profdata

/home/zth/test/20240623_UPCF/weak_symbol/t.c:
    1|       |#include<stdio.h>
    2|       |
    3|       |extern void test();
    4|     16|__attribute__((weak,noinline)) void printf_1(){
    5|     16|  printf("t printf_1\n");
    6|     16|}
    7|       |
    8|      1|int main(){
    9|      1|  int a = 1;
   10|      5|  while(a != 5){
   11|      4|          printf_1();
   12|      4|          a++;
   13|      4|  }
   14|      1|  test();
   15|      1|  return 0;
   16|      1|}

/home/zth/test/20240623_UPCF/weak_symbol/test.c:
    1|       |#include<stdio.h>
    2|       |
    3|       |__attribute__((weak,noinline)) void printf_1(){
    4|       |  printf("test printf_1\n");
    5|       |}
    6|       |
    7|      1|void test(){
    8|      1|  int a = 1;
    9|      5|  while(a != 5){
   10|      4|          printf_1();
   11|      4|          a++;
   12|      4|  }
   13|      1|}

There are some strange phenomenon: First: In t.c, functin printf_1 counts 16, but ifrom the code logic, the function only runs 4 times. If we count the number of times the printf_1 function runs in the test.c file together, it only runs 8 times, not 16 times

Second: Why is the execution count of the printf_1 function not recorded in the code coverage of the test.c file

Is this a bug or am I using it incorrectly

hstk30-hw commented 2 months ago

CC @bogner @dnovillo