]> Cypherpunks repositories - gostls13.git/commitdiff
internal/trace: merge event and tracev2 packages
authorMichael Anthony Knyszek <mknyszek@google.com>
Wed, 29 Jan 2025 17:16:02 +0000 (17:16 +0000)
committerGopher Robot <gobot@golang.org>
Mon, 10 Feb 2025 20:14:51 +0000 (12:14 -0800)
These two packages were historically separate in an attempt to provide a
unified description of trace v1 and trace v2 formats. In practice this
turned out to be pointless, since it made more sense to keep the trace
v1 parser in a self-contained bubble with a converter to v2. Future
trace wire format migrations should probably just follow the same
general strategy, if there's a substantial change. (Minor changes can be
handled more organically.)

Change-Id: Ic765df62065fe53cfae59b505297527c3fa42dfb
Reviewed-on: https://go-review.googlesource.com/c/go/+/645395
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
18 files changed:
src/cmd/trace/main.go
src/go/build/deps_test.go
src/internal/trace/base.go
src/internal/trace/batch.go
src/internal/trace/batchcursor.go
src/internal/trace/event.go
src/internal/trace/generation.go
src/internal/trace/internal/testgen/trace.go
src/internal/trace/internal/tracev1/parser.go
src/internal/trace/order.go
src/internal/trace/raw/event.go
src/internal/trace/raw/reader.go
src/internal/trace/raw/textreader.go
src/internal/trace/raw/writer.go
src/internal/trace/tracev1.go
src/internal/trace/tracev2/events.go [moved from src/internal/trace/tracev2/event.go with 86% similarity]
src/internal/trace/tracev2/spec.go [moved from src/internal/trace/tracev2/event/event.go with 84% similarity]
src/internal/trace/version/version.go

index 625adb1c0c3d998233e0ba5fc36d04a73c2804d1..7786e02d00b2a7280e435faa9bb62efb00b9f362 100644 (file)
@@ -12,7 +12,7 @@ import (
        "fmt"
        "internal/trace"
        "internal/trace/raw"
-       "internal/trace/tracev2/event"
+       "internal/trace/tracev2"
        "internal/trace/traceviewer"
        "io"
        "log"
@@ -372,13 +372,13 @@ func debugEventsFootprint(trc io.Reader) error {
                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 {
index f2de39a0825f609195538fa282741529348ea29f..29773486dd81769d87eb7bb5884e0639aafb2b5a 100644 (file)
@@ -58,7 +58,7 @@ var depsRules = `
          internal/platform,
          internal/profilerecord,
          internal/syslist,
-         internal/trace/tracev2/event,
+         internal/trace/tracev2,
          internal/trace/traceviewer/format,
          log/internal,
          math/bits,
@@ -80,6 +80,7 @@ var depsRules = `
        internal/goexperiment,
        internal/goos,
        internal/profilerecord,
+       internal/trace/tracev2,
        math/bits,
        structs
        < internal/bytealg
@@ -699,16 +700,13 @@ var depsRules = `
        < 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
index c6cc08ff69464dda4cae10c2282a080b913018bc..5e11c6f0498a66fc19181613692b242115d0635a 100644 (file)
@@ -13,7 +13,6 @@ import (
        "strings"
 
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
        "internal/trace/version"
 )
 
@@ -28,7 +27,7 @@ type timedEventArgs [maxArgs - 1]uint64
 // 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
 }
@@ -59,7 +58,7 @@ type evTable struct {
        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
index 0dc87321a6936422984d8660aa5cc302568da888..58f18d63819c53179947b86033ee59cab4fd68d2 100644 (file)
@@ -11,7 +11,6 @@ import (
        "io"
 
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
 )
 
 // timestamp is an unprocessed timestamp.
@@ -23,23 +22,23 @@ type batch struct {
        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.
@@ -52,18 +51,18 @@ func readBatch(r interface {
        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
index 026f24f8b1ee61565f1b11c69a771ae018e9f7ac..8582f30bb06e8800e29d934b3f08665c44fb8cb3 100644 (file)
@@ -10,7 +10,6 @@ import (
        "fmt"
 
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
 )
 
 type batchCursor struct {
@@ -66,7 +65,7 @@ func (b *batchCursor) compare(a *batchCursor) int {
 // 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)
index fa1daf3698004d8032f7e886f2b741bff6155600..ebf8aaa97790baed89f4a509a0ae501c4eaf80a3 100644 (file)
@@ -12,7 +12,6 @@ import (
        "time"
 
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
        "internal/trace/version"
 )
 
@@ -693,7 +692,7 @@ func (e Event) Experimental() ExperimentalEvent {
        }
 }
 
-const evSync = ^event.Type(0)
+const evSync = ^tracev2.EventType(0)
 
 var tracev2Type2Kind = [...]EventKind{
        tracev2.EvCPUSample:           EventStackSample,
index 89d0f6509bbbafdba93acae8de3cfc872a2937a8..90a7f3b6c6bd0e5e1d0d4f1fb6e3409de6ea03d5 100644 (file)
@@ -15,7 +15,6 @@ import (
        "strings"
 
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
 )
 
 // generation contains all the trace data for a single
@@ -166,9 +165,9 @@ func processBatch(g *generation, b batch) error {
                        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
@@ -222,7 +221,7 @@ func addStrings(stringTable *dataTable[stringID, string], b batch) error {
        }
        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")
        }
 
@@ -233,7 +232,7 @@ func addStrings(stringTable *dataTable[stringID, string], b batch) error {
                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)
                }
 
@@ -248,8 +247,8 @@ func addStrings(stringTable *dataTable[stringID, string], b batch) error {
                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.
@@ -280,7 +279,7 @@ func addStacks(stackTable *dataTable[stackID, stack], pcs map[uint64]frame, b ba
        }
        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")
        }
 
@@ -290,7 +289,7 @@ func addStacks(stackTable *dataTable[stackID, stack], pcs map[uint64]frame, b ba
                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)
                }
 
@@ -358,7 +357,7 @@ func addCPUSamples(samples []cpuSample, b batch) ([]cpuSample, error) {
        }
        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")
        }
 
@@ -368,7 +367,7 @@ func addCPUSamples(samples []cpuSample, b batch) ([]cpuSample, error) {
                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)
                }
 
@@ -441,8 +440,8 @@ func parseFreq(b batch) (frequency, error) {
 
 // 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{
index 19d76d1367f6dfb51d54c458f54376156cca6246..0ae7e9924ed4d5b9e25a74a9f3818ae64d583e8c 100644 (file)
@@ -15,7 +15,6 @@ import (
        "internal/trace"
        "internal/trace/raw"
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
        "internal/trace/version"
        "internal/txtar"
 )
@@ -51,8 +50,8 @@ func Main(ver version.Version, f func(*Trace)) {
 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
@@ -65,7 +64,7 @@ type Trace struct {
 // 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,
        }
@@ -86,7 +85,7 @@ func (t *Trace) ExpectSuccess() {
 // 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...))
 }
 
@@ -146,7 +145,7 @@ func (t *Trace) Generate() []byte {
        })
 }
 
-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 {
@@ -362,7 +361,7 @@ func (b *Batch) uintArgFor(arg any, argSpec string) uint64 {
 // 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.
index b4ec7a342c8280bfd1d50b0d92e46d2dd998ba0e..d47de9088a992b302992ee1239bc9521b6793700 100644 (file)
@@ -17,7 +17,6 @@ import (
        "encoding/binary"
        "errors"
        "fmt"
-       "internal/trace/tracev2/event"
        "internal/trace/version"
        "io"
        "math"
@@ -36,12 +35,12 @@ type Event struct {
        // 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.
@@ -253,7 +252,7 @@ func (p *parser) parse() (Trace, error) {
 
 // rawEvent is a helper type used during parsing.
 type rawEvent struct {
-       typ   event.Type
+       typ   EventType
        args  []uint64
        sargs []string
 
@@ -643,7 +642,7 @@ func (p *parser) readRawEvent(flags uint, ev *rawEvent) error {
        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
@@ -1376,60 +1375,62 @@ func (raw *rawEvent) argNum() int {
        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 {
index 3e7ed8941b55e1c6a5a4bf4c8a874de0022a05ba..7b6075d56377320a0ad3060874976a84e2b38b22 100644 (file)
@@ -10,7 +10,6 @@ import (
        "strings"
 
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
        "internal/trace/version"
 )
 
@@ -89,7 +88,7 @@ func (o *ordering) Advance(ev *baseEvent, evt *evTable, m ThreadID, gen uint64)
        return ok, err
 }
 
-func (o *ordering) evName(typ event.Type) string {
+func (o *ordering) evName(typ tracev2.EventType) string {
        return o.traceVer.EventName(typ)
 }
 
@@ -1167,12 +1166,12 @@ type userRegion struct {
 // 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
        }
@@ -1266,7 +1265,7 @@ func (s *rangeState) hasRange(typ rangeType) bool {
 // 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 {
@@ -1386,7 +1385,7 @@ func (q *queue[T]) pop() (T, bool) {
 // 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,
index e3b6b5cd458f7cc7b953744ebd0f502a3da8243e..9042d3f2151eb49b6adc4e4904eca8284f4edb78 100644 (file)
@@ -9,7 +9,7 @@ import (
        "strconv"
        "strings"
 
-       "internal/trace/tracev2/event"
+       "internal/trace/tracev2"
        "internal/trace/version"
 )
 
@@ -20,7 +20,7 @@ import (
 // trace format's framing. (But not interpreted.)
 type Event struct {
        Version version.Version
-       Ev      event.Type
+       Ev      tracev2.EventType
        Args    []uint64
        Data    []byte
 }
index 3f90e2d454725d43855682d40c8dc2a16f6ac19e..af5dfac0e77a72b87c8124868afb73f2270e6a4c 100644 (file)
@@ -10,7 +10,7 @@ import (
        "fmt"
        "io"
 
-       "internal/trace/tracev2/event"
+       "internal/trace/tracev2"
        "internal/trace/version"
 )
 
@@ -19,7 +19,7 @@ import (
 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.
@@ -49,7 +49,7 @@ func (r *Reader) ReadEvent() (Event, error) {
        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 {
index 666db134f1a9d1617d99cd854f74078bb4ec7137..adb111550d1ee7eb67e8ee135709a1696ce70bc2 100644 (file)
@@ -12,7 +12,7 @@ import (
        "strings"
        "unicode"
 
-       "internal/trace/tracev2/event"
+       "internal/trace/tracev2"
        "internal/trace/version"
 )
 
@@ -20,8 +20,8 @@ import (
 // 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
 }
 
@@ -50,7 +50,7 @@ func NewTextReader(r io.Reader) (*TextReader, error) {
        }
        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)
index 971839b8d71fc34e2b1e5529872725a38c8c0936..6b7042cf2af101d399c58ba8e0abb2e665d8178b 100644 (file)
@@ -9,7 +9,7 @@ import (
        "fmt"
        "io"
 
-       "internal/trace/tracev2/event"
+       "internal/trace/tracev2"
        "internal/trace/version"
 )
 
@@ -23,7 +23,7 @@ type Writer struct {
        w     io.Writer
        buf   []byte
        v     version.Version
-       specs []event.Spec
+       specs []tracev2.EventSpec
 }
 
 // NewWriter creates a new byte format writer.
index 9c2a1ebc14c6b50a8507bd941f1080d59d20a27e..667d7be1cd1b4b5b0c4aa19f03f495066bba9b9b 100644 (file)
@@ -32,7 +32,6 @@ import (
        "fmt"
        "internal/trace/internal/tracev1"
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
        "io"
 )
 
@@ -253,7 +252,7 @@ var errSkip = errors.New("skip event")
 // 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[:])
 
similarity index 86%
rename from src/internal/trace/tracev2/event.go
rename to src/internal/trace/tracev2/events.go
index 308ae679e977a018fac8918cc91710553c558cb1..778ef8d005b9ed37bfa28bf6ce61c6b8dd3c6bfb 100644 (file)
@@ -4,12 +4,17 @@
 
 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]
@@ -82,7 +87,9 @@ const (
 // Experiments.
 const (
        // AllocFree is the alloc-free events experiment.
-       AllocFree event.Experiment = 1 + iota
+       AllocFree Experiment = 1 + iota
+
+       NumExperiments
 )
 
 func Experiments() []string {
@@ -90,12 +97,13 @@ 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.
 
@@ -115,11 +123,11 @@ const (
        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",
@@ -456,6 +464,9 @@ var specs = [...]event.Spec{
        },
 }
 
+// GoStatus is the status of a goroutine.
+//
+// They correspond directly to the various goroutine states.
 type GoStatus uint8
 
 const (
@@ -480,6 +491,9 @@ func (s GoStatus) String() string {
        return "Bad"
 }
 
+// ProcStatus is the status of a P.
+//
+// They mostly correspond to the various P states.
 type ProcStatus uint8
 
 const (
@@ -487,6 +501,16 @@ 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
 )
 
@@ -503,8 +527,30 @@ func (s ProcStatus) String() string {
 }
 
 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
 )
similarity index 84%
rename from src/internal/trace/tracev2/event/event.go
rename to src/internal/trace/tracev2/spec.go
index b8b6af00533231d0935226501cf27e4db5fedb68..3ea3c5988908b409e223eef4cef03b3992491ea2 100644 (file)
@@ -2,16 +2,16 @@
 // 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
 
@@ -42,7 +42,7 @@ type Spec struct {
        // 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
@@ -72,10 +72,10 @@ type Spec struct {
        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
@@ -88,11 +88,11 @@ var ArgTypes = [...]string{
        "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
 }
index 50a674bd234cdb3d26c6a3f41f1e2049887d73e1..8c460734cef2684701294f868d63a4e2e46f1640 100644 (file)
@@ -9,7 +9,6 @@ import (
        "io"
 
        "internal/trace/tracev2"
-       "internal/trace/tracev2/event"
 )
 
 // Version represents the version of a trace file.
@@ -24,7 +23,7 @@ const (
        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,
@@ -36,13 +35,13 @@ var versions = map[Version][]event.Spec{
 }
 
 // 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>"
        }