[libFuzzer] fix merging with trace-pc-guard

llvm-svn: 282224
This commit is contained in:
Kostya Serebryany 2016-09-23 01:58:51 +00:00
parent a377ff1511
commit 763d4bc96b
8 changed files with 25 additions and 27 deletions

View File

@ -26,9 +26,6 @@ struct InputInfo {
// 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 {
@ -39,14 +36,13 @@ 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();
}
@ -72,10 +68,9 @@ class InputCorpus {
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);
}
}

View File

@ -342,7 +342,7 @@ int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {
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();

View File

@ -110,7 +110,7 @@ private:
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,

View File

@ -163,6 +163,7 @@ Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
assert(!F);
F = this;
TPC.ResetTotalPCCoverage();
TPC.Reset();
ResetCoverage();
IsMyThread = true;
if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks)
@ -309,7 +310,7 @@ void Fuzzer::RssLimitCallback() {
_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;
@ -337,7 +338,11 @@ void Fuzzer::PrintStats(const char *Where, const char *End) {
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);
}
@ -381,9 +386,7 @@ void Fuzzer::RereadOutputCorpus(size_t MaxSize) {
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");
}
}
@ -406,9 +409,7 @@ void Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) {
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());
}
@ -545,9 +546,7 @@ void Fuzzer::PrintNewPCs() {
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);
@ -566,6 +565,7 @@ UnitVector Fuzzer::FindExtraUnits(const UnitVector &Initial,
size_t OldSize = Res.size();
for (int Iter = 0; Iter < 10; Iter++) {
ShuffleCorpus(&Res);
TPC.Reset();
ResetCoverage();
for (auto &U : Initial)
@ -578,7 +578,7 @@ UnitVector Fuzzer::FindExtraUnits(const UnitVector &Initial,
char Stat[7] = "MIN ";
Stat[3] = '0' + Iter;
PrintStats(Stat);
PrintStats(Stat, "\n", Tmp.size());
size_t NewSize = Tmp.size();
assert(NewSize <= OldSize);
@ -691,7 +691,6 @@ void Fuzzer::MutateAndTestOne() {
void Fuzzer::ResetCoverage() {
ResetEdgeCoverage();
MaxCoverage.Reset();
TPC.Reset();
PrepareCounters(&MaxCoverage);
}

View File

@ -46,6 +46,7 @@ class TracePC {
void Reset() {
NumNewPCIDs = 0;
CounterMap.Reset();
ValueProfileMap.Reset();
ResetGuards();
}

View File

@ -583,7 +583,7 @@ TEST(Corpus, Distribution) {
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++) {

View File

@ -7,7 +7,8 @@ RUN: echo .U.... > %tmp/T1/2
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
@ -19,13 +20,14 @@ RUN: echo .U.... > %tmp/T2/b
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

View File

@ -9,6 +9,7 @@ set(TracePCTests
CallerCalleeTest
NullDerefTest
MinimizeCorpusTest
FullCoverageSetTest
)
foreach(Test ${TracePCTests})