aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2015-12-23 19:18:13 +0100
committerDmitry Vyukov <dvyukov@google.com>2015-12-23 19:18:13 +0100
commit1c801e8512cc5a40ec13ea8b80c87836f5222781 (patch)
tree1d0b8007d2142186a4774c9a395aeb707274aebd /prog
parent2eb388c0f81bfc3acf0c147654905c6d5c03df0d (diff)
prog: factor out execution log parsing functionality
It will be needed to reproduction tool.
Diffstat (limited to 'prog')
-rw-r--r--prog/parse.go68
-rw-r--r--prog/parse_test.go81
2 files changed, 149 insertions, 0 deletions
diff --git a/prog/parse.go b/prog/parse.go
new file mode 100644
index 000000000..e4a4e15ad
--- /dev/null
+++ b/prog/parse.go
@@ -0,0 +1,68 @@
+// 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
+}
+
+func 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
+ const delim = "executing program "
+ if delimPos := bytes.Index(line, []byte(delim)); delimPos != -1 {
+ if ent.P != nil && len(ent.P.Calls) != 0 {
+ ent.End = pos0
+ entries = append(entries, ent)
+ }
+ procStart := delimPos + len(delim)
+ procEnd := procStart
+ for procEnd != len(line) && line[procEnd] >= '0' && line[procEnd] <= '9' {
+ procEnd++
+ }
+ proc, _ := strconv.Atoi(string(line[procStart:procEnd]))
+ ent = &LogEntry{
+ Proc: proc,
+ Start: pos0,
+ }
+ cur = nil
+ continue
+ }
+ if ent == nil {
+ continue
+ }
+ tmp := append(cur, line...)
+ p, err := 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
+}
diff --git a/prog/parse_test.go b/prog/parse_test.go
new file mode 100644
index 000000000..93aa770cd
--- /dev/null
+++ b/prog/parse_test.go
@@ -0,0 +1,81 @@
+// 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 (
+ "testing"
+)
+
+func TestParseSingle(t *testing.T) {
+ const execLog = `getpid()
+gettid()
+`
+ entries := ParseLog([]byte(execLog))
+ if len(entries) != 1 {
+ t.Fatalf("got %v programs, want 1", len(entries))
+ }
+ ent := entries[0]
+ if ent.Start != 0 {
+ t.Fatalf("start offset %v, want 0", ent.Start)
+ }
+ if ent.End != len(execLog) {
+ t.Fatalf("end offset %v, want %v", ent.End, len(execLog))
+ }
+ if ent.Proc != 0 {
+ t.Fatalf("proc %v, want 0", ent.Proc)
+ }
+ want := "getpid-gettid"
+ got := ent.P.String()
+ if got != want {
+ t.Fatalf("bad program: %s, want %s", got, want)
+ }
+}
+
+func TestParseMulti(t *testing.T) {
+ entries := ParseLog([]byte(execLog))
+ if len(entries) != 4 {
+ t.Fatalf("got %v programs, want 4")
+ }
+ off := 0
+ for _, ent := range entries {
+ if off > ent.Start || ent.Start > ent.End || ent.End > len(execLog) {
+ t.Fatalf("bad offsets")
+ }
+ }
+ if entries[0].Proc != 1 || entries[1].Proc != 2 || entries[2].Proc != 33 || entries[3].Proc != 9 {
+ t.Fatalf("bad procs")
+ }
+ if s := entries[0].P.String(); s != "getpid-gettid-munlockall" {
+ t.Fatalf("bad program 0: %s", s)
+ }
+ if s := entries[1].P.String(); s != "getpid-gettid" {
+ t.Fatalf("bad program 1: %s", s)
+ }
+ if s := entries[2].P.String(); s != "gettid-getpid" {
+ t.Fatalf("bad program 2: %s", s)
+ }
+ if s := entries[3].P.String(); s != "munlockall" {
+ t.Fatalf("bad program 3: %s", s)
+ }
+}
+
+const execLog = `
+getpid()
+getpid()
+2015/12/21 12:18:05 executing program 1:
+getpid()
+[ 2351.935478] Modules linked in:
+gettid()
+munlockall()
+2015/12/21 12:18:05 executing program 2:
+[ 2351.935478] Modules linked in:
+getpid()
+gettid()
+2015/12/21 12:18:05 executing program 33:
+gettid()
+getpid()
+[ 2351.935478] Modules linked in:
+2015/12/21 12:18:05 executing program 9:
+munlockall()
+`