Commit 3fafe2e8 authored by Dmitry Vyukov's avatar Dmitry Vyukov

internal/trace: support parsing of 1.5 traces

1. Parse out version from trace header.
2. Restore handling of 1.5 traces.
3. Restore optional symbolization of traces.
4. Add some canned 1.5 traces for regression testing
   (http benchmark trace, runtime/trace stress traces,
    plus one with broken timestamps).

Change-Id: Idb18a001d03ded8e13c2730eeeb37c5836e31256
Reviewed-on: https://go-review.googlesource.com/21803
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAustin Clements <austin@google.com>
parent b04e1452
...@@ -109,6 +109,10 @@ go src=.. ...@@ -109,6 +109,10 @@ go src=..
png png
testdata testdata
+ +
internal
trace
testdata
+
io io
+ +
mime mime
......
...@@ -99,7 +99,7 @@ func parseEvents() ([]*trace.Event, error) { ...@@ -99,7 +99,7 @@ func parseEvents() ([]*trace.Event, error) {
defer tracef.Close() defer tracef.Close()
// Parse and symbolize. // Parse and symbolize.
events, err := trace.Parse(bufio.NewReader(tracef)) events, err := trace.Parse(bufio.NewReader(tracef), programBinary)
if err != nil { if err != nil {
loader.err = fmt.Errorf("failed to parse trace: %v", err) loader.err = fmt.Errorf("failed to parse trace: %v", err)
return return
......
This diff is collapsed.
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
package trace package trace
import ( import (
"bytes"
"io/ioutil"
"path/filepath"
"strings" "strings"
"testing" "testing"
) )
...@@ -22,9 +25,63 @@ func TestCorruptedInputs(t *testing.T) { ...@@ -22,9 +25,63 @@ func TestCorruptedInputs(t *testing.T) {
"go 1.5 trace\x00\x00\x00\x00\xc3\x0200", "go 1.5 trace\x00\x00\x00\x00\xc3\x0200",
} }
for _, data := range tests { for _, data := range tests {
events, err := Parse(strings.NewReader(data)) events, err := Parse(strings.NewReader(data), "")
if err == nil || events != nil { if err == nil || events != nil {
t.Fatalf("no error on input: %q\n", data) t.Fatalf("no error on input: %q", data)
}
}
}
func TestParseCanned(t *testing.T) {
files, err := ioutil.ReadDir("./testdata")
if err != nil {
t.Fatalf("failed to read ./testdata: %v", err)
}
for _, f := range files {
data, err := ioutil.ReadFile(filepath.Join("./testdata", f.Name()))
if err != nil {
t.Fatalf("failed to read input file: %v", err)
}
_, err = Parse(bytes.NewReader(data), "")
switch {
case strings.HasSuffix(f.Name(), "_good"):
if err != nil {
t.Errorf("failed to parse good trace %v: %v", f.Name(), err)
}
case strings.HasSuffix(f.Name(), "_unordered"):
if err != ErrTimeOrder {
t.Errorf("unordered trace is not detected %v: %v", f.Name(), err)
}
default:
t.Errorf("unknown input file suffix: %v", f.Name())
}
}
}
func TestParseVersion(t *testing.T) {
tests := map[string]int{
"go 1.5 trace\x00\x00\x00\x00": 1005,
"go 1.7 trace\x00\x00\x00\x00": 1007,
"go 1.10 trace\x00\x00\x00": 1010,
"go 1.25 trace\x00\x00\x00": 1025,
"go 1.234 trace\x00\x00": 1234,
"go 1.2345 trace\x00": -1,
"go 0.0 trace\x00\x00\x00\x00": -1,
"go a.b trace\x00\x00\x00\x00": -1,
}
for header, ver := range tests {
ver1, err := parseHeader([]byte(header))
if ver == -1 {
if err == nil {
t.Fatalf("no error on input: %q, version %v", header, ver1)
}
} else {
if err != nil {
t.Fatalf("failed to parse: %q (%v)", header, err)
}
if ver != ver1 {
t.Fatalf("wrong version: %v, want %v, input: %q", ver1, ver, header)
}
} }
} }
} }
...@@ -356,7 +356,7 @@ func ReadTrace() []byte { ...@@ -356,7 +356,7 @@ func ReadTrace() []byte {
trace.headerWritten = true trace.headerWritten = true
trace.lockOwner = nil trace.lockOwner = nil
unlock(&trace.lock) unlock(&trace.lock)
return []byte("go 1.5 trace\x00\x00\x00\x00") return []byte("go 1.7 trace\x00\x00\x00\x00")
} }
// Wait for new data. // Wait for new data.
if trace.fullHead == 0 && !trace.shutdown { if trace.fullHead == 0 && !trace.shutdown {
......
...@@ -52,7 +52,7 @@ func TestTrace(t *testing.T) { ...@@ -52,7 +52,7 @@ func TestTrace(t *testing.T) {
t.Fatalf("failed to start tracing: %v", err) t.Fatalf("failed to start tracing: %v", err)
} }
Stop() Stop()
_, err := trace.Parse(buf) _, err := trace.Parse(buf, "")
if err == trace.ErrTimeOrder { if err == trace.ErrTimeOrder {
t.Skipf("skipping trace: %v", err) t.Skipf("skipping trace: %v", err)
} }
...@@ -62,7 +62,7 @@ func TestTrace(t *testing.T) { ...@@ -62,7 +62,7 @@ func TestTrace(t *testing.T) {
} }
func parseTrace(t *testing.T, r io.Reader) ([]*trace.Event, map[uint64]*trace.GDesc, error) { func parseTrace(t *testing.T, r io.Reader) ([]*trace.Event, map[uint64]*trace.GDesc, error) {
events, err := trace.Parse(r) events, err := trace.Parse(r, "")
if err == trace.ErrTimeOrder { if err == trace.ErrTimeOrder {
t.Skipf("skipping trace: %v", err) t.Skipf("skipping trace: %v", err)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment