aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common.h
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2016-08-28 14:59:48 +0200
committerDmitry Vyukov <dvyukov@google.com>2016-08-28 14:59:48 +0200
commit9b91ede8607ae78572fef7aed01f1afe3a033928 (patch)
tree645c01454385dfbb9ee42c2e314b0a6edbaca594 /executor/common.h
parentf0eccc70522c2107f70d9ab6626924612b3da80d (diff)
executor, csource: share some common code between executor and csource
Diffstat (limited to 'executor/common.h')
-rw-r--r--executor/common.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/executor/common.h b/executor/common.h
new file mode 100644
index 000000000..0c4613859
--- /dev/null
+++ b/executor/common.h
@@ -0,0 +1,43 @@
+// Copyright 2016 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+// This file is shared between executor and csource package.
+
+#include <pthread.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+__thread int skip_segv;
+__thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* uctx)
+{
+ if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED))
+ _longjmp(segv_env, 1);
+ exit(sig);
+}
+
+static void install_segv_handler()
+{
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = segv_handler;
+ sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...) \
+ { \
+ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ if (_setjmp(segv_env) == 0) { \
+ __VA_ARGS__; \
+ } \
+ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ }