1 // REQUIRES: darwin || linux
3 // Test using __llvm_profile_set_file_object in continuous mode (%c).
4 // Create & cd into a temporary directory.
5 // RUN: rm -rf %t.dir && mkdir -p %t.dir && cd %t.dir
7 // The -mllvm -runtime-counter-relocation=true flag has effect only on linux.
8 // RUN: %clang -fprofile-instr-generate -fcoverage-mapping -mllvm -instrprof-atomic-counter-update-all=1 -mllvm -runtime-counter-relocation=true -o main.exe %s
10 // Test continuous mode with __llvm_profile_set_file_object with mergin disabled.
11 // RUN: env LLVM_PROFILE_FILE="%t.dir/profdir/%c%mprofraw.old" %run %t.dir/main.exe nomerge %t.dir/profdir/profraw.new 2>&1 | FileCheck %s -check-prefix=WARN
12 // WARN: LLVM Profile Warning: __llvm_profile_set_file_object(fd={{[0-9]+}}) not supported in continuous sync mode when merging is disabled
14 // Test continuous mode with __llvm_profile_set_file_object with mergin enabled.
15 // RUN: rm -rf %t.dir/profdir/
16 // RUN: env LLVM_PROFILE_FILE="%t.dir/profdir/%c%mprofraw.old" %run %t.dir/main.exe merge %t.dir/profdir/profraw.new 'LLVM_PROFILE_FILE=%t.dir/profdir/%c%m.profraw'
17 // RUN: llvm-profdata merge -o %t.dir/profdir/profdata %t.dir/profdir/profraw.new
18 // RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/profdata | FileCheck %s -check-prefix=MERGE
19 // RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/*profraw.old | FileCheck %s -check-prefix=ZERO
21 // Test __llvm_profile_set_file_object with mergin enabled and continuous mode disabled.
22 // RUN: rm -rf %t.dir/profdir/
23 // RUN: env LLVM_PROFILE_FILE="%t.dir/profdir/%mprofraw.old" %run %t.dir/main.exe merge %t.dir/profdir/profraw.new 'LLVM_PROFILE_FILE=%t.dir/profdir/%m.profraw'
24 // RUN: llvm-profdata merge -o %t.dir/profdir/profdata %t.dir/profdir/profraw.new
25 // RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/profdata | FileCheck %s -check-prefix=MERGE
26 // RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/*profraw.old | FileCheck %s -check-prefix=ZERO
29 // MERGE: coverage_test:
30 // MERGE: Hash: {{.*}}
32 // MERGE: Function count: 32
33 // MERGE: Block counts: []
34 // MERGE: Instrumentation level: Front-end
37 // ZERO: coverage_test:
40 // ZERO: Function count: 0
41 // ZERO: Block counts: []
42 // ZERO: Instrumentation level: Front-end
48 #include <sys/types.h>
51 const int num_child_procs_to_spawn
= 32;
53 extern int __llvm_profile_is_continuous_mode_enabled(void);
54 extern int __llvm_profile_set_file_object(FILE *, int);
60 int main(int argc
, char **argv
) {
61 char *file_name
= argv
[2];
63 if (strcmp(argv
[1], "nomerge") == 0) {
64 file
= fopen(file_name
, "a+b");
65 __llvm_profile_set_file_object(file
, 0);
67 else if (strcmp(argv
[1], "merge") == 0) {
70 pid_t child_pids
[num_child_procs_to_spawn
];
71 char *const child_argv
[] = {argv
[0], "set", file_name
, NULL
};
72 char *const child_envp
[] = {argv
[3], NULL
};
73 FILE *file
= fopen(file_name
, "w+");
75 for (I
= 0; I
< num_child_procs_to_spawn
; ++I
) {
77 posix_spawn(&child_pids
[I
], argv
[0], NULL
, NULL
, child_argv
, child_envp
);
79 fprintf(stderr
, "Child %d could not be spawned: ret = %d, msg = %s\n",
80 I
, ret
, strerror(ret
));
84 for (I
= 0; I
< num_child_procs_to_spawn
; ++I
) {
86 pid_t waited_pid
= waitpid(child_pids
[I
], &status
, 0);
87 if (waited_pid
!= child_pids
[I
]) {
88 fprintf(stderr
, "Failed to wait on child %d\n", I
);
91 if (!WIFEXITED(status
)) {
92 fprintf(stderr
, "Child %d did not terminate normally\n", I
);
95 int return_status
= WEXITSTATUS(status
);
96 if (return_status
!= 0) {
97 fprintf(stderr
, "Child %d exited with non zero status %d\n", I
,
102 } else if (strcmp(argv
[1], "set") == 0) {
104 file
= fopen(file_name
, "r+b");
105 if (__llvm_profile_set_file_object(file
, 1)) {
106 fprintf(stderr
, "Call to __llvm_profile_set_file_object failed\n");
109 // After set file object, counter should be written into new file.