[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