aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--report/report.go11
-rw-r--r--syz-manager/cover.go25
-rw-r--r--syz-manager/manager.go3
-rw-r--r--tools/syz-report/syz-report.go2
-rw-r--r--tools/syz-symbolize/symbolize.go2
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)