diff options
| author | Joey Jiao <joeyjiaojg@gmail.com> | 2021-07-13 08:10:40 +0800 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2021-07-14 20:01:00 +0200 |
| commit | b9a2f64e4081e5f8f66f00ebb376068d4064daee (patch) | |
| tree | 9839ef85d2c0a47cb9353aa15a66b3c5b01a998d | |
| parent | 94e0b7079acc1c1ab28a2043fd21321c978f1529 (diff) | |
all: add /modulecover page
| -rw-r--r-- | pkg/cover/backend/backend.go | 3 | ||||
| -rw-r--r-- | pkg/cover/backend/dwarf.go | 1 | ||||
| -rw-r--r-- | pkg/cover/html.go | 84 | ||||
| -rw-r--r-- | pkg/cover/report.go | 7 | ||||
| -rw-r--r-- | syz-manager/html.go | 8 |
5 files changed, 97 insertions, 6 deletions
diff --git a/pkg/cover/backend/backend.go b/pkg/cover/backend/backend.go index 1cebc7ecd..3bd95a6fa 100644 --- a/pkg/cover/backend/backend.go +++ b/pkg/cover/backend/backend.go @@ -26,7 +26,8 @@ type Module struct { type CompileUnit struct { ObjectUnit - Path string + Path string + Module *Module } type Symbol struct { diff --git a/pkg/cover/backend/dwarf.go b/pkg/cover/backend/dwarf.go index 7a9abd221..8a2d524ea 100644 --- a/pkg/cover/backend/dwarf.go +++ b/pkg/cover/backend/dwarf.go @@ -272,6 +272,7 @@ func readTextRanges(debugInfo *dwarf.Data, module *Module, pcFix pcFixFn) ( ObjectUnit: ObjectUnit{ Name: attrName.(string), }, + Module: module, } units = append(units, unit) ranges1, err := debugInfo.Ranges(ent) diff --git a/pkg/cover/html.go b/pkg/cover/html.go index 7afe8b54c..639adcf82 100644 --- a/pkg/cover/html.go +++ b/pkg/cover/html.go @@ -214,6 +214,7 @@ func (rg *ReportGenerator) DoFilterPCs(w http.ResponseWriter, progs []Prog, cove type fileStats struct { Name string + Module string CoveredLines int TotalLines int CoveredPCs int @@ -272,6 +273,7 @@ func (rg *ReportGenerator) convertToStats(progs []Prog) ([]fileStats, error) { } data = append(data, fileStats{ Name: fname, + Module: file.module, CoveredLines: coveredLines, TotalLines: totalLines, CoveredPCs: file.coveredPCs, @@ -374,7 +376,7 @@ func groupCoverByFilePrefixes(datas []fileStats, subsystems []mgrconfig.Subsyste } d[subsystem.Name] = map[string]string{ - "subsystem": subsystem.Name, + "name": subsystem.Name, "lines": fmt.Sprintf("%v / %v / %.2f%%", coveredLines, totalLines, percentLines), "PCsInFiles": fmt.Sprintf("%v / %v / %.2f%%", coveredPCsInFile, totalPCsInFile, percentPCsInFile), "Funcs": fmt.Sprintf("%v / %v / %.2f%%", coveredFuncs, totalFuncs, percentCoveredFunc), @@ -398,6 +400,82 @@ func (rg *ReportGenerator) DoHTMLTable(w io.Writer, progs []Prog, coverFilter ma return coverTableTemplate.Execute(w, d) } +func groupCoverByModule(datas []fileStats) map[string]map[string]string { + d := make(map[string]map[string]string) + + coveredLines := make(map[string]int) + totalLines := make(map[string]int) + coveredPCsInFile := make(map[string]int) + totalPCsInFile := make(map[string]int) + totalFuncs := make(map[string]int) + coveredFuncs := make(map[string]int) + coveredPCsInFuncs := make(map[string]int) + pcsInCoveredFuncs := make(map[string]int) + pcsInFuncs := make(map[string]int) + percentLines := make(map[string]float64) + percentPCsInFile := make(map[string]float64) + percentPCsInFunc := make(map[string]float64) + percentPCsInCoveredFunc := make(map[string]float64) + percentCoveredFunc := make(map[string]float64) + + for _, data := range datas { + coveredLines[data.Module] += data.CoveredLines + totalLines[data.Module] += data.TotalLines + coveredPCsInFile[data.Module] += data.CoveredPCs + totalPCsInFile[data.Module] += data.TotalPCs + totalFuncs[data.Module] += data.TotalFunctions + coveredFuncs[data.Module] += data.CoveredFunctions + coveredPCsInFuncs[data.Module] += data.CoveredPCsInFunctions + pcsInFuncs[data.Module] += data.TotalPCsInFunctions + pcsInCoveredFuncs[data.Module] += data.TotalPCsInCoveredFunctions + } + + for m := range totalLines { + if totalLines[m] != 0 { + percentLines[m] = 100.0 * float64(coveredLines[m]) / float64(totalLines[m]) + } + if totalPCsInFile[m] != 0 { + percentPCsInFile[m] = 100.0 * float64(coveredPCsInFile[m]) / float64(totalPCsInFile[m]) + } + if pcsInFuncs[m] != 0 { + percentPCsInFunc[m] = 100.0 * float64(coveredPCsInFuncs[m]) / float64(pcsInFuncs[m]) + } + if pcsInCoveredFuncs[m] != 0 { + percentPCsInCoveredFunc[m] = 100.0 * float64(coveredPCsInFuncs[m]) / float64(pcsInCoveredFuncs[m]) + } + if totalFuncs[m] != 0 { + percentCoveredFunc[m] = 100.0 * float64(coveredFuncs[m]) / float64(totalFuncs[m]) + } + lines := fmt.Sprintf("%v / %v / %.2f%%", coveredLines[m], totalLines[m], percentLines[m]) + pcsInFiles := fmt.Sprintf("%v / %v / %.2f%%", coveredPCsInFile[m], totalPCsInFile[m], percentPCsInFile[m]) + funcs := fmt.Sprintf("%v / %v / %.2f%%", coveredFuncs[m], totalFuncs[m], percentCoveredFunc[m]) + pcsInFuncs := fmt.Sprintf("%v / %v / %.2f%%", coveredPCsInFuncs[m], pcsInFuncs[m], percentPCsInFunc[m]) + covedFuncs := fmt.Sprintf("%v / %v / %.2f%%", coveredPCsInFuncs[m], pcsInCoveredFuncs[m], percentPCsInCoveredFunc[m]) + d[m] = map[string]string{ + "name": m, + "lines": lines, + "PCsInFiles": pcsInFiles, + "Funcs": funcs, + "PCsInFuncs": pcsInFuncs, + "PCsInCoveredFuncs": covedFuncs, + } + } + + return d +} + +func (rg *ReportGenerator) DoModuleCover(w io.Writer, progs []Prog, coverFilter map[uint32]uint32) error { + progs = fixUpPCs(rg.target.Arch, progs, coverFilter) + data, err := rg.convertToStats(progs) + if err != nil { + return err + } + + d := groupCoverByModule(data) + + return coverTableTemplate.Execute(w, d) +} + var csvHeader = []string{ "Filename", "Function", @@ -898,7 +976,7 @@ var coverTableTemplate = template.Must(template.New("coverTable").Parse(` <table> <thead> <tr> - <th>Subsystem</th> + <th>Name</th> <th>Covered / Total Lines / %</th> <th>Covered / Total PCs in File / %</th> <th>Covered / Total PCs in Function / %</th> @@ -909,7 +987,7 @@ var coverTableTemplate = template.Must(template.New("coverTable").Parse(` <tbody id="content"> {{range $i, $p := .}} <tr> - <td>{{$p.subsystem}}</td> + <td>{{$p.name}}</td> <td>{{$p.lines}}</td> <td>{{$p.PCsInFiles}}</td> <td>{{$p.PCsInFuncs}}</td> diff --git a/pkg/cover/report.go b/pkg/cover/report.go index c7d96b703..788603119 100644 --- a/pkg/cover/report.go +++ b/pkg/cover/report.go @@ -49,6 +49,7 @@ func MakeReportGenerator(target *targets.Target, vm, objDir, srcDir, buildDir st } type file struct { + module string filename string lines map[int]line functions []*function @@ -76,6 +77,7 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog) (map[string]*file, error files := make(map[string]*file) for _, unit := range rg.Units { files[unit.Name] = &file{ + module: unit.Module.Name, filename: unit.Path, lines: make(map[int]line), totalPCs: len(unit.PCs), @@ -92,7 +94,7 @@ func (rg *ReportGenerator) prepareFileMap(progs []Prog) (map[string]*file, error } matchedPC := false for _, frame := range rg.Frames { - f := getFile(files, frame.Name, frame.Path) + f := getFile(files, frame.Name, frame.Path, frame.Module.Name) ln := f.lines[frame.StartLine] coveredBy := progPCs[frame.PC] if len(coveredBy) == 0 { @@ -190,10 +192,11 @@ func (rg *ReportGenerator) lazySymbolize(progs []Prog) error { return nil } -func getFile(files map[string]*file, name, path string) *file { +func getFile(files map[string]*file, name, path, module string) *file { f := files[name] if f == nil { f = &file{ + module: module, filename: path, lines: make(map[int]line), // Special mark for header files, if a file does not have coverage at all it is not shown. diff --git a/syz-manager/html.go b/syz-manager/html.go index 449061a69..e7d58304e 100644 --- a/syz-manager/html.go +++ b/syz-manager/html.go @@ -44,6 +44,7 @@ func (mgr *Manager) initHTTP() { mux.HandleFunc("/crash", mgr.httpCrash) mux.HandleFunc("/cover", mgr.httpCover) mux.HandleFunc("/subsystemcover", mgr.httpSubsystemCover) + mux.HandleFunc("/modulecover", mgr.httpModuleCover) mux.HandleFunc("/prio", mgr.httpPrio) mux.HandleFunc("/file", mgr.httpFile) mux.HandleFunc("/report", mgr.httpReport) @@ -238,6 +239,7 @@ func (mgr *Manager) httpDownloadCorpus(w http.ResponseWriter, r *http.Request) { const ( DoHTML int = iota DoHTMLTable + DoModuleCover DoCSV DoCSVFiles DoRawCoverFiles @@ -253,6 +255,10 @@ func (mgr *Manager) httpSubsystemCover(w http.ResponseWriter, r *http.Request) { mgr.httpCoverCover(w, r, DoHTMLTable, true) } +func (mgr *Manager) httpModuleCover(w http.ResponseWriter, r *http.Request) { + mgr.httpCoverCover(w, r, DoModuleCover, true) +} + func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request, funcFlag int, isHTMLCover bool) { if !mgr.cfg.Cover { if isHTMLCover { @@ -324,6 +330,8 @@ func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request, funcF do := rg.DoHTML if funcFlag == DoHTMLTable { do = rg.DoHTMLTable + } else if funcFlag == DoModuleCover { + do = rg.DoModuleCover } else if funcFlag == DoCSV { do = rg.DoCSV } else if funcFlag == DoCSVFiles { |
