mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-07 11:51:13 +00:00
[libFuzzer] fix merging with trace-pc-guard
llvm-svn: 282224
This commit is contained in:
parent
a377ff1511
commit
763d4bc96b
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ class TracePC {
|
||||
void Reset() {
|
||||
NumNewPCIDs = 0;
|
||||
CounterMap.Reset();
|
||||
ValueProfileMap.Reset();
|
||||
ResetGuards();
|
||||
}
|
||||
|
||||
|
@ -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++) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -9,6 +9,7 @@ set(TracePCTests
|
||||
CallerCalleeTest
|
||||
NullDerefTest
|
||||
MinimizeCorpusTest
|
||||
FullCoverageSetTest
|
||||
)
|
||||
|
||||
foreach(Test ${TracePCTests})
|
||||
|
Loading…
Reference in New Issue
Block a user