aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/report
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/report')
-rw-r--r--pkg/report/bsd.go136
-rw-r--r--pkg/report/bsd_test.go77
-rw-r--r--pkg/report/netbsd.go133
-rw-r--r--pkg/report/netbsd_test.go66
-rw-r--r--pkg/report/openbsd.go122
-rw-r--r--pkg/report/openbsd_test.go66
6 files changed, 226 insertions, 374 deletions
diff --git a/pkg/report/bsd.go b/pkg/report/bsd.go
new file mode 100644
index 000000000..369ffcab9
--- /dev/null
+++ b/pkg/report/bsd.go
@@ -0,0 +1,136 @@
+// Copyright 2017 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 (
+ "bufio"
+ "bytes"
+ "fmt"
+ "path/filepath"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "github.com/google/syzkaller/pkg/symbolizer"
+)
+
+type bsd struct {
+ *config
+ oopses []*oops
+ symbolizeRes []*regexp.Regexp
+ kernelObject string
+ symbols map[string][]symbolizer.Symbol
+}
+
+func ctorBSD(cfg *config, oopses []*oops, symbolizeRes []*regexp.Regexp) (Reporter, error) {
+ var symbols map[string][]symbolizer.Symbol
+ kernelObject := ""
+ if cfg.kernelObj != "" {
+ kernelObject = filepath.Join(cfg.kernelObj, cfg.target.KernelObject)
+ var err error
+ symbols, err = symbolizer.ReadTextSymbols(kernelObject)
+ if err != nil {
+ return nil, err
+ }
+ }
+ ctx := &bsd{
+ config: cfg,
+ oopses: oopses,
+ symbolizeRes: symbolizeRes,
+ kernelObject: kernelObject,
+ symbols: symbols,
+ }
+ return ctx, nil
+}
+
+func (ctx *bsd) ContainsCrash(output []byte) bool {
+ return containsCrash(output, ctx.oopses, ctx.ignores)
+}
+
+func (ctx *bsd) Parse(output []byte) *Report {
+ stripped := bytes.Replace(output, []byte{'\r', '\n'}, []byte{'\n'}, -1)
+ stripped = bytes.Replace(stripped, []byte{'\n', '\r'}, []byte{'\n'}, -1)
+ for len(stripped) != 0 && stripped[0] == '\r' {
+ stripped = stripped[1:]
+ }
+ rep := simpleLineParser(stripped, ctx.oopses, nil, ctx.ignores)
+ if rep == nil {
+ return nil
+ }
+ rep.Output = output
+ return rep
+}
+
+func (ctx *bsd) Symbolize(rep *Report) error {
+ symb := symbolizer.NewSymbolizer()
+ defer symb.Close()
+ var symbolized []byte
+ s := bufio.NewScanner(bytes.NewReader(rep.Report))
+ prefix := rep.reportPrefixLen
+ for s.Scan() {
+ line := append([]byte{}, s.Bytes()...)
+ line = append(line, '\n')
+ newLine := ctx.symbolizeLine(symb.Symbolize, line)
+ if prefix > len(symbolized) {
+ prefix += len(newLine) - len(line)
+ }
+ symbolized = append(symbolized, newLine...)
+ }
+ rep.Report = symbolized
+ rep.reportPrefixLen = prefix
+ return nil
+}
+
+func (ctx *bsd) symbolizeLine(symbFunc func(bin string, pc uint64) ([]symbolizer.Frame, error),
+ line []byte) []byte {
+ var match []int
+ // Check whether the line corresponds to the any of the parts that require symbolization.
+ for _, re := range ctx.symbolizeRes {
+ match = re.FindSubmatchIndex(line)
+ if match != nil {
+ break
+ }
+ }
+ if match == nil {
+ return line
+ }
+ // First part of the matched regex contains the function name.
+ // Second part contains the offset.
+ fn := line[match[2]:match[3]]
+ off, err := strconv.ParseUint(string(line[match[4]:match[5]]), 16, 64)
+ if err != nil {
+ return line
+ }
+
+ // Get the symbol from the list of symbols generated using the kernel object and addr2line.
+ symb := ctx.symbols[string(fn)]
+ if len(symb) == 0 {
+ return line
+ }
+ fnStart := (0xffffffff << 32) | symb[0].Addr
+
+ // Retrieve the frames for the corresponding offset of the function.
+ frames, err := symbFunc(ctx.kernelObject, fnStart+off)
+ if err != nil || len(frames) == 0 {
+ return line
+ }
+ var symbolized []byte
+ // Go through each of the frames and add the corresponding file names and line numbers.
+ for _, frame := range frames {
+ file := frame.File
+ file = strings.TrimPrefix(file, ctx.kernelBuildSrc)
+ file = strings.TrimPrefix(file, "/")
+ info := fmt.Sprintf(" %v:%v", file, frame.Line)
+ modified := append([]byte{}, line...)
+ modified = replace(modified, match[5], match[5], []byte(info))
+ if frame.Inline {
+ // If frames are marked inline then show that in the report also.
+ end := match[5] + len(info)
+ modified = replace(modified, end, end, []byte(" [inline]"))
+ modified = replace(modified, match[5], match[5], []byte(" "+frame.Func))
+ }
+ symbolized = append(symbolized, modified...)
+ }
+ return symbolized
+}
diff --git a/pkg/report/bsd_test.go b/pkg/report/bsd_test.go
new file mode 100644
index 000000000..1fd721d3f
--- /dev/null
+++ b/pkg/report/bsd_test.go
@@ -0,0 +1,77 @@
+// Copyright 2018 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 (
+ "fmt"
+ "testing"
+
+ "github.com/google/syzkaller/pkg/symbolizer"
+)
+
+type symbolizeLineTest struct {
+ line string
+ result string
+}
+
+func testSymbolizeLine(t *testing.T, ctor fn, tests []symbolizeLineTest) {
+ symbols := map[string][]symbolizer.Symbol{
+ "closef": {
+ {Addr: 0x815088a0, Size: 0x12f},
+ },
+ "sleep_finish_all": {
+ {Addr: 0x81237520, Size: 0x173},
+ },
+ }
+ symb := func(bin string, pc uint64) ([]symbolizer.Frame, error) {
+ if bin != "bsd.gdb" {
+ return nil, fmt.Errorf("unknown pc 0x%x", pc)
+ }
+
+ switch pc & 0xffffffff {
+ case 0x8150894f:
+ return []symbolizer.Frame{
+ {
+ Func: "closef",
+ File: "/bsd/src/kern_descrip.c",
+ Line: 1241,
+ },
+ }, nil
+ case 0x81237542:
+ return []symbolizer.Frame{
+ {
+ Func: "sleep_finish_timeout",
+ File: "/bsd/src/kern_synch.c",
+ Line: 336,
+ Inline: true,
+ },
+ {
+ Func: "sleep_finish_all",
+ File: "/bsd/src/kern_synch.c",
+ Line: 157,
+ },
+ }, nil
+ default:
+ return nil, fmt.Errorf("unknown pc 0x%x", pc)
+ }
+ }
+ reporter, _, err := ctor(&config{
+ kernelSrc: "/bsd/src2",
+ kernelBuildSrc: "/bsd/src",
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ bsd := reporter.(*bsd)
+ bsd.symbols = symbols
+ bsd.kernelObject = "bsd.gdb"
+ for i, test := range tests {
+ t.Run(fmt.Sprint(i), func(t *testing.T) {
+ result := bsd.symbolizeLine(symb, []byte(test.line))
+ if test.result != string(result) {
+ t.Errorf("want %q\n\t get %q", test.result, string(result))
+ }
+ })
+ }
+}
diff --git a/pkg/report/netbsd.go b/pkg/report/netbsd.go
index cb5fb1c56..9eea6c2b2 100644
--- a/pkg/report/netbsd.go
+++ b/pkg/report/netbsd.go
@@ -4,144 +4,19 @@
package report
import (
- "bufio"
- "bytes"
- "fmt"
- "path/filepath"
"regexp"
- "strconv"
- "strings"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
-type netbsd struct {
- *config
- kernelObject string
- symbols map[string][]symbolizer.Symbol
-}
-
-var (
- netbsdSymbolizeRe = []*regexp.Regexp{
+func ctorNetbsd(cfg *config) (Reporter, []string, error) {
+ symbolizeRes := []*regexp.Regexp{
// stack
regexp.MustCompile(` at netbsd:([A-Za-z0-9_]+)\+0x([0-9a-f]+)`),
// witness
regexp.MustCompile(`#[0-9]+ +([A-Za-z0-9_]+)\+0x([0-9a-f]+)`),
}
-)
-
-func ctorNetbsd(cfg *config) (Reporter, []string, error) {
- var symbols map[string][]symbolizer.Symbol
cfg.ignores = append(cfg.ignores, regexp.MustCompile("event_init: unable to initialize")) // postfix output
- kernelObject := ""
- if cfg.kernelObj != "" {
- kernelObject = filepath.Join(cfg.kernelObj, cfg.target.KernelObject)
- var err error
- symbols, err = symbolizer.ReadTextSymbols(kernelObject)
- if err != nil {
- return nil, nil, err
- }
- }
- ctx := &netbsd{
- config: cfg,
- kernelObject: kernelObject,
- symbols: symbols,
- }
- return ctx, nil, nil
-}
-
-func (ctx *netbsd) ContainsCrash(output []byte) bool {
- return containsCrash(output, netbsdOopses, ctx.ignores)
-}
-
-func (ctx *netbsd) Parse(output []byte) *Report {
- stripped := bytes.Replace(output, []byte{'\r', '\n'}, []byte{'\n'}, -1)
- stripped = bytes.Replace(stripped, []byte{'\n', '\r'}, []byte{'\n'}, -1)
- for len(stripped) != 0 && stripped[0] == '\r' {
- stripped = stripped[1:]
- }
- rep := simpleLineParser(stripped, netbsdOopses, nil, ctx.ignores)
- if rep == nil {
- return nil
- }
- rep.Output = output
- return rep
-}
-
-func (ctx *netbsd) Symbolize(rep *Report) error {
- symb := symbolizer.NewSymbolizer()
- defer symb.Close()
- var symbolized []byte
- s := bufio.NewScanner(bytes.NewReader(rep.Report))
- prefix := rep.reportPrefixLen
- for s.Scan() {
- line := append([]byte{}, s.Bytes()...)
- line = append(line, '\n')
- newLine := ctx.symbolizeLine(symb.Symbolize, line)
- if prefix > len(symbolized) {
- prefix += len(newLine) - len(line)
- }
- symbolized = append(symbolized, newLine...)
- }
- rep.Report = symbolized
- rep.reportPrefixLen = prefix
- return nil
-}
-
-func (ctx *netbsd) symbolizeLine(symbFunc func(bin string, pc uint64) ([]symbolizer.Frame, error),
- line []byte) []byte {
- var match []int
- // Check whether the line corresponds to the any of the parts that
- // require symbolization.
- for _, re := range netbsdSymbolizeRe {
- match = re.FindSubmatchIndex(line)
- if match != nil {
- break
- }
- }
- if match == nil {
- return line
- }
- // First part of the matched regex contains the function name
- // Second part contains the offset
- fn := line[match[2]:match[3]]
- off, err := strconv.ParseUint(string(line[match[4]:match[5]]), 16, 64)
- if err != nil {
- return line
- }
-
- // Get the symbol from the list of symbols generated using
- // the kernel object and addr2line
- symb := ctx.symbols[string(fn)]
- if len(symb) == 0 {
- return line
- }
- fnStart := (0xffffffff << 32) | symb[0].Addr
-
- // Retrieve the frames for the corresponding offset of the function
- frames, err := symbFunc(ctx.kernelObject, fnStart+off)
- if err != nil || len(frames) == 0 {
- return line
- }
- var symbolized []byte
- // Go through each of the frames and add the corresponding file names
- // and line numbers.
- for _, frame := range frames {
- file := frame.File
- file = strings.TrimPrefix(file, ctx.kernelBuildSrc)
- file = strings.TrimPrefix(file, "/")
- info := fmt.Sprintf(" %v:%v", file, frame.Line)
- modified := append([]byte{}, line...)
- modified = replace(modified, match[5], match[5], []byte(info))
- if frame.Inline {
- // If frames are marked inline then show that in the report also
- end := match[5] + len(info)
- modified = replace(modified, end, end, []byte(" [inline]"))
- modified = replace(modified, match[5], match[5], []byte(" "+frame.Func))
- }
- symbolized = append(symbolized, modified...)
- }
- return symbolized
+ ctx, err := ctorBSD(cfg, netbsdOopses, symbolizeRes)
+ return ctx, nil, err
}
// nolint: lll
diff --git a/pkg/report/netbsd_test.go b/pkg/report/netbsd_test.go
index 3fb93ceb9..24c144ac0 100644
--- a/pkg/report/netbsd_test.go
+++ b/pkg/report/netbsd_test.go
@@ -4,17 +4,11 @@
package report
import (
- "fmt"
"testing"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
func TestNetbsdSymbolizeLine(t *testing.T) {
- tests := []struct {
- line string
- result string
- }{
+ tests := []symbolizeLineTest{
// Normal symbolization.
{
"closef(ffffffff,ffffffff) at netbsd:closef+0xaf\n",
@@ -41,61 +35,5 @@ func TestNetbsdSymbolizeLine(t *testing.T) {
"#10 closef+0xaf kern_descrip.c:1241\n",
},
}
- symbols := map[string][]symbolizer.Symbol{
- "closef": {
- {Addr: 0x815088a0, Size: 0x12f},
- },
- "sleep_finish_all": {
- {Addr: 0x81237520, Size: 0x173},
- },
- }
- symb := func(bin string, pc uint64) ([]symbolizer.Frame, error) {
- if bin != "netbsd.gdb" {
- return nil, fmt.Errorf("unknown pc 0x%x", pc)
- }
-
- switch pc & 0xffffffff {
- case 0x8150894f:
- return []symbolizer.Frame{
- {
- Func: "closef",
- File: "/netbsd/src/kern_descrip.c",
- Line: 1241,
- },
- }, nil
- case 0x81237542:
- return []symbolizer.Frame{
- {
- Func: "sleep_finish_timeout",
- File: "/netbsd/src/kern_synch.c",
- Line: 336,
- Inline: true,
- },
- {
- Func: "sleep_finish_all",
- File: "/netbsd/src/kern_synch.c",
- Line: 157,
- },
- }, nil
- default:
- return nil, fmt.Errorf("unknown pc 0x%x", pc)
- }
- }
- nbsd := netbsd{
- config: &config{
- kernelSrc: "/netbsd/src2",
- kernelBuildSrc: "/netbsd/src",
- kernelObj: "/netbsd/src/obj/sys/arch/amd64/compile/GENERIC",
- },
- kernelObject: "netbsd.gdb",
- symbols: symbols,
- }
- for i, test := range tests {
- t.Run(fmt.Sprint(i), func(t *testing.T) {
- result := nbsd.symbolizeLine(symb, []byte(test.line))
- if test.result != string(result) {
- t.Errorf("want %q\n\t get %q", test.result, string(result))
- }
- })
- }
+ testSymbolizeLine(t, ctorNetbsd, tests)
}
diff --git a/pkg/report/openbsd.go b/pkg/report/openbsd.go
index 8d29dba10..9373b607b 100644
--- a/pkg/report/openbsd.go
+++ b/pkg/report/openbsd.go
@@ -4,47 +4,19 @@
package report
import (
- "bufio"
- "bytes"
- "fmt"
- "path/filepath"
"regexp"
- "strconv"
- "strings"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
-type openbsd struct {
- *config
- kernelObject string
- symbols map[string][]symbolizer.Symbol
-}
-
-var (
- openbsdSymbolizeRe = []*regexp.Regexp{
+func ctorOpenbsd(cfg *config) (Reporter, []string, error) {
+ symbolizeRes := []*regexp.Regexp{
// stack
regexp.MustCompile(` at ([A-Za-z0-9_]+)\+0x([0-9a-f]+)`),
// witness
regexp.MustCompile(`#[0-9]+ +([A-Za-z0-9_]+)\+0x([0-9a-f]+)`),
}
-)
-
-func ctorOpenbsd(cfg *config) (Reporter, []string, error) {
- var symbols map[string][]symbolizer.Symbol
- kernelObject := ""
- if cfg.kernelObj != "" {
- kernelObject = filepath.Join(cfg.kernelObj, cfg.target.KernelObject)
- var err error
- symbols, err = symbolizer.ReadTextSymbols(kernelObject)
- if err != nil {
- return nil, nil, err
- }
- }
- ctx := &openbsd{
- config: cfg,
- kernelObject: kernelObject,
- symbols: symbols,
+ ctx, err := ctorBSD(cfg, openbsdOopses, symbolizeRes)
+ if err != nil {
+ return nil, nil, err
}
suppressions := []string{
"panic: fifo_badop called",
@@ -52,90 +24,6 @@ func ctorOpenbsd(cfg *config) (Reporter, []string, error) {
return ctx, suppressions, nil
}
-func (ctx *openbsd) ContainsCrash(output []byte) bool {
- return containsCrash(output, openbsdOopses, ctx.ignores)
-}
-
-func (ctx *openbsd) Parse(output []byte) *Report {
- stripped := bytes.Replace(output, []byte{'\r', '\n'}, []byte{'\n'}, -1)
- stripped = bytes.Replace(stripped, []byte{'\n', '\r'}, []byte{'\n'}, -1)
- for len(stripped) != 0 && stripped[0] == '\r' {
- stripped = stripped[1:]
- }
- rep := simpleLineParser(stripped, openbsdOopses, nil, ctx.ignores)
- if rep == nil {
- return nil
- }
- rep.Output = output
- return rep
-}
-
-func (ctx *openbsd) Symbolize(rep *Report) error {
- symb := symbolizer.NewSymbolizer()
- defer symb.Close()
- var symbolized []byte
- s := bufio.NewScanner(bytes.NewReader(rep.Report))
- prefix := rep.reportPrefixLen
- for s.Scan() {
- line := append([]byte{}, s.Bytes()...)
- line = append(line, '\n')
- newLine := ctx.symbolizeLine(symb.Symbolize, line)
- if prefix > len(symbolized) {
- prefix += len(newLine) - len(line)
- }
- symbolized = append(symbolized, newLine...)
- }
- rep.Report = symbolized
- rep.reportPrefixLen = prefix
- return nil
-}
-
-func (ctx *openbsd) symbolizeLine(symbFunc func(bin string, pc uint64) ([]symbolizer.Frame, error),
- line []byte) []byte {
- var match []int
- for _, re := range openbsdSymbolizeRe {
- match = re.FindSubmatchIndex(line)
- if match != nil {
- break
- }
- }
- if match == nil {
- return line
- }
- fn := line[match[2]:match[3]]
- off, err := strconv.ParseUint(string(line[match[4]:match[5]]), 16, 64)
- if err != nil {
- return line
- }
-
- symb := ctx.symbols[string(fn)]
- if len(symb) == 0 {
- return line
- }
- fnStart := (0xffffffff << 32) | symb[0].Addr
-
- frames, err := symbFunc(ctx.kernelObject, fnStart+off)
- if err != nil || len(frames) == 0 {
- return line
- }
- var symbolized []byte
- for _, frame := range frames {
- file := frame.File
- file = strings.TrimPrefix(file, ctx.kernelBuildSrc)
- file = strings.TrimPrefix(file, "/")
- info := fmt.Sprintf(" %v:%v", file, frame.Line)
- modified := append([]byte{}, line...)
- modified = replace(modified, match[5], match[5], []byte(info))
- if frame.Inline {
- end := match[5] + len(info)
- modified = replace(modified, end, end, []byte(" [inline]"))
- modified = replace(modified, match[5], match[5], []byte(" "+frame.Func))
- }
- symbolized = append(symbolized, modified...)
- }
- return symbolized
-}
-
var openbsdOopses = append([]*oops{
{
[]byte("cleaned vnode"),
diff --git a/pkg/report/openbsd_test.go b/pkg/report/openbsd_test.go
index af9b93b7a..ec96c4ef3 100644
--- a/pkg/report/openbsd_test.go
+++ b/pkg/report/openbsd_test.go
@@ -4,17 +4,11 @@
package report
import (
- "fmt"
"testing"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
func TestOpenbsdSymbolizeLine(t *testing.T) {
- tests := []struct {
- line string
- result string
- }{
+ tests := []symbolizeLineTest{
// Normal symbolization.
{
"closef(ffffffff,ffffffff) at closef+0xaf\n",
@@ -41,61 +35,5 @@ func TestOpenbsdSymbolizeLine(t *testing.T) {
"#10 closef+0xaf kern_descrip.c:1241\n",
},
}
- symbols := map[string][]symbolizer.Symbol{
- "closef": {
- {Addr: 0x815088a0, Size: 0x12f},
- },
- "sleep_finish_all": {
- {Addr: 0x81237520, Size: 0x173},
- },
- }
- symb := func(bin string, pc uint64) ([]symbolizer.Frame, error) {
- if bin != "bsd.gdb" {
- return nil, fmt.Errorf("unknown pc 0x%x", pc)
- }
-
- switch pc & 0xffffffff {
- case 0x8150894f:
- return []symbolizer.Frame{
- {
- File: "/usr/src/kern_descrip.c",
- Line: 1241,
- Func: "closef",
- },
- }, nil
- case 0x81237542:
- return []symbolizer.Frame{
- {
- Func: "sleep_finish_timeout",
- File: "/usr/src/kern_synch.c",
- Line: 336,
- Inline: true,
- },
- {
- Func: "sleep_finish_all",
- File: "/usr/src/kern_synch.c",
- Line: 157,
- },
- }, nil
- default:
- return nil, fmt.Errorf("unknown pc 0x%x", pc)
- }
- }
- obsd := openbsd{
- config: &config{
- kernelSrc: "/usr/src2",
- kernelBuildSrc: "/usr/src",
- kernelObj: "/usr/src/sys/arch/amd64/compile/SYZKALLER/obj",
- },
- kernelObject: "bsd.gdb",
- symbols: symbols,
- }
- for i, test := range tests {
- t.Run(fmt.Sprint(i), func(t *testing.T) {
- result := obsd.symbolizeLine(symb, []byte(test.line))
- if test.result != string(result) {
- t.Errorf("want %q\n\t get %q", test.result, string(result))
- }
- })
- }
+ testSymbolizeLine(t, ctorOpenbsd, tests)
}