[libFuzzer] fork mode: try harder to cleanup after itself

llvm-svn: 354186
GitOrigin-RevId: 312af158b0b866fcde2d9d2c8cae8fc6ed8942bb
diff --git a/FuzzerFork.cpp b/FuzzerFork.cpp
index 09da192..1f7fe9b 100644
--- a/FuzzerFork.cpp
+++ b/FuzzerFork.cpp
@@ -19,6 +19,7 @@
 #include <atomic>
 #include <chrono>
 #include <fstream>
+#include <memory>
 #include <mutex>
 #include <queue>
 #include <sstream>
@@ -67,6 +68,12 @@
 
   // Fuzzing Outputs.
   int ExitCode;
+
+  ~FuzzJob() {
+    RemoveFile(CFPath);
+    RemoveFile(LogPath);
+    RmDirRecursive(CorpusDir);
+  }
 };
 
 struct GlobalEnv {
@@ -141,14 +148,12 @@
     Set<uint32_t> NewFeatures, NewCov;
     CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features,
                         &NewFeatures, Cov, &NewCov, Job->CFPath, false);
-    RemoveFile(Job->CFPath);
     for (auto &Path : FilesToAdd) {
       auto U = FileToVector(Path);
       auto NewPath = DirPlusFile(MainCorpusDir, Hash(U));
       WriteToFile(U, NewPath);
       Files.push_back(NewPath);
     }
-    RmDirRecursive(Job->CorpusDir);
     Features.insert(NewFeatures.begin(), NewFeatures.end());
     Cov.insert(NewCov.begin(), NewCov.end());
     for (auto Idx : NewCov)
@@ -246,7 +251,7 @@
   }
 
   while (true) {
-    auto Job = MergeQ.Pop();
+    std::unique_ptr<FuzzJob> Job(MergeQ.Pop());
     if (!Job) {
       if (Stop)
         break;
@@ -254,16 +259,19 @@
       continue;
     }
     ExitCode = Job->ExitCode;
-    if (ExitCode != Options.InterruptExitCode)
-      Env.RunOneMergeJob(Job);
+    if (ExitCode == Options.InterruptExitCode) {
+      Printf("==%lu== libFuzzer: a child was interrupted; exiting\n", GetPid());
+      Stop = true;
+      break;
+    }
+
+    Env.RunOneMergeJob(Job.get());
 
     // Continue if our crash is one of the ignorred ones.
     if (Options.IgnoreTimeouts && ExitCode == Options.TimeoutExitCode)
       Env.NumTimeouts++;
     else if (Options.IgnoreOOMs && ExitCode == Options.OOMExitCode)
       Env.NumOOMs++;
-    else if (ExitCode == Options.InterruptExitCode)
-      Stop = true;
     else if (ExitCode != 0) {
       Env.NumCrashes++;
       if (Options.IgnoreCrashes) {
@@ -279,8 +287,6 @@
         Stop = true;
       }
     }
-    RemoveFile(Job->LogPath);
-    delete Job;
 
     // Stop if we are over the time budget.
     // This is not precise, since other threads are still running
@@ -298,11 +304,13 @@
   }
   Stop = true;
 
+  // The workers have already finished doing useful work, or
+  // we were interrupted. Either way, cleanup up now.
+  RmDirRecursive(Env.TempDir);
+
   for (auto &T : Threads)
     T.join();
 
-  RmDirRecursive(Env.TempDir);
-
   // Use the exit code from the last child process.
   Printf("INFO: exiting: %d time: %zds\n", ExitCode,
          Env.secondsSinceProcessStartUp());
diff --git a/FuzzerLoop.cpp b/FuzzerLoop.cpp
index 7dc2fd4..75dc600 100644
--- a/FuzzerLoop.cpp
+++ b/FuzzerLoop.cpp
@@ -258,6 +258,7 @@
 void Fuzzer::MaybeExitGracefully() {
   if (!F->GracefulExitRequested) return;
   Printf("==%lu== INFO: libFuzzer: exiting as requested\n", GetPid());
+  RmDirRecursive(TempPath(".dir"));
   F->PrintFinalStats();
   _Exit(0);
 }
@@ -265,6 +266,7 @@
 void Fuzzer::InterruptCallback() {
   Printf("==%lu== libFuzzer: run interrupted; exiting\n", GetPid());
   PrintFinalStats();
+  RmDirRecursive(TempPath(".dir"));
   // Stop right now, don't perform any at-exit actions.
   _Exit(Options.InterruptExitCode);
 }