1 // Check that indirect call hash tables properly register multiple calls,
2 // and that calls from different processes don't get mixed up when using
3 // --instrumentation-file-append-pid.
9 __attribute__((noinline
)) void funcA(int pid
) { printf("funcA %d\n", pid
); }
10 __attribute__((noinline
)) void funcB(int pid
) { printf("funcB %d\n", pid
); }
11 __attribute__((noinline
)) void funcC(int pid
) { printf("funcC %d\n", pid
); }
12 __attribute__((noinline
)) void funcD(int pid
) { printf("funcD %d\n", pid
); }
13 __attribute__((noinline
)) void funcE(int pid
) { printf("funcE %d\n", pid
); }
14 __attribute__((noinline
)) void funcF(int pid
) { printf("funcF %d\n", pid
); }
15 __attribute__((noinline
)) void funcG(int pid
) { printf("funcG %d\n", pid
); }
16 __attribute__((noinline
)) void funcH(int pid
) { printf("funcH %d\n", pid
); }
17 __attribute__((noinline
)) void funcI(int pid
) { printf("funcI %d\n", pid
); }
18 __attribute__((noinline
)) void funcJ(int pid
) { printf("funcJ %d\n", pid
); }
19 __attribute__((noinline
)) void funcK(int pid
) { printf("funcK %d\n", pid
); }
20 __attribute__((noinline
)) void funcL(int pid
) { printf("funcL %d\n", pid
); }
21 __attribute__((noinline
)) void funcM(int pid
) { printf("funcM %d\n", pid
); }
22 __attribute__((noinline
)) void funcN(int pid
) { printf("funcN %d\n", pid
); }
23 __attribute__((noinline
)) void funcO(int pid
) { printf("funcO %d\n", pid
); }
24 __attribute__((noinline
)) void funcP(int pid
) { printf("funcP %d\n", pid
); }
28 void (*funcs
[])(int) = {funcA
, funcB
, funcC
, funcD
, funcE
, funcF
,
29 funcG
, funcH
, funcI
, funcJ
, funcK
, funcL
,
30 funcM
, funcN
, funcO
, funcP
};
35 printf("Failed to fork!\n");
46 for (; i
< sizeof(funcs
) / sizeof(void *); i
+= 2) {
53 REQUIRES: system-linux,shell,fuser
55 RUN: %clang %cflags %s -o %t.exe -Wl,-q -pie -fpie
57 RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \
58 RUN: --conservative-instrumentation -o %t.instrumented_conservative \
59 RUN: --instrumentation-sleep-time=1 --instrumentation-no-counters-clear \
60 RUN: --instrumentation-wait-forks
62 # Instrumented program needs to finish returning zero
63 # Both output and profile must contain all 16 functions
64 RUN: %t.instrumented_conservative > %t.output
65 # Wait for profile and output to be fully written
66 RUN: bash %S/wait_file.sh %t.output
67 RUN: bash %S/wait_file.sh %t.fdata
68 RUN: cat %t.output | FileCheck %s --check-prefix=CHECK-OUTPUT
69 RUN: cat %t.fdata | FileCheck %s --check-prefix=CHECK-COMMON-PROF
71 CHECK-OUTPUT-DAG: funcA
72 CHECK-OUTPUT-DAG: funcB
73 CHECK-OUTPUT-DAG: funcC
74 CHECK-OUTPUT-DAG: funcD
75 CHECK-OUTPUT-DAG: funcE
76 CHECK-OUTPUT-DAG: funcF
77 CHECK-OUTPUT-DAG: funcG
78 CHECK-OUTPUT-DAG: funcH
79 CHECK-OUTPUT-DAG: funcI
80 CHECK-OUTPUT-DAG: funcJ
81 CHECK-OUTPUT-DAG: funcK
82 CHECK-OUTPUT-DAG: funcL
83 CHECK-OUTPUT-DAG: funcM
84 CHECK-OUTPUT-DAG: funcN
85 CHECK-OUTPUT-DAG: funcO
86 CHECK-OUTPUT-DAG: funcP
88 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcA 0 0 1
89 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcB 0 0 1
90 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcC 0 0 1
91 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcD 0 0 1
92 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcE 0 0 1
93 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcF 0 0 1
94 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcG 0 0 1
95 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcH 0 0 1
96 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcI 0 0 1
97 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcJ 0 0 1
98 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcK 0 0 1
99 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcL 0 0 1
100 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcM 0 0 1
101 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcN 0 0 1
102 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcO 0 0 1
103 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcP 0 0 1
105 RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t \
106 RUN: --instrumentation-file-append-pid \
107 RUN: -o %t.instrumented
109 RUN: %t.instrumented > %t.output
110 # Wait till output is fully written in case child outlives parent
111 RUN: bash %S/wait_file.sh %t.output
112 # Make sure all functions were called
113 RUN: cat %t.output | FileCheck %s --check-prefix=CHECK-OUTPUT
115 RUN: child_pid=$(cat %t.output | grep funcA | awk '{print $2;}')
116 RUN: par_pid=$(cat %t.output | grep funcB | awk '{print $2;}')
118 RUN: bash %S/wait_file.sh %t.$child_pid.fdata
119 RUN: bash %S/wait_file.sh %t.$par_pid.fdata
121 RUN: mv %t.$child_pid.fdata %t.child.fdata
122 RUN: mv %t.$par_pid.fdata %t.parent.fdata
124 # Instrumented binary must produce two profiles with only local calls
125 # recorded. Functions called only in child should not appear in parent's
126 # process and vice versa.
127 RUN: cat %t.child.fdata | FileCheck %s --check-prefix=CHECK-CHILD
128 RUN: cat %t.child.fdata | FileCheck %s --check-prefix=CHECK-NOCHILD
129 RUN: cat %t.parent.fdata | FileCheck %s --check-prefix=CHECK-PARENT
130 RUN: cat %t.parent.fdata | FileCheck %s --check-prefix=CHECK-NOPARENT
132 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcA 0 0 1
133 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcC 0 0 1
134 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcE 0 0 1
135 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcG 0 0 1
136 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcI 0 0 1
137 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcK 0 0 1
138 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcM 0 0 1
139 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcO 0 0 1
141 CHECK-NOCHILD-NOT: funcB
142 CHECK-NOCHILD-NOT: funcD
143 CHECK-NOCHILD-NOT: funcF
144 CHECK-NOCHILD-NOT: funcH
145 CHECK-NOCHILD-NOT: funcJ
146 CHECK-NOCHILD-NOT: funcL
147 CHECK-NOCHILD-NOT: funcN
148 CHECK-NOCHILD-NOT: funcP
150 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcB 0 0 1
151 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcD 0 0 1
152 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcF 0 0 1
153 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcH 0 0 1
154 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcJ 0 0 1
155 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcL 0 0 1
156 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcN 0 0 1
157 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcP 0 0 1
159 CHECK-NOPARENT-NOT: funcA
160 CHECK-NOPARENT-NOT: funcC
161 CHECK-NOPARENT-NOT: funcE
162 CHECK-NOPARENT-NOT: funcG
163 CHECK-NOPARENT-NOT: funcI
164 CHECK-NOPARENT-NOT: funcK
165 CHECK-NOPARENT-NOT: funcM
166 CHECK-NOPARENT-NOT: funcO