Home | History | Annotate | Download | only in Posix
      1 // RUN: %clangxx_asan  -O0 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
      2 // RUN: %clangxx_asan  -O1 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
      3 // RUN: %clangxx_asan  -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
      4 // RUN: %clangxx_asan  -O3 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
      5 // RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t
      6 // Regression test for a CHECK failure with small stack size and large frame.
      7 // RUN: %clangxx_asan  -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=65536 && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
      8 //
      9 // Test that we can find UAR in a thread other than main:
     10 // RUN: %clangxx_asan  -DUseThread -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s
     11 //
     12 // Test the max_uar_stack_size_log/min_uar_stack_size_log flag.
     13 //
     14 // RUN: %env_asan_opts=detect_stack_use_after_return=1:max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s
     15 // RUN: %env_asan_opts=detect_stack_use_after_return=1:min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s
     16 
     17 #include <stdio.h>
     18 #include <pthread.h>
     19 
     20 #ifndef kSize
     21 # define kSize 1
     22 #endif
     23 
     24 #ifndef UseThread
     25 # define UseThread 0
     26 #endif
     27 
     28 #ifndef kStackSize
     29 # define kStackSize 0
     30 #endif
     31 
     32 __attribute__((noinline))
     33 char *Ident(char *x) {
     34   fprintf(stderr, "1: %p\n", x);
     35   return x;
     36 }
     37 
     38 __attribute__((noinline))
     39 char *Func1() {
     40   char local[kSize];
     41   return Ident(local);
     42 }
     43 
     44 __attribute__((noinline))
     45 void Func2(char *x) {
     46   fprintf(stderr, "2: %p\n", x);
     47   *x = 1;
     48   // CHECK: WRITE of size 1 {{.*}} thread T0
     49   // CHECK:     #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-2]]
     50   // CHECK: is located in stack of thread T0 at offset
     51   // CHECK: 'local' <== Memory access at offset {{16|32}} is inside this variable
     52   // THREAD: WRITE of size 1 {{.*}} thread T{{[1-9]}}
     53   // THREAD:     #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-6]]
     54   // THREAD: is located in stack of thread T{{[1-9]}} at offset
     55   // THREAD: 'local' <== Memory access at offset {{16|32}} is inside this variable
     56   // CHECK-20: T0: FakeStack created:{{.*}} stack_size_log: 20
     57   // CHECK-24: T0: FakeStack created:{{.*}} stack_size_log: 24
     58 }
     59 
     60 void *Thread(void *unused)  {
     61   Func2(Func1());
     62   return NULL;
     63 }
     64 
     65 int main(int argc, char **argv) {
     66 #if UseThread
     67   pthread_attr_t attr;
     68   pthread_attr_init(&attr);
     69   if (kStackSize > 0)
     70     pthread_attr_setstacksize(&attr, kStackSize);
     71   pthread_t t;
     72   pthread_create(&t, &attr, Thread, 0);
     73   pthread_attr_destroy(&attr);
     74   pthread_join(t, 0);
     75 #else
     76   Func2(Func1());
     77 #endif
     78   return 0;
     79 }
     80