stack-overflow.cc revision 86277eb844c4983c81de62d7c050e92fe7155788
1// Test ASan detection of stack-overflow condition. 2 3// RUN: %clangxx_asan -O0 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 4// RUN: %clangxx_asan -O3 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=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_OPTIONS=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_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 7// RUN: %clangxx_asan -O0 %s -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 8// RUN: %clangxx_asan -O3 %s -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 9 10// RUN: %clangxx_asan -O0 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 11// RUN: %clangxx_asan -O3 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=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_OPTIONS=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_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 14// RUN: %clangxx_asan -O0 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 15// RUN: %clangxx_asan -O3 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s 16// RUN: not %run %t 2>&1 | FileCheck %s 17// REQUIRES: stable-runtime 18 19#include <assert.h> 20#include <stdlib.h> 21#include <pthread.h> 22#include <unistd.h> 23#include <sys/time.h> 24#include <sys/resource.h> 25#include <sanitizer/asan_interface.h> 26 27const int BS = 1024; 28volatile char x; 29volatile int y = 1; 30volatile int z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13; 31 32void recursive_func(char *p) { 33#if defined(SMALL_FRAME) 34 char *buf = 0; 35#elif defined(SAVE_ALL_THE_REGISTERS) 36 char *buf = 0; 37 int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13; 38 t0 = z0; 39 t1 = z1; 40 t2 = z2; 41 t3 = z3; 42 t4 = z4; 43 t5 = z5; 44 t6 = z6; 45 t7 = z7; 46 t8 = z8; 47 t9 = z9; 48 t10 = z10; 49 t11 = z11; 50 t12 = z12; 51 t13 = z13; 52 53 z0 = t0; 54 z1 = t1; 55 z2 = t2; 56 z3 = t3; 57 z4 = t4; 58 z5 = t5; 59 z6 = t6; 60 z7 = t7; 61 z8 = t8; 62 z9 = t9; 63 z10 = t10; 64 z11 = t11; 65 z12 = t12; 66 z13 = t13; 67#else 68 char buf[BS]; 69 // Check that the stack grows in the righ direction, unless we use fake stack. 70 if (p && !__asan_get_current_fake_stack()) 71 assert(p - buf >= BS); 72 buf[rand() % BS] = 1; 73 buf[rand() % BS] = 2; 74 x = buf[rand() % BS]; 75#endif 76 if (y) 77 recursive_func(buf); 78 x = 1; // prevent tail call optimization 79 // CHECK: {{stack-overflow on address 0x.* \(pc 0x.* bp 0x.* sp 0x.* T.*\)}} 80 // If stack overflow happens during function prologue, stack trace may be 81 // corrupted. Unwind tables are not always 100% exact there. 82 // For this reason, we don't do any further checks. 83} 84 85void *ThreadFn(void* unused) { 86 recursive_func(0); 87 return 0; 88} 89 90void LimitStackAndReexec(int argc, char **argv) { 91 struct rlimit rlim; 92 int res = getrlimit(RLIMIT_STACK, &rlim); 93 assert(res == 0); 94 if (rlim.rlim_cur == RLIM_INFINITY) { 95 rlim.rlim_cur = 256 * 1024; 96 res = setrlimit(RLIMIT_STACK, &rlim); 97 assert(res == 0); 98 99 execv(argv[0], argv); 100 assert(0 && "unreachable"); 101 } 102} 103 104int main(int argc, char **argv) { 105 LimitStackAndReexec(argc, argv); 106#ifdef THREAD 107 pthread_t t; 108 pthread_create(&t, 0, ThreadFn, 0); 109 pthread_join(t, 0); 110#else 111 recursive_func(0); 112#endif 113 return 0; 114} 115