From 3fafe2e8888dadb6877fa1e7569f5bd1f688dd3a Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 11 Apr 2016 08:57:52 +0200 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Austin Clements --- misc/nacl/testzip.proto | 4 + src/cmd/trace/main.go | 2 +- src/internal/trace/parser.go | 314 +++++++++++++----- src/internal/trace/parser_test.go | 61 +++- src/internal/trace/testdata/http_1_5_good | Bin 0 -> 42218 bytes src/internal/trace/testdata/stress_1_5_good | Bin 0 -> 7446 bytes .../trace/testdata/stress_1_5_unordered | Bin 0 -> 8194 bytes .../trace/testdata/stress_start_stop_1_5_good | Bin 0 -> 6997 bytes src/runtime/trace.go | 2 +- src/runtime/trace/trace_test.go | 4 +- 10 files changed, 295 insertions(+), 92 deletions(-) create mode 100644 src/internal/trace/testdata/http_1_5_good create mode 100644 src/internal/trace/testdata/stress_1_5_good create mode 100644 src/internal/trace/testdata/stress_1_5_unordered create mode 100644 src/internal/trace/testdata/stress_start_stop_1_5_good diff --git a/misc/nacl/testzip.proto b/misc/nacl/testzip.proto index 42db92f327..8c14b87f0a 100644 --- a/misc/nacl/testzip.proto +++ b/misc/nacl/testzip.proto @@ -109,6 +109,10 @@ go src=.. png testdata + + internal + trace + testdata + + io + mime diff --git a/src/cmd/trace/main.go b/src/cmd/trace/main.go index 12bf8c3c16..cfd222e132 100644 --- a/src/cmd/trace/main.go +++ b/src/cmd/trace/main.go @@ -99,7 +99,7 @@ func parseEvents() ([]*trace.Event, error) { defer tracef.Close() // Parse and symbolize. - events, err := trace.Parse(bufio.NewReader(tracef)) + events, err := trace.Parse(bufio.NewReader(tracef), programBinary) if err != nil { loader.err = fmt.Errorf("failed to parse trace: %v", err) return diff --git a/src/internal/trace/parser.go b/src/internal/trace/parser.go index 65530b15c3..82ddb8b6c8 100644 --- a/src/internal/trace/parser.go +++ b/src/internal/trace/parser.go @@ -5,17 +5,22 @@ package trace import ( + "bufio" "bytes" "fmt" "io" + "os" + "os/exec" "sort" + "strconv" + "strings" ) // Event describes one event in the trace. type Event struct { Off int // offset in input file (for debugging and error reporting) Type byte // one of Ev* - Seq int64 // sequence number + seq int64 // sequence number Ts int64 // timestamp in nanoseconds P int // P on which the event happened (can be one of TimerP, NetpollP, SyscallP) G uint64 // G on which the event happened @@ -53,12 +58,12 @@ const ( ) // Parse parses, post-processes and verifies the trace. -func Parse(r io.Reader) ([]*Event, error) { - rawEvents, strings, err := readTrace(r) +func Parse(r io.Reader, bin string) ([]*Event, error) { + ver, rawEvents, strings, err := readTrace(r) if err != nil { return nil, err } - events, stacks, err := parseEvents(rawEvents, strings) + events, stacks, err := parseEvents(ver, rawEvents, strings) if err != nil { return nil, err } @@ -66,7 +71,7 @@ func Parse(r io.Reader) ([]*Event, error) { if err != nil { return nil, err } - err = postProcessTrace(events) + err = postProcessTrace(ver, events) if err != nil { return nil, err } @@ -76,6 +81,11 @@ func Parse(r io.Reader) ([]*Event, error) { ev.Stk = stacks[ev.StkID] } } + if ver < 1007 && bin != "" { + if err := symbolize(events, bin); err != nil { + return nil, err + } + } return events, nil } @@ -88,61 +98,82 @@ type rawEvent struct { // readTrace does wire-format parsing and verification. // It does not care about specific event types and argument meaning. -func readTrace(r io.Reader) ([]rawEvent, map[uint64]string, error) { +func readTrace(r io.Reader) (ver int, events []rawEvent, strings map[uint64]string, err error) { // Read and validate trace header. var buf [16]byte - off, err := r.Read(buf[:]) - if off != 16 || err != nil { - return nil, nil, fmt.Errorf("failed to read header: read %v, err %v", off, err) + off, err := io.ReadFull(r, buf[:]) + if err != nil { + err = fmt.Errorf("failed to read header: read %v, err %v", off, err) + return } - if !bytes.Equal(buf[:], []byte("go 1.5 trace\x00\x00\x00\x00")) { - return nil, nil, fmt.Errorf("not a trace file") + ver, err = parseHeader(buf[:]) + if err != nil { + return + } + switch ver { + case 1005, 1007: + break + default: + err = fmt.Errorf("unsupported trace file version %v.%v (update Go toolchain) %v", ver/1000, ver%1000, ver) + return } // Read events. - var events []rawEvent - strings := make(map[uint64]string) + strings = make(map[uint64]string) for { // Read event type and number of arguments (1 byte). off0 := off - n, err := r.Read(buf[:1]) + var n int + n, err = r.Read(buf[:1]) if err == io.EOF { + err = nil break } if err != nil || n != 1 { - return nil, nil, fmt.Errorf("failed to read trace at offset 0x%x: n=%v err=%v", off0, n, err) + err = fmt.Errorf("failed to read trace at offset 0x%x: n=%v err=%v", off0, n, err) + return } off += n typ := buf[0] << 2 >> 2 narg := buf[0] >> 6 + if typ == EvNone || typ >= EvCount || EventDescriptions[typ].minVersion > ver { + err = fmt.Errorf("unknown event type %v at offset 0x%x", typ, off0) + return + } if typ == EvString { // String dictionary entry [ID, length, string]. var id uint64 id, off, err = readVal(r, off) if err != nil { - return nil, nil, err + return } if id == 0 { - return nil, nil, fmt.Errorf("string at offset %d has invalid id 0", off) + err = fmt.Errorf("string at offset %d has invalid id 0", off) + return } if strings[id] != "" { - return nil, nil, fmt.Errorf("string at offset %d has duplicate id %v", off, id) + err = fmt.Errorf("string at offset %d has duplicate id %v", off, id) + return } var ln uint64 ln, off, err = readVal(r, off) if err != nil { - return nil, nil, err + return } if ln == 0 { - return nil, nil, fmt.Errorf("string at offset %d has invalid length 0", off) + err = fmt.Errorf("string at offset %d has invalid length 0", off) + return } if ln > 1e6 { - return nil, nil, fmt.Errorf("string at offset %d has too large length %v", off, ln) + err = fmt.Errorf("string at offset %d has too large length %v", off, ln) + return } buf := make([]byte, ln) - n, err := io.ReadFull(r, buf) + var n int + n, err = io.ReadFull(r, buf) if err != nil { - return nil, nil, fmt.Errorf("failed to read trace at offset %d: read %v, want %v, error %v", off, n, ln, err) + err = fmt.Errorf("failed to read trace at offset %d: read %v, want %v, error %v", off, n, ln, err) + return } off += n strings[id] = string(buf) @@ -154,7 +185,8 @@ func readTrace(r io.Reader) ([]rawEvent, map[uint64]string, error) { var v uint64 v, off, err = readVal(r, off) if err != nil { - return nil, nil, err + err = fmt.Errorf("failed to read event %v argument at offset %v (%v)", typ, off, err) + return } ev.args = append(ev.args, v) } @@ -163,39 +195,62 @@ func readTrace(r io.Reader) ([]rawEvent, map[uint64]string, error) { var v uint64 v, off, err = readVal(r, off) if err != nil { - return nil, nil, err + err = fmt.Errorf("failed to read event %v argument at offset %v (%v)", typ, off, err) + return } evLen := v off1 := off for evLen > uint64(off-off1) { v, off, err = readVal(r, off) if err != nil { - return nil, nil, err + err = fmt.Errorf("failed to read event %v argument at offset %v (%v)", typ, off, err) + return } ev.args = append(ev.args, v) } if evLen != uint64(off-off1) { - return nil, nil, fmt.Errorf("event has wrong length at offset 0x%x: want %v, got %v", off0, evLen, off-off1) + err = fmt.Errorf("event has wrong length at offset 0x%x: want %v, got %v", off0, evLen, off-off1) + return } } events = append(events, ev) } - return events, strings, nil + return +} + +// parseHeader parses trace header of the form "go 1.7 trace\x00\x00\x00\x00" +// and returns parsed version as 1007. +func parseHeader(buf []byte) (int, error) { + if len(buf) != 16 { + return 0, fmt.Errorf("bad header length") + } + if buf[0] != 'g' || buf[1] != 'o' || buf[2] != ' ' || + buf[3] < '1' || buf[3] > '9' || + buf[4] != '.' || + buf[5] < '1' || buf[5] > '9' { + return 0, fmt.Errorf("not a trace file") + } + ver := int(buf[5] - '0') + i := 0 + for ; buf[6+i] >= '0' && buf[6+i] <= '9' && i < 2; i++ { + ver = ver*10 + int(buf[6+i]-'0') + } + ver += int(buf[3]-'0') * 1000 + if !bytes.Equal(buf[6+i:], []byte(" trace\x00\x00\x00\x00")[:10-i]) { + return 0, fmt.Errorf("not a trace file") + } + return ver, nil } // Parse events transforms raw events into events. // It does analyze and verify per-event-type arguments. -func parseEvents(rawEvents []rawEvent, strings map[uint64]string) (events []*Event, stacks map[uint64][]*Frame, err error) { +func parseEvents(ver int, rawEvents []rawEvent, strings map[uint64]string) (events []*Event, stacks map[uint64][]*Frame, err error) { var ticksPerSec, lastSeq, lastTs int64 var lastG, timerGoid uint64 var lastP int lastGs := make(map[int]uint64) // last goroutine running on P stacks = make(map[uint64][]*Frame) for _, raw := range rawEvents { - if raw.typ == EvNone || raw.typ >= EvCount { - err = fmt.Errorf("unknown event type %v at offset 0x%x", raw.typ, raw.off) - return - } desc := EventDescriptions[raw.typ] if desc.Name == "" { err = fmt.Errorf("missing description for event type %v", raw.typ) @@ -246,7 +301,11 @@ func parseEvents(rawEvents []rawEvent, strings map[uint64]string) (events []*Eve raw.off, size) return } - if want := 2 + 4*size; uint64(len(raw.args)) != want { + want := 2 + 4*size + if ver < 1007 { + want = 2 + size + } + if uint64(len(raw.args)) != want { err = fmt.Errorf("EvStack has wrong number of arguments at offset 0x%x: want %v, got %v", raw.off, want, len(raw.args)) return @@ -255,19 +314,23 @@ func parseEvents(rawEvents []rawEvent, strings map[uint64]string) (events []*Eve if id != 0 && size > 0 { stk := make([]*Frame, size) for i := 0; i < int(size); i++ { - pc := raw.args[2+i*4+0] - fn := raw.args[2+i*4+1] - file := raw.args[2+i*4+2] - line := raw.args[2+i*4+3] - stk[i] = &Frame{PC: pc, Fn: strings[fn], File: strings[file], Line: int(line)} + if ver < 1007 { + stk[i] = &Frame{PC: raw.args[2+i]} + } else { + pc := raw.args[2+i*4+0] + fn := raw.args[2+i*4+1] + file := raw.args[2+i*4+2] + line := raw.args[2+i*4+3] + stk[i] = &Frame{PC: pc, Fn: strings[fn], File: strings[file], Line: int(line)} + } } stacks[id] = stk } default: e := &Event{Off: raw.off, Type: raw.typ, P: lastP, G: lastG} - e.Seq = lastSeq + int64(raw.args[0]) + e.seq = lastSeq + int64(raw.args[0]) e.Ts = lastTs + int64(raw.args[1]) - lastSeq = e.Seq + lastSeq = e.seq lastTs = e.Ts for i := range desc.Args { e.Args[i] = raw.args[i+2] @@ -289,7 +352,7 @@ func parseEvents(rawEvents []rawEvent, strings map[uint64]string) (events []*Eve case EvGoSysExit: // EvGoSysExit emission is delayed until the thread has a P. // Give it the real sequence number and time stamp. - e.Seq = int64(e.Args[1]) + e.seq = int64(e.Args[1]) if e.Args[2] != 0 { e.Ts = int64(e.Args[2]) } @@ -387,7 +450,7 @@ var ErrTimeOrder = fmt.Errorf("time stamps out of order") // The resulting trace is guaranteed to be consistent // (for example, a P does not run two Gs at the same time, or a G is indeed // blocked before an unblock event). -func postProcessTrace(events []*Event) error { +func postProcessTrace(ver int, events []*Event) error { const ( gDead = iota gRunnable @@ -510,7 +573,12 @@ func postProcessTrace(events []*Event) error { g.evStart = ev p.g = ev.G if g.evCreate != nil { - ev.StkID = g.evCreate.Args[1] + if ver < 1007 { + // +1 because symbolizer expects return pc. + ev.Stk = []*Frame{{PC: g.evCreate.Args[1] + 1}} + } else { + ev.StkID = g.evCreate.Args[1] + } g.evCreate = nil } @@ -611,6 +679,79 @@ func postProcessTrace(events []*Event) error { return nil } +// symbolize attaches func/file/line info to stack traces. +func symbolize(events []*Event, bin string) error { + // First, collect and dedup all pcs. + pcs := make(map[uint64]*Frame) + for _, ev := range events { + for _, f := range ev.Stk { + pcs[f.PC] = nil + } + } + + // Start addr2line. + cmd := exec.Command("go", "tool", "addr2line", bin) + in, err := cmd.StdinPipe() + if err != nil { + return fmt.Errorf("failed to pipe addr2line stdin: %v", err) + } + cmd.Stderr = os.Stderr + out, err := cmd.StdoutPipe() + if err != nil { + return fmt.Errorf("failed to pipe addr2line stdout: %v", err) + } + err = cmd.Start() + if err != nil { + return fmt.Errorf("failed to start addr2line: %v", err) + } + outb := bufio.NewReader(out) + + // Write all pcs to addr2line. + // Need to copy pcs to an array, because map iteration order is non-deterministic. + var pcArray []uint64 + for pc := range pcs { + pcArray = append(pcArray, pc) + _, err := fmt.Fprintf(in, "0x%x\n", pc-1) + if err != nil { + return fmt.Errorf("failed to write to addr2line: %v", err) + } + } + in.Close() + + // Read in answers. + for _, pc := range pcArray { + fn, err := outb.ReadString('\n') + if err != nil { + return fmt.Errorf("failed to read from addr2line: %v", err) + } + file, err := outb.ReadString('\n') + if err != nil { + return fmt.Errorf("failed to read from addr2line: %v", err) + } + f := &Frame{PC: pc} + f.Fn = fn[:len(fn)-1] + f.File = file[:len(file)-1] + if colon := strings.LastIndex(f.File, ":"); colon != -1 { + ln, err := strconv.Atoi(f.File[colon+1:]) + if err == nil { + f.File = f.File[:colon] + f.Line = ln + } + } + pcs[pc] = f + } + cmd.Wait() + + // Replace frames in events array. + for _, ev := range events { + for i, f := range ev.Stk { + ev.Stk[i] = pcs[f.PC] + } + } + + return nil +} + // readVal reads unsigned base-128 value from r. func readVal(r io.Reader, off0 int) (v uint64, off int, err error) { off = off0 @@ -637,7 +778,7 @@ func (l eventList) Len() int { } func (l eventList) Less(i, j int) bool { - return l[i].Seq < l[j].Seq + return l[i].seq < l[j].seq } func (l eventList) Swap(i, j int) { @@ -701,46 +842,47 @@ const ( ) var EventDescriptions = [EvCount]struct { - Name string - Stack bool - Args []string + Name string + minVersion int + Stack bool + Args []string }{ - EvNone: {"None", false, []string{}}, - EvBatch: {"Batch", false, []string{"p", "seq", "ticks"}}, - EvFrequency: {"Frequency", false, []string{"freq", "unused"}}, - EvStack: {"Stack", false, []string{"id", "siz"}}, - EvGomaxprocs: {"Gomaxprocs", true, []string{"procs"}}, - EvProcStart: {"ProcStart", false, []string{"thread"}}, - EvProcStop: {"ProcStop", false, []string{}}, - EvGCStart: {"GCStart", true, []string{}}, - EvGCDone: {"GCDone", false, []string{}}, - EvGCScanStart: {"GCScanStart", false, []string{}}, - EvGCScanDone: {"GCScanDone", false, []string{}}, - EvGCSweepStart: {"GCSweepStart", true, []string{}}, - EvGCSweepDone: {"GCSweepDone", false, []string{}}, - EvGoCreate: {"GoCreate", true, []string{"g", "stack"}}, - EvGoStart: {"GoStart", false, []string{"g"}}, - EvGoEnd: {"GoEnd", false, []string{}}, - EvGoStop: {"GoStop", true, []string{}}, - EvGoSched: {"GoSched", true, []string{}}, - EvGoPreempt: {"GoPreempt", true, []string{}}, - EvGoSleep: {"GoSleep", true, []string{}}, - EvGoBlock: {"GoBlock", true, []string{}}, - EvGoUnblock: {"GoUnblock", true, []string{"g"}}, - EvGoBlockSend: {"GoBlockSend", true, []string{}}, - EvGoBlockRecv: {"GoBlockRecv", true, []string{}}, - EvGoBlockSelect: {"GoBlockSelect", true, []string{}}, - EvGoBlockSync: {"GoBlockSync", true, []string{}}, - EvGoBlockCond: {"GoBlockCond", true, []string{}}, - EvGoBlockNet: {"GoBlockNet", true, []string{}}, - EvGoSysCall: {"GoSysCall", true, []string{}}, - EvGoSysExit: {"GoSysExit", false, []string{"g", "seq", "ts"}}, - EvGoSysBlock: {"GoSysBlock", false, []string{}}, - EvGoWaiting: {"GoWaiting", false, []string{"g"}}, - EvGoInSyscall: {"GoInSyscall", false, []string{"g"}}, - EvHeapAlloc: {"HeapAlloc", false, []string{"mem"}}, - EvNextGC: {"NextGC", false, []string{"mem"}}, - EvTimerGoroutine: {"TimerGoroutine", false, []string{"g", "unused"}}, - EvFutileWakeup: {"FutileWakeup", false, []string{}}, - EvString: {"String", false, []string{}}, + EvNone: {"None", 1005, false, []string{}}, + EvBatch: {"Batch", 1005, false, []string{"p", "seq", "ticks"}}, + EvFrequency: {"Frequency", 1005, false, []string{"freq", "unused"}}, + EvStack: {"Stack", 1005, false, []string{"id", "siz"}}, + EvGomaxprocs: {"Gomaxprocs", 1005, true, []string{"procs"}}, + EvProcStart: {"ProcStart", 1005, false, []string{"thread"}}, + EvProcStop: {"ProcStop", 1005, false, []string{}}, + EvGCStart: {"GCStart", 1005, true, []string{}}, + EvGCDone: {"GCDone", 1005, false, []string{}}, + EvGCScanStart: {"GCScanStart", 1005, false, []string{}}, + EvGCScanDone: {"GCScanDone", 1005, false, []string{}}, + EvGCSweepStart: {"GCSweepStart", 1005, true, []string{}}, + EvGCSweepDone: {"GCSweepDone", 1005, false, []string{}}, + EvGoCreate: {"GoCreate", 1005, true, []string{"g", "stack"}}, + EvGoStart: {"GoStart", 1005, false, []string{"g"}}, + EvGoEnd: {"GoEnd", 1005, false, []string{}}, + EvGoStop: {"GoStop", 1005, true, []string{}}, + EvGoSched: {"GoSched", 1005, true, []string{}}, + EvGoPreempt: {"GoPreempt", 1005, true, []string{}}, + EvGoSleep: {"GoSleep", 1005, true, []string{}}, + EvGoBlock: {"GoBlock", 1005, true, []string{}}, + EvGoUnblock: {"GoUnblock", 1005, true, []string{"g"}}, + EvGoBlockSend: {"GoBlockSend", 1005, true, []string{}}, + EvGoBlockRecv: {"GoBlockRecv", 1005, true, []string{}}, + EvGoBlockSelect: {"GoBlockSelect", 1005, true, []string{}}, + EvGoBlockSync: {"GoBlockSync", 1005, true, []string{}}, + EvGoBlockCond: {"GoBlockCond", 1005, true, []string{}}, + EvGoBlockNet: {"GoBlockNet", 1005, true, []string{}}, + EvGoSysCall: {"GoSysCall", 1005, true, []string{}}, + EvGoSysExit: {"GoSysExit", 1005, false, []string{"g", "seq", "ts"}}, + EvGoSysBlock: {"GoSysBlock", 1005, false, []string{}}, + EvGoWaiting: {"GoWaiting", 1005, false, []string{"g"}}, + EvGoInSyscall: {"GoInSyscall", 1005, false, []string{"g"}}, + EvHeapAlloc: {"HeapAlloc", 1005, false, []string{"mem"}}, + EvNextGC: {"NextGC", 1005, false, []string{"mem"}}, + EvTimerGoroutine: {"TimerGoroutine", 1005, false, []string{"g", "unused"}}, + EvFutileWakeup: {"FutileWakeup", 1005, false, []string{}}, + EvString: {"String", 1007, false, []string{}}, } diff --git a/src/internal/trace/parser_test.go b/src/internal/trace/parser_test.go index fecefc4053..db8d2a30ce 100644 --- a/src/internal/trace/parser_test.go +++ b/src/internal/trace/parser_test.go @@ -5,6 +5,9 @@ package trace import ( + "bytes" + "io/ioutil" + "path/filepath" "strings" "testing" ) @@ -22,9 +25,63 @@ func TestCorruptedInputs(t *testing.T) { "go 1.5 trace\x00\x00\x00\x00\xc3\x0200", } for _, data := range tests { - events, err := Parse(strings.NewReader(data)) + events, err := Parse(strings.NewReader(data), "") 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) + } } } } diff --git a/src/internal/trace/testdata/http_1_5_good b/src/internal/trace/testdata/http_1_5_good new file mode 100644 index 0000000000000000000000000000000000000000..0736cae674186cfcc6fa31508fec410242936f20 GIT binary patch literal 42218 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 literal 0 HcmV?d00001 diff --git a/src/internal/trace/testdata/stress_1_5_good b/src/internal/trace/testdata/stress_1_5_good new file mode 100644 index 0000000000000000000000000000000000000000..c5055ebd19ffca30e2905abd29cb1306a0ce98a0 GIT binary patch literal 7446 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 z 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 literal 0 HcmV?d00001 diff --git a/src/runtime/trace.go b/src/runtime/trace.go index f54e5e0a7e..dcf534549a 100644 --- a/src/runtime/trace.go +++ b/src/runtime/trace.go @@ -356,7 +356,7 @@ func ReadTrace() []byte { trace.headerWritten = true trace.lockOwner = nil 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. if trace.fullHead == 0 && !trace.shutdown { diff --git a/src/runtime/trace/trace_test.go b/src/runtime/trace/trace_test.go index b787a2fc27..d10e928a66 100644 --- a/src/runtime/trace/trace_test.go +++ b/src/runtime/trace/trace_test.go @@ -52,7 +52,7 @@ func TestTrace(t *testing.T) { t.Fatalf("failed to start tracing: %v", err) } Stop() - _, err := trace.Parse(buf) + _, err := trace.Parse(buf, "") if err == trace.ErrTimeOrder { t.Skipf("skipping trace: %v", err) } @@ -62,7 +62,7 @@ func TestTrace(t *testing.T) { } 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 { t.Skipf("skipping trace: %v", err) } -- 2.48.1