// Copyright 2023 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package go122 import ( "fmt" "internal/trace/event" ) const ( EvNone event.Type = iota // unused // Structural events. EvEventBatch // start of per-M batch of events [generation, M ID, timestamp, batch length] EvStacks // start of a section of the stack table [...EvStack] EvStack // stack table entry [ID, ...{PC, func string ID, file string ID, line #}] EvStrings // start of a section of the string dictionary [...EvString] EvString // string dictionary entry [ID, length, string] EvCPUSamples // start of a section of CPU samples [...EvCPUSample] EvCPUSample // CPU profiling sample [timestamp, M ID, P ID, goroutine ID, stack ID] EvFrequency // timestamp units per sec [freq] // Procs. EvProcsChange // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack ID] EvProcStart // start of P [timestamp, P ID, P seq] EvProcStop // stop of P [timestamp] EvProcSteal // P was stolen [timestamp, P ID, P seq, M ID] EvProcStatus // P status at the start of a generation [timestamp, P ID, status] // Goroutines. EvGoCreate // goroutine creation [timestamp, new goroutine ID, new stack ID, stack ID] EvGoCreateSyscall // goroutine appears in syscall (cgo callback) [timestamp, new goroutine ID] EvGoStart // goroutine starts running [timestamp, goroutine ID, goroutine seq] EvGoDestroy // goroutine ends [timestamp] EvGoDestroySyscall // goroutine ends in syscall (cgo callback) [timestamp] EvGoStop // goroutine yields its time, but is runnable [timestamp, reason, stack ID] EvGoBlock // goroutine blocks [timestamp, reason, stack ID] EvGoUnblock // goroutine is unblocked [timestamp, goroutine ID, goroutine seq, stack ID] EvGoSyscallBegin // syscall enter [timestamp, P seq, stack ID] EvGoSyscallEnd // syscall exit [timestamp] EvGoSyscallEndBlocked // syscall exit and it blocked at some point [timestamp] EvGoStatus // goroutine status at the start of a generation [timestamp, goroutine ID, thread ID, status] // STW. EvSTWBegin // STW start [timestamp, kind] EvSTWEnd // STW done [timestamp] // GC events. EvGCActive // GC active [timestamp, seq] EvGCBegin // GC start [timestamp, seq, stack ID] EvGCEnd // GC done [timestamp, seq] EvGCSweepActive // GC sweep active [timestamp, P ID] EvGCSweepBegin // GC sweep start [timestamp, stack ID] EvGCSweepEnd // GC sweep done [timestamp, swept bytes, reclaimed bytes] EvGCMarkAssistActive // GC mark assist active [timestamp, goroutine ID] EvGCMarkAssistBegin // GC mark assist start [timestamp, stack ID] EvGCMarkAssistEnd // GC mark assist done [timestamp] EvHeapAlloc // gcController.heapLive change [timestamp, heap alloc in bytes] EvHeapGoal // gcController.heapGoal() change [timestamp, heap goal in bytes] // Annotations. EvGoLabel // apply string label to current running goroutine [timestamp, label string ID] EvUserTaskBegin // trace.NewTask [timestamp, internal task ID, internal parent task ID, name string ID, stack ID] EvUserTaskEnd // end of a task [timestamp, internal task ID, stack ID] EvUserRegionBegin // trace.{Start,With}Region [timestamp, internal task ID, name string ID, stack ID] EvUserRegionEnd // trace.{End,With}Region [timestamp, internal task ID, name string ID, stack ID] EvUserLog // trace.Log [timestamp, internal task ID, key string ID, value string ID, stack] // Coroutines. Added in Go 1.23. EvGoSwitch // goroutine switch (coroswitch) [timestamp, goroutine ID, goroutine seq] EvGoSwitchDestroy // goroutine switch and destroy [timestamp, goroutine ID, goroutine seq] EvGoCreateBlocked // goroutine creation (starts blocked) [timestamp, new goroutine ID, new stack ID, stack ID] // GoStatus with stack. Added in Go 1.23. EvGoStatusStack // goroutine status at the start of a generation, with a stack [timestamp, goroutine ID, M ID, status, stack ID] // Batch event for an experimental batch with a custom format. Added in Go 1.23. EvExperimentalBatch // start of extra data [experiment ID, generation, M ID, timestamp, batch length, batch data...] ) // Experiments. const ( // AllocFree is the alloc-free events experiment. AllocFree event.Experiment = 1 + iota ) // Experimental events. const ( _ event.Type = 127 + iota // Experimental events for AllocFree. // Experimental heap span events. Added in Go 1.23. EvSpan // heap span exists [timestamp, id, npages, type/class] EvSpanAlloc // heap span alloc [timestamp, id, npages, type/class] EvSpanFree // heap span free [timestamp, id] // Experimental heap object events. Added in Go 1.23. EvHeapObject // heap object exists [timestamp, id, type] EvHeapObjectAlloc // heap object alloc [timestamp, id, type] EvHeapObjectFree // heap object free [timestamp, id] // Experimental goroutine stack events. Added in Go 1.23. EvGoroutineStack // stack exists [timestamp, id, order] EvGoroutineStackAlloc // stack alloc [timestamp, id, order] EvGoroutineStackFree // stack free [timestamp, id] ) // EventString returns the name of a Go 1.22 event. func EventString(typ event.Type) string { if int(typ) < len(specs) { return specs[typ].Name } return fmt.Sprintf("Invalid(%d)", typ) } func Specs() []event.Spec { return specs[:] } var specs = [...]event.Spec{ // "Structural" Events. EvEventBatch: event.Spec{ Name: "EventBatch", Args: []string{"gen", "m", "time", "size"}, }, EvStacks: event.Spec{ Name: "Stacks", }, EvStack: event.Spec{ Name: "Stack", Args: []string{"id", "nframes"}, IsStack: true, }, EvStrings: event.Spec{ Name: "Strings", }, EvString: event.Spec{ Name: "String", Args: []string{"id"}, HasData: true, }, EvCPUSamples: event.Spec{ Name: "CPUSamples", }, EvCPUSample: event.Spec{ Name: "CPUSample", Args: []string{"time", "m", "p", "g", "stack"}, // N.B. There's clearly a timestamp here, but these Events // are special in that they don't appear in the regular // M streams. }, EvFrequency: event.Spec{ Name: "Frequency", Args: []string{"freq"}, }, EvExperimentalBatch: event.Spec{ Name: "ExperimentalBatch", Args: []string{"exp", "gen", "m", "time"}, HasData: true, // Easier to represent for raw readers. }, // "Timed" Events. EvProcsChange: event.Spec{ Name: "ProcsChange", Args: []string{"dt", "procs_value", "stack"}, IsTimedEvent: true, StackIDs: []int{2}, }, EvProcStart: event.Spec{ Name: "ProcStart", Args: []string{"dt", "p", "p_seq"}, IsTimedEvent: true, }, EvProcStop: event.Spec{ Name: "ProcStop", Args: []string{"dt"}, IsTimedEvent: true, }, EvProcSteal: event.Spec{ Name: "ProcSteal", Args: []string{"dt", "p", "p_seq", "m"}, IsTimedEvent: true, }, EvProcStatus: event.Spec{ Name: "ProcStatus", Args: []string{"dt", "p", "pstatus"}, IsTimedEvent: true, }, EvGoCreate: event.Spec{ Name: "GoCreate", Args: []string{"dt", "new_g", "new_stack", "stack"}, IsTimedEvent: true, StackIDs: []int{3, 2}, }, EvGoCreateSyscall: event.Spec{ Name: "GoCreateSyscall", Args: []string{"dt", "new_g"}, IsTimedEvent: true, }, EvGoStart: event.Spec{ Name: "GoStart", Args: []string{"dt", "g", "g_seq"}, IsTimedEvent: true, }, EvGoDestroy: event.Spec{ Name: "GoDestroy", Args: []string{"dt"}, IsTimedEvent: true, }, EvGoDestroySyscall: event.Spec{ Name: "GoDestroySyscall", Args: []string{"dt"}, IsTimedEvent: true, }, EvGoStop: event.Spec{ Name: "GoStop", Args: []string{"dt", "reason_string", "stack"}, IsTimedEvent: true, StackIDs: []int{2}, StringIDs: []int{1}, }, EvGoBlock: event.Spec{ Name: "GoBlock", Args: []string{"dt", "reason_string", "stack"}, IsTimedEvent: true, StackIDs: []int{2}, StringIDs: []int{1}, }, EvGoUnblock: event.Spec{ Name: "GoUnblock", Args: []string{"dt", "g", "g_seq", "stack"}, IsTimedEvent: true, StackIDs: []int{3}, }, EvGoSyscallBegin: event.Spec{ Name: "GoSyscallBegin", Args: []string{"dt", "p_seq", "stack"}, IsTimedEvent: true, StackIDs: []int{2}, }, EvGoSyscallEnd: event.Spec{ Name: "GoSyscallEnd", Args: []string{"dt"}, StartEv: EvGoSyscallBegin, IsTimedEvent: true, }, EvGoSyscallEndBlocked: event.Spec{ Name: "GoSyscallEndBlocked", Args: []string{"dt"}, StartEv: EvGoSyscallBegin, IsTimedEvent: true, }, EvGoStatus: event.Spec{ Name: "GoStatus", Args: []string{"dt", "g", "m", "gstatus"}, IsTimedEvent: true, }, EvSTWBegin: event.Spec{ Name: "STWBegin", Args: []string{"dt", "kind_string", "stack"}, IsTimedEvent: true, StackIDs: []int{2}, StringIDs: []int{1}, }, EvSTWEnd: event.Spec{ Name: "STWEnd", Args: []string{"dt"}, StartEv: EvSTWBegin, IsTimedEvent: true, }, EvGCActive: event.Spec{ Name: "GCActive", Args: []string{"dt", "gc_seq"}, IsTimedEvent: true, StartEv: EvGCBegin, }, EvGCBegin: event.Spec{ Name: "GCBegin", Args: []string{"dt", "gc_seq", "stack"}, IsTimedEvent: true, StackIDs: []int{2}, }, EvGCEnd: event.Spec{ Name: "GCEnd", Args: []string{"dt", "gc_seq"}, StartEv: EvGCBegin, IsTimedEvent: true, }, EvGCSweepActive: event.Spec{ Name: "GCSweepActive", Args: []string{"dt", "p"}, StartEv: EvGCSweepBegin, IsTimedEvent: true, }, EvGCSweepBegin: event.Spec{ Name: "GCSweepBegin", Args: []string{"dt", "stack"}, IsTimedEvent: true, StackIDs: []int{1}, }, EvGCSweepEnd: event.Spec{ Name: "GCSweepEnd", Args: []string{"dt", "swept_value", "reclaimed_value"}, StartEv: EvGCSweepBegin, IsTimedEvent: true, }, EvGCMarkAssistActive: event.Spec{ Name: "GCMarkAssistActive", Args: []string{"dt", "g"}, StartEv: EvGCMarkAssistBegin, IsTimedEvent: true, }, EvGCMarkAssistBegin: event.Spec{ Name: "GCMarkAssistBegin", Args: []string{"dt", "stack"}, IsTimedEvent: true, StackIDs: []int{1}, }, EvGCMarkAssistEnd: event.Spec{ Name: "GCMarkAssistEnd", Args: []string{"dt"}, StartEv: EvGCMarkAssistBegin, IsTimedEvent: true, }, EvHeapAlloc: event.Spec{ Name: "HeapAlloc", Args: []string{"dt", "heapalloc_value"}, IsTimedEvent: true, }, EvHeapGoal: event.Spec{ Name: "HeapGoal", Args: []string{"dt", "heapgoal_value"}, IsTimedEvent: true, }, EvGoLabel: event.Spec{ Name: "GoLabel", Args: []string{"dt", "label_string"}, IsTimedEvent: true, StringIDs: []int{1}, }, EvUserTaskBegin: event.Spec{ Name: "UserTaskBegin", Args: []string{"dt", "task", "parent_task", "name_string", "stack"}, IsTimedEvent: true, StackIDs: []int{4}, StringIDs: []int{3}, }, EvUserTaskEnd: event.Spec{ Name: "UserTaskEnd", Args: []string{"dt", "task", "stack"}, IsTimedEvent: true, StackIDs: []int{2}, }, EvUserRegionBegin: event.Spec{ Name: "UserRegionBegin", Args: []string{"dt", "task", "name_string", "stack"}, IsTimedEvent: true, StackIDs: []int{3}, StringIDs: []int{2}, }, EvUserRegionEnd: event.Spec{ Name: "UserRegionEnd", Args: []string{"dt", "task", "name_string", "stack"}, StartEv: EvUserRegionBegin, IsTimedEvent: true, StackIDs: []int{3}, StringIDs: []int{2}, }, EvUserLog: event.Spec{ Name: "UserLog", Args: []string{"dt", "task", "key_string", "value_string", "stack"}, IsTimedEvent: true, StackIDs: []int{4}, StringIDs: []int{2, 3}, }, EvGoSwitch: event.Spec{ Name: "GoSwitch", Args: []string{"dt", "g", "g_seq"}, IsTimedEvent: true, }, EvGoSwitchDestroy: event.Spec{ Name: "GoSwitchDestroy", Args: []string{"dt", "g", "g_seq"}, IsTimedEvent: true, }, EvGoCreateBlocked: event.Spec{ Name: "GoCreateBlocked", Args: []string{"dt", "new_g", "new_stack", "stack"}, IsTimedEvent: true, StackIDs: []int{3, 2}, }, EvGoStatusStack: event.Spec{ Name: "GoStatusStack", Args: []string{"dt", "g", "m", "gstatus", "stack"}, IsTimedEvent: true, StackIDs: []int{4}, }, // Experimental events. EvSpan: event.Spec{ Name: "Span", Args: []string{"dt", "id", "npages_value", "kindclass"}, IsTimedEvent: true, Experiment: AllocFree, }, EvSpanAlloc: event.Spec{ Name: "SpanAlloc", Args: []string{"dt", "id", "npages_value", "kindclass"}, IsTimedEvent: true, Experiment: AllocFree, }, EvSpanFree: event.Spec{ Name: "SpanFree", Args: []string{"dt", "id"}, IsTimedEvent: true, Experiment: AllocFree, }, EvHeapObject: event.Spec{ Name: "HeapObject", Args: []string{"dt", "id", "type"}, IsTimedEvent: true, Experiment: AllocFree, }, EvHeapObjectAlloc: event.Spec{ Name: "HeapObjectAlloc", Args: []string{"dt", "id", "type"}, IsTimedEvent: true, Experiment: AllocFree, }, EvHeapObjectFree: event.Spec{ Name: "HeapObjectFree", Args: []string{"dt", "id"}, IsTimedEvent: true, Experiment: AllocFree, }, EvGoroutineStack: event.Spec{ Name: "GoroutineStack", Args: []string{"dt", "id", "order"}, IsTimedEvent: true, Experiment: AllocFree, }, EvGoroutineStackAlloc: event.Spec{ Name: "GoroutineStackAlloc", Args: []string{"dt", "id", "order"}, IsTimedEvent: true, Experiment: AllocFree, }, EvGoroutineStackFree: event.Spec{ Name: "GoroutineStackFree", Args: []string{"dt", "id"}, IsTimedEvent: true, Experiment: AllocFree, }, } type GoStatus uint8 const ( GoBad GoStatus = iota GoRunnable GoRunning GoSyscall GoWaiting ) func (s GoStatus) String() string { switch s { case GoRunnable: return "Runnable" case GoRunning: return "Running" case GoSyscall: return "Syscall" case GoWaiting: return "Waiting" } return "Bad" } type ProcStatus uint8 const ( ProcBad ProcStatus = iota ProcRunning ProcIdle ProcSyscall ProcSyscallAbandoned ) func (s ProcStatus) String() string { switch s { case ProcRunning: return "Running" case ProcIdle: return "Idle" case ProcSyscall: return "Syscall" } return "Bad" } const ( // Various format-specific constants. MaxBatchSize = 64 << 10 MaxFramesPerStack = 128 MaxStringSize = 1 << 10 )