aboutsummaryrefslogtreecommitdiff
path: root/test/asan/TestCases/gc-test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/asan/TestCases/gc-test.cc')
-rw-r--r--test/asan/TestCases/gc-test.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/test/asan/TestCases/gc-test.cc b/test/asan/TestCases/gc-test.cc
new file mode 100644
index 000000000000..ffbea85b2650
--- /dev/null
+++ b/test/asan/TestCases/gc-test.cc
@@ -0,0 +1,50 @@
+// RUN: %clangxx_asan %s -pthread -o %t
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0
+// REQUIRES: stable-runtime
+
+#include <assert.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sanitizer/asan_interface.h>
+
+static const int kNumThreads = 2;
+
+void *Thread(void *unused) {
+ void *fake_stack = __asan_get_current_fake_stack();
+ char var[15];
+ if (fake_stack) {
+ fprintf(stderr, "fake stack found: %p; var: %p\n", fake_stack, var);
+ // CHECK1: fake stack found
+ // CHECK1: fake stack found
+ void *beg, *end;
+ void *real_stack =
+ __asan_addr_is_in_fake_stack(fake_stack, &var[0], &beg, &end);
+ assert(real_stack);
+ assert((char*)beg <= (char*)&var[0]);
+ assert((char*)end > (char*)&var[0]);
+ for (int i = -32; i < 15; i++) {
+ void *beg1, *end1;
+ char *ptr = &var[0] + i;
+ void *real_stack1 =
+ __asan_addr_is_in_fake_stack(fake_stack, ptr, &beg1, &end1);
+ assert(real_stack == real_stack1);
+ assert(beg == beg1);
+ assert(end == end1);
+ }
+ } else {
+ fprintf(stderr, "no fake stack\n");
+ // CHECK0: no fake stack
+ // CHECK0: no fake stack
+ }
+ return NULL;
+}
+
+int main(int argc, char **argv) {
+ pthread_t t[kNumThreads];
+ for (int i = 0; i < kNumThreads; i++)
+ pthread_create(&t[i], 0, Thread, 0);
+ for (int i = 0; i < kNumThreads; i++)
+ pthread_join(t[i], 0);
+ return 0;
+}