aboutsummaryrefslogtreecommitdiff
path: root/test/esan/TestCases/large-stack-linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/esan/TestCases/large-stack-linux.c')
-rw-r--r--test/esan/TestCases/large-stack-linux.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/test/esan/TestCases/large-stack-linux.c b/test/esan/TestCases/large-stack-linux.c
new file mode 100644
index 000000000000..3e024fc4e900
--- /dev/null
+++ b/test/esan/TestCases/large-stack-linux.c
@@ -0,0 +1,74 @@
+// RUN: %clang_esan_wset -O0 %s -o %t 2>&1
+// RUN: %env_esan_opts="verbosity=1 record_snapshots=0" %run %t %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+static void testChildStackLimit(rlim_t StackLimit, char *ToRun) {
+ int Res;
+ struct rlimit Limit;
+ Limit.rlim_cur = RLIM_INFINITY;
+ Limit.rlim_max = RLIM_INFINITY;
+ Res = setrlimit(RLIMIT_STACK, &Limit);
+ if (Res != 0) {
+ // Probably our environment had a large limit and we ourselves got
+ // re-execed and can no longer raise our limit.
+ // We have to bail and emulate the regular test.
+ // We'd prefer to have branches in our FileCheck output to ensure the
+ // initial program was re-execed but this is the best we can do for now.
+ fprintf(stderr, "in esan::initializeLibrary\n");
+ fprintf(stderr, "==1234==The stack size limit is beyond the maximum supported.\n");
+ fprintf(stderr, "Re-execing with a stack size below 1TB.\n");
+ fprintf(stderr, "in esan::initializeLibrary\n");
+ fprintf(stderr, "done\n");
+ fprintf(stderr, "in esan::finalizeLibrary\n");
+ return;
+ }
+
+ pid_t Child = fork();
+ assert(Child >= 0);
+ if (Child > 0) {
+ pid_t WaitRes = waitpid(Child, NULL, 0);
+ assert(WaitRes == Child);
+ } else {
+ char *Args[2];
+ Args[0] = ToRun;
+ Args[1] = NULL;
+ Res = execv(ToRun, Args);
+ assert(0); // Should not be reached.
+ }
+}
+
+int main(int argc, char *argv[]) {
+ // The path to the program to exec must be passed in the first time.
+ if (argc == 2) {
+ fprintf(stderr, "Testing child with infinite stack\n");
+ testChildStackLimit(RLIM_INFINITY, argv[1]);
+ fprintf(stderr, "Testing child with 1TB stack\n");
+ testChildStackLimit(1ULL << 40, argv[1]);
+ }
+ fprintf(stderr, "done\n");
+ // CHECK: in esan::initializeLibrary
+ // CHECK: Testing child with infinite stack
+ // CHECK-NEXT: in esan::initializeLibrary
+ // CHECK-NEXT: =={{[0-9]+}}==The stack size limit is beyond the maximum supported.
+ // CHECK-NEXT: Re-execing with a stack size below 1TB.
+ // CHECK-NEXT: in esan::initializeLibrary
+ // CHECK: done
+ // CHECK: in esan::finalizeLibrary
+ // CHECK: Testing child with 1TB stack
+ // CHECK-NEXT: in esan::initializeLibrary
+ // CHECK-NEXT: =={{[0-9]+}}==The stack size limit is beyond the maximum supported.
+ // CHECK-NEXT: Re-execing with a stack size below 1TB.
+ // CHECK-NEXT: in esan::initializeLibrary
+ // CHECK: done
+ // CHECK-NEXT: in esan::finalizeLibrary
+ // CHECK: done
+ // CHECK-NEXT: in esan::finalizeLibrary
+ return 0;
+}