diff options
| -rw-r--r-- | pkg/repro/repro.go | 8 | ||||
| -rw-r--r-- | syz-manager/manager.go | 71 |
2 files changed, 46 insertions, 33 deletions
diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go index b5e265301..bce549b0a 100644 --- a/pkg/repro/repro.go +++ b/pkg/repro/repro.go @@ -36,7 +36,10 @@ type Result struct { Opts csource.Options CRepro bool Stats Stats - Report []byte + // Description and report of the final crash that we reproduced. + // Can be different from what we started reproducing. + Desc string + Report []byte } type context struct { @@ -45,6 +48,7 @@ type context struct { instances chan *instance bootRequests chan int stats Stats + desc string report []byte } @@ -137,6 +141,7 @@ func Run(crashLog []byte, cfg *mgrconfig.Config, vmPool *vm.Pool, vmIndexes []in if res != nil { ctx.reproLog(3, "repro crashed as:\n%s", string(ctx.report)) res.Stats = ctx.stats + res.Desc = ctx.desc res.Report = ctx.report } @@ -666,6 +671,7 @@ func (ctx *context) testImpl(inst *vm.Instance, command string, duration time.Du ctx.reproLog(2, "program did not crash") return false, nil } + ctx.desc = desc ctx.report = report ctx.reproLog(2, "program crashed: %v", desc) return true, nil diff --git a/syz-manager/manager.go b/syz-manager/manager.go index 2eaa94778..9cb47d5f2 100644 --- a/syz-manager/manager.go +++ b/syz-manager/manager.go @@ -305,7 +305,7 @@ type RunResult struct { type ReproResult struct { instances []int - crash *Crash + desc0 string res *repro.Result err error } @@ -373,7 +373,7 @@ func (mgr *Manager) vmLoop() { Logf(1, "loop: starting repro of '%v' on instances %+v", crash.desc, vmIndexes) go func() { res, err := repro.Run(crash.output, mgr.cfg, mgr.vmPool, vmIndexes) - reproDone <- &ReproResult{vmIndexes, crash, res, err} + reproDone <- &ReproResult{vmIndexes, crash.desc, res, err} }() } for !canRepro() && len(instances) != 0 { @@ -415,18 +415,24 @@ func (mgr *Manager) vmLoop() { } case res := <-reproDone: crepro := false + desc := "" if res.res != nil { crepro = res.res.CRepro + desc = res.res.Desc } - Logf(1, "loop: repro on instances %+v finished '%v', repro=%v crepro=%v", - res.instances, res.crash.desc, res.res != nil, crepro) + Logf(1, "loop: repro on %+v finished '%v', repro=%v crepro=%v desc='%v'", + res.instances, res.desc0, res.res != nil, crepro, desc) if res.err != nil { Logf(0, "repro failed: %v", res.err) } - delete(reproducing, res.crash.desc) + delete(reproducing, res.desc0) instances = append(instances, res.instances...) reproInstances -= instancesPerRepro - mgr.saveRepro(res.crash, res.res) + if res.res == nil { + mgr.saveFailedRepro(res.desc0) + } else { + mgr.saveRepro(res.res) + } case <-shutdown: Logf(1, "loop: shutting down...") shutdown = nil @@ -599,37 +605,38 @@ func (mgr *Manager) needRepro(desc string) bool { return false } -func (mgr *Manager) saveRepro(crash *Crash, res *repro.Result) { - sig := hash.Hash([]byte(crash.desc)) - dir := filepath.Join(mgr.crashdir, sig.String()) - if res == nil { - if mgr.dash != nil { - fr := &dashapi.FailedRepro{ - Manager: mgr.cfg.Name, - BuildID: mgr.cfg.Tag, - Title: crash.desc, - } - if err := mgr.dash.ReportFailedRepro(fr); err != nil { - Logf(0, "failed to report failed repro to dashboard: %v", err) - } +func (mgr *Manager) saveFailedRepro(desc string) { + if mgr.dash != nil { + fr := &dashapi.FailedRepro{ + Manager: mgr.cfg.Name, + BuildID: mgr.cfg.Tag, + Title: desc, } - for i := 0; i < maxReproAttempts; i++ { - name := filepath.Join(dir, fmt.Sprintf("repro%v", i)) - if !osutil.IsExist(name) { - osutil.WriteFile(name, nil) - break - } + if err := mgr.dash.ReportFailedRepro(fr); err != nil { + Logf(0, "failed to report failed repro to dashboard: %v", err) } - return } + dir := filepath.Join(mgr.crashdir, hash.String([]byte(desc))) + for i := 0; i < maxReproAttempts; i++ { + name := filepath.Join(dir, fmt.Sprintf("repro%v", i)) + if !osutil.IsExist(name) { + osutil.WriteFile(name, nil) + break + } + } +} + +func (mgr *Manager) saveRepro(res *repro.Result) { + dir := filepath.Join(mgr.crashdir, hash.String([]byte(res.Desc))) + opts := fmt.Sprintf("# %+v\n", res.Opts) prog := res.Prog.Serialize() osutil.WriteFile(filepath.Join(dir, "repro.prog"), append([]byte(opts), prog...)) if len(mgr.cfg.Tag) > 0 { osutil.WriteFile(filepath.Join(dir, "repro.tag"), []byte(mgr.cfg.Tag)) } - if len(crash.text) > 0 { - osutil.WriteFile(filepath.Join(dir, "repro.report"), []byte(crash.text)) + if len(res.Report) > 0 { + osutil.WriteFile(filepath.Join(dir, "repro.report"), []byte(res.Report)) } osutil.WriteFile(filepath.Join(dir, "repro.log"), res.Stats.Log) stats := fmt.Sprintf("Extracting prog: %s\nMinimizing prog: %s\nSimplifying prog options: %s\nExtracting C: %s\nSimplifying C: %s\n", @@ -652,7 +659,7 @@ func (mgr *Manager) saveRepro(crash *Crash, res *repro.Result) { if mgr.dash != nil { var maintainers []string - guiltyFile := report.ExtractGuiltyFile(crash.text) + guiltyFile := report.ExtractGuiltyFile(res.Report) if guiltyFile != "" { var err error maintainers, err = report.GetMaintainers(mgr.cfg.Kernel_Src, guiltyFile) @@ -663,10 +670,10 @@ func (mgr *Manager) saveRepro(crash *Crash, res *repro.Result) { dc := &dashapi.Crash{ Manager: mgr.cfg.Name, BuildID: mgr.cfg.Tag, - Title: crash.desc, + Title: res.Desc, Maintainers: maintainers, - Log: crash.output, - Report: crash.text, + Log: nil, + Report: res.Report, ReproOpts: []byte(fmt.Sprintf("%+v", res.Opts)), ReproSyz: []byte(res.Prog.Serialize()), ReproC: cprogText, |
