[llvm] r251168 - [libFuzzer] add -merge flag to merge corpora
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 23 18:16:41 PDT 2015
Author: kcc
Date: Fri Oct 23 20:16:40 2015
New Revision: 251168
URL: http://llvm.org/viewvc/llvm-project?rev=251168&view=rev
Log:
[libFuzzer] add -merge flag to merge corpora
Added:
llvm/trunk/lib/Fuzzer/test/merge.test
Modified:
llvm/trunk/docs/LibFuzzer.rst
llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
llvm/trunk/lib/Fuzzer/FuzzerFlags.def
llvm/trunk/lib/Fuzzer/FuzzerInternal.h
llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
Modified: llvm/trunk/docs/LibFuzzer.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LibFuzzer.rst?rev=251168&r1=251167&r2=251168&view=diff
==============================================================================
--- llvm/trunk/docs/LibFuzzer.rst (original)
+++ llvm/trunk/docs/LibFuzzer.rst Fri Oct 23 20:16:40 2015
@@ -64,6 +64,7 @@ The most important flags are::
max_total_time 0 If positive, indicates the maximal total time in seconds to run the fuzzer.
help 0 Print help.
save_minimized_corpus 0 If 1, the minimized corpus is saved into the first input directory. Example: ./fuzzer -save_minimized_corpus=1 NEW_EMPTY_DIR OLD_CORPUS
+ merge 0 If 1, the 2-nd, 3-rd, etc corpora will be merged into the 1-st corpus. Only interesting units will be taken.
jobs 0 Number of jobs to run. If jobs >= 1 we spawn this number of jobs in separate worker processes with stdout/stderr redirected to fuzz-JOB.log.
workers 0 Number of simultaneous worker processes to run the jobs. If zero, "min(jobs,NumberOfCpuCores()/2)" is used.
sync_command 0 Execute an external command "<sync_command> <test_corpus>" to synchronize the test corpus.
Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=251168&r1=251167&r2=251168&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Fri Oct 23 20:16:40 2015
@@ -269,6 +269,11 @@ int FuzzerDriver(const std::vector<std::
if (Flags.test_single_input)
return RunOneTest(&F, Flags.test_single_input);
+ if (Flags.merge) {
+ F.Merge(*Inputs);
+ exit(0);
+ }
+
unsigned Seed = Flags.seed;
// Initialize Seed.
if (Seed == 0)
Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=251168&r1=251167&r2=251168&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Fri Oct 23 20:16:40 2015
@@ -36,6 +36,8 @@ FUZZER_FLAG_INT(
save_minimized_corpus, 0,
"If 1, the minimized corpus is saved into the first input directory. "
"Example: ./fuzzer -save_minimized_corpus=1 NEW_EMPTY_DIR OLD_CORPUS")
+FUZZER_FLAG_INT(merge, 0, "If 1, the 2-nd, 3-rd, etc corpora will be "
+ "merged into the 1-st corpus. Only interesting units will be taken.")
FUZZER_FLAG_INT(use_counters, 1, "Use coverage counters")
FUZZER_FLAG_INT(use_indir_calls, 1, "Use indirect caller-callee counters")
FUZZER_FLAG_INT(use_traces, 0, "Experimental: use instruction traces")
Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=251168&r1=251167&r2=251168&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Fri Oct 23 20:16:40 2015
@@ -104,6 +104,7 @@ class Fuzzer {
void InitializeTraceState();
size_t CorpusSize() const { return Corpus.size(); }
void ReadDir(const std::string &Path, long *Epoch) {
+ Printf("Loading corpus: %s\n", Path.c_str());
ReadDirToVectorOfUnits(Path.c_str(), &Corpus, Epoch);
}
void RereadOutputCorpus();
@@ -121,6 +122,9 @@ class Fuzzer {
void ExecuteCallback(const Unit &U);
+ // Merge Corpora[1:] into Corpora[0].
+ void Merge(const std::vector<std::string> &Corpora);
+
private:
void AlarmCallback();
void MutateAndTestOne(Unit *U);
Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=251168&r1=251167&r2=251168&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Fri Oct 23 20:16:40 2015
@@ -286,6 +286,38 @@ void Fuzzer::ReportNewCoverage(const Uni
exit(0);
}
+void Fuzzer::Merge(const std::vector<std::string> &Corpora) {
+ if (Corpora.size() <= 1) {
+ Printf("Merge requires two or more corpus dirs\n");
+ return;
+ }
+ auto InitialCorpusDir = Corpora[0];
+ ReadDir(InitialCorpusDir, nullptr);
+ Printf("Merge: running the initial corpus '%s' of %d units\n",
+ InitialCorpusDir.c_str(), Corpus.size());
+ for (auto &U : Corpus)
+ RunOne(U);
+
+ std::vector<std::string> ExtraCorpora(Corpora.begin() + 1, Corpora.end());
+
+ size_t NumTried = 0;
+ size_t NumMerged = 0;
+ for (auto &C : ExtraCorpora) {
+ Corpus.clear();
+ ReadDir(C, nullptr);
+ Printf("Merge: merging the extra corpus '%s' of %zd units\n", C.c_str(),
+ Corpus.size());
+ for (auto &U : Corpus) {
+ NumTried++;
+ if (RunOne(U)) {
+ WriteToOutputCorpus(U);
+ NumMerged++;
+ }
+ }
+ }
+ Printf("Merge: written %zd out of %zd units\n", NumMerged, NumTried);
+}
+
void Fuzzer::MutateAndTestOne(Unit *U) {
for (int i = 0; i < Options.MutateDepth; i++) {
StartTraceRecording();
Added: llvm/trunk/lib/Fuzzer/test/merge.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/merge.test?rev=251168&view=auto
==============================================================================
--- llvm/trunk/lib/Fuzzer/test/merge.test (added)
+++ llvm/trunk/lib/Fuzzer/test/merge.test Fri Oct 23 20:16:40 2015
@@ -0,0 +1,29 @@
+CHECK: BINGO
+
+RUN: rm -rf %tmp/T1 %tmp/T2
+RUN: mkdir -p %tmp/T1 %tmp/T2
+RUN: echo F..... > %tmp/T1/1
+RUN: echo .U.... > %tmp/T1/2
+RUN: echo ..Z... > %tmp/T1/3
+
+# T1 has 3 elements, T2 is empty.
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: Merge: running the initial corpus {{.*}} of 3 units
+CHECK1: Merge: written 0 out of 0 units
+
+RUN: echo ...Z.. > %tmp/T2/1
+RUN: echo ....E. > %tmp/T2/2
+RUN: echo .....R > %tmp/T2/3
+RUN: echo F..... > %tmp/T2/a
+RUN: echo .U.... > %tmp/T2/b
+RUN: echo ..Z... > %tmp/T2/c
+
+# T1 has 3 elements, T2 has 6 elements, only 3 are new.
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: Merge: running the initial corpus {{.*}} of 3 units
+CHECK2: Merge: written 3 out of 6 units
+
+# Now, T1 has 6 units and T2 has no new interesting units.
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+CHECK3: Merge: running the initial corpus {{.*}} of 6 units
+CHECK3: Merge: written 0 out of 6 units
More information about the llvm-commits
mailing list