github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/corpus/minimize.go (about)

     1  // Copyright 2024 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package corpus
     5  
     6  import (
     7  	"sort"
     8  
     9  	"github.com/google/syzkaller/pkg/signal"
    10  )
    11  
    12  func (corpus *Corpus) Minimize(cover bool) {
    13  	corpus.mu.Lock()
    14  	defer corpus.mu.Unlock()
    15  
    16  	inputs := make([]signal.Context, 0, len(corpus.progs))
    17  	for _, inp := range corpus.progsMap {
    18  		inputs = append(inputs, signal.Context{
    19  			Signal:  inp.Signal,
    20  			Context: inp,
    21  		})
    22  	}
    23  
    24  	// Note: inputs are unsorted (based on map iteration).
    25  	// This gives some intentional non-determinism during minimization.
    26  	// However, we want to give preference to non-squashed inputs,
    27  	// so let's sort by this criteria.
    28  	// We also want to give preference to smaller corpus programs:
    29  	// - they are faster to execute,
    30  	// - minimization occasionally fails, so we need to clean it up over time.
    31  	sort.SliceStable(inputs, func(i, j int) bool {
    32  		first := inputs[i].Context.(*Item)
    33  		second := inputs[j].Context.(*Item)
    34  		if first.HasAny != second.HasAny {
    35  			return !first.HasAny
    36  		}
    37  		return len(first.Prog.Calls) < len(second.Prog.Calls)
    38  	})
    39  
    40  	corpus.progsMap = make(map[string]*Item)
    41  
    42  	// Overwrite the program lists.
    43  	corpus.ProgramsList = &ProgramsList{}
    44  	for _, area := range corpus.focusAreas {
    45  		area.ProgramsList = &ProgramsList{}
    46  	}
    47  	for _, ctx := range signal.Minimize(inputs) {
    48  		inp := ctx.(*Item)
    49  		corpus.progsMap[inp.Sig] = inp
    50  		corpus.saveProgram(inp.Prog, inp.Signal)
    51  		for area := range inp.areas {
    52  			area.saveProgram(inp.Prog, inp.Signal)
    53  		}
    54  	}
    55  }