diff options
| -rw-r--r-- | report/report.go | 11 | ||||
| -rw-r--r-- | syz-manager/cover.go | 25 | ||||
| -rw-r--r-- | syz-manager/manager.go | 3 | ||||
| -rw-r--r-- | tools/syz-report/syz-report.go | 2 | ||||
| -rw-r--r-- | tools/syz-symbolize/symbolize.go | 2 |
5 files changed, 31 insertions, 12 deletions
diff --git a/report/report.go b/report/report.go index 5a8f4a8bd..0ade02e5d 100644 --- a/report/report.go +++ b/report/report.go @@ -483,11 +483,14 @@ func extractDescription(output []byte, oops *oops) string { return string(output[pos:end]) } -func Symbolize(vmlinux string, text []byte) ([]byte, error) { +func Symbolize(vmlinux string, text []byte, symbols map[string][]symbolizer.Symbol) ([]byte, error) { var symbolized []byte - symbols, err := symbolizer.ReadSymbols(vmlinux) - if err != nil { - return nil, err + if symbols == nil { + var err error + symbols, err = symbolizer.ReadSymbols(vmlinux) + if err != nil { + return nil, err + } } symb := symbolizer.NewSymbolizer() defer symb.Close() diff --git a/syz-manager/cover.go b/syz-manager/cover.go index 986d7e067..66c8630a2 100644 --- a/syz-manager/cover.go +++ b/syz-manager/cover.go @@ -50,8 +50,11 @@ func (a uint64Array) Less(i, j int) bool { return a[i] < a[j] } func (a uint64Array) Swap(i, j int) { a[i], a[j] = a[j], a[i] } var ( - allCoverPCs []uint64 - allCoverReady = make(chan bool) + allCoverPCs []uint64 + allCoverReady = make(chan bool) + allSymbols map[string][]symbolizer.Symbol + allSymbolsReady = make(chan bool) + vmOffsets = make(map[string]uint32) ) const ( @@ -60,6 +63,8 @@ const ( func initAllCover(vmlinux string) { // Running objdump on vmlinux takes 20-30 seconds, so we do it asynchronously on start. + // Running nm on vmlinux may takes 200 microsecond and being called during symbolization of every crash, + // so also do it asynchronously on start and reuse the value during each crash. go func() { pcs, err := coveredPCs(vmlinux) if err == nil { @@ -68,7 +73,13 @@ func initAllCover(vmlinux string) { } else { Logf(0, "failed to run objdump on %v: %v", vmlinux, err) } + + allSymbols, err = symbolizer.ReadSymbols(vmlinux) + if err != nil { + Logf(0, "failed to run nm on %v: %v", vmlinux, err) + } close(allCoverReady) + close(allSymbolsReady) }() } @@ -201,6 +212,9 @@ func parseFile(fn string) ([][]byte, error) { } func getVmOffset(vmlinux string) (uint32, error) { + if v, ok := vmOffsets[vmlinux]; ok { + return v, nil + } out, err := exec.Command("readelf", "-SW", vmlinux).CombinedOutput() if err != nil { return 0, fmt.Errorf("readelf failed: %v\n%s", err, out) @@ -230,14 +244,15 @@ func getVmOffset(vmlinux string) (uint32, error) { } } } + vmOffsets[vmlinux] = addr return addr, nil } // uncoveredPcsInFuncs returns uncovered PCs with __sanitizer_cov_trace_pc calls in functions containing pcs. func uncoveredPcsInFuncs(vmlinux string, pcs []uint64) ([]uint64, error) { - allSymbols, err := symbolizer.ReadSymbols(vmlinux) - if err != nil { - return nil, fmt.Errorf("failed to run nm on vmlinux: %v", err) + <-allSymbolsReady + if allSymbols == nil { + return nil, fmt.Errorf("failed to run nm on vmlinux") } var symbols symbolArray for name, ss := range allSymbols { diff --git a/syz-manager/manager.go b/syz-manager/manager.go index 55f387473..ca3552d9f 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -528,7 +528,8 @@ func (mgr *Manager) saveCrash(crash *Crash) { ioutil.WriteFile(filepath.Join(dir, fmt.Sprintf("tag%v", oldestI)), []byte(mgr.cfg.Tag), 0660) } if len(crash.text) > 0 { - symbolized, err := report.Symbolize(mgr.cfg.Vmlinux, crash.text) + <-allSymbolsReady + symbolized, err := report.Symbolize(mgr.cfg.Vmlinux, crash.text, allSymbols) if err != nil { Logf(0, "failed to symbolize crash: %v", err) } else { diff --git a/tools/syz-report/syz-report.go b/tools/syz-report/syz-report.go index eff8d6b8c..8d6f9785d 100644 --- a/tools/syz-report/syz-report.go +++ b/tools/syz-report/syz-report.go @@ -26,7 +26,7 @@ func main() { fmt.Fprintf(os.Stderr, "report file does not contain a crash\n") os.Exit(1) } - symbolized, err := report.Symbolize(os.Args[1], text) + symbolized, err := report.Symbolize(os.Args[1], text, nil) if err != nil { fmt.Fprintf(os.Stderr, "failed to symbolize report: %v\n", err) } else { diff --git a/tools/syz-symbolize/symbolize.go b/tools/syz-symbolize/symbolize.go index d348b7148..ac2775350 100644 --- a/tools/syz-symbolize/symbolize.go +++ b/tools/syz-symbolize/symbolize.go @@ -32,7 +32,7 @@ func main() { if console := report.ExtractConsoleOutput(text); len(console) != 0 { text = console } - text, err = report.Symbolize(filepath.Join(*flagLinux, "vmlinux"), text) + text, err = report.Symbolize(filepath.Join(*flagLinux, "vmlinux"), text, nil) if err != nil { fmt.Fprintf(os.Stderr, "failed to symbolize: %v\n", err) os.Exit(1) |
