summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Fuzzer/FuzzerDriver.cpp1
-rw-r--r--llvm/lib/Fuzzer/FuzzerFlags.def1
-rw-r--r--llvm/lib/Fuzzer/FuzzerInternal.h1
-rw-r--r--llvm/lib/Fuzzer/FuzzerLoop.cpp30
4 files changed, 25 insertions, 8 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerDriver.cpp b/llvm/lib/Fuzzer/FuzzerDriver.cpp
index 664436ed4f9..c4cfc065156 100644
--- a/llvm/lib/Fuzzer/FuzzerDriver.cpp
+++ b/llvm/lib/Fuzzer/FuzzerDriver.cpp
@@ -245,6 +245,7 @@ int FuzzerDriver(const std::vector<std::string> &Args,
Options.OnlyASCII = Flags.only_ascii;
Options.TBMDepth = Flags.tbm_depth;
Options.TBMWidth = Flags.tbm_width;
+ Options.OutputCSV = Flags.output_csv;
if (Flags.runs >= 0)
Options.MaxNumberOfRuns = Flags.runs;
if (!Inputs->empty())
diff --git a/llvm/lib/Fuzzer/FuzzerFlags.def b/llvm/lib/Fuzzer/FuzzerFlags.def
index 8fc955c18bd..222fa6d12a6 100644
--- a/llvm/lib/Fuzzer/FuzzerFlags.def
+++ b/llvm/lib/Fuzzer/FuzzerFlags.def
@@ -69,3 +69,4 @@ FUZZER_FLAG_STRING(artifact_prefix, "Write fuzzing artifacts (crash, "
"$(artifact_prefix)file")
FUZZER_FLAG_INT(drill, 0, "Experimental: fuzz using a single unit as the seed "
"corpus, then merge with the initial corpus")
+FUZZER_FLAG_INT(output_csv, 0, "Enable pulse output in CSV format.")
diff --git a/llvm/lib/Fuzzer/FuzzerInternal.h b/llvm/lib/Fuzzer/FuzzerInternal.h
index 7cb78fd91ee..9d1849f210f 100644
--- a/llvm/lib/Fuzzer/FuzzerInternal.h
+++ b/llvm/lib/Fuzzer/FuzzerInternal.h
@@ -96,6 +96,7 @@ class Fuzzer {
std::string ArtifactPrefix = "./";
bool SaveArtifacts = true;
bool PrintNEW = true; // Print a status line when new units are found;
+ bool OutputCSV = false;
};
Fuzzer(UserSuppliedFuzzer &USF, FuzzingOptions Options);
void AddToCorpus(const Unit &U) { Corpus.push_back(U); }
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp
index d3c32626a3b..455aa625337 100644
--- a/llvm/lib/Fuzzer/FuzzerLoop.cpp
+++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp
@@ -108,9 +108,23 @@ void Fuzzer::AlarmCallback() {
}
void Fuzzer::PrintStats(const char *Where, const char *End) {
- if (!Options.Verbosity) return;
size_t Seconds = secondsSinceProcessStartUp();
size_t ExecPerSec = (Seconds ? TotalNumberOfRuns / Seconds : 0);
+
+ if (Options.OutputCSV) {
+ static bool csvHeaderPrinted = false;
+ if (!csvHeaderPrinted) {
+ csvHeaderPrinted = true;
+ Printf("runs,block_cov,bits,cc_cov,corpus,execs_per_sec,tbms,reason\n");
+ }
+ Printf("%zd,%zd,%zd,%zd,%zd,%zd,%zd,%s\n", TotalNumberOfRuns,
+ LastRecordedBlockCoverage, TotalBits(),
+ LastRecordedCallerCalleeCoverage, Corpus.size(), ExecPerSec,
+ TotalNumberOfExecutedTraceBasedMutations, Where);
+ }
+
+ if (!Options.Verbosity)
+ return;
Printf("#%zd\t%s", TotalNumberOfRuns, Where);
if (LastRecordedBlockCoverage)
Printf(" cov: %zd", LastRecordedBlockCoverage);
@@ -144,8 +158,7 @@ void Fuzzer::RereadOutputCorpus() {
CurrentUnit.insert(CurrentUnit.begin(), X.begin(), X.end());
if (RunOne(CurrentUnit)) {
Corpus.push_back(X);
- if (Options.Verbosity >= 1)
- PrintStats("RELOAD");
+ PrintStats("RELOAD");
}
}
}
@@ -198,9 +211,8 @@ bool Fuzzer::RunOne(const Unit &U) {
auto UnitStopTime = system_clock::now();
auto TimeOfUnit =
duration_cast<seconds>(UnitStopTime - UnitStartTime).count();
- if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1))
- && secondsSinceProcessStartUp() >= 2
- && Options.Verbosity)
+ if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&
+ secondsSinceProcessStartUp() >= 2)
PrintStats("pulse ");
if (TimeOfUnit > TimeOfLongestUnitInSeconds &&
TimeOfUnit >= Options.ReportSlowUnits) {
@@ -452,11 +464,11 @@ void Fuzzer::Loop() {
SyncCorpus();
RereadOutputCorpus();
if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
- return;
+ break;
if (Options.MaxTotalTimeSec > 0 &&
secondsSinceProcessStartUp() >
static_cast<size_t>(Options.MaxTotalTimeSec))
- return;
+ break;
CurrentUnit = Corpus[J1];
// Optionally, cross with another unit.
if (Options.DoCrossOver && USF.GetRand().RandBool()) {
@@ -476,6 +488,8 @@ void Fuzzer::Loop() {
// Perform several mutations and runs.
MutateAndTestOne(&CurrentUnit);
}
+
+ PrintStats("DONE ", "\n");
}
void Fuzzer::SyncCorpus() {
OpenPOWER on IntegriCloud