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)) 34char *Ident(char *x) { 35 fprintf(stderr, "1: %p\n", x); 36 return x; 37} 38 39__attribute__((noinline)) 40char *Func1() { 41 char local[kSize]; 42 return Ident(local); 43} 44 45__attribute__((noinline)) 46void 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 61void *Thread(void *unused) { 62 Func2(Func1()); 63 return NULL; 64} 65 66int 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