Home | History | Annotate | Download | only in TestCases
      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 
     26 const int BS = 1024;
     27 volatile char x;
     28 volatile int y = 1;
     29 volatile int z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13;
     30 
     31 void recursive_func(char *p) {
     32 #if defined(SMALL_FRAME)
     33   char *buf = 0;
     34 #elif defined(SAVE_ALL_THE_REGISTERS)
     35   char *buf = 0;
     36   int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13;
     37   t0 = z0;
     38   t1 = z1;
     39   t2 = z2;
     40   t3 = z3;
     41   t4 = z4;
     42   t5 = z5;
     43   t6 = z6;
     44   t7 = z7;
     45   t8 = z8;
     46   t9 = z9;
     47   t10 = z10;
     48   t11 = z11;
     49   t12 = z12;
     50   t13 = z13;
     51 
     52   z0 = t0;
     53   z1 = t1;
     54   z2 = t2;
     55   z3 = t3;
     56   z4 = t4;
     57   z5 = t5;
     58   z6 = t6;
     59   z7 = t7;
     60   z8 = t8;
     61   z9 = t9;
     62   z10 = t10;
     63   z11 = t11;
     64   z12 = t12;
     65   z13 = t13;
     66 #else
     67   char buf[BS];
     68   if (p)
     69     assert(p - buf >= BS);
     70   buf[rand() % BS] = 1;
     71   buf[rand() % BS] = 2;
     72   x = buf[rand() % BS];
     73 #endif
     74   if (y)
     75     recursive_func(buf);
     76   x = 1; // prevent tail call optimization
     77   // CHECK: {{stack-overflow on address 0x.* \(pc 0x.* sp 0x.* bp 0x.* T.*\)}}
     78   // If stack overflow happens during function prologue, stack trace may be
     79   // corrupted. Unwind tables are not always 100% exact there.
     80   // For this reason, we don't do any further checks.
     81 }
     82 
     83 void *ThreadFn(void* unused) {
     84   recursive_func(0);
     85   return 0;
     86 }
     87 
     88 void LimitStackAndReexec(int argc, char **argv) {
     89   struct rlimit rlim;
     90   int res = getrlimit(RLIMIT_STACK, &rlim);
     91   assert(res == 0);
     92   if (rlim.rlim_cur == RLIM_INFINITY) {
     93     rlim.rlim_cur = 128 * 1024;
     94     res = setrlimit(RLIMIT_STACK, &rlim);
     95     assert(res == 0);
     96 
     97     execv(argv[0], argv);
     98     assert(0 && "unreachable");
     99   }
    100 }
    101 
    102 int main(int argc, char **argv) {
    103   LimitStackAndReexec(argc, argv);
    104 #ifdef THREAD
    105   pthread_t t;
    106   pthread_create(&t, 0, ThreadFn, 0);
    107   pthread_join(t, 0);
    108 #else
    109   recursive_func(0);
    110 #endif
    111   return 0;
    112 }
    113