1 // Test ASan detection of stack-overflow condition.
3 // RUN: %clangxx_asan -O0 %s -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
4 // RUN: %clangxx_asan -O3 %s -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
5 // RUN: %clangxx_asan -O0 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
6 // RUN: %clangxx_asan -O3 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
7 // RUN: %clangxx_asan -O0 %s -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
8 // RUN: %clangxx_asan -O3 %s -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
10 // RUN: %clangxx_asan -O0 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
11 // RUN: %clangxx_asan -O3 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
12 // RUN: %clangxx_asan -O0 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
13 // RUN: %clangxx_asan -O3 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
14 // RUN: %clangxx_asan -O0 %s -DTHREAD -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
15 // RUN: %clangxx_asan -O3 %s -DTHREAD -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s
16 // RUN: not %run %t 2>&1 | FileCheck %s
17 // REQUIRES: stable-runtime
20 // XFAIL: target={{sparc.*-.*-linux.*}}
29 #include <sys/resource.h>
30 #include <sanitizer/asan_interface.h>
35 volatile int z0
, z1
, z2
, z3
, z4
, z5
, z6
, z7
, z8
, z9
, z10
, z11
, z12
, z13
;
37 void recursive_func(uintptr_t parent_frame_address
) {
38 #if defined(SMALL_FRAME)
40 #elif defined(SAVE_ALL_THE_REGISTERS)
42 int t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
, t8
, t9
, t10
, t11
, t12
, t13
;
74 // Check that the stack grows in the righ direction, unless we use fake stack.
75 assert(parent_frame_address
> (uintptr_t)__builtin_frame_address(0));
81 recursive_func((uintptr_t)__builtin_frame_address(0));
82 x
= 1; // prevent tail call optimization
83 // CHECK: {{stack-overflow on address 0x.* \(pc 0x.* bp 0x.* sp 0x.* T.*\)}}
84 // If stack overflow happens during function prologue, stack trace may be
85 // corrupted. Unwind tables are not always 100% exact there.
86 // For this reason, we don't do any further checks.
89 void *ThreadFn(void* unused
) {
90 recursive_func((uintptr_t)__builtin_frame_address(0));
94 void LimitStackAndReexec(int argc
, char **argv
) {
96 int res
= getrlimit(RLIMIT_STACK
, &rlim
);
98 if (rlim
.rlim_cur
== RLIM_INFINITY
) {
99 rlim
.rlim_cur
= 256 * 1024;
100 res
= setrlimit(RLIMIT_STACK
, &rlim
);
103 execv(argv
[0], argv
);
104 assert(0 && "unreachable");
108 int main(int argc
, char **argv
) {
109 LimitStackAndReexec(argc
, argv
);
112 pthread_create(&t
, 0, ThreadFn
, 0);
115 recursive_func((uintptr_t)__builtin_frame_address(0));