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