aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-12-11 18:18:58 +0100
committerDmitry Vyukov <dvyukov@google.com>2020-12-13 18:56:36 +0100
commit3fc0a844bfb8efd6f8fe32585e4fd5d9f2af3fc3 (patch)
tree9a6f4e9737e4312bb32ec9ea820cfa508e5add80
parent138959733bc731cc789fa7c7473e493b2e104bcc (diff)
syz-manager: better encapsulate report generator
Avoid global variables and implicit dependencies on previous initialization.
-rw-r--r--pkg/cover/report.go3
-rw-r--r--syz-manager/cover.go36
-rw-r--r--syz-manager/covfilter.go11
-rw-r--r--syz-manager/html.go24
4 files changed, 38 insertions, 36 deletions
diff --git a/pkg/cover/report.go b/pkg/cover/report.go
index 14c0b7422..e50e11d13 100644
--- a/pkg/cover/report.go
+++ b/pkg/cover/report.go
@@ -32,6 +32,9 @@ var (
)
func MakeReportGenerator(target *targets.Target, vm, objDir, srcDir, buildDir string) (*ReportGenerator, error) {
+ if objDir == "" {
+ return nil, fmt.Errorf("kernel obj directory is not specified")
+ }
impl, err := backend.Make(target, vm, objDir)
if err != nil {
return nil, err
diff --git a/syz-manager/cover.go b/syz-manager/cover.go
index 39f2ed001..f5ca86631 100644
--- a/syz-manager/cover.go
+++ b/syz-manager/cover.go
@@ -4,36 +4,30 @@
package main
import (
- "fmt"
"sync"
"github.com/google/syzkaller/pkg/cover"
+ "github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/mgrconfig"
- "github.com/google/syzkaller/sys/targets"
)
-var (
- initCoverOnce sync.Once
- initCoverError error
- reportGenerator *cover.ReportGenerator
-)
-
-func initCover(cfg *mgrconfig.Config) error {
- initCoverOnce.Do(func() {
- if cfg.KernelObj == "" {
- initCoverError = fmt.Errorf("kernel_obj is not specified")
- return
- }
- reportGenerator, initCoverError = cover.MakeReportGenerator(
- cfg.SysTarget, cfg.Type, cfg.KernelObj, cfg.KernelSrc, cfg.KernelBuildSrc)
- })
- return initCoverError
-}
+var getReportGenerator = func() func(cfg *mgrconfig.Config) (*cover.ReportGenerator, error) {
+ var once sync.Once
+ var rg *cover.ReportGenerator
+ var err error
+ return func(cfg *mgrconfig.Config) (*cover.ReportGenerator, error) {
+ once.Do(func() {
+ log.Logf(0, "initializing coverage information...")
+ rg, err = cover.MakeReportGenerator(cfg.SysTarget, cfg.Type, cfg.KernelObj, cfg.KernelSrc, cfg.KernelBuildSrc)
+ })
+ return rg, err
+ }
+}()
-func coverToPCs(target *targets.Target, cov []uint32) []uint64 {
+func coverToPCs(rg *cover.ReportGenerator, cov []uint32) []uint64 {
pcs := make([]uint64, 0, len(cov))
for _, pc := range cov {
- pcs = append(pcs, reportGenerator.RestorePC(pc))
+ pcs = append(pcs, rg.RestorePC(pc))
}
return pcs
}
diff --git a/syz-manager/covfilter.go b/syz-manager/covfilter.go
index 5b252603e..db4c5a64f 100644
--- a/syz-manager/covfilter.go
+++ b/syz-manager/covfilter.go
@@ -13,6 +13,7 @@ import (
"sort"
"strconv"
+ "github.com/google/syzkaller/pkg/cover"
"github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/mgrconfig"
"github.com/google/syzkaller/pkg/osutil"
@@ -23,11 +24,11 @@ func createCoverageFilter(cfg *mgrconfig.Config) (string, map[uint32]uint32, err
pcs := make(map[uint32]uint32)
filter := &cfg.CovFilter
if len(filter.Files) != 0 || len(filter.Functions) != 0 {
- log.Logf(0, "initializing coverage information...")
- if err := initCover(cfg); err != nil {
+ rg, err := getReportGenerator(cfg)
+ if err != nil {
return "", nil, err
}
- if err := initFilesFuncs(pcs, filter.Files, filter.Functions); err != nil {
+ if err := initFilesFuncs(pcs, filter.Files, filter.Functions, rg); err != nil {
return "", nil, err
}
}
@@ -48,7 +49,7 @@ func createCoverageFilter(cfg *mgrconfig.Config) (string, map[uint32]uint32, err
return filename, pcs, nil
}
-func initFilesFuncs(pcs map[uint32]uint32, files, funcs []string) error {
+func initFilesFuncs(pcs map[uint32]uint32, files, funcs []string, rg *cover.ReportGenerator) error {
funcsRegexp, err := compileRegexps(funcs)
if err != nil {
return err
@@ -59,7 +60,7 @@ func initFilesFuncs(pcs map[uint32]uint32, files, funcs []string) error {
}
fileDedup := make(map[string]bool)
used := make(map[*regexp.Regexp][]string)
- for _, sym := range reportGenerator.Symbols {
+ for _, sym := range rg.Symbols {
matched := false
for _, re := range funcsRegexp {
if re.MatchString(sym.Name) {
diff --git a/syz-manager/html.go b/syz-manager/html.go
index 24126adb5..0b606f099 100644
--- a/syz-manager/html.go
+++ b/syz-manager/html.go
@@ -214,22 +214,24 @@ func (mgr *Manager) httpCover(w http.ResponseWriter, r *http.Request) {
}
// Note: initCover is executed without mgr.mu because it takes very long time
// (but it only reads config and it protected by initCoverOnce).
- if err := initCover(mgr.cfg); err != nil {
+ rg, err := getReportGenerator(mgr.cfg)
+ if err != nil {
http.Error(w, fmt.Sprintf("failed to generate coverage profile: %v", err), http.StatusInternalServerError)
return
}
mgr.mu.Lock()
defer mgr.mu.Unlock()
- mgr.httpCoverCover(w, r, reportGenerator.DoHTML)
+ mgr.httpCoverCover(w, r, rg, rg.DoHTML)
}
-func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request, do func(io.Writer, []cover.Prog) error) {
+func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request,
+ rg *cover.ReportGenerator, do func(io.Writer, []cover.Prog) error) {
var progs []cover.Prog
if sig := r.FormValue("input"); sig != "" {
inp := mgr.corpus[sig]
progs = append(progs, cover.Prog{
Data: string(inp.Prog),
- PCs: coverToPCs(mgr.sysTarget, inp.Cover),
+ PCs: coverToPCs(rg, inp.Cover),
})
} else {
call := r.FormValue("call")
@@ -239,7 +241,7 @@ func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request, do fu
}
progs = append(progs, cover.Prog{
Data: string(inp.Prog),
- PCs: coverToPCs(mgr.sysTarget, inp.Cover),
+ PCs: coverToPCs(rg, inp.Cover),
})
}
}
@@ -286,13 +288,14 @@ func (mgr *Manager) httpFuncCover(w http.ResponseWriter, r *http.Request) {
http.Error(w, "coverage is not enabled", http.StatusInternalServerError)
return
}
- if err := initCover(mgr.cfg); err != nil {
+ rg, err := getReportGenerator(mgr.cfg)
+ if err != nil {
http.Error(w, fmt.Sprintf("failed to generate coverage profile: %v", err), http.StatusInternalServerError)
return
}
mgr.mu.Lock()
defer mgr.mu.Unlock()
- mgr.httpCoverCover(w, r, reportGenerator.DoCSV)
+ mgr.httpCoverCover(w, r, rg, rg.DoCSV)
}
func (mgr *Manager) httpPrio(w http.ResponseWriter, r *http.Request) {
@@ -392,8 +395,9 @@ func (mgr *Manager) httpReport(w http.ResponseWriter, r *http.Request) {
func (mgr *Manager) httpRawCover(w http.ResponseWriter, r *http.Request) {
// Note: initCover is executed without mgr.mu because it takes very long time
// (but it only reads config and it protected by initCoverOnce).
- if err := initCover(mgr.cfg); err != nil {
- http.Error(w, initCoverError.Error(), http.StatusInternalServerError)
+ rg, err := getReportGenerator(mgr.cfg)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
mgr.mu.Lock()
@@ -403,7 +407,7 @@ func (mgr *Manager) httpRawCover(w http.ResponseWriter, r *http.Request) {
for _, inp := range mgr.corpus {
cov.Merge(inp.Cover)
}
- pcs := coverToPCs(mgr.sysTarget, cov.Serialize())
+ pcs := coverToPCs(rg, cov.Serialize())
sort.Slice(pcs, func(i, j int) bool {
return pcs[i] < pcs[j]
})