[libFuzzer] set libFuzzer's own SEGV handler even one is already present, but call that handler from ours (unless we are unprotecting lazy counters). Call ProtectLazyCounters later, so that it runs after the initialization code in the target.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer@352713 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/FuzzerUtilPosix.cpp b/FuzzerUtilPosix.cpp
index 56b10ff..110785d 100644
--- a/FuzzerUtilPosix.cpp
+++ b/FuzzerUtilPosix.cpp
@@ -11,6 +11,7 @@
#if LIBFUZZER_POSIX
#include "FuzzerIO.h"
#include "FuzzerInternal.h"
+#include "FuzzerTracePC.h"
#include <cassert>
#include <chrono>
#include <cstring>
@@ -32,9 +33,14 @@
Fuzzer::StaticAlarmCallback();
}
-static void SegvHandler(int, siginfo_t *si, void *) {
+static void (*upstream_segv_handler)(int, siginfo_t *, void *);
+
+static void SegvHandler(int sig, siginfo_t *si, void *ucontext) {
assert(si->si_signo == SIGSEGV);
- Fuzzer::StaticSegvSignalCallback(si->si_addr);
+ if (TPC.UnprotectLazyCounters(si->si_addr)) return;
+ if (upstream_segv_handler)
+ return upstream_segv_handler(sig, si, ucontext);
+ Fuzzer::StaticCrashSignalCallback();
}
static void CrashHandler(int, siginfo_t *, void *) {
@@ -61,8 +67,11 @@
exit(1);
}
if (sigact.sa_flags & SA_SIGINFO) {
- if (sigact.sa_sigaction)
- return;
+ if (sigact.sa_sigaction) {
+ if (signum != SIGSEGV)
+ return;
+ upstream_segv_handler = sigact.sa_sigaction;
+ }
} else {
if (sigact.sa_handler != SIG_DFL && sigact.sa_handler != SIG_IGN &&
sigact.sa_handler != SIG_ERR)