Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 95ec60f

Browse files
committed
[libFuzzer] speedup the merge step in the fork mode by merging only the files that have unique features.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@358320 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c438ef3 commit 95ec60f

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

lib/fuzzer/FuzzerFork.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "FuzzerCommand.h"
1212
#include "FuzzerFork.h"
1313
#include "FuzzerIO.h"
14+
#include "FuzzerInternal.h"
1415
#include "FuzzerMerge.h"
1516
#include "FuzzerSHA1.h"
1617
#include "FuzzerTracePC.h"
@@ -63,6 +64,7 @@ struct FuzzJob {
6364
// Inputs.
6465
Command Cmd;
6566
std::string CorpusDir;
67+
std::string FeaturesDir;
6668
std::string LogPath;
6769
std::string CFPath;
6870

@@ -73,6 +75,7 @@ struct FuzzJob {
7375
RemoveFile(CFPath);
7476
RemoveFile(LogPath);
7577
RmDirRecursive(CorpusDir);
78+
RmDirRecursive(FeaturesDir);
7679
}
7780
};
7881

@@ -122,12 +125,17 @@ struct GlobalEnv {
122125
Cmd.addFlag("seed_inputs", Seeds);
123126
Job->LogPath = DirPlusFile(TempDir, std::to_string(JobId) + ".log");
124127
Job->CorpusDir = DirPlusFile(TempDir, "C" + std::to_string(JobId));
128+
Job->FeaturesDir = DirPlusFile(TempDir, "F" + std::to_string(JobId));
125129
Job->CFPath = DirPlusFile(TempDir, std::to_string(JobId) + ".merge");
126130

127131

128132
Cmd.addArgument(Job->CorpusDir);
129-
RmDirRecursive(Job->CorpusDir);
130-
MkDir(Job->CorpusDir);
133+
Cmd.addFlag("features_dir", Job->FeaturesDir);
134+
135+
for (auto &D : {Job->CorpusDir, Job->FeaturesDir}) {
136+
RmDirRecursive(D);
137+
MkDir(D);
138+
}
131139

132140
Cmd.setOutputFile(Job->LogPath);
133141
Cmd.combineOutAndErr();
@@ -142,12 +150,30 @@ struct GlobalEnv {
142150
}
143151

144152
void RunOneMergeJob(FuzzJob *Job) {
145-
Vector<SizedFile> TempFiles;
153+
Vector<SizedFile> TempFiles, MergeCandidates;
154+
// Read all newly created inputs and their feature sets.
155+
// Choose only those inputs that have new features.
146156
GetSizedFilesFromDir(Job->CorpusDir, &TempFiles);
157+
std::sort(TempFiles.begin(), TempFiles.end());
158+
for (auto &F : TempFiles) {
159+
auto FeatureFile = F.File;
160+
FeatureFile.replace(0, Job->CorpusDir.size(), Job->FeaturesDir);
161+
auto FeatureBytes = FileToVector(FeatureFile, 0, false);
162+
assert((FeatureBytes.size() % sizeof(uint32_t)) == 0);
163+
Vector<uint32_t> NewFeatures(FeatureBytes.size() / sizeof(uint32_t));
164+
memcpy(NewFeatures.data(), FeatureBytes.data(), FeatureBytes.size());
165+
for (auto Ft : NewFeatures) {
166+
if (!Features.count(Ft)) {
167+
MergeCandidates.push_back(F);
168+
break;
169+
}
170+
}
171+
}
172+
if (MergeCandidates.empty()) return;
147173

148174
Vector<std::string> FilesToAdd;
149175
Set<uint32_t> NewFeatures, NewCov;
150-
CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features,
176+
CrashResistantMerge(Args, {}, MergeCandidates, &FilesToAdd, Features,
151177
&NewFeatures, Cov, &NewCov, Job->CFPath, false);
152178
for (auto &Path : FilesToAdd) {
153179
auto U = FileToVector(Path);
@@ -265,6 +291,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
265291
Stop = true;
266292
break;
267293
}
294+
Fuzzer::MaybeExitGracefully();
268295

269296
Env.RunOneMergeJob(Job.get());
270297

lib/fuzzer/FuzzerLoop.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,13 +446,12 @@ void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) {
446446
}
447447

448448
static void WriteFeatureSetToFile(const std::string &FeaturesDir,
449-
const uint8_t Sha1[],
449+
const std::string &FileName,
450450
const Vector<uint32_t> &FeatureSet) {
451451
if (FeaturesDir.empty() || FeatureSet.empty()) return;
452452
WriteToFile(reinterpret_cast<const uint8_t *>(FeatureSet.data()),
453453
FeatureSet.size() * sizeof(FeatureSet[0]),
454-
DirPlusFile(FeaturesDir, Sha1ToString(Sha1)));
455-
Printf("Features: %s\n", Sha1ToString(Sha1).c_str());
454+
DirPlusFile(FeaturesDir, FileName));
456455
}
457456

458457
static void RenameFeatureSetFile(const std::string &FeaturesDir,
@@ -490,7 +489,7 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
490489
auto NewII = Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures,
491490
MayDeleteFile, TPC.ObservedFocusFunction(),
492491
UniqFeatureSetTmp, DFT, II);
493-
WriteFeatureSetToFile(Options.FeaturesDir, NewII->Sha1,
492+
WriteFeatureSetToFile(Options.FeaturesDir, Sha1ToString(NewII->Sha1),
494493
NewII->UniqFeatureSet);
495494
return true;
496495
}

0 commit comments

Comments
 (0)