// Stats.
uintptr_t NumExecutedMutations = 0;
uintptr_t NumSuccessfullMutations = 0;
-
- // A set of features (PCIDs, etc) that were first found with this unit.
- std::vector<uintptr_t> Features;
};
class InputCorpus {
size_t size() const { return Inputs.size(); }
bool empty() const { return Inputs.empty(); }
const Unit &operator[] (size_t Idx) const { return Inputs[Idx].U; }
- void AddToCorpus(const Unit &U, uintptr_t *Features, size_t NumFeatures) {
+ void AddToCorpus(const Unit &U) {
uint8_t Hash[kSHA1NumBytes];
ComputeSHA1(U.data(), U.size(), Hash);
if (!Hashes.insert(Sha1ToString(Hash)).second) return;
Inputs.push_back(InputInfo());
InputInfo &II = Inputs.back();
II.U = U;
- II.Features.insert(II.Features.begin(), Features, Features + NumFeatures);
memcpy(II.Sha1, Hash, kSHA1NumBytes);
UpdateCorpusDistribution();
}
void PrintStats() {
for (size_t i = 0; i < Inputs.size(); i++) {
const auto &II = Inputs[i];
- Printf(" [%zd %s]\tsz: %zd\truns: %zd\tsucc: %zd\tfea: %zd\n", i,
+ Printf(" [%zd %s]\tsz: %zd\truns: %zd\tsucc: %zd\n", i,
Sha1ToString(II.Sha1).c_str(), II.U.size(),
- II.NumExecutedMutations, II.NumSuccessfullMutations,
- II.Features.size());
+ II.NumExecutedMutations, II.NumSuccessfullMutations);
}
}
Unit U = FileToVector(InputFilePath);
assert(U.size() > 2);
Printf("INFO: Starting MinimizeCrashInputInternalStep: %zd\n", U.size());
- Corpus->AddToCorpus(U, nullptr, 0);
+ Corpus->AddToCorpus(U);
F->SetMaxInputLen(U.size());
F->SetMaxMutationLen(U.size() - 1);
F->Loop();
bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
void WriteToOutputCorpus(const Unit &U);
void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
- void PrintStats(const char *Where, const char *End = "\n");
+ void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
void PrintStatusForNewUnit(const Unit &U);
void ShuffleCorpus(UnitVector *V);
void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
assert(!F);
F = this;
TPC.ResetTotalPCCoverage();
+ TPC.Reset();
ResetCoverage();
IsMyThread = true;
if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks)
_Exit(Options.ErrorExitCode); // Stop right now.
}
-void Fuzzer::PrintStats(const char *Where, const char *End) {
+void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {
size_t ExecPerSec = execPerSec();
if (Options.OutputCSV) {
static bool csvHeaderPrinted = false;
Printf(" bits: %zd", MaxCoverage.TPCMap.GetNumBitsSinceLastMerge());
if (MaxCoverage.CallerCalleeCoverage)
Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);
- Printf(" units: %zd exec/s: %zd", Corpus.size(), ExecPerSec);
+ if (size_t N = Corpus.size())
+ Printf(" units: %zd", N);
+ if (Units)
+ Printf(" units: %zd", Units);
+ Printf(" exec/s: %zd", ExecPerSec);
Printf("%s", End);
}
X.resize(MaxSize);
if (!Corpus.HasUnit(X)) {
if (RunOne(X)) {
- uintptr_t *NewPCIDs;
- size_t NumNewPCIDs = TPC.GetNewPCIDs(&NewPCIDs);
- Corpus.AddToCorpus(X, NewPCIDs, NumNewPCIDs);
+ Corpus.AddToCorpus(X);
PrintStats("RELOAD");
}
}
for (const auto &U : *InitialCorpus) {
bool NewCoverage = RunOne(U);
if (!Options.PruneCorpus || NewCoverage) {
- uintptr_t *NewPCIDs;
- size_t NumNewPCIDs = TPC.GetNewPCIDs(&NewPCIDs);
- Corpus.AddToCorpus(U, NewPCIDs, NumNewPCIDs);
+ Corpus.AddToCorpus(U);
if (Options.Verbosity >= 2)
Printf("NEW0: %zd L %zd\n", MaxCoverage.BlockCoverage, U.size());
}
void Fuzzer::ReportNewCoverage(InputInfo *II, const Unit &U) {
II->NumSuccessfullMutations++;
- uintptr_t *NewPCIDs;
- size_t NumNewPCIDs = TPC.GetNewPCIDs(&NewPCIDs);
- Corpus.AddToCorpus(U, NewPCIDs, NumNewPCIDs);
+ Corpus.AddToCorpus(U);
MD.RecordSuccessfulMutationSequence();
PrintStatusForNewUnit(U);
WriteToOutputCorpus(U);
size_t OldSize = Res.size();
for (int Iter = 0; Iter < 10; Iter++) {
ShuffleCorpus(&Res);
+ TPC.Reset();
ResetCoverage();
for (auto &U : Initial)
char Stat[7] = "MIN ";
Stat[3] = '0' + Iter;
- PrintStats(Stat);
+ PrintStats(Stat, "\n", Tmp.size());
size_t NewSize = Tmp.size();
assert(NewSize <= OldSize);
void Fuzzer::ResetCoverage() {
ResetEdgeCoverage();
MaxCoverage.Reset();
- TPC.Reset();
PrepareCounters(&MaxCoverage);
}
void Reset() {
NumNewPCIDs = 0;
CounterMap.Reset();
+ ValueProfileMap.Reset();
ResetGuards();
}
size_t N = 10;
size_t TriesPerUnit = 1<<20;
for (size_t i = 0; i < N; i++)
- C.AddToCorpus(Unit{ static_cast<uint8_t>(i) }, nullptr, 0);
+ C.AddToCorpus(Unit{ static_cast<uint8_t>(i) });
std::vector<size_t> Hist(N);
for (size_t i = 0; i < N * TriesPerUnit; i++) {
RUN: echo ..Z... > %tmp/T1/3
# T1 has 3 elements, T2 is empty.
-RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: LLVMFuzzer-FullCoverageSetTest-TracePC -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
CHECK1: === Minimizing the initial corpus of 3 units
CHECK1: === Merge: written 0 units
RUN: echo ..Z... > %tmp/T2/c
# T1 has 3 elements, T2 has 6 elements, only 3 are new.
-RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
CHECK2: === Minimizing the initial corpus of 3 units
CHECK2: === Merging extra 6 units
CHECK2: === Merge: written 3 units
# Now, T1 has 6 units and T2 has no new interesting units.
-RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: LLVMFuzzer-FullCoverageSetTest-TracePC -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
CHECK3: === Minimizing the initial corpus of 6 units
CHECK3: === Merge: written 0 units
CallerCalleeTest
NullDerefTest
MinimizeCorpusTest
+ FullCoverageSetTest
)
foreach(Test ${TracePCTests})