forked from OSchip/llvm-project
[libFuzzer] make the fork mode less verbose
llvm-svn: 353794
This commit is contained in:
parent
9e624d5410
commit
2b9a8f37a4
|
@ -484,11 +484,12 @@ void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options,
|
|||
GetSizedFilesFromDir(Dir, &Corpus);
|
||||
std::sort(Corpus.begin(), Corpus.end());
|
||||
auto CFPath = TempPath(".fork");
|
||||
auto LogPath = TempPath(".log");
|
||||
|
||||
Vector<std::string> Files;
|
||||
Set<uint32_t> Features;
|
||||
if (!Corpus.empty()) {
|
||||
CrashResistantMerge(Args, {}, Corpus, &Files, {}, &Features, CFPath);
|
||||
CrashResistantMerge(Args, {}, Corpus, &Files, {}, &Features, CFPath, false);
|
||||
RemoveFile(CFPath);
|
||||
}
|
||||
auto TempDir = TempPath("Dir");
|
||||
|
@ -500,8 +501,8 @@ void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options,
|
|||
BaseCmd.removeFlag("fork");
|
||||
for (auto &C : Corpora) // Remove all corpora from the args.
|
||||
BaseCmd.removeArgument(C);
|
||||
BaseCmd.addFlag("runs", "1000000");
|
||||
BaseCmd.addFlag("max_total_time", "30");
|
||||
if (!BaseCmd.hasFlag("max_total_time"))
|
||||
BaseCmd.addFlag("max_total_time", "60");
|
||||
BaseCmd.addArgument(TempDir);
|
||||
int ExitCode = 0;
|
||||
for (size_t i = 0; i < 1000000; i++) {
|
||||
|
@ -511,10 +512,11 @@ void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options,
|
|||
Cmd.addFlag("seed_inputs",
|
||||
Files[Rand.SkewTowardsLast(Files.size())] + "," +
|
||||
Files[Rand.SkewTowardsLast(Files.size())]);
|
||||
Printf("RUN %s\n", Cmd.toString().c_str());
|
||||
Cmd.setOutputFile(LogPath);
|
||||
Cmd.combineOutAndErr();
|
||||
RmFilesInDir(TempDir);
|
||||
ExitCode = ExecuteCommand(Cmd);
|
||||
Printf("Exit code: %d\n", ExitCode);
|
||||
// Printf("done [%d] %s\n", ExitCode, Cmd.toString().c_str());
|
||||
if (ExitCode == Options.InterruptExitCode)
|
||||
break;
|
||||
Vector<SizedFile> TempFiles;
|
||||
|
@ -522,7 +524,7 @@ void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options,
|
|||
Set<uint32_t> NewFeatures;
|
||||
GetSizedFilesFromDir(TempDir, &TempFiles);
|
||||
CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features,
|
||||
&NewFeatures, CFPath);
|
||||
&NewFeatures, CFPath, false);
|
||||
RemoveFile(CFPath);
|
||||
for (auto &Path : FilesToAdd) {
|
||||
auto NewPath = F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
|
||||
|
@ -539,7 +541,11 @@ void FuzzWithFork(Fuzzer *F, const FuzzingOptions &Options,
|
|||
if (Options.IgnoreOOMs && ExitCode == Options.OOMExitCode)
|
||||
continue;
|
||||
// And exit if we don't ignore this crash.
|
||||
if (ExitCode != 0) break;
|
||||
if (ExitCode != 0) {
|
||||
Printf("INFO: log from the inner process:\n%s",
|
||||
FileToString(LogPath).c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RmFilesInDir(TempDir);
|
||||
|
@ -568,7 +574,7 @@ void Merge(Fuzzer *F, FuzzingOptions &Options, const Vector<std::string> &Args,
|
|||
Vector<std::string> NewFiles;
|
||||
Set<uint32_t> NewFeatures;
|
||||
CrashResistantMerge(Args, OldCorpus, NewCorpus, &NewFiles, {}, &NewFeatures,
|
||||
CFPath);
|
||||
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.
|
||||
|
|
|
@ -125,6 +125,15 @@ void Printf(const char *Fmt, ...) {
|
|||
fflush(OutputFile);
|
||||
}
|
||||
|
||||
void VPrintf(bool Verbose, const char *Fmt, ...) {
|
||||
if (!Verbose) return;
|
||||
va_list ap;
|
||||
va_start(ap, Fmt);
|
||||
vfprintf(OutputFile, Fmt, ap);
|
||||
va_end(ap);
|
||||
fflush(OutputFile);
|
||||
}
|
||||
|
||||
void RmFilesInDir(const std::string &Path) {
|
||||
Vector<std::string> Files;
|
||||
ListFilesInDirRecursive(Path, 0, &Files, /*TopDir*/true);
|
||||
|
|
|
@ -46,6 +46,7 @@ void DupAndCloseStderr();
|
|||
void CloseStdout();
|
||||
|
||||
void Printf(const char *Fmt, ...);
|
||||
void VPrintf(bool Verbose, const char *Fmt, ...);
|
||||
|
||||
// Print using raw syscalls, useful when printing at early init stages.
|
||||
void RawPrint(const char *Str);
|
||||
|
|
|
@ -255,42 +255,43 @@ static void WriteNewControlFile(const std::string &CFPath,
|
|||
|
||||
// Outer process. Does not call the target code and thus should not fail.
|
||||
void CrashResistantMerge(const Vector<std::string> &Args,
|
||||
const Vector<SizedFile> &OldCorpus,
|
||||
const Vector<SizedFile> &NewCorpus,
|
||||
Vector<std::string> *NewFiles,
|
||||
const Set<uint32_t> &InitialFeatures,
|
||||
Set<uint32_t> *NewFeatures,
|
||||
const std::string &CFPath) {
|
||||
const Vector<SizedFile> &OldCorpus,
|
||||
const Vector<SizedFile> &NewCorpus,
|
||||
Vector<std::string> *NewFiles,
|
||||
const Set<uint32_t> &InitialFeatures,
|
||||
Set<uint32_t> *NewFeatures, const std::string &CFPath,
|
||||
bool V /*Verbose*/) {
|
||||
size_t NumAttempts = 0;
|
||||
if (FileSize(CFPath)) {
|
||||
Printf("MERGE-OUTER: non-empty control file provided: '%s'\n",
|
||||
VPrintf(V, "MERGE-OUTER: non-empty control file provided: '%s'\n",
|
||||
CFPath.c_str());
|
||||
Merger M;
|
||||
std::ifstream IF(CFPath);
|
||||
if (M.Parse(IF, /*ParseCoverage=*/false)) {
|
||||
Printf("MERGE-OUTER: control file ok, %zd files total,"
|
||||
VPrintf(V, "MERGE-OUTER: control file ok, %zd files total,"
|
||||
" first not processed file %zd\n",
|
||||
M.Files.size(), M.FirstNotProcessedFile);
|
||||
if (!M.LastFailure.empty())
|
||||
Printf("MERGE-OUTER: '%s' will be skipped as unlucky "
|
||||
VPrintf(V, "MERGE-OUTER: '%s' will be skipped as unlucky "
|
||||
"(merge has stumbled on it the last time)\n",
|
||||
M.LastFailure.c_str());
|
||||
if (M.FirstNotProcessedFile >= M.Files.size()) {
|
||||
Printf("MERGE-OUTER: nothing to do, merge has been completed before\n");
|
||||
VPrintf(
|
||||
V, "MERGE-OUTER: nothing to do, merge has been completed before\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
NumAttempts = M.Files.size() - M.FirstNotProcessedFile;
|
||||
} else {
|
||||
Printf("MERGE-OUTER: bad control file, will overwrite it\n");
|
||||
VPrintf(V, "MERGE-OUTER: bad control file, will overwrite it\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!NumAttempts) {
|
||||
// The supplied control file is empty or bad, create a fresh one.
|
||||
NumAttempts = OldCorpus.size() + NewCorpus.size();
|
||||
Printf("MERGE-OUTER: %zd files, %zd in the initial corpus\n", NumAttempts,
|
||||
OldCorpus.size());
|
||||
VPrintf(V, "MERGE-OUTER: %zd files, %zd in the initial corpus\n",
|
||||
NumAttempts, OldCorpus.size());
|
||||
WriteNewControlFile(CFPath, OldCorpus, NewCorpus);
|
||||
}
|
||||
|
||||
|
@ -301,13 +302,17 @@ void CrashResistantMerge(const Vector<std::string> &Args,
|
|||
BaseCmd.removeFlag("fork");
|
||||
for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) {
|
||||
Fuzzer::MaybeExitGracefully();
|
||||
Printf("MERGE-OUTER: attempt %zd\n", Attempt);
|
||||
VPrintf(V, "MERGE-OUTER: attempt %zd\n", Attempt);
|
||||
Command Cmd(BaseCmd);
|
||||
Cmd.addFlag("merge_control_file", CFPath);
|
||||
Cmd.addFlag("merge_inner", "1");
|
||||
if (!V) {
|
||||
Cmd.setOutputFile("/dev/null"); // TODO: need to handle this on Windows?
|
||||
Cmd.combineOutAndErr();
|
||||
}
|
||||
auto ExitCode = ExecuteCommand(Cmd);
|
||||
if (!ExitCode) {
|
||||
Printf("MERGE-OUTER: succesfull in %zd attempt(s)\n", Attempt);
|
||||
VPrintf(V, "MERGE-OUTER: succesfull in %zd attempt(s)\n", Attempt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -315,14 +320,16 @@ void CrashResistantMerge(const Vector<std::string> &Args,
|
|||
Merger M;
|
||||
std::ifstream IF(CFPath);
|
||||
IF.seekg(0, IF.end);
|
||||
Printf("MERGE-OUTER: the control file has %zd bytes\n", (size_t)IF.tellg());
|
||||
VPrintf(V, "MERGE-OUTER: the control file has %zd bytes\n",
|
||||
(size_t)IF.tellg());
|
||||
IF.seekg(0, IF.beg);
|
||||
M.ParseOrExit(IF, true);
|
||||
IF.close();
|
||||
Printf("MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n",
|
||||
M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb());
|
||||
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);
|
||||
Printf("MERGE-OUTER: %zd new files with %zd new features added\n",
|
||||
VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added\n",
|
||||
NewFiles->size(), NumNewFeatures);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,8 @@ void CrashResistantMerge(const Vector<std::string> &Args,
|
|||
Vector<std::string> *NewFiles,
|
||||
const Set<uint32_t> &InitialFeatures,
|
||||
Set<uint32_t> *NewFeatures,
|
||||
const std::string &CFPath);
|
||||
const std::string &CFPath,
|
||||
bool Verbose);
|
||||
|
||||
} // namespace fuzzer
|
||||
|
||||
|
|
Loading…
Reference in New Issue