-
Notifications
You must be signed in to change notification settings - Fork 2
/
freebsd.go
138 lines (129 loc) · 3.7 KB
/
freebsd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 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 (
"bytes"
"regexp"
)
type freebsd struct {
*config
}
func ctorFreebsd(cfg *config) (Reporter, []string, error) {
ctx := &freebsd{
config: cfg,
}
return ctx, nil, nil
}
func (ctx *freebsd) ContainsCrash(output []byte) bool {
return containsCrash(output, freebsdOopses, ctx.ignores)
}
func (ctx *freebsd) Parse(output []byte) *Report {
rep := &Report{
Output: output,
}
var oops *oops
for pos := 0; pos < len(output); {
next := bytes.IndexByte(output[pos:], '\n')
if next != -1 {
next += pos
} else {
next = len(output)
}
for _, oops1 := range freebsdOopses {
if !matchOops(output[pos:next], oops1, ctx.ignores) {
continue
}
if oops == nil {
oops = oops1
rep.StartPos = pos
}
rep.EndPos = next
}
// Console output is indistinguishable from fuzzer output,
// so we just collect everything after the oops.
if oops != nil {
lineEnd := next
if lineEnd != 0 && output[lineEnd-1] == '\r' {
lineEnd--
}
rep.Report = append(rep.Report, output[pos:lineEnd]...)
rep.Report = append(rep.Report, '\n')
}
pos = next + 1
}
if oops == nil {
return nil
}
title, corrupted, _ := extractDescription(output[rep.StartPos:], oops, freebsdStackParams)
rep.Title = title
rep.Corrupted = corrupted != ""
rep.CorruptedReason = corrupted
return rep
}
func (ctx *freebsd) Symbolize(rep *Report) error {
return nil
}
var freebsdStackParams = &stackParams{}
var freebsdOopses = append([]*oops{
{
[]byte("Fatal trap"),
[]oopsFormat{
{
title: compile("Fatal trap (.+?)\\r?\\n(?:.*\\n)+?" +
"KDB: stack backtrace:\\r?\\n" +
"(?:#[0-9]+ {{ADDR}} at (?:kdb_backtrace|vpanic|panic|trap_fatal|" +
"trap_pfault|trap|calltrap|m_copydata|__rw_wlock_hard)" +
"\\+{{ADDR}}\\r?\\n)*#[0-9]+ {{ADDR}} at {{FUNC}}{{ADDR}}"),
fmt: "Fatal trap %[1]v in %[2]v",
},
{
title: compile("(Fatal trap [0-9]+:.*) while in (?:user|kernel) mode\\r?\\n(?:.*\\n)+?" +
"KDB: stack backtrace:\\r?\\n" +
"(?:[a-zA-Z0-9_]+\\(\\) at [a-zA-Z0-9_]+\\+0x.*\\r?\\n)*" +
"--- trap 0x[0-9a-fA-F]+.* ---\\r?\\n" +
"([a-zA-Z0-9_]+)\\(\\) at [a-zA-Z0-9_]+\\+0x.*\\r?\\n"),
fmt: "%[1]v in %[2]v",
},
},
[]*regexp.Regexp{},
},
{
[]byte("panic:"),
[]oopsFormat{
{
title: compile("panic: ffs_write: type {{ADDR}} [0-9]+ \\([0-9]+,[0-9]+\\)"),
fmt: "panic: ffs_write: type ADDR X (Y,Z)",
},
{
title: compile("panic: ([a-zA-Z]+[a-zA-Z0-9_]*\\(\\)) of destroyed (mutex|rmlock|rwlock|sx) @ " +
"/.*/(sys/.*:[0-9]+)"),
fmt: "panic: %[1]v of destroyed %[2]v at %[3]v",
},
{
title: compile("panic: No chunks on the queues for sid [0-9]+\\.\\r?\\n"),
fmt: "panic: sctp: no chunks on the queues",
},
{
title: compile("panic: size_on_all_streams = [0-9]+ smaller than control length [0-9]+\\r?\\n"),
fmt: "panic: size_on_all_streams smaller than control length",
},
{
title: compile("panic: sbflush_internal: ccc [0-9]+ mb [0-9]+ mbcnt [0-9]+\\r?\\n"),
fmt: "panic: sbflush_internal: residual data",
},
{
title: compile("(panic: sx lock still held)\\r?\\n(?:.*\\n)+?" +
"KDB: stack backtrace:\\r?\\n" +
"(?:[a-zA-Z0-9_]+\\(\\) at [a-zA-Z0-9_]+\\+0x.*\\r?\\n)*" +
"sx_destroy\\(\\) at [a-zA-Z0-9_+/ ]+\\r?\\n" +
"([a-zA-Z0-9_]+)\\(\\) at [a-zA-Z0-9_+/ ]+\\+0x.*\\r?\\n"),
fmt: "%[1]v in %[2]v",
},
{
title: compile("panic: pfi_dynaddr_setup: dyn is 0x[0-9a-f]+\\r?\\n"),
fmt: "panic: pfi_dynaddr_setup: non-NULL dyn",
},
},
[]*regexp.Regexp{},
},
}, commonOopses...)