1 // RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s 2 // RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s 3 // XFAIL: windows-msvc 4 5 // FIXME: Fix this test under GCC. 6 // REQUIRES: Clang 7 8 // FIXME: Fix this test for dynamic runtime on arm linux. 9 // UNSUPPORTED: (arm-linux || armhf-linux) && asan-dynamic-runtime 10 11 // UNSUPPORTED: ios 12 13 #include <stdio.h> 14 #include <string.h> 15 #include <stdlib.h> 16 17 __attribute__((noinline)) pretend_to_do_something(char * x)18char *pretend_to_do_something(char *x) { 19 __asm__ __volatile__("" : : "r" (x) : "memory"); 20 return x; 21 } 22 23 __attribute__((noinline)) LeakStack()24char *LeakStack() { 25 char x[1024]; 26 memset(x, 0, sizeof(x)); 27 return pretend_to_do_something(x); 28 } 29 30 template<size_t kFrameSize> 31 __attribute__((noinline)) RecursiveFunctionWithStackFrame(int depth)32void RecursiveFunctionWithStackFrame(int depth) { 33 if (depth <= 0) return; 34 char x[kFrameSize]; 35 x[0] = depth; 36 pretend_to_do_something(x); 37 RecursiveFunctionWithStackFrame<kFrameSize>(depth - 1); 38 } 39 main(int argc,char ** argv)40int main(int argc, char **argv) { 41 #ifdef _MSC_VER 42 // FIXME: This test crashes on Windows and raises a dialog. Avoid running it 43 // in addition to XFAILing it. 44 return 42; 45 #endif 46 47 int n_iter = argc >= 2 ? atoi(argv[1]) : 1000; 48 int depth = argc >= 3 ? atoi(argv[2]) : 500; 49 for (int i = 0; i < n_iter; i++) { 50 RecursiveFunctionWithStackFrame<10>(depth); 51 RecursiveFunctionWithStackFrame<100>(depth); 52 RecursiveFunctionWithStackFrame<500>(depth); 53 RecursiveFunctionWithStackFrame<1024>(depth); 54 RecursiveFunctionWithStackFrame<2000>(depth); 55 // The stack size is tight for the main thread in multithread 56 // environment on FreeBSD and NetBSD. 57 #if !defined(__FreeBSD__) && !defined(__NetBSD__) 58 RecursiveFunctionWithStackFrame<5000>(depth); 59 RecursiveFunctionWithStackFrame<10000>(depth); 60 #endif 61 } 62 char *stale_stack = LeakStack(); 63 RecursiveFunctionWithStackFrame<1024>(10); 64 stale_stack[100]++; 65 // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address 66 // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame 67 // CHECK: in LeakStack{{.*}}heavy_uar_test.cpp: 68 // CHECK: [{{16|32}}, {{1040|1056}}) 'x' 69 return 0; 70 } 71