1 // RUN: %clang_esan_wset -O0 %s -o %t 2>&1 2 // RUN: %env_esan_opts="verbosity=1 record_snapshots=0" %run %t %t 2>&1 | FileCheck %s 3 4 #include <assert.h> 5 #include <stdio.h> 6 #include <sys/mman.h> 7 #include <sys/resource.h> 8 #include <sys/types.h> 9 #include <sys/wait.h> 10 #include <unistd.h> 11 12 static void testChildStackLimit(rlim_t StackLimit, char *ToRun) { 13 int Res; 14 struct rlimit Limit; 15 Limit.rlim_cur = RLIM_INFINITY; 16 Limit.rlim_max = RLIM_INFINITY; 17 Res = setrlimit(RLIMIT_STACK, &Limit); 18 if (Res != 0) { 19 // Probably our environment had a large limit and we ourselves got 20 // re-execed and can no longer raise our limit. 21 // We have to bail and emulate the regular test. 22 // We'd prefer to have branches in our FileCheck output to ensure the 23 // initial program was re-execed but this is the best we can do for now. 24 fprintf(stderr, "in esan::initializeLibrary\n"); 25 fprintf(stderr, "==1234==The stack size limit is beyond the maximum supported.\n"); 26 fprintf(stderr, "Re-execing with a stack size below 1TB.\n"); 27 fprintf(stderr, "in esan::initializeLibrary\n"); 28 fprintf(stderr, "done\n"); 29 fprintf(stderr, "in esan::finalizeLibrary\n"); 30 return; 31 } 32 33 pid_t Child = fork(); 34 assert(Child >= 0); 35 if (Child > 0) { 36 pid_t WaitRes = waitpid(Child, NULL, 0); 37 assert(WaitRes == Child); 38 } else { 39 char *Args[2]; 40 Args[0] = ToRun; 41 Args[1] = NULL; 42 Res = execv(ToRun, Args); 43 assert(0); // Should not be reached. 44 } 45 } 46 47 int main(int argc, char *argv[]) { 48 // The path to the program to exec must be passed in the first time. 49 if (argc == 2) { 50 fprintf(stderr, "Testing child with infinite stack\n"); 51 testChildStackLimit(RLIM_INFINITY, argv[1]); 52 fprintf(stderr, "Testing child with 1TB stack\n"); 53 testChildStackLimit(1ULL << 40, argv[1]); 54 } 55 fprintf(stderr, "done\n"); 56 // CHECK: in esan::initializeLibrary 57 // CHECK: Testing child with infinite stack 58 // CHECK-NEXT: in esan::initializeLibrary 59 // CHECK-NEXT: =={{[0-9]+}}==The stack size limit is beyond the maximum supported. 60 // CHECK-NEXT: Re-execing with a stack size below 1TB. 61 // CHECK-NEXT: in esan::initializeLibrary 62 // CHECK: done 63 // CHECK: in esan::finalizeLibrary 64 // CHECK: Testing child with 1TB stack 65 // CHECK-NEXT: in esan::initializeLibrary 66 // CHECK-NEXT: =={{[0-9]+}}==The stack size limit is beyond the maximum supported. 67 // CHECK-NEXT: Re-execing with a stack size below 1TB. 68 // CHECK-NEXT: in esan::initializeLibrary 69 // CHECK: done 70 // CHECK-NEXT: in esan::finalizeLibrary 71 // CHECK: done 72 // CHECK-NEXT: in esan::finalizeLibrary 73 return 0; 74 } 75