@@ -416,13 +416,18 @@ size_t Centipede::AddPcPairFeatures(FeatureVec &fv) {
416416}
417417
418418bool Centipede::RunBatch (
419- const std::vector<ByteArray> &input_vec,
420- BlobFileWriter *absl_nullable corpus_file,
421- BlobFileWriter *absl_nullable features_file,
422- BlobFileWriter *absl_nullable unconditional_features_file) {
419+ const std::vector<ByteArray>& input_vec,
420+ const std::vector<size_t >& mutant_origins,
421+ BlobFileWriter* absl_nullable corpus_file,
422+ BlobFileWriter* absl_nullable features_file,
423+ BlobFileWriter* absl_nullable unconditional_features_file) {
423424 BatchResult batch_result;
424425 bool success = ExecuteAndReportCrash (env_.binary , input_vec, batch_result);
425426 FUZZTEST_CHECK_EQ (input_vec.size (), batch_result.results ().size ());
427+ FUZZTEST_CHECK (mutant_origins.empty () ||
428+ mutant_origins.size () >= input_vec.size ())
429+ << " Got " << mutant_origins.size () << " with " << input_vec.size ()
430+ << " input" ;
426431
427432 for (const auto &extra_binary : env_.extra_binaries ) {
428433 if (ShouldStop ()) break ;
@@ -474,6 +479,7 @@ bool Centipede::RunBatch(
474479 }
475480 }
476481 }
482+ corpus_.UpdateWeights (fs_, coverage_frontier_, env_.exec_time_weight_scaling );
477483 return batch_gained_new_coverage;
478484}
479485
@@ -563,7 +569,7 @@ void Centipede::Rerun(std::vector<ByteArray> &to_rerun) {
563569 size_t batch_size = std::min (to_rerun.size (), env_.batch_size );
564570 std::vector<ByteArray> batch (to_rerun.end () - batch_size, to_rerun.end ());
565571 to_rerun.resize (to_rerun.size () - batch_size);
566- if (RunBatch (batch, nullptr , nullptr , features_file.get ())) {
572+ if (RunBatch (batch, {}, nullptr , nullptr , features_file.get ())) {
567573 UpdateAndMaybeLogStats (" rerun-old" , 1 );
568574 }
569575 }
@@ -757,7 +763,7 @@ void Centipede::LoadSeedInputs(BlobFileWriter *absl_nonnull corpus_file,
757763 seed_inputs.push_back ({0 });
758764 }
759765
760- RunBatch (seed_inputs, corpus_file, features_file,
766+ RunBatch (seed_inputs, {}, corpus_file, features_file,
761767 /* unconditional_features_file=*/ nullptr );
762768 FUZZTEST_LOG (INFO) << " Number of input seeds available: "
763769 << num_seeds_available
@@ -838,21 +844,39 @@ void Centipede::FuzzingLoop() {
838844 auto remaining_runs = env_.num_runs - new_runs;
839845 auto batch_size = std::min (env_.batch_size , remaining_runs);
840846 std::vector<MutationInputRef> mutation_inputs;
847+ std::vector<size_t > mutate_batch_origins;
841848 mutation_inputs.reserve (env_.mutate_batch_size );
849+ mutate_batch_origins.reserve (env_.mutate_batch_size );
842850 for (size_t i = 0 ; i < env_.mutate_batch_size ; i++) {
843- const auto & corpus_record = env_.use_corpus_weights
844- ? corpus_.WeightedRandom (rng_)
845- : corpus_.UniformRandom (rng_);
851+ const size_t origin = env_.use_corpus_weights
852+ ? corpus_.WeightedRandom (rng_)
853+ : corpus_.UniformRandom (rng_);
854+ mutate_batch_origins.push_back (origin);
855+ const auto & corpus_record = corpus_.Records ()[origin];
846856 mutation_inputs.push_back (
847857 MutationInputRef{corpus_record.data , &corpus_record.metadata });
848858 }
849859
850- const std::vector<ByteArray > mutants =
860+ const std::vector<Mutant > mutants =
851861 user_callbacks_.Mutate (mutation_inputs, batch_size);
852862 if (ShouldStop ()) break ;
853863
864+ std::vector<ByteArray> next_batch;
865+ next_batch.reserve (mutants.size ());
866+ std::vector<size_t > mutant_origins;
867+ mutant_origins.reserve (mutants.size ());
868+ for (auto & mutant : mutants) {
869+ next_batch.push_back (std::move (mutant.data ));
870+ if (mutant.origin == Mutant::kOriginNone ) {
871+ mutant_origins.push_back (Mutant::kOriginNone );
872+ } else {
873+ mutant_origins.push_back (mutate_batch_origins[mutant.origin ]);
874+ }
875+ }
876+
854877 bool gained_new_coverage =
855- RunBatch (mutants, corpus_file.get (), features_file.get (), nullptr );
878+ RunBatch (next_batch, mutant_origins, corpus_file.get (),
879+ features_file.get (), nullptr );
856880 new_runs += mutants.size ();
857881
858882 if (gained_new_coverage) {
0 commit comments