[llvm-bugs] [Bug 51025] New: [llvm-cov] The function array causes wrong coverage

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Jul 8 07:13:46 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=51025

            Bug ID: 51025
           Summary: [llvm-cov] The function array causes wrong coverage
           Product: Runtime Libraries
           Version: 12.0
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: libprofile library
          Assignee: unassignedbugs at nondot.org
          Reporter: byone.heng at gmail.com
                CC: llvm-bugs at lists.llvm.org

$./clang -v                                                                     
clang version 12.0.0 (https://github.com/llvm/llvm-project.git
b6c8feb29fce39121884f7e08ec6eb0f58da3fb7)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/x/project/llvm-project/build/install/bin/.
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64

$cat test.c
———————————————————

const volatile int true_var = 1;
static volatile unsigned int false_var = 0;

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int malloc_depth = 0;

static char memory[128* 1024];
static size_t memory_p = 0;

void f1(void) {}
void f2(void) {}

typedef void (*fun_t)(void);
static const fun_t funs[2] = { f1, f2, };

static void * malloc_impl(size_t size) {
    void * r = &memory[memory_p];
    /* The malloc() and calloc() functions return a pointer to the allocated
     * memory, which is suitably aligned for any built-in type.  Use 16
     * bytes here as the basic alignment requirement for user-defined malloc
     * and calloc.  See PR97594 for the details.  */
    #define ROUND_UP_FOR_16B_ALIGNMENT(x) ((x + 15) & (-16))

    memory_p += ROUND_UP_FOR_16B_ALIGNMENT(size);

    // force TOPN profile
    funs[size % 2]();
    return r;
}

// Override default malloc, check it it get s called recursively
void * malloc(size_t size) {
    // Must not be called recursively. Malloc implementation does not support
it.
    if (malloc_depth != 0) __builtin_trap();

    if( false_var > 0 )
    {
    ++malloc_depth;
    void * r = malloc_impl(size);
    --malloc_depth;
    return r;
    }
    ++malloc_depth;
      void * r = malloc_impl(size);
    --malloc_depth;
    return r;
}

// Called from gcov
void *calloc(size_t nmemb, size_t size) {
    // Must not be called recursively.  Malloc implementation does not support
it.
    if (malloc_depth != 0) __builtin_trap();

    ++malloc_depth;
      void * r = malloc_impl(size * nmemb);
      memset(r, 0, size * nmemb);
    --malloc_depth;
    return r;
}

void free(void *ptr){}

int main() {
    void * p = malloc(8);
    return p != 0 ? 0 : 1;
}


——————————————————

$clang -O0 -g -fcoverage-mapping -fprofile-instr-generate=test.profraw test.c;
./a.out; llvm-profdata merge test.profraw -o test.profdata; llvm-cov show a.out
-instr-profile=test.profdata test.c > test.lcov; cat test.lcov

    4|       |const volatile int true_var = 1;
    5|       |static volatile unsigned int false_var = 0;
    6|       |
    7|       |#define _GNU_SOURCE
    8|       |
    9|       |#include <stdio.h>
   10|       |#include <stdlib.h>
   11|       |#include <string.h>
   12|       |
   13|       |static int malloc_depth = 0;
   14|       |
   15|       |static char memory[128* 1024];
   16|       |static size_t memory_p = 0;
   17|       |
   18|      6|void f1(void) {}
   19|      1|void f2(void) {}
   20|       |
   21|       |typedef void (*fun_t)(void);
   22|       |static const fun_t funs[2] = { f1, f2, };
   23|       |
   24|      7|static void * malloc_impl(size_t size) {
   25|      7|    void * r = &memory[memory_p];
   26|       |    /* The malloc() and calloc() functions return a pointer to
the allocated
   27|       |     * memory, which is suitably aligned for any built-in type. 
Use 16
   28|       |     * bytes here as the basic alignment requirement for
user-defined malloc
   29|       |     * and calloc.  See PR97594 for the details.  */
   30|      7|    #define ROUND_UP_FOR_16B_ALIGNMENT(x) ((x + 15) & (-16))
   31|       |
   32|      7|    memory_p += ROUND_UP_FOR_16B_ALIGNMENT(size);
   33|       |
   34|       |    // force TOPN profile
   35|      7|    printf("%d\n",size%2);
   36|      7|    funs[size % 2]();
   37|      7|    return r;
   38|      7|}
   39|       |
   40|       |// Override default malloc, check it it get s called recursively
   41|      7|void * malloc(size_t size) {
   42|       |    // Must not be called recursively. Malloc implementation does
not support it.
   43|      7|    if (malloc_depth != 0) __builtin_trap();
   44|       |
   45|      7|    if( false_var > 0 )
   46|      0|    {
   47|      0|    ++malloc_depth;
   48|      0|    void * r = malloc_impl(size);
   49|      0|    --malloc_depth;
   50|      0|    return r;
   51|      0|    }
   52|      7|    ++malloc_depth;
   53|      7|      void * r = malloc_impl(size);
   54|      7|    --malloc_depth;
   55|      7|    return r;
   56|      7|}
   57|       |
   58|       |// Called from gcov
   59|      0|void *calloc(size_t nmemb, size_t size) {
   60|       |    // Must not be called recursively.  Malloc implementation
does not support it.
   61|      0|    if (malloc_depth != 0) __builtin_trap();
   62|       |
   63|      0|    ++malloc_depth;
   64|      0|      void * r = malloc_impl(size * nmemb);
   65|      0|      memset(r, 0, size * nmemb);
   66|      0|    --malloc_depth;
   67|      0|    return r;
   68|      0|}
   69|       |
   70|      1|void free(void *ptr){}
   71|       |
   72|      1|int main() {
   73|      1|    void * p = malloc(8);
   74|      1|    return p != 0 ? 0 : 1;
   75|      1|}

In my opinion, line 18 should be executed 7 times, and line 19 should not be
executed.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210708/a64b320f/attachment-0001.html>


More information about the llvm-bugs mailing list