summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Metzman <metzman@chromium.org>2019-01-15 22:12:51 +0000
committerJonathan Metzman <metzman@chromium.org>2019-01-15 22:12:51 +0000
commitada3f5a6ec6ee50a5193e704be7f463d1f0576c9 (patch)
treeb5de736f3c3b39386c1d500cfc80ee74b8365343
parentf86f30b8db40447eb8bdaa7af89a4eb3832423d0 (diff)
[libFuzzer] Remove unstable edge handling
Summary: Remove code for handling unstable edges from libFuzzer since it has not been found useful. Differential Revision: https://reviews.llvm.org/D56730
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerCorpus.h6
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerDriver.cpp4
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerFlags.def9
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerInternal.h1
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerLoop.cpp38
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerOptions.h2
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerTracePC.cpp87
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerTracePC.h20
-rw-r--r--compiler-rt/test/fuzzer/PrintUnstableStatsTest.cpp69
-rw-r--r--compiler-rt/test/fuzzer/handle-unstable.test43
-rw-r--r--compiler-rt/test/fuzzer/print_unstable_stats.test24
11 files changed, 9 insertions, 294 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerCorpus.h b/compiler-rt/lib/fuzzer/FuzzerCorpus.h
index 8ad14656cff..f844c07c757 100644
--- a/compiler-rt/lib/fuzzer/FuzzerCorpus.h
+++ b/compiler-rt/lib/fuzzer/FuzzerCorpus.h
@@ -238,12 +238,6 @@ class InputCorpus {
return false;
}
- bool IsFeatureNew(size_t Idx, uint32_t NewSize, bool Shrink) {
- assert(NewSize);
- uint32_t OldSize = GetFeature(Idx % kFeatureSetSize);
- return OldSize == 0 || (Shrink && OldSize > NewSize);
- }
-
size_t NumFeatures() const { return NumAddedFeatures; }
size_t NumFeatureUpdates() const { return NumUpdatedFeatures; }
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
index 918a972fff3..ff2a639ac4a 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
@@ -617,10 +617,6 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Options.PrintFinalStats = Flags.print_final_stats;
Options.PrintCorpusStats = Flags.print_corpus_stats;
Options.PrintCoverage = Flags.print_coverage;
- Options.PrintUnstableStats = Flags.print_unstable_stats;
- if (Flags.handle_unstable == TracePC::MinUnstable ||
- Flags.handle_unstable == TracePC::ZeroUnstable)
- Options.HandleUnstable = Flags.handle_unstable;
Options.DumpCoverage = Flags.dump_coverage;
if (Flags.exit_on_src_pos)
Options.ExitOnSrcPos = Flags.exit_on_src_pos;
diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def
index 9e212ef656d..91281c979c5 100644
--- a/compiler-rt/lib/fuzzer/FuzzerFlags.def
+++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def
@@ -110,15 +110,6 @@ FUZZER_FLAG_INT(print_coverage, 0, "If 1, print coverage information as text"
FUZZER_FLAG_INT(dump_coverage, 0, "Deprecated."
" If 1, dump coverage information as a"
" .sancov file at exit.")
-FUZZER_FLAG_INT(handle_unstable, 0, "Experimental."
- " Executes every input 3 times in total if a unique feature"
- " is found during the first execution."
- " If 1, we only use the minimum hit count from the 3 runs"
- " to determine whether an input is interesting."
- " If 2, we disregard edges that are found unstable for"
- " feature collection.")
-FUZZER_FLAG_INT(print_unstable_stats, 0, "Experimental."
- " If 1, print unstable statistics at exit.")
FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.")
FUZZER_FLAG_INT(handle_bus, 1, "If 1, try to intercept SIGBUS.")
FUZZER_FLAG_INT(handle_abrt, 1, "If 1, try to intercept SIGABRT.")
diff --git a/compiler-rt/lib/fuzzer/FuzzerInternal.h b/compiler-rt/lib/fuzzer/FuzzerInternal.h
index bfc898248ad..a7fdc89cba5 100644
--- a/compiler-rt/lib/fuzzer/FuzzerInternal.h
+++ b/compiler-rt/lib/fuzzer/FuzzerInternal.h
@@ -67,7 +67,6 @@ public:
static void StaticGracefulExitCallback();
void ExecuteCallback(const uint8_t *Data, size_t Size);
- void CheckForUnstableCounters(const uint8_t *Data, size_t Size);
bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
InputInfo *II = nullptr, bool *FoundUniqFeatures = nullptr);
diff --git a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
index 09c57c3f6b7..a32a3072300 100644
--- a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
@@ -355,8 +355,6 @@ void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {
void Fuzzer::PrintFinalStats() {
if (Options.PrintCoverage)
TPC.PrintCoverage();
- if (Options.PrintUnstableStats)
- TPC.PrintUnstableStats();
if (Options.DumpCoverage)
TPC.DumpCoverage();
if (Options.PrintCorpusStats)
@@ -449,29 +447,6 @@ void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) {
}
}
-void Fuzzer::CheckForUnstableCounters(const uint8_t *Data, size_t Size) {
- auto CBSetupAndRun = [&]() {
- ScopedEnableMsanInterceptorChecks S;
- UnitStartTime = system_clock::now();
- TPC.ResetMaps();
- RunningUserCallback = true;
- CB(Data, Size);
- RunningUserCallback = false;
- UnitStopTime = system_clock::now();
- };
-
- // Copy original run counters into our unstable counters
- TPC.InitializeUnstableCounters();
-
- // First Rerun
- CBSetupAndRun();
- if (TPC.UpdateUnstableCounters(Options.HandleUnstable)) {
- // Second Rerun
- CBSetupAndRun();
- TPC.UpdateAndApplyUnstableCounters(Options.HandleUnstable);
- }
-}
-
bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
InputInfo *II, bool *FoundUniqFeatures) {
if (!Size)
@@ -482,17 +457,6 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
UniqFeatureSetTmp.clear();
size_t FoundUniqFeaturesOfII = 0;
size_t NumUpdatesBefore = Corpus.NumFeatureUpdates();
- bool NewFeaturesUnstable = false;
-
- if (Options.HandleUnstable || Options.PrintUnstableStats) {
- TPC.CollectFeatures([&](size_t Feature) {
- if (Corpus.IsFeatureNew(Feature, Size, Options.Shrink))
- NewFeaturesUnstable = true;
- });
- if (NewFeaturesUnstable)
- CheckForUnstableCounters(Data, Size);
- }
-
TPC.CollectFeatures([&](size_t Feature) {
if (Corpus.AddFeature(Feature, Size, Options.Shrink))
UniqFeatureSetTmp.push_back(Feature);
@@ -501,12 +465,10 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
II->UniqFeatureSet.end(), Feature))
FoundUniqFeaturesOfII++;
});
-
if (FoundUniqFeatures)
*FoundUniqFeatures = FoundUniqFeaturesOfII;
PrintPulseAndReportSlowInput(Data, Size);
size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore;
-
if (NumNewFeatures) {
TPC.UpdateObservedPCs();
Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile,
diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h
index bb642f1e236..ab90df82a63 100644
--- a/compiler-rt/lib/fuzzer/FuzzerOptions.h
+++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h
@@ -54,8 +54,6 @@ struct FuzzingOptions {
bool PrintFinalStats = false;
bool PrintCorpusStats = false;
bool PrintCoverage = false;
- bool PrintUnstableStats = false;
- int HandleUnstable = 0;
bool DumpCoverage = false;
bool DetectLeaks = true;
int PurgeAllocatorIntervalSec = 1;
diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp
index 252660b0e11..80b33105bb2 100644
--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp
@@ -58,59 +58,6 @@ size_t TracePC::GetTotalPCCoverage() {
return Res;
}
-template<class CallBack>
-void TracePC::IterateInline8bitCounters(CallBack CB) const {
- if (NumInline8bitCounters && NumInline8bitCounters == NumPCsInPCTables) {
- size_t CounterIdx = 0;
- for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
- uint8_t *Beg = ModuleCounters[i].Start;
- size_t Size = ModuleCounters[i].Stop - Beg;
- assert(Size == (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
- for (size_t j = 0; j < Size; j++, CounterIdx++)
- CB(i, j, CounterIdx);
- }
- }
-}
-
-// Initializes unstable counters by copying Inline8bitCounters to unstable
-// counters.
-void TracePC::InitializeUnstableCounters() {
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- UnstableCounters[UnstableIdx].Counter = ModuleCounters[i].Start[j];
- });
-}
-
-// Compares the current counters with counters from previous runs
-// and records differences as unstable edges.
-bool TracePC::UpdateUnstableCounters(int UnstableMode) {
- bool Updated = false;
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) {
- Updated = true;
- UnstableCounters[UnstableIdx].IsUnstable = true;
- if (UnstableMode == ZeroUnstable)
- UnstableCounters[UnstableIdx].Counter = 0;
- else if (UnstableMode == MinUnstable)
- UnstableCounters[UnstableIdx].Counter = std::min(
- ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter);
- }
- });
- return Updated;
-}
-
-// Updates and applies unstable counters to ModuleCounters in single iteration
-void TracePC::UpdateAndApplyUnstableCounters(int UnstableMode) {
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) {
- UnstableCounters[UnstableIdx].IsUnstable = true;
- if (UnstableMode == ZeroUnstable)
- ModuleCounters[i].Start[j] = 0;
- else if (UnstableMode == MinUnstable)
- ModuleCounters[i].Start[j] = std::min(
- ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter);
- }
- });
-}
void TracePC::HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop) {
if (Start == Stop) return;
@@ -245,10 +192,15 @@ void TracePC::UpdateObservedPCs() {
if (NumPCsInPCTables) {
if (NumInline8bitCounters == NumPCsInPCTables) {
- IterateInline8bitCounters([&](int i, int j, int CounterIdx) {
- if (ModuleCounters[i].Start[j])
- Observe(ModulePCTable[i].Start[j]);
- });
+ for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
+ uint8_t *Beg = ModuleCounters[i].Start;
+ size_t Size = ModuleCounters[i].Stop - Beg;
+ assert(Size ==
+ (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
+ for (size_t j = 0; j < Size; j++)
+ if (Beg[j])
+ Observe(ModulePCTable[i].Start[j]);
+ }
} else if (NumGuards == NumPCsInPCTables) {
size_t GuardIdx = 1;
for (size_t i = 0; i < NumModules; i++) {
@@ -380,27 +332,6 @@ void TracePC::DumpCoverage() {
}
}
-void TracePC::PrintUnstableStats() {
- size_t count = 0;
- Printf("UNSTABLE_FUNCTIONS:\n");
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- const PCTableEntry &TE = ModulePCTable[i].Start[j];
- if (UnstableCounters[UnstableIdx].IsUnstable) {
- count++;
- if (ObservedFuncs.count(TE.PC)) {
- auto VisualizePC = GetNextInstructionPc(TE.PC);
- std::string FunctionStr = DescribePC("%F", VisualizePC);
- if (FunctionStr.find("in ") == 0)
- FunctionStr = FunctionStr.substr(3);
- Printf("%s\n", FunctionStr.c_str());
- }
- }
- });
-
- Printf("stat::stability_rate: %.2f\n",
- 100 - static_cast<float>(count * 100) / NumInline8bitCounters);
-}
-
// Value profile.
// We keep track of various values that affect control flow.
// These values are inserted into a bit-set-based hash map.
diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.h b/compiler-rt/lib/fuzzer/FuzzerTracePC.h
index 39f97acdb07..46d6c24887f 100644
--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.h
+++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.h
@@ -74,11 +74,6 @@ class TracePC {
// How many bits of PC are used from __sanitizer_cov_trace_pc.
static const size_t kTracePcBits = 18;
- enum HandleUnstableOptions {
- MinUnstable = 1,
- ZeroUnstable = 2,
- };
-
void HandleInit(uint32_t *Start, uint32_t *Stop);
void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop);
void HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop);
@@ -109,7 +104,6 @@ class TracePC {
void PrintCoverage();
void DumpCoverage();
- void PrintUnstableStats();
template<class CallBack>
void IterateCoveredFunctions(CallBack CB);
@@ -142,18 +136,7 @@ class TracePC {
void SetFocusFunction(const std::string &FuncName);
bool ObservedFocusFunction();
- void InitializeUnstableCounters();
- bool UpdateUnstableCounters(int UnstableMode);
- void UpdateAndApplyUnstableCounters(int UnstableMode);
-
private:
- struct UnstableEdge {
- uint8_t Counter;
- bool IsUnstable;
- };
-
- UnstableEdge UnstableCounters[kNumPCs];
-
bool UseCounters = false;
uint32_t UseValueProfileMask = false;
bool DoPrintNewPCs = false;
@@ -185,9 +168,6 @@ private:
Set<uintptr_t> ObservedPCs;
std::unordered_map<uintptr_t, uintptr_t> ObservedFuncs; // PC => Counter.
- template <class Callback>
- void IterateInline8bitCounters(Callback CB) const;
-
std::pair<size_t, size_t> FocusFunction = {-1, -1}; // Module and PC IDs.
ValueBitMap ValueProfileMap;
diff --git a/compiler-rt/test/fuzzer/PrintUnstableStatsTest.cpp b/compiler-rt/test/fuzzer/PrintUnstableStatsTest.cpp
deleted file mode 100644
index 2b9de88d730..00000000000
--- a/compiler-rt/test/fuzzer/PrintUnstableStatsTest.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <assert.h>
-#include <cstdint>
-#include <cstdio>
-#include <cstdlib>
-
-int x = 0;
-bool skip0 = false;
-bool skip1 = false;
-bool skip2 = false;
-
-__attribute__((noinline)) void det0() { x++; }
-__attribute__((noinline)) void det1() { x++; }
-__attribute__((noinline)) void det2() { x++; }
-__attribute__((noinline)) void det3() { x++; }
-__attribute__((noinline)) void det4() { x++; }
-
-__attribute__((noinline)) void ini0() { x++; }
-__attribute__((noinline)) void ini1() { x++; }
-__attribute__((noinline)) void ini2() { x++; }
-
-__attribute__((noinline)) void t0(int a) { x += a; }
-__attribute__((noinline)) void t1() { x++; }
-__attribute__((noinline)) void t2(int a, int b) { x += a + b; }
-__attribute__((noinline)) void t3() { x++; }
-__attribute__((noinline)) void t4(int a, int b, int c) { x += a + b +c; }
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- if (Size == 1 && Data[0] == 'A' && !skip0) {
- skip0 = true;
- ini0();
- }
- if (Size == 1 && Data[0] == 'B' && !skip1) {
- skip1 = true;
- ini1();
- }
- if (Size == 1 && Data[0] == 'C' && !skip2) {
- skip2 = true;
- ini2();
- }
-
- det0();
- det1();
- int a = rand();
- det2();
-
- switch (a % 5) {
- case 0:
- t0(a);
- break;
- case 1:
- t1();
- break;
- case 2:
- t2(a, a);
- break;
- case 3:
- t3();
- break;
- case 4:
- t4(a, a, a);
- break;
- default:
- assert(false);
- }
-
- det3();
- det4();
- return 0;
-}
diff --git a/compiler-rt/test/fuzzer/handle-unstable.test b/compiler-rt/test/fuzzer/handle-unstable.test
deleted file mode 100644
index d202246891d..00000000000
--- a/compiler-rt/test/fuzzer/handle-unstable.test
+++ /dev/null
@@ -1,43 +0,0 @@
-# Tests -handle_unstable
-# FIXME: Disabled on Windows until symbolization works properly.
-UNSUPPORTED: windows
-
-RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-HandleUnstableTest
-
-; Normal
-RUN: %run %t-HandleUnstableTest -print_coverage=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=NORMAL
-NORMAL-DAG: det0()
-NORMAL-DAG: det1()
-NORMAL-DAG: det2()
-NORMAL-DAG: det3()
-NORMAL-DAG: det4()
-NORMAL-DAG: ini0()
-NORMAL-DAG: ini1()
-NORMAL-DAG: ini2()
-NORMAL-DAG: t0(int)
-NORMAL-DAG: t1()
-NORMAL-DAG: t2(int, int)
-NORMAL-DAG: t3()
-NORMAL-DAG: t4(int, int, int)
-
-; MinUnstable
-RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=MIN
-MIN-NOT: ini0()
-MIN-NOT: ini1()
-MIN-NOT: ini2()
-MIN: det0()
-MIN: det1()
-MIN: det2()
-MIN: det3()
-MIN: det4()
-
-; ZeroUnstable
-RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=2 -runs=1 2>&1 | FileCheck %s --check-prefix=ZERO
-ZERO-NOT: ini0()
-ZERO-NOT: ini1()
-ZERO-NOT: ini2()
-ZERO: det0()
-ZERO: det1()
-ZERO: det2()
-ZERO: det3()
-ZERO: det4()
diff --git a/compiler-rt/test/fuzzer/print_unstable_stats.test b/compiler-rt/test/fuzzer/print_unstable_stats.test
deleted file mode 100644
index 41b27913076..00000000000
--- a/compiler-rt/test/fuzzer/print_unstable_stats.test
+++ /dev/null
@@ -1,24 +0,0 @@
-# Tests -print_unstable_stats
-# Disabled on Windows because of differences symbolizing and flakiness.
-UNSUPPORTED: aarch64, windows
-
-RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-PrintUnstableStatsTest
-
-RUN: %run %t-PrintUnstableStatsTest -print_unstable_stats=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=LONG
-# We do not observe ini functions since we take the minimum hit counts, and minimum hit counts for ini is 0.
-LONG: UNSTABLE_FUNCTIONS:
-LONG-NOT: det0()
-LONG-NOT: det1()
-LONG-NOT: det2()
-LONG-NOT: det3()
-LONG-NOT: det4()
-LONG-NOT: ini0()
-LONG-NOT: ini1()
-LONG-NOT: ini2()
-LONG-DAG: t0(int)
-LONG-DAG: t1()
-LONG-DAG: t2(int, int)
-LONG-DAG: t3()
-LONG-DAG: t4(int, int, int)
-
-LONG-DAG: stat::stability_rate: 27.59