| 743 | } |
| 744 | |
| 745 | void Fuzzer::MutateAndTestOne() { |
| 746 | MD.StartMutationSequence(); |
| 747 | |
| 748 | auto &II = Corpus.ChooseUnitToMutate(MD.GetRand()); |
| 749 | if (Options.DoCrossOver) { |
| 750 | auto &CrossOverII = Corpus.ChooseUnitToCrossOverWith( |
| 751 | MD.GetRand(), Options.CrossOverUniformDist); |
| 752 | MD.SetCrossOverWith(&CrossOverII.U); |
| 753 | } |
| 754 | const auto &U = II.U; |
| 755 | memcpy(BaseSha1, II.Sha1, sizeof(BaseSha1)); |
| 756 | assert(CurrentUnitData); |
| 757 | size_t Size = U.size(); |
| 758 | assert(Size <= MaxInputLen && "Oversized Unit"); |
| 759 | memcpy(CurrentUnitData, U.data(), Size); |
| 760 | |
| 761 | assert(MaxMutationLen > 0); |
| 762 | |
| 763 | size_t CurrentMaxMutationLen = |
| 764 | Min(MaxMutationLen, Max(U.size(), TmpMaxMutationLen)); |
| 765 | assert(CurrentMaxMutationLen > 0); |
| 766 | |
| 767 | for (int i = 0; i < Options.MutateDepth; i++) { |
| 768 | if (TotalNumberOfRuns >= Options.MaxNumberOfRuns) |
| 769 | break; |
| 770 | MaybeExitGracefully(); |
| 771 | size_t NewSize = 0; |
| 772 | if (II.HasFocusFunction && !II.DataFlowTraceForFocusFunction.empty() && |
| 773 | Size <= CurrentMaxMutationLen) |
| 774 | NewSize = MD.MutateWithMask(CurrentUnitData, Size, Size, |
| 775 | II.DataFlowTraceForFocusFunction); |
| 776 | |
| 777 | // If MutateWithMask either failed or wasn't called, call default Mutate. |
| 778 | if (!NewSize) |
| 779 | NewSize = MD.Mutate(CurrentUnitData, Size, CurrentMaxMutationLen); |
| 780 | assert(NewSize > 0 && "Mutator returned empty unit"); |
| 781 | assert(NewSize <= CurrentMaxMutationLen && "Mutator return oversized unit"); |
| 782 | Size = NewSize; |
| 783 | II.NumExecutedMutations++; |
| 784 | Corpus.IncrementNumExecutedMutations(); |
| 785 | |
| 786 | bool FoundUniqFeatures = false; |
| 787 | bool NewCov = RunOne(CurrentUnitData, Size, /*MayDeleteFile=*/true, &II, |
| 788 | /*ForceAddToCorpus*/ false, &FoundUniqFeatures); |
| 789 | TryDetectingAMemoryLeak(CurrentUnitData, Size, |
| 790 | /*DuringInitialCorpusExecution*/ false); |
| 791 | if (NewCov) { |
| 792 | ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size}); |
| 793 | break; // We will mutate this input more in the next rounds. |
| 794 | } |
| 795 | if (Options.ReduceDepth && !FoundUniqFeatures) |
| 796 | break; |
| 797 | } |
| 798 | |
| 799 | II.NeedsEnergyUpdate = true; |
| 800 | } |
| 801 | |
| 802 | void Fuzzer::PurgeAllocator() { |
nothing calls this directly
no test coverage detected