Skip to content

Commit 98a8624

Browse files
author
kcc
committed
[libFuzzer] when doing the merge, keep track of the coveraged edges, not just features
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer@354087 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 001e5f7 commit 98a8624

File tree

4 files changed

+33
-25
lines changed

4 files changed

+33
-25
lines changed

FuzzerDriver.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,9 @@ void Merge(Fuzzer *F, FuzzingOptions &Options, const Vector<std::string> &Args,
483483

484484
std::string CFPath = CFPathOrNull ? CFPathOrNull : TempPath(".txt");
485485
Vector<std::string> NewFiles;
486-
Set<uint32_t> NewFeatures;
486+
Set<uint32_t> NewFeatures, NewCov;
487487
CrashResistantMerge(Args, OldCorpus, NewCorpus, &NewFiles, {}, &NewFeatures,
488-
CFPath, true);
488+
{}, &NewCov, CFPath, true);
489489
for (auto &Path : NewFiles)
490490
F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
491491
// We are done, delete the control file if it was a temporary one.

FuzzerFork.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ struct GlobalEnv {
7272
Vector<std::string> CorpusDirs;
7373
std::string MainCorpusDir;
7474
std::string TempDir;
75-
Set<uint32_t> Features;
75+
Set<uint32_t> Features, Cov;
7676
Vector<std::string> Files;
7777
Random *Rand;
7878
int Verbosity = 0;
@@ -122,9 +122,9 @@ struct GlobalEnv {
122122
GetSizedFilesFromDir(Job->CorpusDir, &TempFiles);
123123

124124
Vector<std::string> FilesToAdd;
125-
Set<uint32_t> NewFeatures;
125+
Set<uint32_t> NewFeatures, NewCov;
126126
CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features,
127-
&NewFeatures, Job->CFPath, false);
127+
&NewFeatures, Cov, &NewCov, Job->CFPath, false);
128128
RemoveFile(Job->CFPath);
129129
for (auto &Path : FilesToAdd) {
130130
auto U = FileToVector(Path);
@@ -134,11 +134,12 @@ struct GlobalEnv {
134134
}
135135
RmDirRecursive(Job->CorpusDir);
136136
Features.insert(NewFeatures.begin(), NewFeatures.end());
137+
Cov.insert(NewCov.begin(), NewCov.end());
137138
auto Stats = ParseFinalStatsFromLog(Job->LogPath);
138139
NumRuns += Stats.number_of_executed_units;
139140
if (!FilesToAdd.empty())
140-
Printf("#%zd: ft: %zd corp: %zd exec/s %zd\n", NumRuns,
141-
Features.size(), Files.size(),
141+
Printf("#%zd: cov: %zd ft: %zd corp: %zd exec/s %zd\n", NumRuns,
142+
Cov.size(), Features.size(), Files.size(),
142143
Stats.average_exec_per_sec);
143144
}
144145
};
@@ -202,6 +203,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
202203

