Home | History | Annotate | Download | only in trace
      1 // Copyright 2014 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package trace
      6 
      7 import (
      8 	"bufio"
      9 	"bytes"
     10 	"fmt"
     11 	"io"
     12 	"math/rand"
     13 	"os"
     14 	"os/exec"
     15 	"path/filepath"
     16 	"runtime"
     17 	"strconv"
     18 	"strings"
     19 	_ "unsafe"
     20 )
     21 
     22 func goCmd() string {
     23 	var exeSuffix string
     24 	if runtime.GOOS == "windows" {
     25 		exeSuffix = ".exe"
     26 	}
     27 	path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
     28 	if _, err := os.Stat(path); err == nil {
     29 		return path
     30 	}
     31 	return "go"
     32 }
     33 
     34 // Event describes one event in the trace.
     35 type Event struct {
     36 	Off   int       // offset in input file (for debugging and error reporting)
     37 	Type  byte      // one of Ev*
     38 	seq   int64     // sequence number
     39 	Ts    int64     // timestamp in nanoseconds
     40 	P     int       // P on which the event happened (can be one of TimerP, NetpollP, SyscallP)
     41 	G     uint64    // G on which the event happened
     42 	StkID uint64    // unique stack ID
     43 	Stk   []*Frame  // stack trace (can be empty)
     44 	Args  [3]uint64 // event-type-specific arguments
     45 	SArgs []string  // event-type-specific string args
     46 	// linked event (can be nil), depends on event type:
     47 	// for GCStart: the GCStop
     48 	// for GCSTWStart: the GCSTWDone
     49 	// for GCSweepStart: the GCSweepDone
     50 	// for GoCreate: first GoStart of the created goroutine
     51 	// for GoStart/GoStartLabel: the associated GoEnd, GoBlock or other blocking event
     52 	// for GoSched/GoPreempt: the next GoStart
     53 	// for GoBlock and other blocking events: the unblock event
     54 	// for GoUnblock: the associated GoStart
     55 	// for blocking GoSysCall: the associated GoSysExit
     56 	// for GoSysExit: the next GoStart
     57 	// for GCMarkAssistStart: the associated GCMarkAssistDone
     58 	Link *Event
     59 }
     60 
     61 // Frame is a frame in stack traces.
     62 type Frame struct {
     63 	PC   uint64
     64 	Fn   string
     65 	File string
     66 	Line int
     67 }
     68 
     69 const (
     70 	// Special P identifiers:
     71 	FakeP    = 1000000 + iota
     72 	TimerP   // depicts timer unblocks
     73 	NetpollP // depicts network unblocks
     74 	SyscallP // depicts returns from syscalls
     75 	GCP      // depicts GC state
     76 )
     77 
     78 // ParseResult is the result of Parse.
     79 type ParseResult struct {
     80 	// Events is the sorted list of Events in the trace.
     81 	Events []*Event
     82 	// Stacks is the stack traces keyed by stack IDs from the trace.
     83 	Stacks map[uint64][]*Frame
     84 }
     85 
     86 // Parse parses, post-processes and verifies the trace.
     87 func Parse(r io.Reader, bin string) (ParseResult, error) {
     88 	ver, res, err := parse(r, bin)
     89 	if err != nil {
     90 		return ParseResult{}, err
     91 	}
     92 	if ver < 1007 && bin == "" {
     93 		return ParseResult{}, fmt.Errorf("for traces produced by go 1.6 or below, the binary argument must be provided")
     94 	}
     95 	return res, nil
     96 }
     97 
     98 // parse parses, post-processes and verifies the trace. It returns the
     99 // trace version and the list of events.
    100 func parse(r io.Reader, bin string) (int, ParseResult, error) {
    101 	ver, rawEvents, strings, err := readTrace(r)
    102 	if err != nil {
    103 		return 0, ParseResult{}, err
    104 	}
    105 	events, stacks, err := parseEvents(ver, rawEvents, strings)
    106 	if err != nil {
    107 		return 0, ParseResult{}, err
    108 	}
    109 	events, err = removeFutile(events)
    110 	if err != nil {
    111 		return 0, ParseResult{}, err
    112 	}
    113 	err = postProcessTrace(ver, events)
    114 	if err != nil {
    115 		return 0, ParseResult{}, err
    116 	}
    117 	// Attach stack traces.
    118 	for _, ev := range events {
    119 		if ev.StkID != 0 {
    120 			ev.Stk = stacks[ev.StkID]
    121 		}
    122 	}
    123 	if ver < 1007 && bin != "" {
    124 		if err := symbolize(events, bin); err != nil {
    125 			return 0, ParseResult{}, err
    126 		}
    127 	}
    128 	return ver, ParseResult{Events: events, Stacks: stacks}, nil
    129 }
    130 
    131 // rawEvent is a helper type used during parsing.
    132 type rawEvent struct {
    133 	off  int
    134 	typ  byte
    135 	args []uint64
    136 }
    137 
    138 // readTrace does wire-format parsing and verification.
    139 // It does not care about specific event types and argument meaning.
    140 func readTrace(r io.Reader) (ver int, events []rawEvent, strings map[uint64]string, err error) {
    141 	// Read and validate trace header.
    142 	var buf [16]byte
    143 	off, err := io.ReadFull(r, buf[:])
    144 	if err != nil {
    145 		err = fmt.Errorf("failed to read header: read %v, err %v", off, err)
    146 		return
    147 	}
    148 	ver, err = parseHeader(buf[:])
    149 	if err != nil {
    150 		return
    151 	}
    152 	switch ver {
    153 	case 1005, 1007, 1008, 1009, 1010:
    154 		// Note: When adding a new version, add canned traces
    155 		// from the old version to the test suite using mkcanned.bash.
    156 		break
    157 	default:
    158 		err = fmt.Errorf("unsupported trace file version %v.%v (update Go toolchain) %v", ver/1000, ver%1000, ver)
    159 		return
    160 	}
    161 
    162 	// Read events.
    163 	strings = make(map[uint64]string)
    164 	for {
    165 		// Read event type and number of arguments (1 byte).
    166 		off0 := off
    167 		var n int
    168 		n, err = r.Read(buf[:1])
    169 		if err == io.EOF {
    170 			err = nil
    171 			break
    172 		}
    173 		if err != nil || n != 1 {
    174 			err = fmt.Errorf("failed to read trace at offset 0x%x: n=%v err=%v", off0, n, err)
    175 			return
    176 		}
    177 		off += n
    178 		typ := buf[0] << 2 >> 2
    179 		narg := buf[0]>>6 + 1
    180 		inlineArgs := byte(4)
    181 		if ver < 1007 {
    182 			narg++
    183 			inlineArgs++
    184 		}
    185 		if typ == EvNone || typ >= EvCount || EventDescriptions[typ].minVersion > ver {
    186 			err = fmt.Errorf("unknown event type %v at offset 0x%x", typ, off0)
    187 			return
    188 		}
    189 		if typ == EvString {
    190 			// String dictionary entry [ID, length, string].
    191 			var id uint64
    192 			id, off, err = readVal(r, off)
    193 			if err != nil {
    194 				return
    195 			}
    196 			if id == 0 {
    197 				err = fmt.Errorf("string at offset %d has invalid id 0", off)
    198 				return
    199 			}
    200 			if strings[id] != "" {
    201 				err = fmt.Errorf("string at offset %d has duplicate id %v", off, id)
    202 				return
    203 			}
    204 			var ln uint64
    205 			ln, off, err = readVal(r, off)
    206 			if err != nil {
    207 				return
    208 			}
    209 			if ln == 0 {
    210 				err = fmt.Errorf("string at offset %d has invalid length 0", off)
    211 				return
    212 			}
    213 			if ln > 1e6 {
    214 				err = fmt.Errorf("string at offset %d has too large length %v", off, ln)
    215 				return
    216 			}
    217 			buf := make([]byte, ln)
    218 			var n int
    219 			n, err = io.ReadFull(r, buf)
    220 			if err != nil {
    221 				err = fmt.Errorf("failed to read trace at offset %d: read %v, want %v, error %v", off, n, ln, err)
    222 				return
    223 			}
    224 			off += n
    225 			strings[id] = string(buf)
    226 			continue
    227 		}
    228 		ev := rawEvent{typ: typ, off: off0}
    229 		if narg < inlineArgs {
    230 			for i := 0; i < int(narg); i++ {
    231 				var v uint64
    232 				v, off, err = readVal(r, off)
    233 				if err != nil {
    234 					err = fmt.Errorf("failed to read event %v argument at offset %v (%v)", typ, off, err)
    235 					return
    236 				}
    237 				ev.args = append(ev.args, v)
    238 			}
    239 		} else {
    240 			// More than inlineArgs args, the first value is length of the event in bytes.
    241 			var v uint64
    242 			v, off, err = readVal(r, off)
    243 			if err != nil {
    244 				err = fmt.Errorf("failed to read event %v argument at offset %v (%v)", typ, off, err)
    245 				return
    246 			}
    247 			evLen := v
    248 			off1 := off
    249 			for evLen > uint64(off-off1) {
    250 				v, off, err = readVal(r, off)
    251 				if err != nil {
    252 					err = fmt.Errorf("failed to read event %v argument at offset %v (%v)", typ, off, err)
    253 					return
    254 				}
    255 				ev.args = append(ev.args, v)
    256 			}
    257 			if evLen != uint64(off-off1) {
    258 				err = fmt.Errorf("event has wrong length at offset 0x%x: want %v, got %v", off0, evLen, off-off1)
    259 				return
    260 			}
    261 		}
    262 		events = append(events, ev)
    263 	}
    264 	return
    265 }
    266 
    267 // parseHeader parses trace header of the form "go 1.7 trace\x00\x00\x00\x00"
    268 // and returns parsed version as 1007.
    269 func parseHeader(buf []byte) (int, error) {
    270 	if len(buf) != 16 {
    271 		return 0, fmt.Errorf("bad header length")
    272 	}
    273 	if buf[0] != 'g' || buf[1] != 'o' || buf[2] != ' ' ||
    274 		buf[3] < '1' || buf[3] > '9' ||
    275 		buf[4] != '.' ||
    276 		buf[5] < '1' || buf[5] > '9' {
    277 		return 0, fmt.Errorf("not a trace file")
    278 	}
    279 	ver := int(buf[5] - '0')
    280 	i := 0
    281 	for ; buf[6+i] >= '0' && buf[6+i] <= '9' && i < 2; i++ {
    282 		ver = ver*10 + int(buf[6+i]-'0')
    283 	}
    284 	ver += int(buf[3]-'0') * 1000
    285 	if !bytes.Equal(buf[6+i:], []byte(" trace\x00\x00\x00\x00")[:10-i]) {
    286 		return 0, fmt.Errorf("not a trace file")
    287 	}
    288 	return ver, nil
    289 }
    290 
    291 // Parse events transforms raw events into events.
    292 // It does analyze and verify per-event-type arguments.
    293 func parseEvents(ver int, rawEvents []rawEvent, strings map[uint64]string) (events []*Event, stacks map[uint64][]*Frame, err error) {
    294 	var ticksPerSec, lastSeq, lastTs int64
    295 	var lastG uint64
    296 	var lastP int
    297 	timerGoids := make(map[uint64]bool)
    298 	lastGs := make(map[int]uint64) // last goroutine running on P
    299 	stacks = make(map[uint64][]*Frame)
    300 	batches := make(map[int][]*Event) // events by P
    301 	for _, raw := range rawEvents {
    302 		desc := EventDescriptions[raw.typ]
    303 		if desc.Name == "" {
    304 			err = fmt.Errorf("missing description for event type %v", raw.typ)
    305 			return
    306 		}
    307 		narg := argNum(raw, ver)
    308 		if len(raw.args) != narg {
    309 			err = fmt.Errorf("%v has wrong number of arguments at offset 0x%x: want %v, got %v",
    310 				desc.Name, raw.off, narg, len(raw.args))
    311 			return
    312 		}
    313 		switch raw.typ {
    314 		case EvBatch:
    315 			lastGs[lastP] = lastG
    316 			lastP = int(raw.args[0])
    317 			lastG = lastGs[lastP]
    318 			if ver < 1007 {
    319 				lastSeq = int64(raw.args[1])
    320 				lastTs = int64(raw.args[2])
    321 			} else {
    322 				lastTs = int64(raw.args[1])
    323 			}
    324 		case EvFrequency:
    325 			ticksPerSec = int64(raw.args[0])
    326 			if ticksPerSec <= 0 {
    327 				// The most likely cause for this is tick skew on different CPUs.
    328 				// For example, solaris/amd64 seems to have wildly different
    329 				// ticks on different CPUs.
    330 				err = ErrTimeOrder
    331 				return
    332 			}
    333 		case EvTimerGoroutine:
    334 			timerGoids[raw.args[0]] = true
    335 		case EvStack:
    336 			if len(raw.args) < 2 {
    337 				err = fmt.Errorf("EvStack has wrong number of arguments at offset 0x%x: want at least 2, got %v",
    338 					raw.off, len(raw.args))
    339 				return
    340 			}
    341 			size := raw.args[1]
    342 			if size > 1000 {
    343 				err = fmt.Errorf("EvStack has bad number of frames at offset 0x%x: %v",
    344 					raw.off, size)
    345 				return
    346 			}
    347 			want := 2 + 4*size
    348 			if ver < 1007 {
    349 				want = 2 + size
    350 			}
    351 			if uint64(len(raw.args)) != want {
    352 				err = fmt.Errorf("EvStack has wrong number of arguments at offset 0x%x: want %v, got %v",
    353 					raw.off, want, len(raw.args))
    354 				return
    355 			}
    356 			id := raw.args[0]
    357 			if id != 0 && size > 0 {
    358 				stk := make([]*Frame, size)
    359 				for i := 0; i < int(size); i++ {
    360 					if ver < 1007 {
    361 						stk[i] = &Frame{PC: raw.args[2+i]}
    362 					} else {
    363 						pc := raw.args[2+i*4+0]
    364 						fn := raw.args[2+i*4+1]
    365 						file := raw.args[2+i*4+2]
    366 						line := raw.args[2+i*4+3]
    367 						stk[i] = &Frame{PC: pc, Fn: strings[fn], File: strings[file], Line: int(line)}
    368 					}
    369 				}
    370 				stacks[id] = stk
    371 			}
    372 		default:
    373 			e := &Event{Off: raw.off, Type: raw.typ, P: lastP, G: lastG}
    374 			var argOffset int
    375 			if ver < 1007 {
    376 				e.seq = lastSeq + int64(raw.args[0])
    377 				e.Ts = lastTs + int64(raw.args[1])
    378 				lastSeq = e.seq
    379 				argOffset = 2
    380 			} else {
    381 				e.Ts = lastTs + int64(raw.args[0])
    382 				argOffset = 1
    383 			}
    384 			lastTs = e.Ts
    385 			for i := argOffset; i < narg; i++ {
    386 				if i == narg-1 && desc.Stack {
    387 					e.StkID = raw.args[i]
    388 				} else {
    389 					e.Args[i-argOffset] = raw.args[i]
    390 				}
    391 			}
    392 			switch raw.typ {
    393 			case EvGoStart, EvGoStartLocal, EvGoStartLabel:
    394 				lastG = e.Args[0]
    395 				e.G = lastG
    396 				if raw.typ == EvGoStartLabel {
    397 					e.SArgs = []string{strings[e.Args[2]]}
    398 				}
    399 			case EvGCSTWStart:
    400 				e.G = 0
    401 				switch e.Args[0] {
    402 				case 0:
    403 					e.SArgs = []string{"mark termination"}
    404 				case 1:
    405 					e.SArgs = []string{"sweep termination"}
    406 				default:
    407 					err = fmt.Errorf("unknown STW kind %d", e.Args[0])
    408 					return
    409 				}
    410 			case EvGCStart, EvGCDone, EvGCSTWDone:
    411 				e.G = 0
    412 			case EvGoEnd, EvGoStop, EvGoSched, EvGoPreempt,
    413 				EvGoSleep, EvGoBlock, EvGoBlockSend, EvGoBlockRecv,
    414 				EvGoBlockSelect, EvGoBlockSync, EvGoBlockCond, EvGoBlockNet,
    415 				EvGoSysBlock, EvGoBlockGC:
    416 				lastG = 0
    417 			case EvGoSysExit, EvGoWaiting, EvGoInSyscall:
    418 				e.G = e.Args[0]
    419 			}
    420 			batches[lastP] = append(batches[lastP], e)
    421 		}
    422 	}
    423 	if len(batches) == 0 {
    424 		err = fmt.Errorf("trace is empty")
    425 		return
    426 	}
    427 	if ticksPerSec == 0 {
    428 		err = fmt.Errorf("no EvFrequency event")
    429 		return
    430 	}
    431 	if BreakTimestampsForTesting {
    432 		var batchArr [][]*Event
    433 		for _, batch := range batches {
    434 			batchArr = append(batchArr, batch)
    435 		}
    436 		for i := 0; i < 5; i++ {
    437 			batch := batchArr[rand.Intn(len(batchArr))]
    438 			batch[rand.Intn(len(batch))].Ts += int64(rand.Intn(2000) - 1000)
    439 		}
    440 	}
    441 	if ver < 1007 {
    442 		events, err = order1005(batches)
    443 	} else {
    444 		events, err = order1007(batches)
    445 	}
    446 	if err != nil {
    447 		return
    448 	}
    449 
    450 	// Translate cpu ticks to real time.
    451 	minTs := events[0].Ts
    452 	// Use floating point to avoid integer overflows.
    453 	freq := 1e9 / float64(ticksPerSec)
    454 	for _, ev := range events {
    455 		ev.Ts = int64(float64(ev.Ts-minTs) * freq)
    456 		// Move timers and syscalls to separate fake Ps.
    457 		if timerGoids[ev.G] && ev.Type == EvGoUnblock {
    458 			ev.P = TimerP
    459 		}
    460 		if ev.Type == EvGoSysExit {
    461 			ev.P = SyscallP
    462 		}
    463 	}
    464 
    465 	return
    466 }
    467 
    468 // removeFutile removes all constituents of futile wakeups (block, unblock, start).
    469 // For example, a goroutine was unblocked on a mutex, but another goroutine got
    470 // ahead and acquired the mutex before the first goroutine is scheduled,
    471 // so the first goroutine has to block again. Such wakeups happen on buffered
    472 // channels and sync.Mutex, but are generally not interesting for end user.
    473 func removeFutile(events []*Event) ([]*Event, error) {
    474 	// Two non-trivial aspects:
    475 	// 1. A goroutine can be preempted during a futile wakeup and migrate to another P.
    476 	//	We want to remove all of that.
    477 	// 2. Tracing can start in the middle of a futile wakeup.
    478 	//	That is, we can see a futile wakeup event w/o the actual wakeup before it.
    479 	// postProcessTrace runs after us and ensures that we leave the trace in a consistent state.
    480 
    481 	// Phase 1: determine futile wakeup sequences.
    482 	type G struct {
    483 		futile bool
    484 		wakeup []*Event // wakeup sequence (subject for removal)
    485 	}
    486 	gs := make(map[uint64]G)
    487 	futile := make(map[*Event]bool)
    488 	for _, ev := range events {
    489 		switch ev.Type {
    490 		case EvGoUnblock:
    491 			g := gs[ev.Args[0]]
    492 			g.wakeup = []*Event{ev}
    493 			gs[ev.Args[0]] = g
    494 		case EvGoStart, EvGoPreempt, EvFutileWakeup:
    495 			g := gs[ev.G]
    496 			g.wakeup = append(g.wakeup, ev)
    497 			if ev.Type == EvFutileWakeup {
    498 				g.futile = true
    499 			}
    500 			gs[ev.G] = g
    501 		case EvGoBlock, EvGoBlockSend, EvGoBlockRecv, EvGoBlockSelect, EvGoBlockSync, EvGoBlockCond:
    502 			g := gs[ev.G]
    503 			if g.futile {
    504 				futile[ev] = true
    505 				for _, ev1 := range g.wakeup {
    506 					futile[ev1] = true
    507 				}
    508 			}
    509 			delete(gs, ev.G)
    510 		}
    511 	}
    512 
    513 	// Phase 2: remove futile wakeup sequences.
    514 	newEvents := events[:0] // overwrite the original slice
    515 	for _, ev := range events {
    516 		if !futile[ev] {
    517 			newEvents = append(newEvents, ev)
    518 		}
    519 	}
    520 	return newEvents, nil
    521 }
    522 
    523 // ErrTimeOrder is returned by Parse when the trace contains
    524 // time stamps that do not respect actual event ordering.
    525 var ErrTimeOrder = fmt.Errorf("time stamps out of order")
    526 
    527 // postProcessTrace does inter-event verification and information restoration.
    528 // The resulting trace is guaranteed to be consistent
    529 // (for example, a P does not run two Gs at the same time, or a G is indeed
    530 // blocked before an unblock event).
    531 func postProcessTrace(ver int, events []*Event) error {
    532 	const (
    533 		gDead = iota
    534 		gRunnable
    535 		gRunning
    536 		gWaiting
    537 	)
    538 	type gdesc struct {
    539 		state        int
    540 		ev           *Event
    541 		evStart      *Event
    542 		evCreate     *Event
    543 		evMarkAssist *Event
    544 	}
    545 	type pdesc struct {
    546 		running bool
    547 		g       uint64
    548 		evSTW   *Event
    549 		evSweep *Event
    550 	}
    551 
    552 	gs := make(map[uint64]gdesc)
    553 	ps := make(map[int]pdesc)
    554 	gs[0] = gdesc{state: gRunning}
    555 	var evGC, evSTW *Event
    556 
    557 	checkRunning := func(p pdesc, g gdesc, ev *Event, allowG0 bool) error {
    558 		name := EventDescriptions[ev.Type].Name
    559 		if g.state != gRunning {
    560 			return fmt.Errorf("g %v is not running while %v (offset %v, time %v)", ev.G, name, ev.Off, ev.Ts)
    561 		}
    562 		if p.g != ev.G {
    563 			return fmt.Errorf("p %v is not running g %v while %v (offset %v, time %v)", ev.P, ev.G, name, ev.Off, ev.Ts)
    564 		}
    565 		if !allowG0 && ev.G == 0 {
    566 			return fmt.Errorf("g 0 did %v (offset %v, time %v)", EventDescriptions[ev.Type].Name, ev.Off, ev.Ts)
    567 		}
    568 		return nil
    569 	}
    570 
    571 	for _, ev := range events {
    572 		g := gs[ev.G]
    573 		p := ps[ev.P]
    574 
    575 		switch ev.Type {
    576 		case EvProcStart:
    577 			if p.running {
    578 				return fmt.Errorf("p %v is running before start (offset %v, time %v)", ev.P, ev.Off, ev.Ts)
    579 			}
    580 			p.running = true
    581 		case EvProcStop:
    582 			if !p.running {
    583 				return fmt.Errorf("p %v is not running before stop (offset %v, time %v)", ev.P, ev.Off, ev.Ts)
    584 			}
    585 			if p.g != 0 {
    586 				return fmt.Errorf("p %v is running a goroutine %v during stop (offset %v, time %v)", ev.P, p.g, ev.Off, ev.Ts)
    587 			}
    588 			p.running = false
    589 		case EvGCStart:
    590 			if evGC != nil {
    591 				return fmt.Errorf("previous GC is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
    592 			}
    593 			evGC = ev
    594 			// Attribute this to the global GC state.
    595 			ev.P = GCP
    596 		case EvGCDone:
    597 			if evGC == nil {
    598 				return fmt.Errorf("bogus GC end (offset %v, time %v)", ev.Off, ev.Ts)
    599 			}
    600 			evGC.Link = ev
    601 			evGC = nil
    602 		case EvGCSTWStart:
    603 			evp := &evSTW
    604 			if ver < 1010 {
    605 				// Before 1.10, EvGCSTWStart was per-P.
    606 				evp = &p.evSTW
    607 			}
    608 			if *evp != nil {
    609 				return fmt.Errorf("previous STW is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
    610 			}
    611 			*evp = ev
    612 		case EvGCSTWDone:
    613 			evp := &evSTW
    614 			if ver < 1010 {
    615 				// Before 1.10, EvGCSTWDone was per-P.
    616 				evp = &p.evSTW
    617 			}
    618 			if *evp == nil {
    619 				return fmt.Errorf("bogus STW end (offset %v, time %v)", ev.Off, ev.Ts)
    620 			}
    621 			(*evp).Link = ev
    622 			*evp = nil
    623 		case EvGCSweepStart:
    624 			if p.evSweep != nil {
    625 				return fmt.Errorf("previous sweeping is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
    626 			}
    627 			p.evSweep = ev
    628 		case EvGCMarkAssistStart:
    629 			if g.evMarkAssist != nil {
    630 				return fmt.Errorf("previous mark assist is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
    631 			}
    632 			g.evMarkAssist = ev
    633 		case EvGCMarkAssistDone:
    634 			// Unlike most events, mark assists can be in progress when a
    635 			// goroutine starts tracing, so we can't report an error here.
    636 			if g.evMarkAssist != nil {
    637 				g.evMarkAssist.Link = ev
    638 				g.evMarkAssist = nil
    639 			}
    640 		case EvGCSweepDone:
    641 			if p.evSweep == nil {
    642 				return fmt.Errorf("bogus sweeping end (offset %v, time %v)", ev.Off, ev.Ts)
    643 			}
    644 			p.evSweep.Link = ev
    645 			p.evSweep = nil
    646 		case EvGoWaiting:
    647 			if g.state != gRunnable {
    648 				return fmt.Errorf("g %v is not runnable before EvGoWaiting (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
    649 			}
    650 			g.state = gWaiting
    651 			g.ev = ev
    652 		case EvGoInSyscall:
    653 			if g.state != gRunnable {
    654 				return fmt.Errorf("g %v is not runnable before EvGoInSyscall (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
    655 			}
    656 			g.state = gWaiting
    657 			g.ev = ev
    658 		case EvGoCreate:
    659 			if err := checkRunning(p, g, ev, true); err != nil {
    660 				return err
    661 			}
    662 			if _, ok := gs[ev.Args[0]]; ok {
    663 				return fmt.Errorf("g %v already exists (offset %v, time %v)", ev.Args[0], ev.Off, ev.Ts)
    664 			}
    665 			gs[ev.Args[0]] = gdesc{state: gRunnable, ev: ev, evCreate: ev}
    666 		case EvGoStart, EvGoStartLabel:
    667 			if g.state != gRunnable {
    668 				return fmt.Errorf("g %v is not runnable before start (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
    669 			}
    670 			if p.g != 0 {
    671 				return fmt.Errorf("p %v is already running g %v while start g %v (offset %v, time %v)", ev.P, p.g, ev.G, ev.Off, ev.Ts)
    672 			}
    673 			g.state = gRunning
    674 			g.evStart = ev
    675 			p.g = ev.G
    676 			if g.evCreate != nil {
    677 				if ver < 1007 {
    678 					// +1 because symbolizer expects return pc.
    679 					ev.Stk = []*Frame{{PC: g.evCreate.Args[1] + 1}}
    680 				} else {
    681 					ev.StkID = g.evCreate.Args[1]
    682 				}
    683 				g.evCreate = nil
    684 			}
    685 
    686 			if g.ev != nil {
    687 				g.ev.Link = ev
    688 				g.ev = nil
    689 			}
    690 		case EvGoEnd, EvGoStop:
    691 			if err := checkRunning(p, g, ev, false); err != nil {
    692 				return err
    693 			}
    694 			g.evStart.Link = ev
    695 			g.evStart = nil
    696 			g.state = gDead
    697 			p.g = 0
    698 		case EvGoSched, EvGoPreempt:
    699 			if err := checkRunning(p, g, ev, false); err != nil {
    700 				return err
    701 			}
    702 			g.state = gRunnable
    703 			g.evStart.Link = ev
    704 			g.evStart = nil
    705 			p.g = 0
    706 			g.ev = ev
    707 		case EvGoUnblock:
    708 			if g.state != gRunning {
    709 				return fmt.Errorf("g %v is not running while unpark (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
    710 			}
    711 			if ev.P != TimerP && p.g != ev.G {
    712 				return fmt.Errorf("p %v is not running g %v while unpark (offset %v, time %v)", ev.P, ev.G, ev.Off, ev.Ts)
    713 			}
    714 			g1 := gs[ev.Args[0]]
    715 			if g1.state != gWaiting {
    716 				return fmt.Errorf("g %v is not waiting before unpark (offset %v, time %v)", ev.Args[0], ev.Off, ev.Ts)
    717 			}
    718 			if g1.ev != nil && g1.ev.Type == EvGoBlockNet && ev.P != TimerP {
    719 				ev.P = NetpollP
    720 			}
    721 			if g1.ev != nil {
    722 				g1.ev.Link = ev
    723 			}
    724 			g1.state = gRunnable
    725 			g1.ev = ev
    726 			gs[ev.Args[0]] = g1
    727 		case EvGoSysCall:
    728 			if err := checkRunning(p, g, ev, false); err != nil {
    729 				return err
    730 			}
    731 			g.ev = ev
    732 		case EvGoSysBlock:
    733 			if err := checkRunning(p, g, ev, false); err != nil {
    734 				return err
    735 			}
    736 			g.state = gWaiting
    737 			g.evStart.Link = ev
    738 			g.evStart = nil
    739 			p.g = 0
    740 		case EvGoSysExit:
    741 			if g.state != gWaiting {
    742 				return fmt.Errorf("g %v is not waiting during syscall exit (offset %v, time %v)", ev.G, ev.Off, ev.Ts)
    743 			}
    744 			if g.ev != nil && g.ev.Type == EvGoSysCall {
    745 				g.ev.Link = ev
    746 			}
    747 			g.state = gRunnable
    748 			g.ev = ev
    749 		case EvGoSleep, EvGoBlock, EvGoBlockSend, EvGoBlockRecv,
    750 			EvGoBlockSelect, EvGoBlockSync, EvGoBlockCond, EvGoBlockNet, EvGoBlockGC:
    751 			if err := checkRunning(p, g, ev, false); err != nil {
    752 				return err
    753 			}
    754 			g.state = gWaiting
    755 			g.ev = ev
    756 			g.evStart.Link = ev
    757 			g.evStart = nil
    758 			p.g = 0
    759 		}
    760 
    761 		gs[ev.G] = g
    762 		ps[ev.P] = p
    763 	}
    764 
    765 	// TODO(dvyukov): restore stacks for EvGoStart events.
    766 	// TODO(dvyukov): test that all EvGoStart events has non-nil Link.
    767 
    768 	return nil
    769 }
    770 
    771 // symbolize attaches func/file/line info to stack traces.
    772 func symbolize(events []*Event, bin string) error {
    773 	// First, collect and dedup all pcs.
    774 	pcs := make(map[uint64]*Frame)
    775 	for _, ev := range events {
    776 		for _, f := range ev.Stk {
    777 			pcs[f.PC] = nil
    778 		}
    779 	}
    780 
    781 	// Start addr2line.
    782 	cmd := exec.Command(goCmd(), "tool", "addr2line", bin)
    783 	in, err := cmd.StdinPipe()
    784 	if err != nil {
    785 		return fmt.Errorf("failed to pipe addr2line stdin: %v", err)
    786 	}
    787 	cmd.Stderr = os.Stderr
    788 	out, err := cmd.StdoutPipe()
    789 	if err != nil {
    790 		return fmt.Errorf("failed to pipe addr2line stdout: %v", err)
    791 	}
    792 	err = cmd.Start()
    793 	if err != nil {
    794 		return fmt.Errorf("failed to start addr2line: %v", err)
    795 	}
    796 	outb := bufio.NewReader(out)
    797 
    798 	// Write all pcs to addr2line.
    799 	// Need to copy pcs to an array, because map iteration order is non-deterministic.
    800 	var pcArray []uint64
    801 	for pc := range pcs {
    802 		pcArray = append(pcArray, pc)
    803 		_, err := fmt.Fprintf(in, "0x%x\n", pc-1)
    804 		if err != nil {
    805 			return fmt.Errorf("failed to write to addr2line: %v", err)
    806 		}
    807 	}
    808 	in.Close()
    809 
    810 	// Read in answers.
    811 	for _, pc := range pcArray {
    812 		fn, err := outb.ReadString('\n')
    813 		if err != nil {
    814 			return fmt.Errorf("failed to read from addr2line: %v", err)
    815 		}
    816 		file, err := outb.ReadString('\n')
    817 		if err != nil {
    818 			return fmt.Errorf("failed to read from addr2line: %v", err)
    819 		}
    820 		f := &Frame{PC: pc}
    821 		f.Fn = fn[:len(fn)-1]
    822 		f.File = file[:len(file)-1]
    823 		if colon := strings.LastIndex(f.File, ":"); colon != -1 {
    824 			ln, err := strconv.Atoi(f.File[colon+1:])
    825 			if err == nil {
    826 				f.File = f.File[:colon]
    827 				f.Line = ln
    828 			}
    829 		}
    830 		pcs[pc] = f
    831 	}
    832 	cmd.Wait()
    833 
    834 	// Replace frames in events array.
    835 	for _, ev := range events {
    836 		for i, f := range ev.Stk {
    837 			ev.Stk[i] = pcs[f.PC]
    838 		}
    839 	}
    840 
    841 	return nil
    842 }
    843 
    844 // readVal reads unsigned base-128 value from r.
    845 func readVal(r io.Reader, off0 int) (v uint64, off int, err error) {
    846 	off = off0
    847 	for i := 0; i < 10; i++ {
    848 		var buf [1]byte
    849 		var n int
    850 		n, err = r.Read(buf[:])
    851 		if err != nil || n != 1 {
    852 			return 0, 0, fmt.Errorf("failed to read trace at offset %d: read %v, error %v", off0, n, err)
    853 		}
    854 		off++
    855 		v |= uint64(buf[0]&0x7f) << (uint(i) * 7)
    856 		if buf[0]&0x80 == 0 {
    857 			return
    858 		}
    859 	}
    860 	return 0, 0, fmt.Errorf("bad value at offset 0x%x", off0)
    861 }
    862 
    863 // Print dumps events to stdout. For debugging.
    864 func Print(events []*Event) {
    865 	for _, ev := range events {
    866 		PrintEvent(ev)
    867 	}
    868 }
    869 
    870 // PrintEvent dumps the event to stdout. For debugging.
    871 func PrintEvent(ev *Event) {
    872 	desc := EventDescriptions[ev.Type]
    873 	fmt.Printf("%v %v p=%v g=%v off=%v", ev.Ts, desc.Name, ev.P, ev.G, ev.Off)
    874 	for i, a := range desc.Args {
    875 		fmt.Printf(" %v=%v", a, ev.Args[i])
    876 	}
    877 	fmt.Printf("\n")
    878 }
    879 
    880 // argNum returns total number of args for the event accounting for timestamps,
    881 // sequence numbers and differences between trace format versions.
    882 func argNum(raw rawEvent, ver int) int {
    883 	desc := EventDescriptions[raw.typ]
    884 	if raw.typ == EvStack {
    885 		return len(raw.args)
    886 	}
    887 	narg := len(desc.Args)
    888 	if desc.Stack {
    889 		narg++
    890 	}
    891 	switch raw.typ {
    892 	case EvBatch, EvFrequency, EvTimerGoroutine:
    893 		if ver < 1007 {
    894 			narg++ // there was an unused arg before 1.7
    895 		}
    896 		return narg
    897 	}
    898 	narg++ // timestamp
    899 	if ver < 1007 {
    900 		narg++ // sequence
    901 	}
    902 	switch raw.typ {
    903 	case EvGCSweepDone:
    904 		if ver < 1009 {
    905 			narg -= 2 // 1.9 added two arguments
    906 		}
    907 	case EvGCStart, EvGoStart, EvGoUnblock:
    908 		if ver < 1007 {
    909 			narg-- // 1.7 added an additional seq arg
    910 		}
    911 	case EvGCSTWStart:
    912 		if ver < 1010 {
    913 			narg-- // 1.10 added an argument
    914 		}
    915 	}
    916 	return narg
    917 }
    918 
    919 // BreakTimestampsForTesting causes the parser to randomly alter timestamps (for testing of broken cputicks).
    920 var BreakTimestampsForTesting bool
    921 
    922 // Event types in the trace.
    923 // Verbatim copy from src/runtime/trace.go with the "trace" prefix removed.
    924 const (
    925 	EvNone              = 0  // unused
    926 	EvBatch             = 1  // start of per-P batch of events [pid, timestamp]
    927 	EvFrequency         = 2  // contains tracer timer frequency [frequency (ticks per second)]
    928 	EvStack             = 3  // stack [stack id, number of PCs, array of {PC, func string ID, file string ID, line}]
    929 	EvGomaxprocs        = 4  // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack id]
    930 	EvProcStart         = 5  // start of P [timestamp, thread id]
    931 	EvProcStop          = 6  // stop of P [timestamp]
    932 	EvGCStart           = 7  // GC start [timestamp, seq, stack id]
    933 	EvGCDone            = 8  // GC done [timestamp]
    934 	EvGCSTWStart        = 9  // GC mark termination start [timestamp, kind]
    935 	EvGCSTWDone         = 10 // GC mark termination done [timestamp]
    936 	EvGCSweepStart      = 11 // GC sweep start [timestamp, stack id]
    937 	EvGCSweepDone       = 12 // GC sweep done [timestamp, swept, reclaimed]
    938 	EvGoCreate          = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
    939 	EvGoStart           = 14 // goroutine starts running [timestamp, goroutine id, seq]
    940 	EvGoEnd             = 15 // goroutine ends [timestamp]
    941 	EvGoStop            = 16 // goroutine stops (like in select{}) [timestamp, stack]
    942 	EvGoSched           = 17 // goroutine calls Gosched [timestamp, stack]
    943 	EvGoPreempt         = 18 // goroutine is preempted [timestamp, stack]
    944 	EvGoSleep           = 19 // goroutine calls Sleep [timestamp, stack]
    945 	EvGoBlock           = 20 // goroutine blocks [timestamp, stack]
    946 	EvGoUnblock         = 21 // goroutine is unblocked [timestamp, goroutine id, seq, stack]
    947 	EvGoBlockSend       = 22 // goroutine blocks on chan send [timestamp, stack]
    948 	EvGoBlockRecv       = 23 // goroutine blocks on chan recv [timestamp, stack]
    949 	EvGoBlockSelect     = 24 // goroutine blocks on select [timestamp, stack]
    950 	EvGoBlockSync       = 25 // goroutine blocks on Mutex/RWMutex [timestamp, stack]
    951 	EvGoBlockCond       = 26 // goroutine blocks on Cond [timestamp, stack]
    952 	EvGoBlockNet        = 27 // goroutine blocks on network [timestamp, stack]
    953 	EvGoSysCall         = 28 // syscall enter [timestamp, stack]
    954 	EvGoSysExit         = 29 // syscall exit [timestamp, goroutine id, seq, real timestamp]
    955 	EvGoSysBlock        = 30 // syscall blocks [timestamp]
    956 	EvGoWaiting         = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
    957 	EvGoInSyscall       = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
    958 	EvHeapAlloc         = 33 // memstats.heap_live change [timestamp, heap_alloc]
    959 	EvNextGC            = 34 // memstats.next_gc change [timestamp, next_gc]
    960 	EvTimerGoroutine    = 35 // denotes timer goroutine [timer goroutine id]
    961 	EvFutileWakeup      = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
    962 	EvString            = 37 // string dictionary entry [ID, length, string]
    963 	EvGoStartLocal      = 38 // goroutine starts running on the same P as the last event [timestamp, goroutine id]
    964 	EvGoUnblockLocal    = 39 // goroutine is unblocked on the same P as the last event [timestamp, goroutine id, stack]
    965 	EvGoSysExitLocal    = 40 // syscall exit on the same P as the last event [timestamp, goroutine id, real timestamp]
    966 	EvGoStartLabel      = 41 // goroutine starts running with label [timestamp, goroutine id, seq, label string id]
    967 	EvGoBlockGC         = 42 // goroutine blocks on GC assist [timestamp, stack]
    968 	EvGCMarkAssistStart = 43 // GC mark assist start [timestamp, stack]
    969 	EvGCMarkAssistDone  = 44 // GC mark assist done [timestamp]
    970 	EvCount             = 45
    971 )
    972 
    973 var EventDescriptions = [EvCount]struct {
    974 	Name       string
    975 	minVersion int
    976 	Stack      bool
    977 	Args       []string
    978 }{
    979 	EvNone:              {"None", 1005, false, []string{}},
    980 	EvBatch:             {"Batch", 1005, false, []string{"p", "ticks"}}, // in 1.5 format it was {"p", "seq", "ticks"}
    981 	EvFrequency:         {"Frequency", 1005, false, []string{"freq"}},   // in 1.5 format it was {"freq", "unused"}
    982 	EvStack:             {"Stack", 1005, false, []string{"id", "siz"}},
    983 	EvGomaxprocs:        {"Gomaxprocs", 1005, true, []string{"procs"}},
    984 	EvProcStart:         {"ProcStart", 1005, false, []string{"thread"}},
    985 	EvProcStop:          {"ProcStop", 1005, false, []string{}},
    986 	EvGCStart:           {"GCStart", 1005, true, []string{"seq"}}, // in 1.5 format it was {}
    987 	EvGCDone:            {"GCDone", 1005, false, []string{}},
    988 	EvGCSTWStart:        {"GCSTWStart", 1005, false, []string{"kind"}}, // <= 1.9, args was {} (implicitly {0})
    989 	EvGCSTWDone:         {"GCSTWDone", 1005, false, []string{}},
    990 	EvGCSweepStart:      {"GCSweepStart", 1005, true, []string{}},
    991 	EvGCSweepDone:       {"GCSweepDone", 1005, false, []string{"swept", "reclaimed"}}, // before 1.9, format was {}
    992 	EvGoCreate:          {"GoCreate", 1005, true, []string{"g", "stack"}},
    993 	EvGoStart:           {"GoStart", 1005, false, []string{"g", "seq"}}, // in 1.5 format it was {"g"}
    994 	EvGoEnd:             {"GoEnd", 1005, false, []string{}},
    995 	EvGoStop:            {"GoStop", 1005, true, []string{}},
    996 	EvGoSched:           {"GoSched", 1005, true, []string{}},
    997 	EvGoPreempt:         {"GoPreempt", 1005, true, []string{}},
    998 	EvGoSleep:           {"GoSleep", 1005, true, []string{}},
    999 	EvGoBlock:           {"GoBlock", 1005, true, []string{}},
   1000 	EvGoUnblock:         {"GoUnblock", 1005, true, []string{"g", "seq"}}, // in 1.5 format it was {"g"}
   1001 	EvGoBlockSend:       {"GoBlockSend", 1005, true, []string{}},
   1002 	EvGoBlockRecv:       {"GoBlockRecv", 1005, true, []string{}},
   1003 	EvGoBlockSelect:     {"GoBlockSelect", 1005, true, []string{}},
   1004 	EvGoBlockSync:       {"GoBlockSync", 1005, true, []string{}},
   1005 	EvGoBlockCond:       {"GoBlockCond", 1005, true, []string{}},
   1006 	EvGoBlockNet:        {"GoBlockNet", 1005, true, []string{}},
   1007 	EvGoSysCall:         {"GoSysCall", 1005, true, []string{}},
   1008 	EvGoSysExit:         {"GoSysExit", 1005, false, []string{"g", "seq", "ts"}},
   1009 	EvGoSysBlock:        {"GoSysBlock", 1005, false, []string{}},
   1010 	EvGoWaiting:         {"GoWaiting", 1005, false, []string{"g"}},
   1011 	EvGoInSyscall:       {"GoInSyscall", 1005, false, []string{"g"}},
   1012 	EvHeapAlloc:         {"HeapAlloc", 1005, false, []string{"mem"}},
   1013 	EvNextGC:            {"NextGC", 1005, false, []string{"mem"}},
   1014 	EvTimerGoroutine:    {"TimerGoroutine", 1005, false, []string{"g"}}, // in 1.5 format it was {"g", "unused"}
   1015 	EvFutileWakeup:      {"FutileWakeup", 1005, false, []string{}},
   1016 	EvString:            {"String", 1007, false, []string{}},
   1017 	EvGoStartLocal:      {"GoStartLocal", 1007, false, []string{"g"}},
   1018 	EvGoUnblockLocal:    {"GoUnblockLocal", 1007, true, []string{"g"}},
   1019 	EvGoSysExitLocal:    {"GoSysExitLocal", 1007, false, []string{"g", "ts"}},
   1020 	EvGoStartLabel:      {"GoStartLabel", 1008, false, []string{"g", "seq", "label"}},
   1021 	EvGoBlockGC:         {"GoBlockGC", 1008, true, []string{}},
   1022 	EvGCMarkAssistStart: {"GCMarkAssistStart", 1009, true, []string{}},
   1023 	EvGCMarkAssistDone:  {"GCMarkAssistDone", 1009, false, []string{}},
   1024 }
   1025