huangcm
2025-02-24 69ed55dec4b2116a19e4cca4393cbc014fce5fb2
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
// 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 prog
 
import (
   "bytes"
   "strconv"
)
 
// LogEntry describes one program in execution log.
type LogEntry struct {
   P         *Prog
   Proc      int  // index of parallel proc
   Start     int  // start offset in log
   End       int  // end offset in log
   Fault     bool // program was executed with fault injection in FaultCall/FaultNth
   FaultCall int
   FaultNth  int
}
 
func (target *Target) ParseLog(data []byte) []*LogEntry {
   var entries []*LogEntry
   ent := &LogEntry{}
   var cur []byte
   for pos := 0; pos < len(data); {
       nl := bytes.IndexByte(data[pos:], '\n')
       if nl == -1 {
           nl = len(data)
       } else {
           nl += pos
       }
       line := data[pos : nl+1]
       pos0 := pos
       pos = nl + 1
 
       if proc, ok := extractInt(line, "executing program "); ok {
           if ent.P != nil && len(ent.P.Calls) != 0 {
               ent.End = pos0
               entries = append(entries, ent)
           }
           ent = &LogEntry{
               Proc:  proc,
               Start: pos0,
           }
           if faultCall, ok := extractInt(line, "fault-call:"); ok {
               ent.Fault = true
               ent.FaultCall = faultCall
               ent.FaultNth, _ = extractInt(line, "fault-nth:")
           }
           cur = nil
           continue
       }
       if ent == nil {
           continue
       }
       tmp := append(cur, line...)
       p, err := target.Deserialize(tmp)
       if err != nil {
           continue
       }
       cur = tmp
       ent.P = p
   }
   if ent.P != nil && len(ent.P.Calls) != 0 {
       ent.End = len(data)
       entries = append(entries, ent)
   }
   return entries
}
 
func extractInt(line []byte, prefix string) (int, bool) {
   pos := bytes.Index(line, []byte(prefix))
   if pos == -1 {
       return 0, false
   }
   pos += len(prefix)
   end := pos
   for end != len(line) && line[end] >= '0' && line[end] <= '9' {
       end++
   }
   v, _ := strconv.Atoi(string(line[pos:end]))
   return v, true
}