[lib/Fuzzer] guess the right number of workers if -jobs=N is given but -workers=M...
authorKostya Serebryany <kcc@google.com>
Tue, 12 May 2015 18:51:57 +0000 (18:51 +0000)
committerKostya Serebryany <kcc@google.com>
Tue, 12 May 2015 18:51:57 +0000 (18:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237163 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LibFuzzer.rst
lib/Fuzzer/FuzzerDriver.cpp
lib/Fuzzer/FuzzerFlags.def
lib/Fuzzer/FuzzerInternal.h
lib/Fuzzer/FuzzerUtil.cpp

index 949ccd5841876218f9b541cc26669d533ab920e1..d454b741ba07ae44f643297042a1d52275062d1c 100644 (file)
@@ -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
 ----------
index 8e960c4f570e83a5c2e69da4df91ba19dc5e9781..d1f6953a748941925efc23d48a82e5ec16876faf 100644 (file)
@@ -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);
 
index 25dffe452b82ff2962b17ab5db31d4e0dc9cc46c..4507fdadee73e6a45e2a1f7bb3f0fd56ea788ed9 100644 (file)
@@ -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.")
index 868668885b364b0374e28bfe43cf603458a3fbef..496b6db1650d9cee3511d145e11fedbd782c5dd9 100644 (file)
@@ -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 {
index 3635f39a10def348bec49580a346884229c1afc7..dc7154ca385db2f92aab09f941bf515250926e06 100644 (file)
@@ -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