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