llvm.org GIT mirror llvm / 8848feb
[libFuzzer] refactoring in preparation for -reduce_inputs; NFC intended git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307857 91177308-0d34-0410-b5e6-96231b3b80d8 Kostya Serebryany 3 years ago
5 changed file(s) with 40 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
264264 Unit U = FileToVector(InputFilePath);
265265 if (MaxLen && MaxLen < U.size())
266266 U.resize(MaxLen);
267 F->RunOne(U.data(), U.size());
267 F->ExecuteCallback(U.data(), U.size());
268268 F->TryDetectingAMemoryLeak(U.data(), U.size(), true);
269269 return 0;
270270 }
571571 Options.UseCmp = Flags.use_cmp;
572572 Options.UseValueProfile = Flags.use_value_profile;
573573 Options.Shrink = Flags.shrink;
574 Options.ReduceInputs = Flags.reduce_inputs;
574575 Options.ShuffleAtStartUp = Flags.shuffle;
575576 Options.PreferSmall = Flags.prefer_small;
576577 Options.ReloadIntervalSec = Flags.reload;
656657 size_t Size = SMR.ReadByteArraySize();
657658 SMR.WriteByteArray(nullptr, 0);
658659 const Unit tmp(SMR.GetByteArray(), SMR.GetByteArray() + Size);
659 F->RunOne(tmp.data(), tmp.size());
660 F->ExecuteCallback(tmp.data(), tmp.size());
660661 SMR.PostServer();
661662 }
662663 return 0;
6464 FUZZER_FLAG_INT(use_value_profile, 0,
6565 "Experimental. Use value profile to guide fuzzing.")
6666 FUZZER_FLAG_INT(use_cmp, 1, "Use CMP traces to guide mutations")
67 FUZZER_FLAG_INT(shrink, 0, "Experimental. Try to shrink corpus elements.")
67 FUZZER_FLAG_INT(shrink, 0, "Experimental. Try to shrink corpus inputs.")
68 FUZZER_FLAG_INT(reduce_inputs, 0, "Experimental. "
69 "Try to reduce the size of inputs wile preserving their full feature sets")
6870 FUZZER_FLAG_UNSIGNED(jobs, 0, "Number of jobs to run. If jobs >= 1 we spawn"
6971 " this number of jobs in separate worker processes"
7072 " with stdout/stderr redirected to fuzz-JOB.log.")
6464 static void StaticFileSizeExceedCallback();
6565
6666 void ExecuteCallback(const uint8_t *Data, size_t Size);
67 size_t RunOne(const uint8_t *Data, size_t Size);
67 bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false);
6868
6969 // Merge Corpora[1:] into Corpora[0].
7070 void Merge(const std::vector &Corpora);
9494 void InterruptCallback();
9595 void MutateAndTestOne();
9696 void ReportNewCoverage(InputInfo *II, const Unit &U);
97 size_t RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
97 void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);
9898 void WriteToOutputCorpus(const Unit &U);
9999 void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
100100 void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
141141 size_t MaxInputLen = 0;
142142 size_t MaxMutationLen = 0;
143143
144 std::vector FeatureSetTmp;
145
144146 // Need to know our own thread.
145147 static thread_local bool IsMyThread;
146148 };
347347 if (U.size() > MaxSize)
348348 U.resize(MaxSize);
349349 if (!Corpus.HasUnit(U)) {
350 if (size_t NumFeatures = RunOne(U)) {
351 CheckExitOnSrcPosOrItem();
352 Corpus.AddToCorpus(U, NumFeatures);
350 if (RunOne(U.data(), U.size()))
353351 Reloaded = true;
354 }
355352 }
356353 }
357354 if (Reloaded)
376373 ExecuteCallback(&dummy, 0);
377374
378375 for (const auto &U : *InitialCorpus) {
379 if (size_t NumFeatures = RunOne(U)) {
380 CheckExitOnSrcPosOrItem();
381 Corpus.AddToCorpus(U, NumFeatures);
382 }
376 RunOne(U.data(), U.size());
383377 TryDetectingAMemoryLeak(U.data(), U.size(),
384378 /*DuringInitialCorpusExecution*/ true);
385379 }
391385 }
392386 }
393387
394 size_t Fuzzer::RunOne(const uint8_t *Data, size_t Size) {
395 if (!Size) return 0;
396 TotalNumberOfRuns++;
397
398 ExecuteCallback(Data, Size);
399
400 size_t NumUpdatesBefore = Corpus.NumFeatureUpdates();
401 TPC.CollectFeatures([&](size_t Feature) {
402 Corpus.AddFeature(Feature, Size, Options.Shrink);
403 });
404 size_t NumUpdatesAfter = Corpus.NumFeatureUpdates();
405
388 void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) {
406389 auto TimeOfUnit =
407390 duration_cast(UnitStopTime - UnitStartTime).count();
408391 if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&
414397 Printf("Slowest unit: %zd s:\n", TimeOfLongestUnitInSeconds);
415398 WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-");
416399 }
417 return NumUpdatesAfter - NumUpdatesBefore;
400 }
401
402 bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile) {
403 if (!Size) return false;
404
405 ExecuteCallback(Data, Size);
406
407 FeatureSetTmp.clear();
408 size_t NumUpdatesBefore = Corpus.NumFeatureUpdates();
409 TPC.CollectFeatures([&](size_t Feature) {
410 Corpus.AddFeature(Feature, Size, Options.Shrink);
411 if (Options.ReduceInputs)
412 FeatureSetTmp.push_back(Feature);
413 });
414 PrintPulseAndReportSlowInput(Data, Size);
415 size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore;
416 if (NumNewFeatures) {
417 CheckExitOnSrcPosOrItem();
418 Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile);
419 }
420 return NumNewFeatures > 0;
418421 }
419422
420423 size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
442445 }
443446
444447 void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
448 TotalNumberOfRuns++;
445449 assert(InFuzzingThread());
446450 if (SMR.IsClient())
447451 SMR.WriteByteArray(Data, Size);
594598 if (i == 0)
595599 StartTraceRecording();
596600 II.NumExecutedMutations++;
597 if (size_t NumFeatures = RunOne(CurrentUnitData, Size)) {
598 Corpus.AddToCorpus({CurrentUnitData, CurrentUnitData + Size}, NumFeatures,
599 /*MayDeleteFile=*/true);
601 if (RunOne(CurrentUnitData, Size, /*MayDeleteFile=*/true))
600602 ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size});
601 CheckExitOnSrcPosOrItem();
602 }
603
603604 StopTraceRecording();
604605 TryDetectingAMemoryLeak(CurrentUnitData, Size,
605606 /*DuringInitialCorpusExecution*/ false);
637638 for (int i = 0; i < Options.MutateDepth; i++) {
638639 size_t NewSize = MD.Mutate(CurrentUnitData, U.size(), MaxMutationLen);
639640 assert(NewSize > 0 && NewSize <= MaxMutationLen);
640 RunOne(CurrentUnitData, NewSize);
641 ExecuteCallback(CurrentUnitData, NewSize);
642 PrintPulseAndReportSlowInput(CurrentUnitData, NewSize);
641643 TryDetectingAMemoryLeak(CurrentUnitData, NewSize,
642644 /*DuringInitialCorpusExecution*/ false);
643645 }
3131 bool UseCmp = false;
3232 bool UseValueProfile = false;
3333 bool Shrink = false;
34 bool ReduceInputs = false;
3435 int ReloadIntervalSec = 1;
3536 bool ShuffleAtStartUp = true;
3637 bool PreferSmall = true;