summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Fuzzer/FuzzerLoop.cpp
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2015-11-04 23:22:25 +0000
committerKostya Serebryany <kcc@google.com>2015-11-04 23:22:25 +0000
commite692621a9dc6eff696939a552fe7aa1fed4300ad (patch)
tree923baa6ac86011e7e8689574dd0d12eeb67d75d8 /llvm/lib/Fuzzer/FuzzerLoop.cpp
parent58a7e659d94d14fe6e78012d474691964f31a29a (diff)
downloadbcm5719-llvm-e692621a9dc6eff696939a552fe7aa1fed4300ad.tar.gz
bcm5719-llvm-e692621a9dc6eff696939a552fe7aa1fed4300ad.zip
[libFuzzer] when choosing the next unit to mutate, give some preference to the most recent units (they are more likely to be interesting)
llvm-svn: 252097
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerLoop.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp71
1 files changed, 45 insertions, 26 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp
index 4f07961e066..64c567d83f7 100644
--- a/llvm/lib/Fuzzer/FuzzerLoop.cpp
+++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp
@@ -346,39 +346,58 @@ void Fuzzer::MutateAndTestOne(Unit *U) {
}
}
+// Returns an index of random unit from the corpus to mutate.
+// Hypothesis: units added to the corpus last are more likely to be interesting.
+// This function gives more wieght to the more recent units.
+size_t Fuzzer::ChooseUnitToMutate() {
+ size_t N = Corpus.size();
+ size_t Total = (N + 1) * N / 2;
+ size_t R = USF.GetRand()(Total);
+ size_t IdxBeg = 0, IdxEnd = N;
+ // Binary search.
+ while (IdxEnd - IdxBeg >= 2) {
+ size_t Idx = IdxBeg + (IdxEnd - IdxBeg) / 2;
+ if (R > (Idx + 1) * Idx / 2)
+ IdxBeg = Idx;
+ else
+ IdxEnd = Idx;
+ }
+ assert(IdxBeg < N);
+ return IdxBeg;
+}
+
void Fuzzer::Loop() {
for (auto &U: Options.Dictionary)
USF.GetMD().AddWordToDictionary(U.data(), U.size());
while (true) {
- for (size_t J1 = 0; J1 < Corpus.size(); J1++) {
- SyncCorpus();
- RereadOutputCorpus();
- if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
- return;
- if (Options.MaxTotalTimeSec > 0 &&
- secondsSinceProcessStartUp() >
- static_cast<size_t>(Options.MaxTotalTimeSec))
- return;
- CurrentUnit = Corpus[J1];
- // Optionally, cross with another unit.
- if (Options.DoCrossOver && USF.GetRand().RandBool()) {
- size_t J2 = USF.GetRand()(Corpus.size());
- if (!Corpus[J1].empty() && !Corpus[J2].empty()) {
- assert(!Corpus[J2].empty());
- CurrentUnit.resize(Options.MaxLen);
- size_t NewSize = USF.CrossOver(
- Corpus[J1].data(), Corpus[J1].size(), Corpus[J2].data(),
- Corpus[J2].size(), CurrentUnit.data(), CurrentUnit.size());
- assert(NewSize > 0 && "CrossOver returned empty unit");
- assert(NewSize <= (size_t)Options.MaxLen &&
- "CrossOver returned overisized unit");
- CurrentUnit.resize(NewSize);
- }
+ size_t J1 = ChooseUnitToMutate();;
+ SyncCorpus();
+ RereadOutputCorpus();
+ if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
+ return;
+ if (Options.MaxTotalTimeSec > 0 &&
+ secondsSinceProcessStartUp() >
+ static_cast<size_t>(Options.MaxTotalTimeSec))
+ return;
+ CurrentUnit = Corpus[J1];
+ // Optionally, cross with another unit.
+ if (Options.DoCrossOver && USF.GetRand().RandBool()) {
+ size_t J2 = ChooseUnitToMutate();
+ if (!Corpus[J1].empty() && !Corpus[J2].empty()) {
+ assert(!Corpus[J2].empty());
+ CurrentUnit.resize(Options.MaxLen);
+ size_t NewSize = USF.CrossOver(
+ Corpus[J1].data(), Corpus[J1].size(), Corpus[J2].data(),
+ Corpus[J2].size(), CurrentUnit.data(), CurrentUnit.size());
+ assert(NewSize > 0 && "CrossOver returned empty unit");
+ assert(NewSize <= (size_t)Options.MaxLen &&
+ "CrossOver returned overisized unit");
+ CurrentUnit.resize(NewSize);
}
- // Perform several mutations and runs.
- MutateAndTestOne(&CurrentUnit);
}
+ // Perform several mutations and runs.
+ MutateAndTestOne(&CurrentUnit);
}
}
OpenPOWER on IntegriCloud