diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index ceaa9070512f0..2058e25388fb0 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -867,7 +867,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { } if (Flags.fork) - FuzzWithFork(F->GetMD().GetRand(), Options, Args, *Inputs, Flags.fork); + FuzzWithFork(F->GetMD().GetRand(), Options, Args, *Inputs, Flags.fork, Flags.NumCorpuses); if (Flags.merge) Merge(F, Options, Args, *Inputs, Flags.merge_control_file); diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def index ab31da0ae5d60..03e5b0ef9048f 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFlags.def +++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def @@ -56,6 +56,7 @@ FUZZER_FLAG_INT(timeout_exitcode, 70, "When libFuzzer reports a timeout " FUZZER_FLAG_INT(max_total_time, 0, "If positive, indicates the maximal total " "time in seconds to run the fuzzer.") FUZZER_FLAG_INT(help, 0, "Print help.") +FUZZER_FLAG_INT(NumCorpuses, 1, "Divide the corpus into N parts according to size.") FUZZER_FLAG_INT(fork, 0, "Experimental mode where fuzzing happens " "in a subprocess") FUZZER_FLAG_INT(ignore_timeouts, 1, "Ignore timeouts in fork mode") diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp index 5134a5d979e6b..3dfc4385a4e68 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp @@ -114,7 +114,7 @@ struct GlobalEnv { .count(); } - FuzzJob *CreateNewJob(size_t JobId) { + FuzzJob *CreateNewJob(size_t JobId, int NumCorpuses) { Command Cmd(Args); Cmd.removeFlag("fork"); Cmd.removeFlag("runs"); @@ -133,7 +133,7 @@ struct GlobalEnv { } auto Job = new FuzzJob; std::string Seeds; - if (size_t CorpusSubsetSize = + /*if (size_t CorpusSubsetSize = std::min(Files.size(), (size_t)sqrt(Files.size() + 2))) { auto Time1 = std::chrono::system_clock::now(); for (size_t i = 0; i < CorpusSubsetSize; i++) { @@ -145,6 +145,31 @@ struct GlobalEnv { auto DftTimeInSeconds = duration_cast(Time2 - Time1).count(); assert(DftTimeInSeconds < std::numeric_limits::max()); Job->DftTimeInSeconds = static_cast(DftTimeInSeconds); + }*/ + if (size_t CorpusSubsetSize = + std::min(Files.size(), (size_t)sqrt(Files.size() + 2))) { + size_t AverageSize = Files.size()/NumCorpuses +1; + auto Time1 = std::chrono::system_clock::now(); + size_t StartIndex = ((JobId-1)%NumCorpuses) * AverageSize; + printf("\n Job %d Choose Corpus %d ",JobId,(JobId)%NumCorpuses); + for (size_t i = 0; i < CorpusSubsetSize; i++) { + size_t j = Rand->SkewTowardsLast(AverageSize); + size_t m = j + StartIndex; + if (m < Files.size()) { + auto &SF = Files[m]; + Seeds += (Seeds.empty() ? "" : ",") + SF; + CollectDFT(SF); + } + else { + auto &SF = Files[Rand->SkewTowardsLast(Files.size())]; + Seeds += (Seeds.empty() ? "" : ",") + SF; + CollectDFT(SF); + } + } + auto Time2 = std::chrono::system_clock::now(); + auto DftTimeInSeconds = duration_cast(Time2 - Time1).count(); + assert(DftTimeInSeconds < std::numeric_limits::max()); + Job->DftTimeInSeconds = static_cast(DftTimeInSeconds); } if (!Seeds.empty()) { Job->SeedListPath = @@ -284,7 +309,7 @@ void WorkerThread(JobQueue *FuzzQ, JobQueue *MergeQ) { // This is just a skeleton of an experimental -fork=1 feature. void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, const Vector &Args, - const Vector &CorpusDirs, int NumJobs) { + const Vector &CorpusDirs, int NumJobs, int NumCorpuses) { Printf("INFO: -fork=%d: fuzzing in separate process(s)\n", NumJobs); GlobalEnv Env; @@ -341,8 +366,9 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, Vector Threads; for (int t = 0; t < NumJobs; t++) { Threads.push_back(std::thread(WorkerThread, &FuzzQ, &MergeQ)); - FuzzQ.Push(Env.CreateNewJob(JobId++)); + FuzzQ.Push(Env.CreateNewJob(JobId++, NumCorpuses)); } + //printf("\n 创建%d个jobs\n",NumJobs); while (true) { std::unique_ptr Job(MergeQ.Pop()); @@ -399,7 +425,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, break; } - FuzzQ.Push(Env.CreateNewJob(JobId++)); + FuzzQ.Push(Env.CreateNewJob(JobId++, NumCorpuses)); } for (auto &T : Threads) diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.h b/compiler-rt/lib/fuzzer/FuzzerFork.h index b29a43e13fbc5..5bf40d0b13265 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFork.h +++ b/compiler-rt/lib/fuzzer/FuzzerFork.h @@ -18,7 +18,7 @@ namespace fuzzer { void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, const Vector &Args, - const Vector &CorpusDirs, int NumJobs); + const Vector &CorpusDirs, int NumJobs, int NumCorpuses); } // namespace fuzzer #endif // LLVM_FUZZER_FORK_H