aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Fuzzer/FuzzerLoop.cpp
diff options
context:
space:
mode:
authorMike Aizatsky <aizatsky@chromium.org>2016-05-24 23:14:29 +0000
committerMike Aizatsky <aizatsky@chromium.org>2016-05-24 23:14:29 +0000
commitaf432a45e3218d29ce322ff2a074ad3b230b13f5 (patch)
tree4c6ded29bf06f8b08ca1a5d9d2af37e402917416 /llvm/lib/Fuzzer/FuzzerLoop.cpp
parent515c15c2073c62caa1ff8ea8de072a3cf6db590c (diff)
downloadllvm-af432a45e3218d29ce322ff2a074ad3b230b13f5.zip
llvm-af432a45e3218d29ce322ff2a074ad3b230b13f5.tar.gz
llvm-af432a45e3218d29ce322ff2a074ad3b230b13f5.tar.bz2
[libfuzzer] Trying random unit prefixes during corpus load.
Differential Revision: http://reviews.llvm.org/D20301 llvm-svn: 270632
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerLoop.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp
index 0adbc89..ed8a1fb 100644
--- a/llvm/lib/Fuzzer/FuzzerLoop.cpp
+++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp
@@ -59,6 +59,7 @@ __attribute__((weak)) int __lsan_do_recoverable_leak_check();
namespace fuzzer {
static const size_t kMaxUnitSizeToPrint = 256;
+static const size_t TruncateMaxRuns = 1000;
static void MissingWeakApiFunction(const char *FnName) {
Printf("ERROR: %s is not defined. Exiting.\n"
@@ -353,12 +354,54 @@ void Fuzzer::ShuffleCorpus(UnitVector *V) {
});
}
+// Tries random prefixes of corpus items.
+// Prefix length is chosen according to exponential distribution
+// to sample short lengths much more heavily.
+void Fuzzer::TruncateUnits(std::vector<Unit> *NewCorpus) {
+ size_t MaxCorpusLen = 0;
+ for (const auto &U : Corpus)
+ MaxCorpusLen = std::max(MaxCorpusLen, U.size());
+
+ if (MaxCorpusLen <= 1)
+ return;
+
+ // 50% of exponential distribution is Log[2]/lambda.
+ // Choose lambda so that median is MaxCorpusLen / 2.
+ double Lambda = 2.0 * log(2.0) / static_cast<double>(MaxCorpusLen);
+ std::exponential_distribution<> Dist(Lambda);
+ std::vector<double> Sizes;
+ size_t TruncatePoints = std::max(1ul, TruncateMaxRuns / Corpus.size());
+ Sizes.reserve(TruncatePoints);
+ for (size_t I = 0; I < TruncatePoints; ++I) {
+ Sizes.push_back(Dist(MD.GetRand().Get_mt19937()) + 1);
+ }
+ std::sort(Sizes.begin(), Sizes.end());
+
+ for (size_t S : Sizes) {
+ for (const auto &U : Corpus) {
+ if (S < U.size() && RunOne(U.data(), S)) {
+ Unit U1(U.begin(), U.begin() + S);
+ NewCorpus->push_back(U1);
+ WriteToOutputCorpus(U1);
+ PrintStatusForNewUnit(U1);
+ }
+ }
+ }
+ PrintStats("TRUNC ");
+}
+
void Fuzzer::ShuffleAndMinimize() {
PrintStats("READ ");
std::vector<Unit> NewCorpus;
if (Options.ShuffleAtStartUp)
ShuffleCorpus(&Corpus);
+ if (Options.TruncateUnits) {
+ ResetCoverage();
+ TruncateUnits(&NewCorpus);
+ ResetCoverage();
+ }
+
for (const auto &U : Corpus) {
if (RunOne(U)) {
NewCorpus.push_back(U);