summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2019-02-12 00:12:33 +0000
committerKostya Serebryany <kcc@google.com>2019-02-12 00:12:33 +0000
commit63f48717b58d76523fdbfdba6fa1e2c10ae9e3da (patch)
tree4d83c194d8dd5d507aac81d062664802b4df0929 /compiler-rt/lib/fuzzer/FuzzerDriver.cpp
parent9ebc9dbd3c7d8ce5fb35d3d166279b39808dac0b (diff)
downloadbcm5719-llvm-63f48717b58d76523fdbfdba6fa1e2c10ae9e3da.tar.gz
bcm5719-llvm-63f48717b58d76523fdbfdba6fa1e2c10ae9e3da.zip
[libFuzzer] extend the -fork=1 functionality. Still not fully usable, but good enough for the first unit test
llvm-svn: 353775
Diffstat (limited to 'compiler-rt/lib/fuzzer/FuzzerDriver.cpp')
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerDriver.cpp66
1 files changed, 48 insertions, 18 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
index c381fb84452..232b3a8732a 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
@@ -472,46 +472,76 @@ int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {
}
// This is just a skeleton of an experimental -fork=1 feature.
-void FuzzWithFork(const FuzzingOptions &Options,
+void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options,
const Vector<std::string> &Args,
const Vector<std::string> &Corpora) {
Printf("INFO: -fork=1: doing fuzzing in a separate process in order to "
"be more resistant to crashes, timeouts, and OOMs\n");
+ auto Rand = F->GetMD().GetRand();
Vector<SizedFile> Corpus;
for (auto &Dir : Corpora)
GetSizedFilesFromDir(Dir, &Corpus);
std::sort(Corpus.begin(), Corpus.end());
+ auto CFPath = TempPath(".fork");
Vector<std::string> Files;
Set<uint32_t> Features;
if (!Corpus.empty()) {
- auto CFPath = TempPath(".fork");
CrashResistantMerge(Args, {}, Corpus, &Files, {}, &Features, CFPath);
RemoveFile(CFPath);
}
- Printf("INFO: -fork=1: %zd seeds, starting to fuzz\n", Files.size());
+ auto TempDir = TempPath("Dir");
+ MkDir(TempDir);
+ Printf("INFO: -fork=1: %zd seeds, starting to fuzz; scratch: %s\n",
+ Files.size(), TempDir.c_str());
- Command Cmd(Args);
- Cmd.removeFlag("fork");
+ Command BaseCmd(Args);
+ BaseCmd.removeFlag("fork");
for (auto &C : Corpora) // Remove all corpora from the args.
- Cmd.removeArgument(C);
- if (Files.size() >= 2)
- Cmd.addFlag("seed_inputs",
- Files.back() + "," + Files[Files.size() - 2]);
- Cmd.addFlag("runs", "1000000");
- Cmd.addFlag("max_total_time", "30");
- for (size_t i = 0; i < 1000; i++) {
+ BaseCmd.removeArgument(C);
+ BaseCmd.addFlag("runs", "1000000");
+ BaseCmd.addFlag("max_total_time", "30");
+ BaseCmd.addArgument(TempDir);
+ int ExitCode = 0;
+ for (size_t i = 0; i < 1000000; i++) {
+ // TODO: take new files from disk e.g. those generated by another process.
+ Command Cmd(BaseCmd);
+ if (Files.size() >= 2)
+ Cmd.addFlag("seed_inputs",
+ Files[Rand.SkewTowardsLast(Files.size())] + "," +
+ Files[Rand.SkewTowardsLast(Files.size())]);
Printf("RUN %s\n", Cmd.toString().c_str());
- int ExitCode = ExecuteCommand(Cmd);
+ RmFilesInDir(TempDir);
+ ExitCode = ExecuteCommand(Cmd);
+ Printf("Exit code: %d\n", ExitCode);
if (ExitCode == Options.InterruptExitCode)
- exit(0);
- if (ExitCode == Options.TimeoutExitCode || ExitCode == Options.OOMExitCode)
- continue;
+ break;
+ Vector<SizedFile> TempFiles;
+ Vector<std::string>FilesToAdd;
+ Set<uint32_t> NewFeatures;
+ GetSizedFilesFromDir(TempDir, &TempFiles);
+ CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features,
+ &NewFeatures, CFPath);
+ RemoveFile(CFPath);
+ for (auto &Path : FilesToAdd) {
+ auto NewPath = F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
+ if (!NewPath.empty())
+ Files.push_back(NewPath);
+ }
+ Features.insert(NewFeatures.begin(), NewFeatures.end());
+ Printf("INFO: temp_files: %zd files_added: %zd newft: %zd ft: %zd\n",
+ TempFiles.size(), FilesToAdd.size(), NewFeatures.size(),
+ Features.size());
if (ExitCode != 0) break;
}
- exit(0);
+ RmFilesInDir(TempDir);
+ RmDir(TempDir);
+
+ // Use the exit code from the last child process.
+ Printf("Fork: exiting: %d\n", ExitCode);
+ exit(ExitCode);
}
void Merge(Fuzzer *F, FuzzingOptions &Options, const Vector<std::string> &Args,
@@ -770,7 +800,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
}
if (Flags.fork)
- FuzzWithFork(Options, Args, *Inputs);
+ FuzzWithFork(F, Options, Args, *Inputs);
if (Flags.merge)
Merge(F, Options, Args, *Inputs, Flags.merge_control_file);
OpenPOWER on IntegriCloud