diff options
| -rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerMerge.cpp | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp index 6f111a5e4d7..78f2253a48c 100644 --- a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp @@ -221,6 +221,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { M.Files.size() - M.FirstNotProcessedFile); std::ofstream OF(CFPath, std::ofstream::out | std::ofstream::app); + Set<size_t> AllFeatures; for (size_t i = M.FirstNotProcessedFile; i < M.Files.size(); i++) { auto U = FileToVector(M.Files[i].Name); if (U.size() > MaxInputLen) { @@ -234,10 +235,15 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { // Run. TPC.ResetMaps(); ExecuteCallback(U.data(), U.size()); - // Collect coverage. - Set<size_t> Features; + // Collect coverage. We are iterating over the files in this order: + // * First, files in the initial corpus ordered by size, smallest first. + // * Then, all other files, smallest first. + // So it makes no sense to record all features for all files, instead we + // only record features that were not seen before. + Set<size_t> UniqFeatures; TPC.CollectFeatures([&](size_t Feature) -> bool { - Features.insert(Feature); + if (AllFeatures.insert(Feature).second) + UniqFeatures.insert(Feature); return true; }); // Show stats. @@ -245,7 +251,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { PrintStats("pulse "); // Write the post-run marker and the coverage. OF << "DONE " << i; - for (size_t F : Features) + for (size_t F : UniqFeatures) OF << " " << std::hex << F; OF << "\n"; } @@ -260,11 +266,13 @@ void Fuzzer::CrashResistantMerge(const Vector<std::string> &Args, Printf("Merge requires two or more corpus dirs\n"); return; } - Vector<std::string> AllFiles; - ListFilesInDirRecursive(Corpora[0], nullptr, &AllFiles, /*TopDir*/true); + Vector<SizedFile> AllFiles; + GetSizedFilesFromDir(Corpora[0], &AllFiles); size_t NumFilesInFirstCorpus = AllFiles.size(); + std::sort(AllFiles.begin(), AllFiles.end()); for (size_t i = 1; i < Corpora.size(); i++) - ListFilesInDirRecursive(Corpora[i], nullptr, &AllFiles, /*TopDir*/true); + GetSizedFilesFromDir(Corpora[i], &AllFiles); + std::sort(AllFiles.begin() + NumFilesInFirstCorpus, AllFiles.end()); Printf("MERGE-OUTER: %zd files, %zd in the initial corpus\n", AllFiles.size(), NumFilesInFirstCorpus); auto CFPath = DirPlusFile(TmpDir(), @@ -274,8 +282,8 @@ void Fuzzer::CrashResistantMerge(const Vector<std::string> &Args, std::ofstream ControlFile(CFPath); ControlFile << AllFiles.size() << "\n"; ControlFile << NumFilesInFirstCorpus << "\n"; - for (auto &Path: AllFiles) - ControlFile << Path << "\n"; + for (auto &SF: AllFiles) + ControlFile << SF.File << "\n"; if (!ControlFile) { Printf("MERGE-OUTER: failed to write to the control file: %s\n", CFPath.c_str()); |

