blob: 9c42817776f95adcdee808b6b802f8d43bb78b53 [file] [log] [blame]
Stephen Hines6d186232014-11-26 17:56:19 -08001// Test caller-callee coverage with large number of threads
2// and various numbers of callers and callees.
3
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -07004// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t
5// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 10 1 2>&1 | FileCheck %s --check-prefix=CHECK-10-1
6// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 9 2 2>&1 | FileCheck %s --check-prefix=CHECK-9-2
7// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 7 3 2>&1 | FileCheck %s --check-prefix=CHECK-7-3
8// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 17 1 2>&1 | FileCheck %s --check-prefix=CHECK-17-1
9// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 15 2 2>&1 | FileCheck %s --check-prefix=CHECK-15-2
10// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 18 3 2>&1 | FileCheck %s --check-prefix=CHECK-18-3
Stephen Hines6d186232014-11-26 17:56:19 -080011// RUN: rm -f caller-callee*.sancov
12//
13// REQUIRES: asan-64-bits
14//
15// CHECK-10-1: CovDump: 10 caller-callee pairs written
16// CHECK-9-2: CovDump: 18 caller-callee pairs written
17// CHECK-7-3: CovDump: 21 caller-callee pairs written
18// CHECK-17-1: CovDump: 14 caller-callee pairs written
19// CHECK-15-2: CovDump: 28 caller-callee pairs written
20// CHECK-18-3: CovDump: 42 caller-callee pairs written
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <pthread.h>
25int P = 0;
26struct Foo {virtual void f() {if (P) printf("Foo::f()\n");}};
27struct Foo1 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
28struct Foo2 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
29struct Foo3 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
30struct Foo4 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
31struct Foo5 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
32struct Foo6 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
33struct Foo7 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
34struct Foo8 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
35struct Foo9 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
36struct Foo10 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
37struct Foo11 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
38struct Foo12 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
39struct Foo13 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
40struct Foo14 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
41struct Foo15 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
42struct Foo16 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
43struct Foo17 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
44struct Foo18 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
45struct Foo19 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
46
47Foo *foo[20] = {
48 new Foo, new Foo1, new Foo2, new Foo3, new Foo4, new Foo5, new Foo6,
49 new Foo7, new Foo8, new Foo9, new Foo10, new Foo11, new Foo12, new Foo13,
50 new Foo14, new Foo15, new Foo16, new Foo17, new Foo18, new Foo19,
51};
52
53int n_functions = 10;
54int n_callers = 2;
55
56void *Thread(void *arg) {
57 if (n_callers >= 1) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f();
58 if (n_callers >= 2) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f();
59 if (n_callers >= 3) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f();
60 return arg;
61}
62
63int main(int argc, char **argv) {
64 if (argc >= 2)
65 n_functions = atoi(argv[1]);
66 if (argc >= 3)
67 n_callers = atoi(argv[2]);
68 const int kNumThreads = 16;
69 pthread_t t[kNumThreads];
70 for (int i = 0; i < kNumThreads; i++)
71 pthread_create(&t[i], 0, Thread, 0);
72 for (int i = 0; i < kNumThreads; i++)
73 pthread_join(t[i], 0);
74}