1// REQUIRES: target={{.*(darwin|linux|solaris|aix).*}}
2
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
6
7// RUN: %clang_profgen -fprofile-continuous -fcoverage-mapping -fprofile-update=atomic -o main.exe %s
8
9// Test continuous mode with __llvm_profile_set_file_object with mergin disabled.
10// 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
11// WARN: LLVM Profile Warning: __llvm_profile_set_file_object(fd={{[0-9]+}}) not supported in continuous sync mode when merging is disabled
12
13// Test continuous mode with __llvm_profile_set_file_object with mergin enabled.
14// RUN: rm -rf %t.dir/profdir/
15// 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'
16// RUN: llvm-profdata merge -o %t.dir/profdir/profdata %t.dir/profdir/profraw.new
17// RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/profdata | FileCheck %s -check-prefix=MERGE
18// RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/*profraw.old | FileCheck %s -check-prefix=ZERO
19
20// Test __llvm_profile_set_file_object with mergin enabled and continuous mode disabled.
21// RUN: rm -rf %t.dir/profdir/
22// 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'
23// RUN: llvm-profdata merge -o %t.dir/profdir/profdata %t.dir/profdir/profraw.new
24// RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/profdata | FileCheck %s -check-prefix=MERGE
25// RUN: llvm-profdata show --counts --all-functions %t.dir/profdir/*profraw.old | FileCheck %s -check-prefix=ZERO
26
27// MERGE: Counters:
28// MERGE: coverage_test:
29// MERGE: Hash: {{.*}}
30// MERGE: Counters: 1
31// MERGE: Function count: 32
32// MERGE: Block counts: []
33// MERGE: Instrumentation level: Front-end
34
35// ZERO: Counters:
36// ZERO: coverage_test:
37// ZERO: Hash: {{.*}}
38// ZERO: Counters: 1
39// ZERO: Function count: 0
40// ZERO: Block counts: []
41// ZERO: Instrumentation level: Front-end
42
43#include <spawn.h>
44#include <stdio.h>
45#include <string.h>
46
47#include <sys/types.h>
48#include <sys/wait.h>
49
50const int num_child_procs_to_spawn = 32;
51
52extern int __llvm_profile_is_continuous_mode_enabled(void);
53extern int __llvm_profile_set_file_object(FILE *, int);
54
55int coverage_test() {
56 return 0;
57}
58
59int main(int argc, char **argv) {
60 char *file_name = argv[2];
61 FILE *file = NULL;
62 if (strcmp(s1: argv[1], s2: "nomerge") == 0) {
63 file = fopen(filename: file_name, modes: "a+b");
64 __llvm_profile_set_file_object(file, 0);
65 }
66 else if (strcmp(s1: argv[1], s2: "merge") == 0) {
67 // Parent process.
68 int I;
69 pid_t child_pids[num_child_procs_to_spawn];
70 char *const child_argv[] = {argv[0], "set", file_name, NULL};
71 char *const child_envp[] = {argv[3], NULL};
72 FILE *file = fopen(filename: file_name, modes: "w+");
73 fclose(stream: file);
74 for (I = 0; I < num_child_procs_to_spawn; ++I) {
75 int ret =
76 posix_spawn(pid: &child_pids[I], path: argv[0], NULL, NULL, argv: child_argv, envp: child_envp);
77 if (ret != 0) {
78 fprintf(stderr, format: "Child %d could not be spawned: ret = %d, msg = %s\n",
79 I, ret, strerror(errnum: ret));
80 return 1;
81 }
82 }
83 for (I = 0; I < num_child_procs_to_spawn; ++I) {
84 int status;
85 pid_t waited_pid = waitpid(pid: child_pids[I], stat_loc: &status, options: 0);
86 if (waited_pid != child_pids[I]) {
87 fprintf(stderr, format: "Failed to wait on child %d\n", I);
88 return 1;
89 }
90 if (!WIFEXITED(status)) {
91 fprintf(stderr, format: "Child %d did not terminate normally\n", I);
92 return 1;
93 }
94 int return_status = WEXITSTATUS(status);
95 if (return_status != 0) {
96 fprintf(stderr, format: "Child %d exited with non zero status %d\n", I,
97 return_status);
98 return 1;
99 }
100 }
101 } else if (strcmp(s1: argv[1], s2: "set") == 0) {
102 // Child processes.
103 file = fopen(filename: file_name, modes: "r+b");
104 if (__llvm_profile_set_file_object(file, 1)) {
105 fprintf(stderr, format: "Call to __llvm_profile_set_file_object failed\n");
106 return 1;
107 }
108 // After set file object, counter should be written into new file.
109 coverage_test();
110 }
111 return 0;
112}
113

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of compiler-rt/test/profile/ContinuousSyncMode/set-file-object.c