79 lines · cpp
1// Most Windows linkers set stack size default to 1 MB. Bump it up to 8 MB.2// DEFINE: %{stack} = %if target={{.*-windows-gnu}} %{ -Wl,--stack,8388608 %} \3// DEFINE: %if target={{.*-windows-msvc.*}} %{ -Wl,/STACK:8388608 %}4 5// RUN: %clangxx_asan %{stack} -O0 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s6// RUN: %clangxx_asan %{stack} -O2 %s -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s7// RUN: %clangxx_asan %{stack} -O0 %s -o %t -fsanitize-address-use-after-return=always && not %run %t 2>&1 | FileCheck %s8// RUN: %clangxx_asan %{stack} -O2 %s -o %t -fsanitize-address-use-after-return=always && not %run %t 2>&1 | FileCheck %s9 10// FIXME: Fix this test under GCC.11// REQUIRES: Clang12 13// FIXME: Fix this test for dynamic runtime on arm linux.14// UNSUPPORTED: (arm-linux || armhf-linux) && asan-dynamic-runtime15 16// UNSUPPORTED: ios17 18#include "defines.h"19#include <stdio.h>20#include <stdlib.h>21#include <string.h>22#ifdef _WIN3223# include <windows.h>24#endif25 26ATTRIBUTE_NOINLINE27char *pretend_to_do_something(char *x) {28 __asm__ __volatile__("" : : "r" (x) : "memory");29 return x;30}31 32ATTRIBUTE_NOINLINE33char *LeakStack() {34 char x[1024];35 memset(x, 0, sizeof(x));36 return pretend_to_do_something(x);37}38 39template <size_t kFrameSize>40ATTRIBUTE_NOINLINE void RecursiveFunctionWithStackFrame(int depth) {41 if (depth <= 0) return;42 char x[kFrameSize];43 x[0] = depth;44 pretend_to_do_something(x);45 RecursiveFunctionWithStackFrame<kFrameSize>(depth - 1);46}47 48int main(int argc, char **argv) {49#ifdef _WIN3250 // Prevent the crash dialog from showing in case something bad like a stack51 // overflow happens.52 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);53#endif54 55 int n_iter = argc >= 2 ? atoi(argv[1]) : 1000;56 int depth = argc >= 3 ? atoi(argv[2]) : 500;57 for (int i = 0; i < n_iter; i++) {58 RecursiveFunctionWithStackFrame<10>(depth);59 RecursiveFunctionWithStackFrame<100>(depth);60 RecursiveFunctionWithStackFrame<500>(depth);61 RecursiveFunctionWithStackFrame<1024>(depth);62 RecursiveFunctionWithStackFrame<2000>(depth);63 // The stack size is tight for the main thread in multithread64 // environment on FreeBSD and NetBSD.65#if !defined(__FreeBSD__) && !defined(__NetBSD__)66 RecursiveFunctionWithStackFrame<5000>(depth);67 RecursiveFunctionWithStackFrame<10000>(depth);68#endif69 }70 char *stale_stack = LeakStack();71 RecursiveFunctionWithStackFrame<1024>(10);72 stale_stack[100]++;73 // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address74 // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame75 // CHECK: in LeakStack{{.*}}heavy_uar_test.cpp:76 // CHECK: [{{16|32}}, {{1040|1056}}) 'x'77 return 0;78}79