diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h index 06e20057245f..6188cb573561 100644 --- a/llvm/lib/Fuzzer/FuzzerInternal.h +++ b/llvm/lib/Fuzzer/FuzzerInternal.h @@ -521,6 +521,8 @@ private: // Need to know our own thread. static thread_local bool IsMyThread; + + bool InMergeMode = false; }; // Global interface to functions that may or may not be available. diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 017ea03eaf7f..c71d30227842 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -188,7 +188,22 @@ void Fuzzer::StaticDeathCallback() { F->DeathCallback(); } +static void WarnOnUnsuccessfullMerge(bool DoWarn) { + Printf( + "***\n" + "***\n" + "***\n" + "*** NOTE: merge did not succeed due to a failure on one of the inputs.\n" + "*** You will need to filter out crashes from the corpus, e.g. like this:\n" + "*** for f in WITH_CRASHES/*; do ./fuzzer $f && cp $f NO_CRASHES; done\n" + "*** Future versions may have crash-resistant merge, stay tuned.\n" + "***\n" + "***\n" + "***\n"); +} + void Fuzzer::DumpCurrentUnit(const char *Prefix) { + WarnOnUnsuccessfullMerge(InMergeMode); if (!CurrentUnitData) return; // Happens when running individual inputs. MD.PrintMutationSequence(); Printf("; base unit: %s\n", Sha1ToString(BaseSha1).c_str()); @@ -612,6 +627,7 @@ void Fuzzer::Merge(const std::vector &Corpora) { Printf("Merge requires two or more corpus dirs\n"); return; } + InMergeMode = true; std::vector ExtraCorpora(Corpora.begin() + 1, Corpora.end()); assert(Options.MaxLen > 0); diff --git a/llvm/lib/Fuzzer/test/merge.test b/llvm/lib/Fuzzer/test/merge.test index 6f19e21d132d..b3dcc7994575 100644 --- a/llvm/lib/Fuzzer/test/merge.test +++ b/llvm/lib/Fuzzer/test/merge.test @@ -28,3 +28,9 @@ CHECK2: === Merge: written 3 units RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3 CHECK3: === Minimizing the initial corpus of 6 units CHECK3: === Merge: written 0 units + + +# Check that when merge fails we print an error message. +RUN: echo 'Hi!' > %tmp/T1/HiI +RUN: not LLVMFuzzer-NullDerefTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=MERGE_FAIL +MERGE_FAIL: NOTE: merge did not succeed due to a failure on one of the inputs.