summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Shlyapnikov <alekseys@google.com>2017-10-23 22:04:30 +0000
committerAlex Shlyapnikov <alekseys@google.com>2017-10-23 22:04:30 +0000
commit6f1c26f222b5df888a42ac53f1b600f2bd511c1b (patch)
treecc314d8e1a5620e66d803ffcb18aa7cb464057dc
parent30680e943735ae8f008af0513e85725f3d6cfee6 (diff)
downloadbcm5719-llvm-6f1c26f222b5df888a42ac53f1b600f2bd511c1b.tar.gz
bcm5719-llvm-6f1c26f222b5df888a42ac53f1b600f2bd511c1b.zip
[libFuzzer] Periodically purge allocator's quarantine to prolong fuzzing sessions.
Summary: Fuzzing targets that allocate/deallocate a lot of memory tend to consume a lot of RSS when ASan quarantine is enabled. Purging quarantine between iterations and returning memory to OS keeps RSS down and should not reduce the quarantine effectiveness provided the fuzz target does not preserve state between iterations (in this case this feature can be turned off). Based on D39153. Reviewers: vitalybuka Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39155 llvm-svn: 316382
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerDriver.cpp1
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerExtFunctions.def1
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerFlags.def4
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerInternal.h3
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerLoop.cpp23
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerOptions.h1
6 files changed, 32 insertions, 1 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
index 29248dcee52..18c73ca75b8 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
@@ -578,6 +578,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Options.ReloadIntervalSec = Flags.reload;
Options.OnlyASCII = Flags.only_ascii;
Options.DetectLeaks = Flags.detect_leaks;
+ Options.PurgeAllocatorIntervalSec = Flags.purge_allocator_interval;
Options.TraceMalloc = Flags.trace_malloc;
Options.RssLimitMb = Flags.rss_limit_mb;
if (Flags.runs >= 0)
diff --git a/compiler-rt/lib/fuzzer/FuzzerExtFunctions.def b/compiler-rt/lib/fuzzer/FuzzerExtFunctions.def
index 3bc5302c31c..25a655bfd71 100644
--- a/compiler-rt/lib/fuzzer/FuzzerExtFunctions.def
+++ b/compiler-rt/lib/fuzzer/FuzzerExtFunctions.def
@@ -33,6 +33,7 @@ EXT_FUNC(__sanitizer_install_malloc_and_free_hooks, int,
(void (*malloc_hook)(const volatile void *, size_t),
void (*free_hook)(const volatile void *)),
false);
+EXT_FUNC(__sanitizer_purge_allocator, void, (), false);
EXT_FUNC(__sanitizer_print_memory_profile, int, (size_t, size_t), false);
EXT_FUNC(__sanitizer_print_stack_trace, void, (), true);
EXT_FUNC(__sanitizer_symbolize_pc, void,
diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def
index efbc067903e..e4bca46f0ad 100644
--- a/compiler-rt/lib/fuzzer/FuzzerFlags.def
+++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def
@@ -114,6 +114,10 @@ FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; "
"Be careful, this will also close e.g. asan's stderr/stdout.")
FUZZER_FLAG_INT(detect_leaks, 1, "If 1, and if LeakSanitizer is enabled "
"try to detect memory leaks during fuzzing (i.e. not only at shut down).")
+FUZZER_FLAG_INT(purge_allocator_interval, 1, "Purge allocator caches and "
+ "quarantines every <N> seconds. When rss_limit_mb is specified (>0), "
+ "purging starts when RSS exceeds 50% of rss_limit_mb. Pass "
+ "purge_allocator_interval=-1 to disable this functionality.")
FUZZER_FLAG_INT(trace_malloc, 0, "If >= 1 will print all mallocs/frees. "
"If >= 2 will also print stack traces.")
FUZZER_FLAG_INT(rss_limit_mb, 2048, "If non-zero, the fuzzer will exit upon"
diff --git a/compiler-rt/lib/fuzzer/FuzzerInternal.h b/compiler-rt/lib/fuzzer/FuzzerInternal.h
index 34fdeb82158..97c14085e01 100644
--- a/compiler-rt/lib/fuzzer/FuzzerInternal.h
+++ b/compiler-rt/lib/fuzzer/FuzzerInternal.h
@@ -96,6 +96,7 @@ private:
void CrashOnOverwrittenData();
void InterruptCallback();
void MutateAndTestOne();
+ void PurgeAllocator();
void ReportNewCoverage(InputInfo *II, const Unit &U);
void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);
void WriteToOutputCorpus(const Unit &U);
@@ -124,6 +125,8 @@ private:
bool HasMoreMallocsThanFrees = false;
size_t NumberOfLeakDetectionAttempts = 0;
+ system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now();
+
UserCallback CB;
InputCorpus &Corpus;
MutationDispatcher &MD;
diff --git a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
index 30844e32837..58e8168d16b 100644
--- a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
@@ -587,7 +587,7 @@ void Fuzzer::MutateAndTestOne() {
size_t NewSize = 0;
NewSize = MD.Mutate(CurrentUnitData, Size, CurrentMaxMutationLen);
assert(NewSize > 0 && "Mutator returned empty unit");
- assert(NewSize <= CurrentMaxMutationLen && "Mutator return overisized unit");
+ assert(NewSize <= CurrentMaxMutationLen && "Mutator return oversized unit");
Size = NewSize;
II.NumExecutedMutations++;
if (RunOne(CurrentUnitData, Size, /*MayDeleteFile=*/true, &II))
@@ -598,6 +598,25 @@ void Fuzzer::MutateAndTestOne() {
}
}
+void Fuzzer::PurgeAllocator() {
+ if (Options.PurgeAllocatorIntervalSec < 0 ||
+ !EF->__sanitizer_purge_allocator) {
+ return;
+ }
+ if (duration_cast<seconds>(system_clock::now() -
+ LastAllocatorPurgeAttemptTime).count() <
+ Options.PurgeAllocatorIntervalSec) {
+ return;
+ }
+
+ if (Options.RssLimitMb <= 0 ||
+ GetPeakRSSMb() > static_cast<size_t>(Options.RssLimitMb) / 2) {
+ EF->__sanitizer_purge_allocator();
+ }
+
+ LastAllocatorPurgeAttemptTime = system_clock::now();
+}
+
void Fuzzer::ReadAndExecuteSeedCorpora(const Vector<std::string> &CorpusDirs) {
const size_t kMaxSaneLen = 1 << 20;
const size_t kMinDefaultLen = 4096;
@@ -699,6 +718,8 @@ void Fuzzer::Loop(const Vector<std::string> &CorpusDirs) {
// Perform several mutations and runs.
MutateAndTestOne();
+
+ PurgeAllocator();
}
PrintStats("DONE ", "\n");
diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h
index e57c7df5b0f..73953e1548b 100644
--- a/compiler-rt/lib/fuzzer/FuzzerOptions.h
+++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h
@@ -54,6 +54,7 @@ struct FuzzingOptions {
bool DumpCoverage = false;
bool UseClangCoverage = false;
bool DetectLeaks = true;
+ int PurgeAllocatorIntervalSec = 1;
int UseFeatureFrequency = false;
int TraceMalloc = 0;
bool HandleAbrt = false;
OpenPOWER on IntegriCloud