From 0df8b231c3d20ee5d0663883503270a9495c337f Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Wed, 8 Feb 2023 12:48:49 +0100 Subject: pkg/report: add a ReportToGuiltyFile method We cannot unfortunately just substitute Report and invoke Symbolize(), because in this case a non-emtpy reportPrefixLen may lead to `panic: runtime error: slice bounds out`. Create a special external method in the pkg/report package. --- pkg/report/linux.go | 7 +++++-- pkg/report/report.go | 14 ++++++++++++++ tools/syz-fillreports/fillreports.go | 23 +++-------------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pkg/report/linux.go b/pkg/report/linux.go index b0650339e..0e2d8e1a4 100644 --- a/pkg/report/linux.go +++ b/pkg/report/linux.go @@ -691,8 +691,11 @@ func (ctx *linux) decompileOpcodes(text []byte, report *Report) []byte { } func (ctx *linux) extractGuiltyFile(rep *Report) string { - report := rep.Report[rep.reportPrefixLen:] - if strings.HasPrefix(rep.Title, "INFO: rcu detected stall") { + return ctx.extractGuiltyFileRaw(rep.Title, rep.Report[rep.reportPrefixLen:]) +} + +func (ctx *linux) extractGuiltyFileRaw(title string, report []byte) string { + if strings.HasPrefix(title, "INFO: rcu detected stall") { // Special case for rcu stalls. // There are too many frames that we want to skip before actual guilty frames, // we would need to ignore too many files and that would be fragile. diff --git a/pkg/report/report.go b/pkg/report/report.go index 7dd9714b3..77244fcd9 100644 --- a/pkg/report/report.go +++ b/pkg/report/report.go @@ -259,6 +259,20 @@ func (reporter *Reporter) isInteresting(rep *Report) bool { return false } +// There are cases when we need to extract a guilty file, but have no ability to do it the +// proper way -- parse and symbolize the raw console output log. One of such cases is +// the syz-fillreports tool, which only has access to the already symbolized logs. +// ReportToGuiltyFile does its best to extract the data. +func (reporter *Reporter) ReportToGuiltyFile(title string, report []byte) string { + ii, ok := reporter.impl.(interface { + extractGuiltyFileRaw(title string, report []byte) string + }) + if !ok { + return "" + } + return ii.extractGuiltyFileRaw(title, report) +} + func extractReportType(rep *Report) Type { // Type/frame extraction logic should be integrated with oops types. // But for now we do this more ad-hoc analysis here to at least isolate diff --git a/tools/syz-fillreports/fillreports.go b/tools/syz-fillreports/fillreports.go index 501a9bcfa..1a730e95c 100644 --- a/tools/syz-fillreports/fillreports.go +++ b/tools/syz-fillreports/fillreports.go @@ -62,32 +62,15 @@ func processReport(dash *dashapi.Dashboard, bugReport *dashapi.BugReport, bugID log.Fatalf("%v: failed to create a reporter for %s/%s", bugReport.ID, bugReport.OS, bugReport.Arch) } - rep := reporter.Parse(bugReport.Log) - if rep == nil { - log.Printf("%v: no crash is detected", bugReport.ID) - return - } - // In order to extract a guilty path, the report needs to be normally symbolized, - // and for symbolization we need the kernel object file (e.g. vmlinux) for the - // kernel, on which the crash was triggered. - // We do not have it for all our crashes, but we can do a hack here -- we already - // have a symbolized report on the dashboard, so we can substitute it into the - // partially processed Report object. This is not the most robust solution, as - // it relies on the internals of how the `Symbolize` method works, but it's short - // and works now, and furthermore we do not really have other options. - rep.Report = bugReport.Report - err = reporter.Symbolize(rep) - if err != nil { - log.Printf("%v: symbolize failed: %v", bugReport.ID, err) - } - if rep.GuiltyFile == "" { + guiltyFile := reporter.ReportToGuiltyFile(bugReport.Title, bugReport.Report) + if guiltyFile == "" { log.Printf("%v: no guilty files extracted", bugReport.ID) return } err = dash.UpdateReport(&dashapi.UpdateReportReq{ BugID: bugID, CrashID: bugReport.CrashID, - GuiltyFiles: &[]string{rep.GuiltyFile}, + GuiltyFiles: &[]string{guiltyFile}, }) if err != nil { log.Printf("%v: failed to save: %v", bugReport.ID, err) -- cgit mrf-deployment