private:
void AlarmCallback();
void MutateAndTestOne(Unit *U);
- void ReportNewCoverage(size_t NewCoverage, const Unit &U);
- size_t RunOne(const Unit &U);
+ void ReportNewCoverage(const Unit &U);
+ bool RunOne(const Unit &U);
void RunOneAndUpdateCorpus(Unit &U);
- size_t RunOneMaximizeTotalCoverage(const Unit &U);
- size_t RunOneMaximizeCoveragePairs(const Unit &U);
void WriteToOutputCorpus(const Unit &U);
void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
void PrintStats(const char *Where, size_t Cov, const char *End = "\n");
void SyncCorpus();
+ size_t RecordBlockCoverage();
+ void PrepareCoverageBeforeRun();
+ bool CheckCoverageAfterRun();
+
+
// Trace-based fuzzing: we run a unit with some kind of tracing
// enabled and record potentially useful mutations. Then
// We apply these mutations one by one to the unit and run it again.
system_clock::time_point UnitStartTime;
long TimeOfLongestUnitInSeconds = 0;
long EpochOfLastReadOfOutputCorpus = 0;
+ size_t LastRecordedBlockCoverage = 0;
};
class SimpleUserSuppliedFuzzer: public UserSuppliedFuzzer {
if (!Options.Verbosity) return;
size_t Seconds = secondsSinceProcessStartUp();
size_t ExecPerSec = (Seconds ? TotalNumberOfRuns / Seconds : 0);
- Printf("#%zd\t%s cov: %zd bits: %zd units: %zd exec/s: %zd",
- TotalNumberOfRuns, Where, Cov, TotalBits(), Corpus.size(), ExecPerSec);
+ Printf("#%zd\t%s", TotalNumberOfRuns, Where);
+ Printf(" cov: %zd", Cov);
+ if (auto TB = TotalBits())
+ Printf(" bits: %zd", TB);
+ Printf(" units: %zd exec/s: %zd", Corpus.size(), ExecPerSec);
if (TotalNumberOfExecutedTraceBasedMutations)
Printf(" tbm: %zd", TotalNumberOfExecutedTraceBasedMutations);
Printf("%s", End);
if (UnitHashesAddedToCorpus.insert(Hash(X)).second) {
CurrentUnit.clear();
CurrentUnit.insert(CurrentUnit.begin(), X.begin(), X.end());
- size_t NewCoverage = RunOne(CurrentUnit);
- if (NewCoverage) {
+ if (RunOne(CurrentUnit)) {
Corpus.push_back(X);
if (Options.Verbosity >= 1)
- PrintStats("RELOAD", NewCoverage);
+ PrintStats("RELOAD", LastRecordedBlockCoverage);
}
}
}
}
void Fuzzer::ShuffleAndMinimize() {
- size_t MaxCov = 0;
bool PreferSmall = (Options.PreferSmallDuringInitialShuffle == 1 ||
(Options.PreferSmallDuringInitialShuffle == -1 &&
USF.GetRand().RandBool()));
U.insert(U.begin(), C.begin() + First, C.begin() + Last);
if (Options.OnlyASCII)
ToASCII(U);
- size_t NewCoverage = RunOne(U);
- if (NewCoverage) {
- MaxCov = NewCoverage;
+ if (RunOne(U)) {
NewCorpus.push_back(U);
if (Options.Verbosity >= 2)
- Printf("NEW0: %zd L %zd\n", NewCoverage, U.size());
+ Printf("NEW0: %zd L %zd\n", LastRecordedBlockCoverage, U.size());
}
}
}
Corpus = NewCorpus;
for (auto &X : Corpus)
UnitHashesAddedToCorpus.insert(Hash(X));
- PrintStats("INITED", MaxCov);
+ PrintStats("INITED", LastRecordedBlockCoverage);
}
-size_t Fuzzer::RunOne(const Unit &U) {
+bool Fuzzer::RunOne(const Unit &U) {
UnitStartTime = system_clock::now();
TotalNumberOfRuns++;
- size_t Res = RunOneMaximizeTotalCoverage(U);
+
+ PrepareCoverageBeforeRun();
+ ExecuteCallback(U);
+ bool Res = CheckCoverageAfterRun();
+
auto UnitStopTime = system_clock::now();
auto TimeOfUnit =
duration_cast<seconds>(UnitStopTime - UnitStartTime).count();
+ if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) && Options.Verbosity)
+ PrintStats("pulse ", LastRecordedBlockCoverage);
if (TimeOfUnit > TimeOfLongestUnitInSeconds &&
TimeOfUnit >= Options.ReportSlowUnits) {
TimeOfLongestUnitInSeconds = TimeOfUnit;
return;
if (Options.OnlyASCII)
ToASCII(U);
- ReportNewCoverage(RunOne(U), U);
+ if (RunOne(U))
+ ReportNewCoverage(U);
}
void Fuzzer::ExecuteCallback(const Unit &U) {
assert(Res == 0);
}
-size_t Fuzzer::RunOneMaximizeTotalCoverage(const Unit &U) {
- size_t NumCounters = __sanitizer_get_number_of_counters();
+size_t Fuzzer::RecordBlockCoverage() {
+ return LastRecordedBlockCoverage = __sanitizer_get_total_unique_coverage();
+}
+
+void Fuzzer::PrepareCoverageBeforeRun() {
if (Options.UseCounters) {
+ size_t NumCounters = __sanitizer_get_number_of_counters();
CounterBitmap.resize(NumCounters);
__sanitizer_update_counter_bitset_and_clear_counters(0);
}
- size_t OldCoverage = __sanitizer_get_total_unique_coverage();
- ExecuteCallback(U);
- size_t NewCoverage = __sanitizer_get_total_unique_coverage();
+ RecordBlockCoverage();
+}
+
+bool Fuzzer::CheckCoverageAfterRun() {
+ size_t OldCoverage = LastRecordedBlockCoverage;
+ size_t NewCoverage = RecordBlockCoverage();
size_t NumNewBits = 0;
if (Options.UseCounters)
NumNewBits = __sanitizer_update_counter_bitset_and_clear_counters(
CounterBitmap.data());
-
- if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) && Options.Verbosity)
- PrintStats("pulse ", NewCoverage);
-
- if (NewCoverage > OldCoverage || NumNewBits)
- return NewCoverage;
- return 0;
+ return NewCoverage > OldCoverage || NumNewBits;
}
void Fuzzer::WriteToOutputCorpus(const Unit &U) {
Options.OutputCorpus.c_str());
}
-void Fuzzer::ReportNewCoverage(size_t NewCoverage, const Unit &U) {
- if (!NewCoverage) return;
+void Fuzzer::ReportNewCoverage(const Unit &U) {
Corpus.push_back(U);
UnitHashesAddedToCorpus.insert(Hash(U));
- PrintStats("NEW ", NewCoverage, "");
+ PrintStats("NEW ", LastRecordedBlockCoverage, "");
if (Options.Verbosity) {
Printf(" L: %zd", U.size());
if (U.size() < 30) {