summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2013-09-04 14:39:43 +0000
committerKostya Serebryany <kcc@google.com>2013-09-04 14:39:43 +0000
commit2e57127cf74c36fe5149a00865b7b8404daa1509 (patch)
tree17967775a6f0e18a6b60d20bbb2188b7d880ed2d /compiler-rt
parent3a3563d4be1ba20791fe882f8297612ac1354ea2 (diff)
downloadbcm5719-llvm-2e57127cf74c36fe5149a00865b7b8404daa1509.tar.gz
bcm5719-llvm-2e57127cf74c36fe5149a00865b7b8404daa1509.zip
[asan] add a test that demonstrates why the current use-after-return is not signal-safe
llvm-svn: 189943
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc66
1 files changed, 66 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc b/compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc
new file mode 100644
index 00000000000..59a2814876f
--- /dev/null
+++ b/compiler-rt/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc
@@ -0,0 +1,66 @@
+// This test shows that the current implementation of use-after-return is
+// not signal-safe.
+// RUN: %clangxx_asan -O1 %s -o %t -lpthread && %t
+// FAILS: %clangxx_asan -fsanitize=use-after-return -O1 %s -o %t -lpthread&& %t
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <pthread.h>
+
+int *g;
+int n_signals;
+
+typedef void (*Sigaction)(int, siginfo_t *, void *);
+
+void SignalHandler(int, siginfo_t*, void*) {
+ int local;
+ g = &local;
+ n_signals++;
+ // printf("s: %p\n", &local);
+}
+
+static void EnableSigprof(Sigaction SignalHandler) {
+ struct sigaction sa;
+ sa.sa_sigaction = SignalHandler;
+ sa.sa_flags = SA_RESTART | SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ if (sigaction(SIGPROF, &sa, NULL) != 0) {
+ perror("sigaction");
+ abort();
+ }
+ struct itimerval timer;
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = 1;
+ timer.it_value = timer.it_interval;
+ if (setitimer(ITIMER_PROF, &timer, 0) != 0) {
+ perror("setitimer");
+ abort();
+ }
+}
+
+void RecursiveFunction(int depth) {
+ if (depth == 0) return;
+ int local;
+ g = &local;
+ // printf("r: %p\n", &local);
+ // printf("[%2d] n_signals: %d\n", depth, n_signals);
+ RecursiveFunction(depth - 1);
+ RecursiveFunction(depth - 1);
+}
+
+void *Thread(void *) {
+ RecursiveFunction(18);
+ return NULL;
+}
+
+int main(int argc, char **argv) {
+ EnableSigprof(SignalHandler);
+
+ const int kNumThread = 32;
+ pthread_t t[kNumThread];
+ for (int i = 0; i < kNumThread; i++)
+ pthread_create(&t[i], 0, Thread, 0);
+ for (int i = 0; i < kNumThread; i++)
+ pthread_join(t[i], 0);
+}
OpenPOWER on IntegriCloud