diff options
| -rw-r--r-- | lib/fuzzer/FuzzerFork.cpp | 30 | ||||
| -rw-r--r-- | lib/fuzzer/FuzzerLoop.cpp | 2 | ||||
| -rw-r--r-- | test/fuzzer/fork-sigusr.test | 15 |
3 files changed, 36 insertions, 11 deletions
diff --git a/lib/fuzzer/FuzzerFork.cpp b/lib/fuzzer/FuzzerFork.cpp index 09da1924b..1f7fe9b33 100644 --- a/lib/fuzzer/FuzzerFork.cpp +++ b/lib/fuzzer/FuzzerFork.cpp @@ -19,6 +19,7 @@ #include <atomic> #include <chrono> #include <fstream> +#include <memory> #include <mutex> #include <queue> #include <sstream> @@ -67,6 +68,12 @@ struct FuzzJob { // Fuzzing Outputs. int ExitCode; + + ~FuzzJob() { + RemoveFile(CFPath); + RemoveFile(LogPath); + RmDirRecursive(CorpusDir); + } }; struct GlobalEnv { @@ -141,14 +148,12 @@ struct GlobalEnv { 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 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, } while (true) { - auto Job = MergeQ.Pop(); + std::unique_ptr<FuzzJob> Job(MergeQ.Pop()); if (!Job) { if (Stop) break; @@ -254,16 +259,19 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, 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 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, 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 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, } 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/lib/fuzzer/FuzzerLoop.cpp b/lib/fuzzer/FuzzerLoop.cpp index 7dc2fd48d..75dc60087 100644 --- a/lib/fuzzer/FuzzerLoop.cpp +++ b/lib/fuzzer/FuzzerLoop.cpp @@ -258,6 +258,7 @@ void Fuzzer::ExitCallback() { 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::MaybeExitGracefully() { 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); } diff --git a/test/fuzzer/fork-sigusr.test b/test/fuzzer/fork-sigusr.test new file mode 100644 index 000000000..f00a8b387 --- /dev/null +++ b/test/fuzzer/fork-sigusr.test @@ -0,0 +1,15 @@ +# Check that libFuzzer honors SIGUSR1/SIGUSR2 +# FIXME: Disabled on Windows for now because of reliance on posix only features +# (eg: export, "&", pkill). +UNSUPPORTED: darwin, windows +RUN: rm -rf %t +RUN: mkdir -p %t +RUN: %cpp_compiler %S/ShallowOOMDeepCrash.cpp -o %t/ForkSIGUSR + +RUN: %run %t/ForkSIGUSR -fork=3 -rss_limit_mb=128 -ignore_crashes=1 2> %t/log & export PID=$! +RUN: sleep 3 +RUN: pkill -SIGUSR2 -f %t/ForkSIGUSR +RUN: sleep 3 +RUN: cat %t/log | FileCheck %s + +CHECK: libFuzzer: {{.*}}exiting |
