aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/report/linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/report/linux.go')
-rw-r--r--pkg/report/linux.go47
1 files changed, 37 insertions, 10 deletions
diff --git a/pkg/report/linux.go b/pkg/report/linux.go
index ef7b8ac5c..833828ee8 100644
--- a/pkg/report/linux.go
+++ b/pkg/report/linux.go
@@ -27,6 +27,7 @@ type linux struct {
consoleOutputRe *regexp.Regexp
questionableRe *regexp.Regexp
guiltyFileBlacklist []*regexp.Regexp
+ reportStartIgnores [][]byte
eoi []byte
}
@@ -78,6 +79,11 @@ func ctorLinux(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symb
regexp.MustCompile(`^net/core/skbuff.c`),
regexp.MustCompile(`^fs/proc/generic.c`),
}
+ // These pattern do _not_ start a new report, i.e. can be in a middle of another report.
+ ctx.reportStartIgnores = [][]byte{
+ []byte("invalid opcode: 0000"),
+ []byte("Kernel panic - not syncing: panic_on_warn set"),
+ }
return ctx, nil
}
@@ -94,6 +100,8 @@ func (ctx *linux) Parse(output []byte) *Report {
var consoleReportPrefix [][]byte
var consoleReport []byte
textLines := 0
+ firstReportEnd := 0
+ secondReportPos := 0
skipText := false
for pos := 0; pos < len(output); {
next := bytes.IndexByte(output[pos:], '\n')
@@ -102,8 +110,9 @@ func (ctx *linux) Parse(output []byte) *Report {
} else {
next = len(output)
}
+ line := output[pos:next]
for _, oops1 := range linuxOopses {
- match := matchOops(output[pos:next], oops1, ctx.ignores)
+ match := matchOops(line, oops1, ctx.ignores)
if match == -1 {
continue
}
@@ -111,25 +120,36 @@ func (ctx *linux) Parse(output []byte) *Report {
oops = oops1
rep.StartPos = pos
rep.Title = string(output[pos+match : next])
+ } else if secondReportPos == 0 {
+ ignored := false
+ for _, ignore := range ctx.reportStartIgnores {
+ if bytes.Contains(line, ignore) {
+ ignored = true
+ break
+ }
+ }
+ if !ignored {
+ secondReportPos = pos
+ }
}
rep.EndPos = next
}
if oops == nil {
- logReportPrefix = append(logReportPrefix, append([]byte{}, output[pos:next]...))
+ logReportPrefix = append(logReportPrefix, append([]byte{}, line...))
if len(logReportPrefix) > 5 {
logReportPrefix = logReportPrefix[1:]
}
}
- if ctx.consoleOutputRe.Match(output[pos:next]) &&
- (!ctx.questionableRe.Match(output[pos:next]) ||
- bytes.Index(output[pos:next], ctx.eoi) != -1) {
- lineStart := bytes.Index(output[pos:next], []byte("] ")) + pos + 2
+ if ctx.consoleOutputRe.Match(line) &&
+ (!ctx.questionableRe.Match(line) || bytes.Index(line, ctx.eoi) != -1) {
+ lineStart := bytes.Index(line, []byte("] ")) + pos + 2
lineEnd := next
if lineEnd != 0 && output[lineEnd-1] == '\r' {
lineEnd--
}
if oops == nil {
- consoleReportPrefix = append(consoleReportPrefix, append([]byte{}, output[lineStart:lineEnd]...))
+ consoleReportPrefix = append(consoleReportPrefix,
+ append([]byte{}, output[lineStart:lineEnd]...))
if len(consoleReportPrefix) > 5 {
consoleReportPrefix = consoleReportPrefix[1:]
}
@@ -139,7 +159,8 @@ func (ctx *linux) Parse(output []byte) *Report {
skipLine := skipText
if bytes.Contains(ln, []byte("Disabling lock debugging due to kernel taint")) {
skipLine = true
- } else if textLines > 40 && bytes.Contains(ln, []byte("Kernel panic - not syncing")) {
+ } else if textLines > 40 &&
+ bytes.Contains(ln, []byte("Kernel panic - not syncing")) {
// If panic_on_warn set, then we frequently have 2 stacks:
// one for the actual report (or maybe even more than one),
// and then one for panic caused by panic_on_warn. This makes
@@ -155,6 +176,9 @@ func (ctx *linux) Parse(output []byte) *Report {
if !skipLine {
consoleReport = append(consoleReport, ln...)
consoleReport = append(consoleReport, '\n')
+ if secondReportPos == 0 {
+ firstReportEnd = len(consoleReport)
+ }
}
}
}
@@ -163,17 +187,20 @@ func (ctx *linux) Parse(output []byte) *Report {
if oops == nil {
return nil
}
+ if secondReportPos == 0 {
+ secondReportPos = len(output)
+ }
var report []byte
var reportPrefix [][]byte
// Try extracting report from console output only.
- title, corrupted, format := extractDescription(consoleReport, oops, linuxStackParams)
+ title, corrupted, format := extractDescription(consoleReport[:firstReportEnd], oops, linuxStackParams)
if title != "" {
// Success.
report = consoleReport
reportPrefix = consoleReportPrefix
} else {
// Failure. Try extracting report from the whole log.
- report = output[rep.StartPos:]
+ report = output[rep.StartPos:secondReportPos]
reportPrefix = logReportPrefix
title, corrupted, format = extractDescription(report, oops, linuxStackParams)
if title == "" {