1// Copyright 2018 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4package report 5 6import ( 7 "bufio" 8 "bytes" 9 "fmt" 10 "path/filepath" 11 "regexp" 12 "strconv" 13 "strings" 14 15 "github.com/google/syzkaller/pkg/symbolizer" 16) 17 18type akaros struct { 19 ignores []*regexp.Regexp 20 objfile string 21} 22 23func ctorAkaros(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter, []string, error) { 24 ctx := &akaros{ 25 ignores: ignores, 26 objfile: filepath.Join(kernelObj, "akaros-kernel-64b"), 27 } 28 return ctx, nil, nil 29} 30 31func (ctx *akaros) ContainsCrash(output []byte) bool { 32 return containsCrash(output, akarosOopses, ctx.ignores) 33} 34 35func (ctx *akaros) Parse(output []byte) *Report { 36 rep := simpleLineParser(output, akarosOopses, akarosStackParams, ctx.ignores) 37 if rep == nil { 38 return nil 39 } 40 rep.Report = ctx.minimizeReport(rep.Report) 41 return rep 42} 43 44func (ctx *akaros) Symbolize(rep *Report) error { 45 symb := symbolizer.NewSymbolizer() 46 defer symb.Close() 47 var symbolized []byte 48 s := bufio.NewScanner(bytes.NewReader(rep.Report)) 49 for s.Scan() { 50 line := bytes.Trim(s.Bytes(), "\r") 51 line = ctx.symbolizeLine(symb.Symbolize, ctx.objfile, line) 52 symbolized = append(symbolized, line...) 53 symbolized = append(symbolized, '\n') 54 } 55 rep.Report = symbolized 56 return nil 57} 58 59func (ctx *akaros) symbolizeLine(symbFunc func(bin string, pc uint64) ([]symbolizer.Frame, error), 60 objfile string, line []byte) []byte { 61 match := akarosSymbolizeRe.FindSubmatchIndex(line) 62 if match == nil { 63 return line 64 } 65 addr, err := strconv.ParseUint(string(line[match[2]:match[3]]), 0, 64) 66 if err != nil { 67 return line 68 } 69 frames, err := symbFunc(objfile, addr-1) 70 if err != nil || len(frames) == 0 { 71 return line 72 } 73 var symbolized []byte 74 for i, frame := range frames { 75 if i != 0 { 76 symbolized = append(symbolized, '\n') 77 } 78 file := frame.File 79 if pos := strings.LastIndex(file, "/kern/"); pos != -1 { 80 file = file[pos+6:] 81 } 82 modified := append([]byte{}, line...) 83 modified = append(modified, fmt.Sprintf(" at %v:%v", file, frame.Line)...) 84 if frame.Inline { 85 modified = replace(modified, match[4], match[5], []byte(frame.Func)) 86 modified = replace(modified, match[2], match[3], []byte(" [inline] ")) 87 } 88 symbolized = append(symbolized, modified...) 89 } 90 return symbolized 91} 92 93func (ctx *akaros) minimizeReport(report []byte) []byte { 94 out := new(bytes.Buffer) 95 for s := bufio.NewScanner(bytes.NewReader(report)); s.Scan(); { 96 line := bytes.Trim(s.Bytes(), "\r") 97 if len(line) == 0 || 98 bytes.Contains(line, []byte("Entering Nanwan's Dungeon")) || 99 bytes.Contains(line, []byte("Type 'help' for a list of commands")) { 100 continue 101 } 102 out.Write(line) 103 out.WriteByte('\n') 104 } 105 return out.Bytes() 106} 107 108var ( 109 akarosSymbolizeRe = compile(`^#[0-9]+ \[\<(0x[0-9a-f]+)\>\] in ([a-zA-Z0-9_]+)`) 110 akarosBacktraceRe = compile(`(?:Stack Backtrace|Backtrace of kernel context) on Core [0-9]+:`) 111) 112 113var akarosStackParams = &stackParams{ 114 stackStartRes: []*regexp.Regexp{ 115 akarosBacktraceRe, 116 }, 117 frameRes: []*regexp.Regexp{ 118 compile(`^#[0-9]+ {{PC}} in ([a-zA-Z0-9_]+)`), 119 }, 120 skipPatterns: []string{ 121 "backtrace", 122 "mon_backtrace", 123 "monitor", 124 "_panic", 125 "_warn", 126 }, 127} 128 129var akarosOopses = []*oops{ 130 { 131 []byte("kernel panic"), 132 []oopsFormat{ 133 { 134 title: compile("kernel panic at {{SRC}}, from core [0-9]+: assertion failed: (.*)"), 135 fmt: "assertion failed: %[2]v", 136 stack: &stackFmt{ 137 parts: []*regexp.Regexp{ 138 akarosBacktraceRe, 139 parseStackTrace, 140 }, 141 }, 142 }, 143 { 144 title: compile("kernel panic at {{SRC}}, from core [0-9]+: (.*)"), 145 fmt: "kernel panic: %[2]v", 146 stack: &stackFmt{ 147 parts: []*regexp.Regexp{ 148 akarosBacktraceRe, 149 parseStackTrace, 150 }, 151 }, 152 }, 153 { 154 title: compile("kernel panic"), 155 fmt: "kernel panic", 156 noStackTrace: true, 157 corrupted: true, 158 }, 159 }, 160 []*regexp.Regexp{}, 161 }, 162 { 163 []byte("kernel warning"), 164 []oopsFormat{ 165 { 166 title: compile("kernel warning at {{SRC}}, from core [0-9]+"), 167 fmt: "kernel warning in %[2]v", 168 stack: &stackFmt{ 169 parts: []*regexp.Regexp{ 170 akarosBacktraceRe, 171 parseStackTrace, 172 }, 173 }, 174 }, 175 { 176 title: compile("kernel warning"), 177 fmt: "kernel warning", 178 noStackTrace: true, 179 corrupted: true, 180 }, 181 }, 182 []*regexp.Regexp{}, 183 }, 184} 185