blob: 8338f808539e0238e63f05b4543c4660d4a0e22b [file] [log] [blame]
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -08001// 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: arm-linux-gnueabi,win32
Stephen Hines2d1fdb22014-05-28 23:58:16 -07004
5// FIXME: Fix this test under GCC.
6// REQUIRES: Clang
Stephen Hines2d1fdb22014-05-28 23:58:16 -07007
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11
12__attribute__((noinline))
13char *pretend_to_do_something(char *x) {
14 __asm__ __volatile__("" : : "r" (x) : "memory");
15 return x;
16}
17
18__attribute__((noinline))
19char *LeakStack() {
20 char x[1024];
21 memset(x, 0, sizeof(x));
22 return pretend_to_do_something(x);
23}
24
25template<size_t kFrameSize>
26__attribute__((noinline))
Stephen Hines86277eb2015-03-23 12:06:32 -070027void RecursiveFunctionWithStackFrame(int depth) {
Stephen Hines2d1fdb22014-05-28 23:58:16 -070028 if (depth <= 0) return;
29 char x[kFrameSize];
30 x[0] = depth;
31 pretend_to_do_something(x);
Stephen Hines86277eb2015-03-23 12:06:32 -070032 RecursiveFunctionWithStackFrame<kFrameSize>(depth - 1);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070033}
34
35int main(int argc, char **argv) {
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080036#ifdef _MSC_VER
37 // FIXME: This test crashes on Windows and raises a dialog. Avoid running it
38 // in addition to XFAILing it.
39 return 42;
40#endif
41
Stephen Hines2d1fdb22014-05-28 23:58:16 -070042 int n_iter = argc >= 2 ? atoi(argv[1]) : 1000;
43 int depth = argc >= 3 ? atoi(argv[2]) : 500;
44 for (int i = 0; i < n_iter; i++) {
Stephen Hines86277eb2015-03-23 12:06:32 -070045 RecursiveFunctionWithStackFrame<10>(depth);
46 RecursiveFunctionWithStackFrame<100>(depth);
47 RecursiveFunctionWithStackFrame<500>(depth);
48 RecursiveFunctionWithStackFrame<1024>(depth);
49 RecursiveFunctionWithStackFrame<2000>(depth);
50 // The stack size is tight for the main thread in multithread
51 // environment on FreeBSD.
52#if !defined(__FreeBSD__)
53 RecursiveFunctionWithStackFrame<5000>(depth);
54 RecursiveFunctionWithStackFrame<10000>(depth);
55#endif
Stephen Hines2d1fdb22014-05-28 23:58:16 -070056 }
57 char *stale_stack = LeakStack();
Stephen Hines86277eb2015-03-23 12:06:32 -070058 RecursiveFunctionWithStackFrame<1024>(10);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070059 stale_stack[100]++;
60 // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address
61 // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame
Stephen Hines86277eb2015-03-23 12:06:32 -070062 // CHECK: in LeakStack{{.*}}heavy_uar_test.cc:
Stephen Hines2d1fdb22014-05-28 23:58:16 -070063 // CHECK: [{{16|32}}, {{1040|1056}}) 'x'
64 return 0;
65}