report: add a new package for report parsing and processing

Move vm.FindCrash to the new package.
This commit is contained in:
Dmitry Vyukov 2016-08-30 15:19:28 +02:00
parent bc9b349bd7
commit 14dfa4f109
5 changed files with 60 additions and 53 deletions

52
report/report.go Normal file
View File

@ -0,0 +1,52 @@
// Copyright 2016 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package report
import (
"bytes"
)
var oopses = [][]byte{
[]byte("Kernel panic"),
[]byte("BUG:"),
[]byte("kernel BUG"),
[]byte("WARNING:"),
[]byte("INFO:"),
[]byte("unable to handle"),
[]byte("Unable to handle kernel"),
[]byte("general protection fault"),
[]byte("UBSAN:"),
[]byte("unreferenced object"),
}
// FindCrash searches kernel console output for oops messages.
// Desc contains a more-or-less representative description of the first oops,
// start and end denote region of output with oops message(s).
func FindCrash(output []byte) (desc string, start int, end int, found bool) {
for pos := 0; pos < len(output); {
next := bytes.IndexByte(output[pos:], '\n')
if next != -1 {
next += pos
} else {
next = len(output)
}
for _, oops := range oopses {
match := bytes.Index(output[pos:next], oops)
if match == -1 {
continue
}
if !found {
found = true
start = pos
desc = string(output[pos+match : next])
if desc[len(desc)-1] == '\r' {
desc = desc[:len(desc)-1]
}
}
end = next
}
pos = next + 1
}
return
}

View File

@ -1,7 +1,7 @@
// Copyright 2015 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
package vm
package report
import (
"strings"

View File

@ -25,6 +25,7 @@ import (
"github.com/google/syzkaller/config"
"github.com/google/syzkaller/cover"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/report"
. "github.com/google/syzkaller/rpctype"
"github.com/google/syzkaller/sys"
"github.com/google/syzkaller/vm"
@ -351,10 +352,10 @@ func (mgr *Manager) runInstance(vmCfg *vm.Config, first bool) bool {
if bytes.Index(output[matchPos:], []byte("executing program")) != -1 {
lastExecuteTime = time.Now()
}
if _, _, _, found := vm.FindCrash(output[matchPos:]); found {
if _, _, _, found := report.FindCrash(output[matchPos:]); found {
// Give it some time to finish writing the error message.
waitForOutput(10 * time.Second)
desc, start, end, _ := vm.FindCrash(output[matchPos:])
desc, start, end, _ := report.FindCrash(output[matchPos:])
start = start + matchPos - beforeContext
if start < 0 {
start = 0

View File

@ -19,6 +19,7 @@ import (
"github.com/google/syzkaller/csource"
"github.com/google/syzkaller/fileutil"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/report"
"github.com/google/syzkaller/vm"
_ "github.com/google/syzkaller/vm/adb"
_ "github.com/google/syzkaller/vm/kvm"
@ -64,7 +65,7 @@ func main() {
entries := prog.ParseLog(data)
log.Printf("parsed %v programs", len(entries))
crashDesc, crashStart, _, found := vm.FindCrash(data)
crashDesc, crashStart, _, found := report.FindCrash(data)
if !found {
log.Fatalf("can't find crash message in the log")
}
@ -275,7 +276,7 @@ func testImpl(inst vm.Instance, command string, timeout time.Duration) (res bool
select {
case out := <-outc:
output = append(output, out...)
if desc, _, _, found := vm.FindCrash(output); found {
if desc, _, _, found := report.FindCrash(output); found {
log.Printf("program crashed with '%s'", desc)
return true
}

View File

@ -4,7 +4,6 @@
package vm
import (
"bytes"
"errors"
"fmt"
"io"
@ -76,50 +75,4 @@ func LongPipe() (io.ReadCloser, io.WriteCloser, error) {
return r, w, err
}
// FindCrash searches kernel console output for oops messages.
// Desc contains a more-or-less representative description of the first oops,
// start and end denote region of output with oops message(s).
func FindCrash(output []byte) (desc string, start int, end int, found bool) {
for pos := 0; pos < len(output); {
next := bytes.IndexByte(output[pos:], '\n')
if next != -1 {
next += pos
} else {
next = len(output)
}
for _, oops := range oopses {
match := bytes.Index(output[pos:next], oops)
if match == -1 {
continue
}
if !found {
found = true
start = pos
desc = string(output[pos+match : next])
if desc[len(desc)-1] == '\r' {
desc = desc[:len(desc)-1]
}
}
end = next
}
pos = next + 1
}
return
}
var (
oopses = [][]byte{
[]byte("Kernel panic"),
[]byte("BUG:"),
[]byte("kernel BUG"),
[]byte("WARNING:"),
[]byte("INFO:"),
[]byte("unable to handle"),
[]byte("Unable to handle kernel"),
[]byte("general protection fault"),
[]byte("UBSAN:"),
[]byte("unreferenced object"),
}
TimeoutErr = errors.New("timeout")
)
var TimeoutErr = errors.New("timeout")