From: Kostya Serebryany Date: Tue, 12 May 2015 18:51:57 +0000 (+0000) Subject: [lib/Fuzzer] guess the right number of workers if -jobs=N is given but -workers=M... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=eaba2dd2f13a53fd148ccd41c27214c147b958b0 [lib/Fuzzer] guess the right number of workers if -jobs=N is given but -workers=M is not. Update the docs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237163 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LibFuzzer.rst b/docs/LibFuzzer.rst index 949ccd58418..d454b741ba0 100644 --- a/docs/LibFuzzer.rst +++ b/docs/LibFuzzer.rst @@ -156,13 +156,11 @@ You may run ``N`` independent fuzzer jobs in parallel on ``M`` CPUs:: N=100; M=4; ./pcre_fuzzer ./CORPUS -jobs=$N -workers=$M -This is useful when you already have an exhaustive test corpus. -If you've just started fuzzing with no good corpus running independent -jobs will create a corpus with too many duplicates. -One way to avoid this and still use all of your CPUs is to use the flag ``-exit_on_first=1`` -which will cause the fuzzer to exit on the first new synthesised input:: +By default (``-reload=1``) the fuzzer processes will periodically scan the CORPUS directory +and reload any new tests. This way the test inputs found by one process will be picked up +by all others. - N=100; M=4; ./pcre_fuzzer ./CORPUS -jobs=$N -workers=$M -exit_on_first=1 +If ``-workers=$M`` is not supplied, ``min($N,NumberOfCpuCore/2)`` will be used. Heartbleed ---------- diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index 8e960c4f570..d1f6953a748 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -203,6 +203,12 @@ int FuzzerDriver(int argc, char **argv, UserCallback Callback) { return 0; } + if (Flags.jobs > 0 && Flags.workers == 0) { + Flags.workers = std::min(NumberOfCpuCores() / 2, Flags.jobs); + if (Flags.workers > 1) + std::cerr << "Running " << Flags.workers << " workers\n"; + } + if (Flags.workers > 0 && Flags.jobs > 0) return RunInMultipleProcesses(argc, argv, Flags.workers, Flags.jobs); diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def index 25dffe452b8..4507fdadee7 100644 --- a/lib/Fuzzer/FuzzerFlags.def +++ b/lib/Fuzzer/FuzzerFlags.def @@ -44,7 +44,8 @@ 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.") + "Number of simultaneous worker processes to run the jobs." + " If zero, \"min(jobs,NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload, 1, "Reload the main corpus periodically to get new units" "discovered by other processes.") diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index 868668885b3..496b6db1650 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -44,6 +44,8 @@ std::string Hash(const Unit &U); void SetTimer(int Seconds); void PrintFileAsBase64(const std::string &Path); +int NumberOfCpuCores(); + class Fuzzer { public: struct FuzzingOptions { diff --git a/lib/Fuzzer/FuzzerUtil.cpp b/lib/Fuzzer/FuzzerUtil.cpp index 3635f39a10d..dc7154ca385 100644 --- a/lib/Fuzzer/FuzzerUtil.cpp +++ b/lib/Fuzzer/FuzzerUtil.cpp @@ -61,4 +61,12 @@ void SetTimer(int Seconds) { assert(Res == 0); } +int NumberOfCpuCores() { + FILE *F = popen("nproc", "r"); + int N = 0; + fscanf(F, "%d", &N); + fclose(F); + return N; +} + } // namespace fuzzer