diff options
| author | Taras Madan <tarasmadan@google.com> | 2024-03-15 21:21:01 +0100 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2024-03-20 10:11:25 +0000 |
| commit | 2c154a8fc72ca5d6a1a6f519d43e943cf5d2957f (patch) | |
| tree | a8d54f2831e29aa19c77f18bee2412a945070f7d /pkg | |
| parent | a485f2390d41decb9fca41e15902295e293464d2 (diff) | |
pkg/cover: add full symbolization for /cover?jsonl=1
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/cover/backend/backend.go | 13 | ||||
| -rw-r--r-- | pkg/cover/backend/dwarf.go | 5 | ||||
| -rw-r--r-- | pkg/cover/html.go | 5 | ||||
| -rw-r--r-- | pkg/cover/report.go | 46 |
4 files changed, 39 insertions, 30 deletions
diff --git a/pkg/cover/backend/backend.go b/pkg/cover/backend/backend.go index 0091adb4f..a343dfe02 100644 --- a/pkg/cover/backend/backend.go +++ b/pkg/cover/backend/backend.go @@ -11,12 +11,13 @@ import ( ) type Impl struct { - Units []*CompileUnit - Symbols []*Symbol - Frames []Frame - Symbolize func(pcs map[*Module][]uint64) ([]Frame, error) - RestorePC func(pc uint32) uint64 - CoverPoints map[uint64]bool + Units []*CompileUnit + Symbols []*Symbol + Frames []Frame + Symbolize func(pcs map[*Module][]uint64) ([]Frame, error) + RestorePC func(pc uint32) uint64 + CallbackPoints map[uint64]bool + CoverageCallbackPoints []uint64 } type Module struct { diff --git a/pkg/cover/backend/dwarf.go b/pkg/cover/backend/dwarf.go index 0142afc7e..35ddd27a6 100644 --- a/pkg/cover/backend/dwarf.go +++ b/pkg/cover/backend/dwarf.go @@ -261,8 +261,9 @@ func makeDWARFUnsafe(params *dwarfParams) (*Impl, error) { Symbolize: func(pcs map[*Module][]uint64) ([]Frame, error) { return symbolize(target, objDir, srcDir, buildDir, splitBuildDelimiters, pcs) }, - RestorePC: makeRestorePC(params, pcBase), - CoverPoints: allCoverPointsMap, + RestorePC: makeRestorePC(params, pcBase), + CallbackPoints: allCoverPointsMap, + CoverageCallbackPoints: allCoverPoints[0], } return impl, nil } diff --git a/pkg/cover/html.go b/pkg/cover/html.go index 1411bdf62..bfceca2be 100644 --- a/pkg/cover/html.go +++ b/pkg/cover/html.go @@ -186,7 +186,7 @@ func fileLineContents(file *file, lines [][]byte) lineCoverExport { func (rg *ReportGenerator) DoRawCoverFiles(w io.Writer, params CoverHandlerParams) error { progs := fixUpPCs(rg.target.Arch, params.Progs, params.CoverFilter) - if err := rg.lazySymbolize(progs); err != nil { + if err := rg.symbolizePCs(uniquePCs(progs)); err != nil { return err } @@ -226,6 +226,9 @@ type coverageInfo struct { // DoCoverJSONL is a handler for "/cover?jsonl=1". func (rg *ReportGenerator) DoCoverJSONL(w io.Writer, params CoverHandlerParams) error { + if err := rg.symbolizePCs(rg.CoverageCallbackPoints); err != nil { + return fmt.Errorf("failed to rg.fullSymbolize(): %w", err) + } var progs = fixUpPCs(rg.target.Arch, params.Progs, params.CoverFilter) fm, err := rg.prepareFileMap(progs, params.Debug) if err != nil { diff --git a/pkg/cover/report.go b/pkg/cover/report.go index 85478d44c..f52a2bcaa 100644 --- a/pkg/cover/report.go +++ b/pkg/cover/report.go @@ -11,6 +11,7 @@ import ( "github.com/google/syzkaller/pkg/host" "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/sys/targets" + "golang.org/x/exp/maps" ) type ReportGenerator struct { @@ -91,7 +92,7 @@ func coverageCallbackMismatch(debug bool, numPCs int, unmatchedProgPCs map[uint6 type fileMap map[string]*file func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, error) { - if err := rg.lazySymbolize(progs); err != nil { + if err := rg.symbolizePCs(uniquePCs(progs)); err != nil { return nil, err } files := make(fileMap) @@ -105,14 +106,14 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, er } progPCs := make(map[uint64]map[int]bool) unmatchedProgPCs := make(map[uint64]bool) - verifyCoverPoints := (len(rg.CoverPoints) > 0) + verifyCallbackPoints := (len(rg.CallbackPoints) > 0) for i, prog := range progs { for _, pc := range prog.PCs { if progPCs[pc] == nil { progPCs[pc] = make(map[int]bool) } progPCs[pc][i] = true - if verifyCoverPoints && !rg.CoverPoints[pc] { + if verifyCallbackPoints && !rg.CallbackPoints[pc] { unmatchedProgPCs[pc] = true } } @@ -148,7 +149,7 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, er } // If the backend provided coverage callback locations for the binaries, use them to // verify data returned by kcov. - if verifyCoverPoints && (len(unmatchedProgPCs) > 0) { + if verifyCallbackPoints && (len(unmatchedProgPCs) > 0) { return nil, coverageCallbackMismatch(debug, len(progPCs), unmatchedProgPCs) } for _, unit := range rg.Units { @@ -180,29 +181,32 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog, debug bool) (fileMap, er return files, nil } -func (rg *ReportGenerator) lazySymbolize(progs []Prog) error { +func uniquePCs(progs []Prog) []uint64 { + PCs := make(map[uint64]bool) + for _, p := range progs { + for _, pc := range p.PCs { + PCs[pc] = true + } + } + return maps.Keys(PCs) +} + +func (rg *ReportGenerator) symbolizePCs(PCs []uint64) error { + if len(PCs) == 0 { + return fmt.Errorf("no coverage collected so far to symbolize") + } if len(rg.Symbols) == 0 { return nil } symbolize := make(map[*backend.Symbol]bool) - uniquePCs := make(map[uint64]bool) pcs := make(map[*backend.Module][]uint64) - for _, prog := range progs { - for _, pc := range prog.PCs { - if uniquePCs[pc] { - continue - } - uniquePCs[pc] = true - sym := rg.findSymbol(pc) - if sym == nil || (sym.Symbolized || symbolize[sym]) { - continue - } - symbolize[sym] = true - pcs[sym.Module] = append(pcs[sym.Module], sym.PCs...) + for _, pc := range PCs { + sym := rg.findSymbol(pc) + if sym == nil || sym.Symbolized || symbolize[sym] { + continue } - } - if len(uniquePCs) == 0 { - return fmt.Errorf("no coverage collected so far") + symbolize[sym] = true + pcs[sym.Module] = append(pcs[sym.Module], sym.PCs...) } frames, err := rg.Symbolize(pcs) if err != nil { |
