summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2019-02-15 00:08:16 +0000
committerKostya Serebryany <kcc@google.com>2019-02-15 00:08:16 +0000
commit8d70b932e3dbd7218d31d28c2c5ed277018de7e9 (patch)
tree17b0e7ba2e0f8f4e591900d680e9de019a0133ef
parenta35757418b2f100086f7c4ca811719af4d0b07b1 (diff)
downloadcompiler-rt-8d70b932e3dbd7218d31d28c2c5ed277018de7e9.tar.gz
[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@354087 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/fuzzer/FuzzerDriver.cpp4
-rw-r--r--lib/fuzzer/FuzzerFork.cpp12
-rw-r--r--lib/fuzzer/FuzzerMerge.cpp31
-rw-r--r--lib/fuzzer/FuzzerMerge.h11
4 files changed, 33 insertions, 25 deletions
diff --git a/lib/fuzzer/FuzzerDriver.cpp b/lib/fuzzer/FuzzerDriver.cpp
index 434c48128..9f1621fcd 100644
--- a/lib/fuzzer/FuzzerDriver.cpp
+++ b/lib/fuzzer/FuzzerDriver.cpp
@@ -483,9 +483,9 @@ void Merge(Fuzzer *F, FuzzingOptions &Options, const Vector<std::string> &Args,
std::string CFPath = CFPathOrNull ? CFPathOrNull : TempPath(".txt");
Vector<std::string> NewFiles;
- Set<uint32_t> NewFeatures;
+ Set<uint32_t> NewFeatures, NewCov;
CrashResistantMerge(Args, OldCorpus, NewCorpus, &NewFiles, {}, &NewFeatures,
- CFPath, true);
+ {}, &NewCov, CFPath, true);
for (auto &Path : NewFiles)
F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
// We are done, delete the control file if it was a temporary one.
diff --git a/lib/fuzzer/FuzzerFork.cpp b/lib/fuzzer/FuzzerFork.cpp
index 7c82f3f04..41fb5c1c5 100644
--- a/lib/fuzzer/FuzzerFork.cpp
+++ b/lib/fuzzer/FuzzerFork.cpp
@@ -72,7 +72,7 @@ struct GlobalEnv {
Vector<std::string> CorpusDirs;
std::string MainCorpusDir;
std::string TempDir;
- Set<uint32_t> Features;
+ Set<uint32_t> Features, Cov;
Vector<std::string> Files;
Random *Rand;
int Verbosity = 0;
@@ -122,9 +122,9 @@ struct GlobalEnv {
GetSizedFilesFromDir(Job->CorpusDir, &TempFiles);
Vector<std::string> FilesToAdd;
- Set<uint32_t> NewFeatures;
+ Set<uint32_t> NewFeatures, NewCov;
CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features,
- &NewFeatures, Job->CFPath, false);
+ &NewFeatures, Cov, &NewCov, Job->CFPath, false);
RemoveFile(Job->CFPath);
for (auto &Path : FilesToAdd) {
auto U = FileToVector(Path);
@@ -134,11 +134,12 @@ struct GlobalEnv {
}
RmDirRecursive(Job->CorpusDir);
Features.insert(NewFeatures.begin(), NewFeatures.end());
+ Cov.insert(NewCov.begin(), NewCov.end());
auto Stats = ParseFinalStatsFromLog(Job->LogPath);
NumRuns += Stats.number_of_executed_units;
if (!FilesToAdd.empty())
- Printf("#%zd: ft: %zd corp: %zd exec/s %zd\n", NumRuns,
- Features.size(), Files.size(),
+ Printf("#%zd: cov: %zd ft: %zd corp: %zd exec/s %zd\n", NumRuns,
+ Cov.size(), Features.size(), Files.size(),
Stats.average_exec_per_sec);
}
};
@@ -202,6 +203,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
auto CFPath = DirPlusFile(Env.TempDir, "merge.txt");
CrashResistantMerge(Env.Args, {}, SeedFiles, &Env.Files, {}, &Env.Features,
+ {}, &Env.Cov,
CFPath, false);
RemoveFile(CFPath);
Printf("INFO: -fork=%d: %zd seeds, starting to fuzz; scratch: %s\n",
diff --git a/lib/fuzzer/FuzzerMerge.cpp b/lib/fuzzer/FuzzerMerge.cpp
index 55e5c9ad3..549d180d4 100644
--- a/lib/fuzzer/FuzzerMerge.cpp
+++ b/lib/fuzzer/FuzzerMerge.cpp
@@ -77,7 +77,7 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) {
const size_t kInvalidStartMarker = -1;
size_t LastSeenStartMarker = kInvalidStartMarker;
Vector<uint32_t> TmpFeatures;
- Set<uintptr_t> PCs;
+ Set<uint32_t> PCs;
while (std::getline(IS, Line, '\n')) {
std::istringstream ISS1(Line);
std::string Marker;
@@ -106,10 +106,11 @@ bool Merger::Parse(std::istream &IS, bool ParseCoverage) {
Files[CurrentFileIdx].Features = TmpFeatures;
}
} else if (Marker == "COV") {
+ size_t CurrentFileIdx = N;
if (ParseCoverage)
while (ISS1 >> std::hex >> N)
if (PCs.insert(N).second)
- NumCoveredPCs++;
+ Files[CurrentFileIdx].Cov.push_back(N);
} else {
return false;
}
@@ -130,9 +131,9 @@ size_t Merger::ApproximateMemoryConsumption() const {
// Decides which files need to be merged (add those to NewFiles).
// Returns the number of new features added.
-size_t Merger::Merge(const Set<uint32_t> &InitialFeatures,
- Set<uint32_t> *NewFeatures,
- Vector<std::string> *NewFiles) {
+void Merger::Merge(const Set<uint32_t> &InitialFeatures,
+ Set<uint32_t> *NewFeatures, const Set<uint32_t> &InitialCov,
+ Set<uint32_t> *NewCov, Vector<std::string> *NewFiles) {
NewFiles->clear();
assert(NumFilesInFirstCorpus <= Files.size());
Set<uint32_t> AllFeatures = InitialFeatures;
@@ -142,8 +143,6 @@ size_t Merger::Merge(const Set<uint32_t> &InitialFeatures,
auto &Cur = Files[i].Features;
AllFeatures.insert(Cur.begin(), Cur.end());
}
- size_t InitialNumFeatures = AllFeatures.size();
-
// Remove all features that we already know from all other inputs.
for (size_t i = NumFilesInFirstCorpus; i < Files.size(); i++) {
auto &Cur = Files[i].Features;
@@ -178,8 +177,10 @@ size_t Merger::Merge(const Set<uint32_t> &InitialFeatures,
}
if (FoundNewFeatures)
NewFiles->push_back(Files[i].Name);
+ for (auto Cov : Files[i].Cov)
+ if (InitialCov.find(Cov) == InitialCov.end())
+ NewCov->insert(Cov);
}
- return AllFeatures.size() - InitialNumFeatures;
}
Set<uint32_t> Merger::AllFeatures() const {
@@ -241,7 +242,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) {
for (size_t F : UniqFeatures)
OF << " " << std::hex << F;
OF << "\n";
- OF << "COV " << i;
+ OF << "COV " << std::dec << i;
TPC.ForEachObservedPC([&](const TracePC::PCTableEntry *TE) {
if (AllPCs.insert(TE).second)
OF << " " << TPC.PCTableEntryIdx(TE);
@@ -276,7 +277,10 @@ void CrashResistantMerge(const Vector<std::string> &Args,
const Vector<SizedFile> &NewCorpus,
Vector<std::string> *NewFiles,
const Set<uint32_t> &InitialFeatures,
- Set<uint32_t> *NewFeatures, const std::string &CFPath,
+ Set<uint32_t> *NewFeatures,
+ const Set<uint32_t> &InitialCov,
+ Set<uint32_t> *NewCov,
+ const std::string &CFPath,
bool V /*Verbose*/) {
if (NewCorpus.empty() && OldCorpus.empty()) return; // Nothing to merge.
size_t NumAttempts = 0;
@@ -346,9 +350,10 @@ void CrashResistantMerge(const Vector<std::string> &Args,
VPrintf(V,
"MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n",
M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb());
- size_t NumNewFeatures = M.Merge(InitialFeatures, NewFeatures, NewFiles);
- VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added\n",
- NewFiles->size(), NumNewFeatures);
+ M.Merge(InitialFeatures, NewFeatures, InitialCov, NewCov, NewFiles);
+ VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added; "
+ "%zd new coverage edges\n",
+ NewFiles->size(), NewFeatures->size(), NewCov->size());
}
} // namespace fuzzer
diff --git a/lib/fuzzer/FuzzerMerge.h b/lib/fuzzer/FuzzerMerge.h
index 157611cb9..7a0cd4b71 100644
--- a/lib/fuzzer/FuzzerMerge.h
+++ b/lib/fuzzer/FuzzerMerge.h
@@ -51,12 +51,11 @@ namespace fuzzer {
struct MergeFileInfo {
std::string Name;
size_t Size = 0;
- Vector<uint32_t> Features;
+ Vector<uint32_t> Features, Cov;
};
struct Merger {
Vector<MergeFileInfo> Files;
- size_t NumCoveredPCs = 0;
size_t NumFilesInFirstCorpus = 0;
size_t FirstNotProcessedFile = 0;
std::string LastFailure;
@@ -64,9 +63,9 @@ struct Merger {
bool Parse(std::istream &IS, bool ParseCoverage);
bool Parse(const std::string &Str, bool ParseCoverage);
void ParseOrExit(std::istream &IS, bool ParseCoverage);
- size_t Merge(const Set<uint32_t> &InitialFeatures,
- Set<uint32_t> *NewFeatures,
- Vector<std::string> *NewFiles);
+ void Merge(const Set<uint32_t> &InitialFeatures, Set<uint32_t> *NewFeatures,
+ const Set<uint32_t> &InitialCov, Set<uint32_t> *NewCov,
+ Vector<std::string> *NewFiles);
size_t ApproximateMemoryConsumption() const;
Set<uint32_t> AllFeatures() const;
};
@@ -77,6 +76,8 @@ void CrashResistantMerge(const Vector<std::string> &Args,
Vector<std::string> *NewFiles,
const Set<uint32_t> &InitialFeatures,
Set<uint32_t> *NewFeatures,
+ const Set<uint32_t> &InitialCov,
+ Set<uint32_t> *NewCov,
const std::string &CFPath,
bool Verbose);