summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2019-05-23 00:22:46 +0000
committerKostya Serebryany <kcc@google.com>2019-05-23 00:22:46 +0000
commitb7cc3d9953312b1f31b673429fcd49864cae118b (patch)
tree48338cb7ce5c0696ca543e9b5fb80bf990dc38aa /compiler-rt/lib
parent020d7f1abbcbdf1e3b72140d77c8e63a0280add7 (diff)
downloadbcm5719-llvm-b7cc3d9953312b1f31b673429fcd49864cae118b.tar.gz
bcm5719-llvm-b7cc3d9953312b1f31b673429fcd49864cae118b.zip
[libFuzzer] automatically collect the data flow trace (DFT) in the fork mode if -collect_data_flow= is given
llvm-svn: 361448
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp2
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerDriver.cpp4
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerFork.cpp36
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerMerge.cpp1
-rw-r--r--compiler-rt/lib/fuzzer/FuzzerOptions.h1
5 files changed, 41 insertions, 3 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp
index 975a98afc50..74bfa8f32df 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerDataFlowTrace.cpp
@@ -174,6 +174,8 @@ bool DataFlowTrace::Init(const std::string &DirPath,
if (*FocusFunction == L)
FocusFuncIdx = NumFunctions - 1;
}
+ if (!NumFunctions)
+ return false;
if (*FocusFunction == "auto") {
// AUTOFOCUS works like this:
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
index 95ce8bbe994..d55caf4c6ec 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
@@ -700,6 +700,8 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Options.DataFlowTrace = Flags.data_flow_trace;
if (Flags.features_dir)
Options.FeaturesDir = Flags.features_dir;
+ if (Flags.collect_data_flow)
+ Options.CollectDataFlow = Flags.collect_data_flow;
Options.LazyCounters = Flags.lazy_counters;
unsigned Seed = Flags.seed;
@@ -710,7 +712,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
if (Flags.verbosity)
Printf("INFO: Seed: %u\n", Seed);
- if (Flags.collect_data_flow) {
+ if (Flags.collect_data_flow && !Flags.fork && !Flags.merge) {
if (RunIndividualFiles)
return CollectDataFlow(Flags.collect_data_flow, Flags.data_flow_trace,
ReadCorpora({}, *Inputs));
diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp
index dd16ec1e288..870a2244850 100644
--- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp
@@ -86,6 +86,8 @@ struct GlobalEnv {
Vector<std::string> CorpusDirs;
std::string MainCorpusDir;
std::string TempDir;
+ std::string DFTDir;
+ std::string DataFlowBinary;
Set<uint32_t> Features, Cov;
Vector<std::string> Files;
Random *Rand;
@@ -109,13 +111,18 @@ struct GlobalEnv {
Command Cmd(Args);
Cmd.removeFlag("fork");
Cmd.removeFlag("runs");
+ Cmd.removeFlag("collect_data_flow");
for (auto &C : CorpusDirs) // Remove all corpora from the args.
Cmd.removeArgument(C);
Cmd.addFlag("reload", "0"); // working in an isolated dir, no reload.
Cmd.addFlag("print_final_stats", "1");
Cmd.addFlag("print_funcs", "0"); // no need to spend time symbolizing.
Cmd.addFlag("max_total_time", std::to_string(std::min((size_t)300, JobId)));
-
+ if (!DataFlowBinary.empty()) {
+ Cmd.addFlag("data_flow_trace", DFTDir);
+ if (!Cmd.hasFlag("focus_function"))
+ Cmd.addFlag("focus_function", "auto");
+ }
auto Job = new FuzzJob;
std::string Seeds;
if (size_t CorpusSubsetSize =
@@ -124,7 +131,8 @@ struct GlobalEnv {
Seeds += (Seeds.empty() ? "" : ",") +
Files[Rand->SkewTowardsLast(Files.size())];
if (!Seeds.empty()) {
- Job->SeedListPath = std::to_string(JobId) + ".seeds";
+ Job->SeedListPath =
+ DirPlusFile(TempDir, std::to_string(JobId) + ".seeds");
WriteToFile(Seeds, Job->SeedListPath);
Cmd.addFlag("seed_inputs", "@" + Job->SeedListPath);
}
@@ -188,6 +196,7 @@ struct GlobalEnv {
auto NewPath = DirPlusFile(MainCorpusDir, Hash(U));
WriteToFile(U, NewPath);
Files.push_back(NewPath);
+ CollectDFT(NewPath);
}
Features.insert(NewFeatures.begin(), NewFeatures.end());
Cov.insert(NewCov.begin(), NewCov.end());
@@ -204,6 +213,23 @@ struct GlobalEnv {
Stats.average_exec_per_sec,
NumOOMs, NumTimeouts, NumCrashes, secondsSinceProcessStartUp());
}
+
+
+ void CollectDFT(const std::string &InputPath) {
+ if (DataFlowBinary.empty()) return;
+ Command Cmd(Args);
+ Cmd.removeFlag("fork");
+ Cmd.removeFlag("runs");
+ Cmd.addFlag("data_flow_trace", DFTDir);
+ Cmd.addArgument(InputPath);
+ for (auto &C : CorpusDirs) // Remove all corpora from the args.
+ Cmd.removeArgument(C);
+ Cmd.setOutputFile(DirPlusFile(TempDir, "dft.log"));
+ Cmd.combineOutAndErr();
+ // Printf("CollectDFT: %s %s\n", InputPath.c_str(), Cmd.toString().c_str());
+ ExecuteCommand(Cmd);
+ }
+
};
struct JobQueue {
@@ -248,14 +274,17 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
Env.Rand = &Rand;
Env.Verbosity = Options.Verbosity;
Env.ProcessStartTime = std::chrono::system_clock::now();
+ Env.DataFlowBinary = Options.CollectDataFlow;
Vector<SizedFile> SeedFiles;
for (auto &Dir : CorpusDirs)
GetSizedFilesFromDir(Dir, &SeedFiles);
std::sort(SeedFiles.begin(), SeedFiles.end());
Env.TempDir = TempPath(".dir");
+ Env.DFTDir = DirPlusFile(Env.TempDir, "DFT");
RmDirRecursive(Env.TempDir); // in case there is a leftover from old runs.
MkDir(Env.TempDir);
+ MkDir(Env.DFTDir);
if (CorpusDirs.empty())
@@ -267,6 +296,9 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
CrashResistantMerge(Env.Args, {}, SeedFiles, &Env.Files, {}, &Env.Features,
{}, &Env.Cov,
CFPath, false);
+ for (auto &F : Env.Files)
+ Env.CollectDFT(F);
+
RemoveFile(CFPath);
Printf("INFO: -fork=%d: %zd seed inputs, starting to fuzz in %s\n", NumJobs,
Env.Files.size(), Env.TempDir.c_str());
diff --git a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp
index dace45ece1d..75b2b5d59b9 100644
--- a/compiler-rt/lib/fuzzer/FuzzerMerge.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerMerge.cpp
@@ -324,6 +324,7 @@ void CrashResistantMerge(const Vector<std::string> &Args,
Command BaseCmd(Args);
BaseCmd.removeFlag("merge");
BaseCmd.removeFlag("fork");
+ BaseCmd.removeFlag("collect_data_flow");
for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) {
Fuzzer::MaybeExitGracefully();
VPrintf(V, "MERGE-OUTER: attempt %zd\n", Attempt);
diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h
index d48439daaf4..687f2ffa732 100644
--- a/compiler-rt/lib/fuzzer/FuzzerOptions.h
+++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h
@@ -51,6 +51,7 @@ struct FuzzingOptions {
std::string ExitOnItem;
std::string FocusFunction;
std::string DataFlowTrace;
+ std::string CollectDataFlow;
std::string FeaturesDir;
bool SaveArtifacts = true;
bool PrintNEW = true; // Print a status line when new units are found;
OpenPOWER on IntegriCloud