diff options
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerFlags.def | 5 | ||||
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerMain.cpp | 35 |
2 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerFlags.def b/llvm/lib/Fuzzer/FuzzerFlags.def index 264c105950c..cbaa81e0384 100644 --- a/llvm/lib/Fuzzer/FuzzerFlags.def +++ b/llvm/lib/Fuzzer/FuzzerFlags.def @@ -29,3 +29,8 @@ FUZZER_FLAG(int, use_full_coverage_set, 0, "Maximize the number of different full" " coverage sets as opposed to maximizing the total coverage." " This is potentially MUCH slower, but may discover more paths.") +FUZZER_FLAG(int, 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.") +FUZZER_FLAG(int, workers, 0, + "Number of simultaneous worker processes to run the jobs.") diff --git a/llvm/lib/Fuzzer/FuzzerMain.cpp b/llvm/lib/Fuzzer/FuzzerMain.cpp index 03e0566049d..e0720b41bb0 100644 --- a/llvm/lib/Fuzzer/FuzzerMain.cpp +++ b/llvm/lib/Fuzzer/FuzzerMain.cpp @@ -15,6 +15,8 @@ #include <cstring> #include <unistd.h> #include <iostream> +#include <thread> +#include <atomic> // ASAN options: // * don't dump the coverage to disk. @@ -102,6 +104,35 @@ static void ParseFlags(int argc, char **argv) { } } +static void WorkerThread(const std::string &Cmd, std::atomic<int> *Counter, + int NumJobs) { + while (true) { + int C = (*Counter)++; + if (C >= NumJobs) return; + std::string ToRun = Cmd + " > fuzz-" + std::to_string(C) + ".log 2>&1\n"; + if (Flags.verbosity) + std::cerr << ToRun; + system(ToRun.c_str()); + } +} + +static int RunInMultipleProcesses(int argc, char **argv, int NumWorkers, + int NumJobs) { + std::atomic<int> Counter(0); + std::string Cmd; + for (int i = 0; i < argc; i++) { + if (FlagValue(argv[i], "jobs") || FlagValue(argv[i], "workers")) continue; + Cmd += argv[i]; + Cmd += " "; + } + std::vector<std::thread> V; + for (int i = 0; i < NumWorkers; i++) + V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs)); + for (auto &T : V) + T.join(); + return 0; +} + int main(int argc, char **argv) { using namespace fuzzer; @@ -111,6 +142,10 @@ int main(int argc, char **argv) { PrintHelp(); return 0; } + + if (Flags.workers > 0 && Flags.jobs > 0) + return RunInMultipleProcesses(argc, argv, Flags.workers, Flags.jobs); + Fuzzer::FuzzingOptions Options; Options.Verbosity = Flags.verbosity; Options.MaxLen = Flags.max_len; |