forked from OSchip/llvm-project
output_csv libfuzzer option
Summary: The option outputs statistics in CSV format preceded by 1 header line. This is intended for machine processing of the output. -verbosity=0 should likely be set. Differential Revision: http://reviews.llvm.org/D14600 llvm-svn: 252856
This commit is contained in:
parent
3702255bc9
commit
a9c2387192
|
@ -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())
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue