"fmt"
"internal/trace"
"internal/trace/raw"
- "internal/trace/tracev2/event"
+ "internal/trace/tracev2"
"internal/trace/traceviewer"
"io"
"log"
return err
}
type eventStats struct {
- typ event.Type
+ typ tracev2.EventType
count int
bytes int
}
var stats [256]eventStats
for i := range stats {
- stats[i].typ = event.Type(i)
+ stats[i].typ = tracev2.EventType(i)
}
eventsRead := 0
for {
internal/platform,
internal/profilerecord,
internal/syslist,
- internal/trace/tracev2/event,
+ internal/trace/tracev2,
internal/trace/traceviewer/format,
log/internal,
math/bits,
internal/goexperiment,
internal/goos,
internal/profilerecord,
+ internal/trace/tracev2,
math/bits,
structs
< internal/bytealg
< crypto/internal/fips140/check/checktest;
# v2 execution trace parser.
- internal/trace/tracev2/event
- < internal/trace/tracev2;
-
FMT, io, internal/trace/tracev2
< internal/trace/version;
FMT, encoding/binary, internal/trace/version
< internal/trace/raw;
- FMT, internal/trace/tracev2/event, internal/trace/version, io, sort, encoding/binary
+ FMT, internal/trace/version, io, sort, encoding/binary
< internal/trace/internal/tracev1;
FMT, encoding/binary, internal/trace/version, internal/trace/internal/tracev1, container/heap, math/rand
"strings"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
"internal/trace/version"
)
// baseEvent is the basic unprocessed event. This serves as a common
// fundamental data structure across.
type baseEvent struct {
- typ event.Type
+ typ tracev2.EventType
time Time
args timedEventArgs
}
nextExtra extraStringID
// expBatches contains extra unparsed data relevant to a specific experiment.
- expBatches map[event.Experiment][]ExperimentalBatch
+ expBatches map[tracev2.Experiment][]ExperimentalBatch
}
// addExtraString adds an extra string to the evTable and returns
"io"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
)
// timestamp is an unprocessed timestamp.
m ThreadID
time timestamp
data []byte
- exp event.Experiment
+ exp tracev2.Experiment
}
func (b *batch) isStringsBatch() bool {
- return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == tracev2.EvStrings
+ return b.exp == tracev2.NoExperiment && len(b.data) > 0 && tracev2.EventType(b.data[0]) == tracev2.EvStrings
}
func (b *batch) isStacksBatch() bool {
- return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == tracev2.EvStacks
+ return b.exp == tracev2.NoExperiment && len(b.data) > 0 && tracev2.EventType(b.data[0]) == tracev2.EvStacks
}
func (b *batch) isCPUSamplesBatch() bool {
- return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == tracev2.EvCPUSamples
+ return b.exp == tracev2.NoExperiment && len(b.data) > 0 && tracev2.EventType(b.data[0]) == tracev2.EvCPUSamples
}
func (b *batch) isFreqBatch() bool {
- return b.exp == event.NoExperiment && len(b.data) > 0 && event.Type(b.data[0]) == tracev2.EvFrequency
+ return b.exp == tracev2.NoExperiment && len(b.data) > 0 && tracev2.EventType(b.data[0]) == tracev2.EvFrequency
}
// readBatch reads the next full batch from r.
if err != nil {
return batch{}, 0, err
}
- if typ := event.Type(b); typ != tracev2.EvEventBatch && typ != tracev2.EvExperimentalBatch {
+ if typ := tracev2.EventType(b); typ != tracev2.EvEventBatch && typ != tracev2.EvExperimentalBatch {
return batch{}, 0, fmt.Errorf("expected batch event, got event %d", typ)
}
// Read the experiment of we have one.
- exp := event.NoExperiment
- if event.Type(b) == tracev2.EvExperimentalBatch {
+ exp := tracev2.NoExperiment
+ if tracev2.EventType(b) == tracev2.EvExperimentalBatch {
e, err := r.ReadByte()
if err != nil {
return batch{}, 0, err
}
- exp = event.Experiment(e)
+ exp = tracev2.Experiment(e)
}
// Read the batch header: gen (generation), thread (M) ID, base timestamp
"fmt"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
)
type batchCursor struct {
// be the case for every event in a plain EventBatch.
func readTimedBaseEvent(b []byte, e *baseEvent) (int, timestamp, error) {
// Get the event type.
- typ := event.Type(b[0])
+ typ := tracev2.EventType(b[0])
specs := tracev2.Specs()
if int(typ) >= len(specs) {
return 0, 0, fmt.Errorf("found invalid event type: %v", typ)
"time"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
"internal/trace/version"
)
}
}
-const evSync = ^event.Type(0)
+const evSync = ^tracev2.EventType(0)
var tracev2Type2Kind = [...]EventKind{
tracev2.EvCPUSample: EventStackSample,
"strings"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
)
// generation contains all the trace data for a single
return fmt.Errorf("found multiple frequency events")
}
g.freq = freq
- case b.exp != event.NoExperiment:
+ case b.exp != tracev2.NoExperiment:
if g.expBatches == nil {
- g.expBatches = make(map[event.Experiment][]ExperimentalBatch)
+ g.expBatches = make(map[tracev2.Experiment][]ExperimentalBatch)
}
if err := addExperimentalBatch(g.expBatches, b); err != nil {
return err
}
r := bytes.NewReader(b.data)
hdr, err := r.ReadByte() // Consume the EvStrings byte.
- if err != nil || event.Type(hdr) != tracev2.EvStrings {
+ if err != nil || tracev2.EventType(hdr) != tracev2.EvStrings {
return fmt.Errorf("missing strings batch header")
}
if err != nil {
return err
}
- if event.Type(ev) != tracev2.EvString {
+ if tracev2.EventType(ev) != tracev2.EvString {
return fmt.Errorf("expected string event, got %d", ev)
}
if err != nil {
return err
}
- if len > tracev2.MaxStringSize {
- return fmt.Errorf("invalid string size %d, maximum is %d", len, tracev2.MaxStringSize)
+ if len > tracev2.MaxEventTrailerDataSize {
+ return fmt.Errorf("invalid string size %d, maximum is %d", len, tracev2.MaxEventTrailerDataSize)
}
// Copy out the string.
}
r := bytes.NewReader(b.data)
hdr, err := r.ReadByte() // Consume the EvStacks byte.
- if err != nil || event.Type(hdr) != tracev2.EvStacks {
+ if err != nil || tracev2.EventType(hdr) != tracev2.EvStacks {
return fmt.Errorf("missing stacks batch header")
}
if err != nil {
return err
}
- if event.Type(ev) != tracev2.EvStack {
+ if tracev2.EventType(ev) != tracev2.EvStack {
return fmt.Errorf("expected stack event, got %d", ev)
}
}
r := bytes.NewReader(b.data)
hdr, err := r.ReadByte() // Consume the EvCPUSamples byte.
- if err != nil || event.Type(hdr) != tracev2.EvCPUSamples {
+ if err != nil || tracev2.EventType(hdr) != tracev2.EvCPUSamples {
return nil, fmt.Errorf("missing CPU samples batch header")
}
if err != nil {
return nil, err
}
- if event.Type(ev) != tracev2.EvCPUSample {
+ if tracev2.EventType(ev) != tracev2.EvCPUSample {
return nil, fmt.Errorf("expected CPU sample event, got %d", ev)
}
// addExperimentalBatch takes an experimental batch and adds it to the list of experimental
// batches for the experiment its a part of.
-func addExperimentalBatch(expBatches map[event.Experiment][]ExperimentalBatch, b batch) error {
- if b.exp == event.NoExperiment {
+func addExperimentalBatch(expBatches map[tracev2.Experiment][]ExperimentalBatch, b batch) error {
+ if b.exp == tracev2.NoExperiment {
return fmt.Errorf("internal error: addExperimentalBatch called on non-experimental batch")
}
expBatches[b.exp] = append(expBatches[b.exp], ExperimentalBatch{
"internal/trace"
"internal/trace/raw"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
"internal/trace/version"
"internal/txtar"
)
type Trace struct {
// Trace data state.
ver version.Version
- names map[string]event.Type
- specs []event.Spec
+ names map[string]tracev2.EventType
+ specs []tracev2.EventSpec
events []raw.Event
gens []*Generation
validTimestamps bool
// NewTrace creates a new trace.
func NewTrace(ver version.Version) *Trace {
return &Trace{
- names: event.Names(ver.Specs()),
+ names: tracev2.EventNames(ver.Specs()),
specs: ver.Specs(),
validTimestamps: true,
}
// RawEvent emits an event into the trace. name must correspond to one
// of the names in Specs() result for the version that was passed to
// this trace.
-func (t *Trace) RawEvent(typ event.Type, data []byte, args ...uint64) {
+func (t *Trace) RawEvent(typ tracev2.EventType, data []byte, args ...uint64) {
t.events = append(t.events, t.createEvent(typ, data, args...))
}
})
}
-func (t *Trace) createEvent(ev event.Type, data []byte, args ...uint64) raw.Event {
+func (t *Trace) createEvent(ev tracev2.EventType, data []byte, args ...uint64) raw.Event {
spec := t.specs[ev]
if ev != tracev2.EvStack {
if arity := len(spec.Args); len(args) != arity {
// RawEvent emits an event into a batch. name must correspond to one
// of the names in Specs() result for the version that was passed to
// this trace.
-func (b *Batch) RawEvent(typ event.Type, data []byte, args ...uint64) {
+func (b *Batch) RawEvent(typ tracev2.EventType, data []byte, args ...uint64) {
ev := b.gen.trace.createEvent(typ, data, args...)
// Compute the size of the event and add it to the batch.
"encoding/binary"
"errors"
"fmt"
- "internal/trace/tracev2/event"
"internal/trace/version"
"io"
"math"
// pointers, the latter so that the garbage collector won't have to scan any
// memory of our millions of events.
- Ts Timestamp // timestamp in nanoseconds
- G uint64 // G on which the event happened
- Args [4]uint64 // event-type-specific arguments
- StkID uint32 // unique stack ID
- P int32 // P on which the event happened (can be a real P or one of TimerP, NetpollP, SyscallP)
- Type event.Type // one of Ev*
+ Ts Timestamp // timestamp in nanoseconds
+ G uint64 // G on which the event happened
+ Args [4]uint64 // event-type-specific arguments
+ StkID uint32 // unique stack ID
+ P int32 // P on which the event happened (can be a real P or one of TimerP, NetpollP, SyscallP)
+ Type EventType // one of Ev*
}
// Frame is a frame in stack traces.
// rawEvent is a helper type used during parsing.
type rawEvent struct {
- typ event.Type
+ typ EventType
args []uint64
sargs []string
if !ok {
return io.EOF
}
- typ := event.Type(b << 2 >> 2)
+ typ := EventType(b << 2 >> 2)
// Most events have a timestamp before the actual arguments, so we add 1 and
// parse it like it's the first argument. EvString has a special format and
// the number of arguments doesn't matter. EvBatch writes '1' as the number
return narg
}
+type EventType uint8
+
// Event types in the trace.
// Verbatim copy from src/runtime/trace.go with the "trace" prefix removed.
const (
- EvNone event.Type = 0 // unused
- EvBatch event.Type = 1 // start of per-P batch of events [pid, timestamp]
- EvFrequency event.Type = 2 // contains tracer timer frequency [frequency (ticks per second)]
- EvStack event.Type = 3 // stack [stack id, number of PCs, array of {PC, func string ID, file string ID, line}]
- EvGomaxprocs event.Type = 4 // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack id]
- EvProcStart event.Type = 5 // start of P [timestamp, thread id]
- EvProcStop event.Type = 6 // stop of P [timestamp]
- EvGCStart event.Type = 7 // GC start [timestamp, seq, stack id]
- EvGCDone event.Type = 8 // GC done [timestamp]
- EvSTWStart event.Type = 9 // GC mark termination start [timestamp, kind]
- EvSTWDone event.Type = 10 // GC mark termination done [timestamp]
- EvGCSweepStart event.Type = 11 // GC sweep start [timestamp, stack id]
- EvGCSweepDone event.Type = 12 // GC sweep done [timestamp, swept, reclaimed]
- EvGoCreate event.Type = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
- EvGoStart event.Type = 14 // goroutine starts running [timestamp, goroutine id, seq]
- EvGoEnd event.Type = 15 // goroutine ends [timestamp]
- EvGoStop event.Type = 16 // goroutine stops (like in select{}) [timestamp, stack]
- EvGoSched event.Type = 17 // goroutine calls Gosched [timestamp, stack]
- EvGoPreempt event.Type = 18 // goroutine is preempted [timestamp, stack]
- EvGoSleep event.Type = 19 // goroutine calls Sleep [timestamp, stack]
- EvGoBlock event.Type = 20 // goroutine blocks [timestamp, stack]
- EvGoUnblock event.Type = 21 // goroutine is unblocked [timestamp, goroutine id, seq, stack]
- EvGoBlockSend event.Type = 22 // goroutine blocks on chan send [timestamp, stack]
- EvGoBlockRecv event.Type = 23 // goroutine blocks on chan recv [timestamp, stack]
- EvGoBlockSelect event.Type = 24 // goroutine blocks on select [timestamp, stack]
- EvGoBlockSync event.Type = 25 // goroutine blocks on Mutex/RWMutex [timestamp, stack]
- EvGoBlockCond event.Type = 26 // goroutine blocks on Cond [timestamp, stack]
- EvGoBlockNet event.Type = 27 // goroutine blocks on network [timestamp, stack]
- EvGoSysCall event.Type = 28 // syscall enter [timestamp, stack]
- EvGoSysExit event.Type = 29 // syscall exit [timestamp, goroutine id, seq, real timestamp]
- EvGoSysBlock event.Type = 30 // syscall blocks [timestamp]
- EvGoWaiting event.Type = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
- EvGoInSyscall event.Type = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
- EvHeapAlloc event.Type = 33 // gcController.heapLive change [timestamp, heap live bytes]
- EvHeapGoal event.Type = 34 // gcController.heapGoal change [timestamp, heap goal bytes]
- EvTimerGoroutine event.Type = 35 // denotes timer goroutine [timer goroutine id]
- EvFutileWakeup event.Type = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
- EvString event.Type = 37 // string dictionary entry [ID, length, string]
- EvGoStartLocal event.Type = 38 // goroutine starts running on the same P as the last event [timestamp, goroutine id]
- EvGoUnblockLocal event.Type = 39 // goroutine is unblocked on the same P as the last event [timestamp, goroutine id, stack]
- EvGoSysExitLocal event.Type = 40 // syscall exit on the same P as the last event [timestamp, goroutine id, real timestamp]
- EvGoStartLabel event.Type = 41 // goroutine starts running with label [timestamp, goroutine id, seq, label string id]
- EvGoBlockGC event.Type = 42 // goroutine blocks on GC assist [timestamp, stack]
- EvGCMarkAssistStart event.Type = 43 // GC mark assist start [timestamp, stack]
- EvGCMarkAssistDone event.Type = 44 // GC mark assist done [timestamp]
- EvUserTaskCreate event.Type = 45 // trace.NewTask [timestamp, internal task id, internal parent id, stack, name string]
- EvUserTaskEnd event.Type = 46 // end of task [timestamp, internal task id, stack]
- EvUserRegion event.Type = 47 // trace.WithRegion [timestamp, internal task id, mode(0:start, 1:end), name string]
- EvUserLog event.Type = 48 // trace.Log [timestamp, internal id, key string id, stack, value string]
- EvCPUSample event.Type = 49 // CPU profiling sample [timestamp, stack, real timestamp, real P id (-1 when absent), goroutine id]
- EvCount event.Type = 50
+ EvNone EventType = 0 // unused
+ EvBatch EventType = 1 // start of per-P batch of events [pid, timestamp]
+ EvFrequency EventType = 2 // contains tracer timer frequency [frequency (ticks per second)]
+ EvStack EventType = 3 // stack [stack id, number of PCs, array of {PC, func string ID, file string ID, line}]
+ EvGomaxprocs EventType = 4 // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack id]
+ EvProcStart EventType = 5 // start of P [timestamp, thread id]
+ EvProcStop EventType = 6 // stop of P [timestamp]
+ EvGCStart EventType = 7 // GC start [timestamp, seq, stack id]
+ EvGCDone EventType = 8 // GC done [timestamp]
+ EvSTWStart EventType = 9 // GC mark termination start [timestamp, kind]
+ EvSTWDone EventType = 10 // GC mark termination done [timestamp]
+ EvGCSweepStart EventType = 11 // GC sweep start [timestamp, stack id]
+ EvGCSweepDone EventType = 12 // GC sweep done [timestamp, swept, reclaimed]
+ EvGoCreate EventType = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
+ EvGoStart EventType = 14 // goroutine starts running [timestamp, goroutine id, seq]
+ EvGoEnd EventType = 15 // goroutine ends [timestamp]
+ EvGoStop EventType = 16 // goroutine stops (like in select{}) [timestamp, stack]
+ EvGoSched EventType = 17 // goroutine calls Gosched [timestamp, stack]
+ EvGoPreempt EventType = 18 // goroutine is preempted [timestamp, stack]
+ EvGoSleep EventType = 19 // goroutine calls Sleep [timestamp, stack]
+ EvGoBlock EventType = 20 // goroutine blocks [timestamp, stack]
+ EvGoUnblock EventType = 21 // goroutine is unblocked [timestamp, goroutine id, seq, stack]
+ EvGoBlockSend EventType = 22 // goroutine blocks on chan send [timestamp, stack]
+ EvGoBlockRecv EventType = 23 // goroutine blocks on chan recv [timestamp, stack]
+ EvGoBlockSelect EventType = 24 // goroutine blocks on select [timestamp, stack]
+ EvGoBlockSync EventType = 25 // goroutine blocks on Mutex/RWMutex [timestamp, stack]
+ EvGoBlockCond EventType = 26 // goroutine blocks on Cond [timestamp, stack]
+ EvGoBlockNet EventType = 27 // goroutine blocks on network [timestamp, stack]
+ EvGoSysCall EventType = 28 // syscall enter [timestamp, stack]
+ EvGoSysExit EventType = 29 // syscall exit [timestamp, goroutine id, seq, real timestamp]
+ EvGoSysBlock EventType = 30 // syscall blocks [timestamp]
+ EvGoWaiting EventType = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
+ EvGoInSyscall EventType = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
+ EvHeapAlloc EventType = 33 // gcController.heapLive change [timestamp, heap live bytes]
+ EvHeapGoal EventType = 34 // gcController.heapGoal change [timestamp, heap goal bytes]
+ EvTimerGoroutine EventType = 35 // denotes timer goroutine [timer goroutine id]
+ EvFutileWakeup EventType = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
+ EvString EventType = 37 // string dictionary entry [ID, length, string]
+ EvGoStartLocal EventType = 38 // goroutine starts running on the same P as the last event [timestamp, goroutine id]
+ EvGoUnblockLocal EventType = 39 // goroutine is unblocked on the same P as the last event [timestamp, goroutine id, stack]
+ EvGoSysExitLocal EventType = 40 // syscall exit on the same P as the last event [timestamp, goroutine id, real timestamp]
+ EvGoStartLabel EventType = 41 // goroutine starts running with label [timestamp, goroutine id, seq, label string id]
+ EvGoBlockGC EventType = 42 // goroutine blocks on GC assist [timestamp, stack]
+ EvGCMarkAssistStart EventType = 43 // GC mark assist start [timestamp, stack]
+ EvGCMarkAssistDone EventType = 44 // GC mark assist done [timestamp]
+ EvUserTaskCreate EventType = 45 // trace.NewTask [timestamp, internal task id, internal parent id, stack, name string]
+ EvUserTaskEnd EventType = 46 // end of task [timestamp, internal task id, stack]
+ EvUserRegion EventType = 47 // trace.WithRegion [timestamp, internal task id, mode(0:start, 1:end), name string]
+ EvUserLog EventType = 48 // trace.Log [timestamp, internal id, key string id, stack, value string]
+ EvCPUSample EventType = 49 // CPU profiling sample [timestamp, stack, real timestamp, real P id (-1 when absent), goroutine id]
+ EvCount EventType = 50
)
var EventDescriptions = [256]struct {
"strings"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
"internal/trace/version"
)
return ok, err
}
-func (o *ordering) evName(typ event.Type) string {
+func (o *ordering) evName(typ tracev2.EventType) string {
return o.traceVer.EventName(typ)
}
// they may have an optional subtype that describes the range
// in more detail.
type rangeType struct {
- typ event.Type // "Begin" event.
- desc stringID // Optional subtype.
+ typ tracev2.EventType // "Begin" event.
+ desc stringID // Optional subtype.
}
// makeRangeType constructs a new rangeType.
-func makeRangeType(typ event.Type, desc stringID) rangeType {
+func makeRangeType(typ tracev2.EventType, desc stringID) rangeType {
if styp := tracev2.Specs()[typ].StartEv; styp != tracev2.EvNone {
typ = styp
}
// endRange ends a special range in time on the goroutine.
//
// This must line up with the start event type of the range the goroutine is currently in.
-func (s *rangeState) endRange(typ event.Type) (stringID, error) {
+func (s *rangeState) endRange(typ tracev2.EventType) (stringID, error) {
st := tracev2.Specs()[typ].StartEv
idx := -1
for i, r := range s.inFlight {
// It's just a convenience function; it's always OK to construct
// an Event manually if this isn't quite the right way to express
// the contents of the event.
-func makeEvent(table *evTable, ctx schedCtx, typ event.Type, time Time, args ...uint64) Event {
+func makeEvent(table *evTable, ctx schedCtx, typ tracev2.EventType, time Time, args ...uint64) Event {
ev := Event{
table: table,
ctx: ctx,
"strconv"
"strings"
- "internal/trace/tracev2/event"
+ "internal/trace/tracev2"
"internal/trace/version"
)
// trace format's framing. (But not interpreted.)
type Event struct {
Version version.Version
- Ev event.Type
+ Ev tracev2.EventType
Args []uint64
Data []byte
}
"fmt"
"io"
- "internal/trace/tracev2/event"
+ "internal/trace/tracev2"
"internal/trace/version"
)
type Reader struct {
r *bufio.Reader
v version.Version
- specs []event.Spec
+ specs []tracev2.EventSpec
}
// NewReader creates a new reader for the trace wire format.
if int(evb) >= len(r.specs) || evb == 0 {
return Event{}, fmt.Errorf("invalid event type: %d", evb)
}
- ev := event.Type(evb)
+ ev := tracev2.EventType(evb)
spec := r.specs[ev]
args, err := r.readArgs(len(spec.Args))
if err != nil {
"strings"
"unicode"
- "internal/trace/tracev2/event"
+ "internal/trace/tracev2"
"internal/trace/version"
)
// into an event stream.
type TextReader struct {
v version.Version
- specs []event.Spec
- names map[string]event.Type
+ specs []tracev2.EventSpec
+ names map[string]tracev2.EventType
s *bufio.Scanner
}
}
tr.v = v
tr.specs = v.Specs()
- tr.names = event.Names(tr.specs)
+ tr.names = tracev2.EventNames(tr.specs)
for _, r := range line {
if !unicode.IsSpace(r) {
return nil, fmt.Errorf("encountered unexpected non-space at the end of the header: %q", line)
"fmt"
"io"
- "internal/trace/tracev2/event"
+ "internal/trace/tracev2"
"internal/trace/version"
)
w io.Writer
buf []byte
v version.Version
- specs []event.Spec
+ specs []tracev2.EventSpec
}
// NewWriter creates a new byte format writer.
"fmt"
"internal/trace/internal/tracev1"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
"io"
)
// encountering events that tracev1 shouldn't be able to emit, ocnvertEvent
// returns a descriptive error.
func (it *traceV1Converter) convertEvent(ev *tracev1.Event) (OUT Event, ERR error) {
- var mappedType event.Type
+ var mappedType tracev2.EventType
var mappedArgs timedEventArgs
copy(mappedArgs[:], ev.Args[:])
package tracev2
-import (
- "internal/trace/tracev2/event"
-)
-
+// Event types in the trace, args are given in square brackets.
+//
+// Naming scheme:
+// - Time range event pairs have suffixes "Begin" and "End".
+// - "Start", "Stop", "Create", "Destroy", "Block", "Unblock"
+// are suffixes reserved for scheduling resources.
+//
+// NOTE: If you add an event type, make sure you also update all
+// tables in this file!
const (
- EvNone event.Type = iota // unused
+ EvNone EventType = iota // unused
// Structural events.
EvEventBatch // start of per-M batch of events [generation, M ID, timestamp, batch length]
// Experiments.
const (
// AllocFree is the alloc-free events experiment.
- AllocFree event.Experiment = 1 + iota
+ AllocFree Experiment = 1 + iota
+
+ NumExperiments
)
func Experiments() []string {
}
var experiments = [...]string{
- AllocFree: "AllocFree",
+ NoExperiment: "None",
+ AllocFree: "AllocFree",
}
// Experimental events.
const (
- _ event.Type = 127 + iota
+ _ EventType = 127 + iota
// Experimental events for AllocFree.
EvGoroutineStackFree // stack free [timestamp, id]
)
-func Specs() []event.Spec {
+func Specs() []EventSpec {
return specs[:]
}
-var specs = [...]event.Spec{
+var specs = [...]EventSpec{
// "Structural" Events.
EvEventBatch: {
Name: "EventBatch",
},
}
+// GoStatus is the status of a goroutine.
+//
+// They correspond directly to the various goroutine states.
type GoStatus uint8
const (
return "Bad"
}
+// ProcStatus is the status of a P.
+//
+// They mostly correspond to the various P states.
type ProcStatus uint8
const (
ProcRunning
ProcIdle
ProcSyscall
+
+ // ProcSyscallAbandoned is a special case of
+ // ProcSyscall. It's used in the very specific case
+ // where the first a P is mentioned in a generation is
+ // part of a ProcSteal event. If that's the first time
+ // it's mentioned, then there's no GoSyscallBegin to
+ // connect the P stealing back to at that point. This
+ // special state indicates this to the parser, so it
+ // doesn't try to find a GoSyscallEndBlocked that
+ // corresponds with the ProcSteal.
ProcSyscallAbandoned
)
}
const (
- // Various format-specific constants.
- MaxBatchSize = 64 << 10
+ // MaxBatchSize sets the maximum size that a batch can be.
+ //
+ // Directly controls the trace batch size in the runtime.
+ //
+ // NOTE: If this number decreases, the trace format version must change.
+ MaxBatchSize = 64 << 10
+
+ // Maximum number of PCs in a single stack trace.
+ //
+ // Since events contain only stack ID rather than whole stack trace,
+ // we can allow quite large values here.
+ //
+ // Directly controls the maximum number of frames per stack
+ // in the runtime.
+ //
+ // NOTE: If this number decreases, the trace format version must change.
MaxFramesPerStack = 128
- MaxStringSize = 1 << 10
+
+ // MaxEventTrailerDataSize controls the amount of trailer data that
+ // an event can have in bytes. Must be smaller than MaxBatchSize.
+ // Controls the maximum string size in the trace.
+ //
+ // Directly controls the maximum such value in the runtime.
+ //
+ // NOTE: If this number decreases, the trace format version must change.
+ MaxEventTrailerDataSize = 1 << 10
)
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package event
+package tracev2
-// Type indicates an event's type from which its arguments and semantics can be
+// EventType indicates an event's type from which its arguments and semantics can be
// derived. Its representation matches the wire format's representation of the event
// types that precede all event data.
-type Type uint8
+type EventType uint8
-// Spec is a specification for a trace event. It contains sufficient information
+// EventSpec is a specification for a trace event. It contains sufficient information
// to perform basic parsing of any trace event for any version of Go.
-type Spec struct {
+type EventSpec struct {
// Name is the human-readable name of the trace event.
Name string
// StartEv indicates the event type of the corresponding "start"
// event, if this event is an "end," for a pair of events that
// represent a time range.
- StartEv Type
+ StartEv EventType
// IsTimedEvent indicates whether this is an event that both
// appears in the main event stream and is surfaced to the
Experiment Experiment
}
-// ArgTypes is a list of valid argument types for use in Args.
+// EventArgTypes is a list of valid argument types for use in Args.
//
// See the documentation of Args for more details.
-var ArgTypes = [...]string{
+var EventArgTypes = [...]string{
"seq", // sequence number
"pstatus", // P status
"gstatus", // G status
"task", // trace.TaskID
}
-// Names is a helper that produces a mapping of event names to event types.
-func Names(specs []Spec) map[string]Type {
- nameToType := make(map[string]Type)
+// EventNames is a helper that produces a mapping of event names to event types.
+func EventNames(specs []EventSpec) map[string]EventType {
+ nameToType := make(map[string]EventType)
for i, spec := range specs {
- nameToType[spec.Name] = Type(byte(i))
+ nameToType[spec.Name] = EventType(byte(i))
}
return nameToType
}
"io"
"internal/trace/tracev2"
- "internal/trace/tracev2/event"
)
// Version represents the version of a trace file.
Current = Go123
)
-var versions = map[Version][]event.Spec{
+var versions = map[Version][]tracev2.EventSpec{
// Go 1.11–1.21 use a different parser and are only set here for the sake of
// Version.Valid.
Go111: nil,
}
// Specs returns the set of event.Specs for this version.
-func (v Version) Specs() []event.Spec {
+func (v Version) Specs() []tracev2.EventSpec {
return versions[v]
}
// EventName returns a string name of a wire format event
// for a particular trace version.
-func (v Version) EventName(typ event.Type) string {
+func (v Version) EventName(typ tracev2.EventType) string {
if !v.Valid() {
return "<invalid trace version>"
}