diff --git a/pkg/corpus/corpus.go b/pkg/corpus/corpus.go index 99abd818845f..f647d54bf124 100644 --- a/pkg/corpus/corpus.go +++ b/pkg/corpus/corpus.go @@ -124,6 +124,19 @@ type NewItemEvent struct { NewCover []uint64 } +func (corpus *Corpus) CovOnlySave(inp NewInput) { + newCover := corpus.cover.MergeDiff(inp.Cover) + if corpus.updates != nil { + select { + case <-corpus.ctx.Done(): + case corpus.updates <- NewItemEvent{ + Exists: true, // we only saves the coverage + NewCover: newCover, + }: + } + } +} + func (corpus *Corpus) Save(inp NewInput) { progData := inp.Prog.Serialize() sig := hash.String(progData) diff --git a/pkg/fuzzer/job.go b/pkg/fuzzer/job.go index 8786d046d518..f86c567d8d56 100644 --- a/pkg/fuzzer/job.go +++ b/pkg/fuzzer/job.go @@ -502,24 +502,35 @@ type faultInjectionJob struct { } func (job *faultInjectionJob) run(fuzzer *Fuzzer) { + totalCover := cover.FromRaw([]uint64{}) for nth := 1; nth <= 100; nth++ { fuzzer.Logf(2, "injecting fault into call %v, step %v", job.call, nth) newProg := job.p.Clone() newProg.Calls[job.call].Props.FailNth = nth result := fuzzer.execute(job.exec, &queue.Request{ - Prog: newProg, - Stat: fuzzer.statExecFaultInject, + Prog: newProg, + ExecOpts: setFlags(flatrpc.ExecFlagCollectCover), + Stat: fuzzer.statExecFaultInject, }) if result.Stop() { return } info := result.Info + if info != nil && info.Extra != nil { + newCover := cover.FromRaw(info.Extra.Cover) + totalCover.Merge(newCover.Serialize()) + } if info != nil && len(info.Calls) > job.call && info.Calls[job.call].Flags&flatrpc.CallFlagFaultInjected == 0 { break } } + input := corpus.NewInput{ + Cover: totalCover.Serialize(), + } + fuzzer.Config.Corpus.CovOnlySave(input) + } type hintsJob struct {