github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/pkg/covermerger/file_line_merger.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 covermerger
     5  
     6  import "github.com/google/syzkaller/pkg/log"
     7  
     8  func makeFileLineCoverMerger(fvs FileVersions, base RepoCommit) FileCoverageMerger {
     9  	baseFile := ""
    10  	baseFileExists := false
    11  	for repoCommit, fv := range fvs {
    12  		if repoCommit == base {
    13  			baseFile = fv
    14  			baseFileExists = true
    15  			break
    16  		}
    17  	}
    18  	if !baseFileExists {
    19  		return &DeletedFileLineMerger{}
    20  	}
    21  	a := &FileLineCoverMerger{
    22  		MergeResult: &MergeResult{
    23  			HitCounts:   make(map[int]int64),
    24  			FileExists:  true,
    25  			LineDetails: make(map[int][]*FileRecord),
    26  		},
    27  		baseFile:   baseFile,
    28  		matchers:   make(map[RepoCommit]*LineToLineMatcher),
    29  		lostFrames: map[RepoCommit]int64{},
    30  	}
    31  	for repoBranch, fv := range fvs {
    32  		a.matchers[repoBranch] = makeLineToLineMatcher(fv, baseFile)
    33  	}
    34  	return a
    35  }
    36  
    37  type FileLineCoverMerger struct {
    38  	*MergeResult
    39  	baseFile   string
    40  	matchers   map[RepoCommit]*LineToLineMatcher
    41  	lostFrames map[RepoCommit]int64
    42  }
    43  
    44  func (a *FileLineCoverMerger) Add(record *FileRecord) {
    45  	if record.StartLine < 0 {
    46  		// This record doesn't have information about line coverage.
    47  		// The best we sometimes have is the function name.
    48  		return
    49  	}
    50  	if a.matchers[record.RepoCommit] == nil {
    51  		if record.HitCount > 0 {
    52  			a.lostFrames[record.RepoCommit]++
    53  		}
    54  		return
    55  	}
    56  	if targetLine := a.matchers[record.RepoCommit].SameLinePos(record.StartLine); targetLine != -1 {
    57  		a.HitCounts[targetLine] += int64(record.HitCount)
    58  		a.LineDetails[targetLine] = append(a.LineDetails[targetLine], record)
    59  	}
    60  }
    61  
    62  func (a *FileLineCoverMerger) Result() *MergeResult {
    63  	for repoBranch, lostFrames := range a.lostFrames {
    64  		log.Logf(1, "\t[warn] lost %d frames from repoCommit(%s, %s)",
    65  			lostFrames, repoBranch.Repo, repoBranch.Commit)
    66  	}
    67  	return a.MergeResult
    68  }