Options.FocusFunction = Flags.focus_function;
if (Flags.data_flow_trace)
Options.DataFlowTrace = Flags.data_flow_trace;
+ Options.LazyCounters = Flags.lazy_counters;
unsigned Seed = Flags.seed;
// Initialize Seed.
Options.HandleXfsz = Flags.handle_xfsz;
Options.HandleUsr1 = Flags.handle_usr1;
Options.HandleUsr2 = Flags.handle_usr2;
- Options.LazyCounters = Flags.lazy_counters;
SetSignalHandler(Options);
- if (Options.LazyCounters)
- TPC.ProtectLazyCounters();
std::atexit(Fuzzer::StaticExitCallback);
size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
static void StaticAlarmCallback();
- static void StaticSegvSignalCallback(void *Addr);
static void StaticCrashSignalCallback();
static void StaticExitCallback();
static void StaticInterruptCallback();
F->CrashCallback();
}
-void Fuzzer::StaticSegvSignalCallback(void *Addr) {
- if (TPC.UnprotectLazyCounters(Addr)) return;
- StaticCrashSignalCallback();
-}
-
void Fuzzer::StaticExitCallback() {
assert(F);
F->ExitCallback();
uint8_t dummy = 0;
ExecuteCallback(&dummy, 0);
+ // Protect lazy counters here, after the once-init code has been executed.
+ if (Options.LazyCounters)
+ TPC.ProtectLazyCounters();
+
if (SizedFiles.empty()) {
Printf("INFO: A corpus is not provided, starting from an empty corpus\n");
Unit U({'\n'}); // Valid ASCII input.
#if LIBFUZZER_POSIX
#include "FuzzerIO.h"
#include "FuzzerInternal.h"
+#include "FuzzerTracePC.h"
#include <cassert>
#include <chrono>
#include <cstring>
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 *) {
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)
RUN: %cpp_compiler %S/LargeTest.cpp -o %t-LargeTest
RUN: %run %t-LargeTest -runs=10000
RUN: %env_asan_opts=handle_segv=0 %run %t-LargeTest -runs=10000 -lazy_counters=1 2>&1 | FileCheck %s
+RUN: %run %t-LargeTest -runs=10000 -lazy_counters=1 2>&1 | FileCheck %s
CHECK: pages of counters where protected; libFuzzer's SEGV handler must be installed