203204
auto CFPath = DirPlusFile(Env.TempDir, "merge.txt");
204205
CrashResistantMerge(Env.Args, {}, SeedFiles, &Env.Files, {}, &Env.Features,
206+
{}, &Env.Cov,
205207
CFPath, false);
206208
RemoveFile(CFPath);
207209
Printf("INFO: -fork=%d: %zd seeds, starting to fuzz; scratch: %s\n",

FuzzerMerge.cpp

+18-13
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) {
7777
const size_t kInvalidStartMarker = -1;
7878
size_t LastSeenStartMarker = kInvalidStartMarker;
7979
Vector<uint32_t> TmpFeatures;
80-
Set<uintptr_t> PCs;
80+
Set<uint32_t> PCs;
8181
while (std::getline(IS, Line, '\n')) {
8282
std::istringstream ISS1(Line);
8383
std::string Marker;
@@ -106,10 +106,11 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) {
106106
Files[CurrentFileIdx].Features = TmpFeatures;
107107
}
108108
} else if (Marker == "COV") {
109+
size_t CurrentFileIdx = N;
109110
if (ParseCoverage)
110111
while (ISS1 >> std::hex >> N)
111112
if (PCs.insert(N).second)
112-
NumCoveredPCs++;
113+
Files[CurrentFileIdx].Cov.push_back(N);
113114
} else {
114115
return false;
115116
}
@@ -130,9 +131,9 @@ size_t Merger::ApproximateMemoryConsumption() const {
130131

131132
// Decides which files need to be merged (add those to NewFiles).
132133
// Returns the number of new features added.
133-
size_t Merger::Merge(const Set<uint32_t> &InitialFeatures,
134-
Set<uint32_t> *NewFeatures,
135-
Vector<std::string> *NewFiles) {
134+
void Merger::Merge(const Set<uint32_t> &InitialFeatures,
135+
Set<uint32_t> *NewFeatures, const Set<uint32_t> &InitialCov,
136+
Set<uint32_t> *NewCov, Vector<std::string> *NewFiles) {
136137
NewFiles->clear();
137138
assert(NumFilesInFirstCorpus <= Files.size());
138139
Set<uint32_t> AllFeatures = InitialFeatures;
@@ -142,8 +143,6 @@ size_t Merger::Merge(const Set<uint32_t> &InitialFeatures,
142143
auto &Cur = Files[i].Features;
143144
AllFeatures.insert(Cur.begin(), Cur.end());
144145
}
145-
size_t InitialNumFeatures = AllFeatures.size();
146-
147146
// Remove all features that we already know from all other inputs.
148147
for (size_t i = NumFilesInFirstCorpus; i < Files.size(); i++) {
149148
auto &Cur = Files[i].Features;
@@ -178,8 +177,10 @@ size_t Merger::Merge(const Set<uint32_t> &InitialFeatures,
178177
}
179178
if (FoundNewFeatures)
180179
NewFiles->push_back(Files[i].Name);
180+
for (auto Cov : Files[i].Cov)
181+
if (InitialCov.find(Cov) == InitialCov.end())
182+
NewCov->insert(Cov);
181183
}
182-
return AllFeatures.size() - InitialNumFeatures;
183184
}
184185

185186
Set<uint32_t> Merger::AllFeatures() const {
@@ -241,7 +242,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) {
241242
for (size_t F : UniqFeatures)
242243
OF << " " << std::hex << F;
243244
OF << "\n";
244-
OF << "COV " << i;
245+
OF << "COV " << std::dec << i;
245246
TPC.ForEachObservedPC([&](const TracePC::PCTableEntry *TE) {
246247
if (AllPCs.insert(TE).second)
247248
OF << " " << TPC.PCTableEntryIdx(TE);
@@ -276,7 +277,10 @@ void CrashResistantMerge(const Vector<std::string> &Args,
276277
const Vector<SizedFile> &NewCorpus,
277278
Vector<std::string> *NewFiles,
278279
const Set<uint32_t> &InitialFeatures,
279-
Set<uint32_t> *NewFeatures, const std::string &CFPath,
280+
Set<uint32_t> *NewFeatures,
281+
const Set<uint32_t> &InitialCov,
282+
Set<uint32_t> *NewCov,
283+
const std::string &CFPath,
280284
bool V /*Verbose*/) {
281285
if (NewCorpus.empty() && OldCorpus.empty()) return; // Nothing to merge.
282286
size_t NumAttempts = 0;
@@ -346,9 +350,10 @@ void CrashResistantMerge(const Vector<std::string> &Args,
346350
VPrintf(V,
347351
"MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n",
348352
M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb());
349-
size_t NumNewFeatures = M.Merge(InitialFeatures, NewFeatures, NewFiles);
350-
VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added\n",
351-
NewFiles->size(), NumNewFeatures);
353+
M.Merge(InitialFeatures, NewFeatures, InitialCov, NewCov, NewFiles);
354+
VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added; "
355+
"%zd new coverage edges\n",
356+
NewFiles->size(), NewFeatures->size(), NewCov->size());
352357
}
353358

354359
} // namespace fuzzer

FuzzerMerge.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,21 @@ namespace fuzzer {
5151
struct MergeFileInfo {
5252
std::string Name;
5353
size_t Size = 0;
54-
Vector<uint32_t> Features;
54+
Vector<uint32_t> Features, Cov;
5555
};
5656

5757
struct Merger {
5858
Vector<MergeFileInfo> Files;
59-
size_t NumCoveredPCs = 0;
6059
size_t NumFilesInFirstCorpus = 0;
6160
size_t FirstNotProcessedFile = 0;
6261
std::string LastFailure;
6362

6463
bool Parse(std::istream &IS, bool ParseCoverage);
6564
bool Parse(const std::string &Str, bool ParseCoverage);
6665
void ParseOrExit(std::istream &IS, bool ParseCoverage);
67-
size_t Merge(const Set<uint32_t> &InitialFeatures,
68-
Set<uint32_t> *NewFeatures,
69-
Vector<std::string> *NewFiles);
66+
void Merge(const Set<uint32_t> &InitialFeatures, Set<uint32_t> *NewFeatures,
67+
const Set<uint32_t> &InitialCov, Set<uint32_t> *NewCov,
68+
Vector<std::string> *NewFiles);
7069
size_t ApproximateMemoryConsumption() const;
7170
Set<uint32_t> AllFeatures() const;
7271
};
@@ -77,6 +76,8 @@ void CrashResistantMerge(const Vector<std::string> &Args,
7776
Vector<std::string> *NewFiles,
7877
const Set<uint32_t> &InitialFeatures,
7978
Set<uint32_t> *NewFeatures,
79+
const Set<uint32_t> &InitialCov,
80+
Set<uint32_t> *NewCov,
8081
const std::string &CFPath,
8182
bool Verbose);
8283

0 commit comments

Comments
 (0)