summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-10-05 00:25:17 +0000
committerKostya Serebryany <kcc@google.com>2016-10-05 00:25:17 +0000
commit2455f0d013dc7fa311ac3fd7b3fcce166a468cc1 (patch)
tree3b14eff599b0baa5f8b754b170977e532866bcbe /llvm/lib
parent78b04ae7ac82908348602526f5671a51bb9c9314 (diff)
downloadbcm5719-llvm-2455f0d013dc7fa311ac3fd7b3fcce166a468cc1.tar.gz
bcm5719-llvm-2455f0d013dc7fa311ac3fd7b3fcce166a468cc1.zip
[libFuzzer] clear the corpus elements if they are evicted (i.e. smaller elements with proper coverage are found). Make sure we never try to mutate empty element. Print the corpus size in bytes in the status lines
llvm-svn: 283279
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Fuzzer/FuzzerCorpus.h24
-rw-r--r--llvm/lib/Fuzzer/FuzzerDriver.cpp2
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp18
3 files changed, 38 insertions, 6 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerCorpus.h b/llvm/lib/Fuzzer/FuzzerCorpus.h
index 3b76471db6e..ea4f0c706c7 100644
--- a/llvm/lib/Fuzzer/FuzzerCorpus.h
+++ b/llvm/lib/Fuzzer/FuzzerCorpus.h
@@ -39,9 +39,22 @@ class InputCorpus {
memset(FeatureSet, 0, sizeof(FeatureSet));
}
size_t size() const { return Inputs.size(); }
+ size_t SizeInBytes() const {
+ size_t Res = 0;
+ for (auto &II : Inputs)
+ Res += II.U.size();
+ return Res;
+ }
+ size_t NumActiveUnits() const {
+ size_t Res = 0;
+ for (auto &II : Inputs)
+ Res += !II.U.empty();
+ return Res;
+ }
bool empty() const { return Inputs.empty(); }
const Unit &operator[] (size_t Idx) const { return Inputs[Idx].U; }
void AddToCorpus(const Unit &U) {
+ assert(!U.empty());
uint8_t Hash[kSHA1NumBytes];
ComputeSHA1(U.data(), U.size(), Hash);
if (!Hashes.insert(Sha1ToString(Hash)).second) return;
@@ -60,7 +73,9 @@ class InputCorpus {
bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
bool HasUnit(const std::string &H) { return Hashes.count(H); }
InputInfo &ChooseUnitToMutate(Random &Rand) {
- return Inputs[ChooseUnitIdxToMutate(Rand)];
+ InputInfo &II = Inputs[ChooseUnitIdxToMutate(Rand)];
+ assert(!II.U.empty());
+ return II;
};
// Returns an index of random unit from the corpus to mutate.
@@ -132,8 +147,11 @@ private:
auto &OlderII = Inputs[Fe.SmallestElementIdx];
assert(OlderII.NumFeatures > 0);
OlderII.NumFeatures--;
- if (!OlderII.NumFeatures && FeatureDebug)
- Printf("EVICTED %zd\n", Fe.SmallestElementIdx);
+ if (!OlderII.NumFeatures) {
+ OlderII.U.clear(); // Will be never used again.
+ if (FeatureDebug)
+ Printf("EVICTED %zd\n", Fe.SmallestElementIdx);
+ }
}
Fe.SmallestElementIdx = CurrentElementIdx;
Fe.SmallestElementSize = Size;
diff --git a/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp
index 8f7820d521d..d0de517920d 100644
--- a/llvm/lib/Fuzzer/FuzzerDriver.cpp
+++ b/llvm/lib/Fuzzer/FuzzerDriver.cpp
@@ -511,7 +511,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
}
if (InitialCorpus.empty()) {
- InitialCorpus.push_back(Unit());
+ InitialCorpus.push_back(Unit({0}));
if (Options.Verbosity)
Printf("INFO: A corpus is not provided, starting from an empty corpus\n");
}
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp
index 57dbb9fa427..35d68bce694 100644
--- a/llvm/lib/Fuzzer/FuzzerLoop.cpp
+++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp
@@ -309,10 +309,20 @@ void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {
Printf(" bits: %zd", MaxCoverage.TPCMap.GetNumBitsSinceLastMerge());
if (MaxCoverage.CallerCalleeCoverage)
Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);
- if (size_t N = Corpus.size())
- Printf(" units: %zd", N);
+ if (size_t N = Corpus.size()) {
+ Printf(" corpus: %zd", Corpus.NumActiveUnits());
+ if (size_t N = Corpus.SizeInBytes()) {
+ if (N < (1<<14))
+ Printf("/%zdb", N);
+ else if (N < (1 << 24))
+ Printf("/%zdKb", N >> 10);
+ else
+ Printf("/%zdMb", N >> 20);
+ }
+ }
if (Units)
Printf(" units: %zd", Units);
+
Printf(" exec/s: %zd", ExecPerSec);
Printf("%s", End);
}
@@ -403,6 +413,10 @@ void Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) {
if (Options.ShuffleAtStartUp)
ShuffleCorpus(InitialCorpus);
+ // Test the callback with empty input and never try it again.
+ uint8_t dummy;
+ ExecuteCallback(&dummy, 0);
+
for (const auto &U : *InitialCorpus) {
if (RunOne(U)) {
Corpus.AddToCorpus(U);
OpenPOWER on IntegriCloud