aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-02-08 12:48:49 +0100
committerAleksandr Nogikh <wp32pw@gmail.com>2023-02-08 20:25:02 +0100
commit0df8b231c3d20ee5d0663883503270a9495c337f (patch)
tree4afb44faa171cce7cc37ca38df5ede8b093f4d72
parent6a3c415d02bf3c2d68fa964efa6affba3e24f3d8 (diff)
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.
-rw-r--r--pkg/report/linux.go7
-rw-r--r--pkg/report/report.go14
-rw-r--r--tools/syz-fillreports/fillreports.go23
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)