1799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s 2799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s 3799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar// XFAIL: arm-linux-gnueabi,win32 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FIXME: Fix this test under GCC. 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// REQUIRES: Clang 72c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany 82c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany#include <stdio.h> 92c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany#include <string.h> 1037f9464fc0fa4df2acf04264c52ba542d0e3d3fbKostya Serebryany#include <stdlib.h> 112c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany 122c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany__attribute__((noinline)) 1371c9e9ebd85afdea5d0b56cdf9138fc5afc609cbKostya Serebryanychar *pretend_to_do_something(char *x) { 142c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany __asm__ __volatile__("" : : "r" (x) : "memory"); 152c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany return x; 162c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany} 172c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany 182c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany__attribute__((noinline)) 192c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryanychar *LeakStack() { 202c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany char x[1024]; 212c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany memset(x, 0, sizeof(x)); 222c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany return pretend_to_do_something(x); 232c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany} 242c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany 25fecbf270853bda8aa6c14917fdfee840493a061bKostya Serebryanytemplate<size_t kFrameSize> 262c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany__attribute__((noinline)) 2786277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid RecursiveFunctionWithStackFrame(int depth) { 282c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany if (depth <= 0) return; 29fecbf270853bda8aa6c14917fdfee840493a061bKostya Serebryany char x[kFrameSize]; 3071c9e9ebd85afdea5d0b56cdf9138fc5afc609cbKostya Serebryany x[0] = depth; 312c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany pretend_to_do_something(x); 3286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<kFrameSize>(depth - 1); 332c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany} 342c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany 352c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryanyint main(int argc, char **argv) { 36799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#ifdef _MSC_VER 37799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // FIXME: This test crashes on Windows and raises a dialog. Avoid running it 38799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar // in addition to XFAILing it. 39799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar return 42; 40799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar#endif 41799172d60d32feb1acba1a6867f3a9c39a999e5cPirama Arumuga Nainar 4237f9464fc0fa4df2acf04264c52ba542d0e3d3fbKostya Serebryany int n_iter = argc >= 2 ? atoi(argv[1]) : 1000; 4371c9e9ebd85afdea5d0b56cdf9138fc5afc609cbKostya Serebryany int depth = argc >= 3 ? atoi(argv[2]) : 500; 44fecbf270853bda8aa6c14917fdfee840493a061bKostya Serebryany for (int i = 0; i < n_iter; i++) { 4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<10>(depth); 4686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<100>(depth); 4786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<500>(depth); 4886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<1024>(depth); 4986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<2000>(depth); 5086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // The stack size is tight for the main thread in multithread 5186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // environment on FreeBSD. 5286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if !defined(__FreeBSD__) 5386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<5000>(depth); 5486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<10000>(depth); 5586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif 56fecbf270853bda8aa6c14917fdfee840493a061bKostya Serebryany } 5771c9e9ebd85afdea5d0b56cdf9138fc5afc609cbKostya Serebryany char *stale_stack = LeakStack(); 5886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines RecursiveFunctionWithStackFrame<1024>(10); 592c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany stale_stack[100]++; 602c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address 612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame 6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // CHECK: in LeakStack{{.*}}heavy_uar_test.cc: 632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK: [{{16|32}}, {{1040|1056}}) 'x' 642c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany return 0; 652c02f6327f51243fc0ba17992cecb2857fa8bdf8Kostya Serebryany} 66