1// Copyright 2015 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 prog 5 6import ( 7 "bytes" 8 "strconv" 9) 10 11// LogEntry describes one program in execution log. 12type LogEntry struct { 13 P *Prog 14 Proc int // index of parallel proc 15 Start int // start offset in log 16 End int // end offset in log 17 Fault bool // program was executed with fault injection in FaultCall/FaultNth 18 FaultCall int 19 FaultNth int 20} 21 22func (target *Target) ParseLog(data []byte) []*LogEntry { 23 var entries []*LogEntry 24 ent := &LogEntry{} 25 var cur []byte 26 for pos := 0; pos < len(data); { 27 nl := bytes.IndexByte(data[pos:], '\n') 28 if nl == -1 { 29 nl = len(data) 30 } else { 31 nl += pos 32 } 33 line := data[pos : nl+1] 34 pos0 := pos 35 pos = nl + 1 36 37 if proc, ok := extractInt(line, "executing program "); ok { 38 if ent.P != nil && len(ent.P.Calls) != 0 { 39 ent.End = pos0 40 entries = append(entries, ent) 41 } 42 ent = &LogEntry{ 43 Proc: proc, 44 Start: pos0, 45 } 46 if faultCall, ok := extractInt(line, "fault-call:"); ok { 47 ent.Fault = true 48 ent.FaultCall = faultCall 49 ent.FaultNth, _ = extractInt(line, "fault-nth:") 50 } 51 cur = nil 52 continue 53 } 54 if ent == nil { 55 continue 56 } 57 tmp := append(cur, line...) 58 p, err := target.Deserialize(tmp) 59 if err != nil { 60 continue 61 } 62 cur = tmp 63 ent.P = p 64 } 65 if ent.P != nil && len(ent.P.Calls) != 0 { 66 ent.End = len(data) 67 entries = append(entries, ent) 68 } 69 return entries 70} 71 72func extractInt(line []byte, prefix string) (int, bool) { 73 pos := bytes.Index(line, []byte(prefix)) 74 if pos == -1 { 75 return 0, false 76 } 77 pos += len(prefix) 78 end := pos 79 for end != len(line) && line[end] >= '0' && line[end] <= '9' { 80 end++ 81 } 82 v, _ := strconv.Atoi(string(line[pos:end])) 83 return v, true 84} 85