Source file src/internal/trace/tracev2/events.go

     1  // Copyright 2023 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 tracev2
     6  
     7  // Event types in the trace, args are given in square brackets.
     8  //
     9  // Naming scheme:
    10  //   - Time range event pairs have suffixes "Begin" and "End".
    11  //   - "Start", "Stop", "Create", "Destroy", "Block", "Unblock"
    12  //     are suffixes reserved for scheduling resources.
    13  //
    14  // NOTE: If you add an event type, make sure you also update all
    15  // tables in this file!
    16  const (
    17  	EvNone EventType = iota // unused
    18  
    19  	// Structural events.
    20  	EvEventBatch // start of per-M batch of events [generation, M ID, timestamp, batch length]
    21  	EvStacks     // start of a section of the stack table [...EvStack]
    22  	EvStack      // stack table entry [ID, ...{PC, func string ID, file string ID, line #}]
    23  	EvStrings    // start of a section of the string dictionary [...EvString]
    24  	EvString     // string dictionary entry [ID, length, string]
    25  	EvCPUSamples // start of a section of CPU samples [...EvCPUSample]
    26  	EvCPUSample  // CPU profiling sample [timestamp, M ID, P ID, goroutine ID, stack ID]
    27  	EvFrequency  // timestamp units per sec [freq]
    28  
    29  	// Procs.
    30  	EvProcsChange // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack ID]
    31  	EvProcStart   // start of P [timestamp, P ID, P seq]
    32  	EvProcStop    // stop of P [timestamp]
    33  	EvProcSteal   // P was stolen [timestamp, P ID, P seq, M ID]
    34  	EvProcStatus  // P status at the start of a generation [timestamp, P ID, status]
    35  
    36  	// Goroutines.
    37  	EvGoCreate            // goroutine creation [timestamp, new goroutine ID, new stack ID, stack ID]
    38  	EvGoCreateSyscall     // goroutine appears in syscall (cgo callback) [timestamp, new goroutine ID]
    39  	EvGoStart             // goroutine starts running [timestamp, goroutine ID, goroutine seq]
    40  	EvGoDestroy           // goroutine ends [timestamp]
    41  	EvGoDestroySyscall    // goroutine ends in syscall (cgo callback) [timestamp]
    42  	EvGoStop              // goroutine yields its time, but is runnable [timestamp, reason, stack ID]
    43  	EvGoBlock             // goroutine blocks [timestamp, reason, stack ID]
    44  	EvGoUnblock           // goroutine is unblocked [timestamp, goroutine ID, goroutine seq, stack ID]
    45  	EvGoSyscallBegin      // syscall enter [timestamp, P seq, stack ID]
    46  	EvGoSyscallEnd        // syscall exit [timestamp]
    47  	EvGoSyscallEndBlocked // syscall exit and it blocked at some point [timestamp]
    48  	EvGoStatus            // goroutine status at the start of a generation [timestamp, goroutine ID, thread ID, status]
    49  
    50  	// STW.
    51  	EvSTWBegin // STW start [timestamp, kind]
    52  	EvSTWEnd   // STW done [timestamp]
    53  
    54  	// GC events.
    55  	EvGCActive           // GC active [timestamp, seq]
    56  	EvGCBegin            // GC start [timestamp, seq, stack ID]
    57  	EvGCEnd              // GC done [timestamp, seq]
    58  	EvGCSweepActive      // GC sweep active [timestamp, P ID]
    59  	EvGCSweepBegin       // GC sweep start [timestamp, stack ID]
    60  	EvGCSweepEnd         // GC sweep done [timestamp, swept bytes, reclaimed bytes]
    61  	EvGCMarkAssistActive // GC mark assist active [timestamp, goroutine ID]
    62  	EvGCMarkAssistBegin  // GC mark assist start [timestamp, stack ID]
    63  	EvGCMarkAssistEnd    // GC mark assist done [timestamp]
    64  	EvHeapAlloc          // gcController.heapLive change [timestamp, heap alloc in bytes]
    65  	EvHeapGoal           // gcController.heapGoal() change [timestamp, heap goal in bytes]
    66  
    67  	// Annotations.
    68  	EvGoLabel         // apply string label to current running goroutine [timestamp, label string ID]
    69  	EvUserTaskBegin   // trace.NewTask [timestamp, internal task ID, internal parent task ID, name string ID, stack ID]
    70  	EvUserTaskEnd     // end of a task [timestamp, internal task ID, stack ID]
    71  	EvUserRegionBegin // trace.{Start,With}Region [timestamp, internal task ID, name string ID, stack ID]
    72  	EvUserRegionEnd   // trace.{End,With}Region [timestamp, internal task ID, name string ID, stack ID]
    73  	EvUserLog         // trace.Log [timestamp, internal task ID, key string ID, value string ID, stack]
    74  
    75  	// Coroutines. Added in Go 1.23.
    76  	EvGoSwitch        // goroutine switch (coroswitch) [timestamp, goroutine ID, goroutine seq]
    77  	EvGoSwitchDestroy // goroutine switch and destroy [timestamp, goroutine ID, goroutine seq]
    78  	EvGoCreateBlocked // goroutine creation (starts blocked) [timestamp, new goroutine ID, new stack ID, stack ID]
    79  
    80  	// GoStatus with stack. Added in Go 1.23.
    81  	EvGoStatusStack // goroutine status at the start of a generation, with a stack [timestamp, goroutine ID, M ID, status, stack ID]
    82  
    83  	// Batch event for an experimental batch with a custom format. Added in Go 1.23.
    84  	EvExperimentalBatch // start of extra data [experiment ID, generation, M ID, timestamp, batch length, batch data...]
    85  
    86  	NumEvents
    87  )
    88  
    89  func (ev EventType) Experimental() bool {
    90  	return ev > MaxEvent && ev < MaxExperimentalEvent
    91  }
    92  
    93  // Experiments.
    94  const (
    95  	// AllocFree is the alloc-free events experiment.
    96  	AllocFree Experiment = 1 + iota
    97  
    98  	NumExperiments
    99  )
   100  
   101  func Experiments() []string {
   102  	return experiments[:]
   103  }
   104  
   105  var experiments = [...]string{
   106  	NoExperiment: "None",
   107  	AllocFree:    "AllocFree",
   108  }
   109  
   110  // Experimental events.
   111  const (
   112  	MaxEvent EventType = 127 + iota
   113  
   114  	// Experimental events for AllocFree.
   115  
   116  	// Experimental heap span events. Added in Go 1.23.
   117  	EvSpan      // heap span exists [timestamp, id, npages, type/class]
   118  	EvSpanAlloc // heap span alloc [timestamp, id, npages, type/class]
   119  	EvSpanFree  // heap span free [timestamp, id]
   120  
   121  	// Experimental heap object events. Added in Go 1.23.
   122  	EvHeapObject      // heap object exists [timestamp, id, type]
   123  	EvHeapObjectAlloc // heap object alloc [timestamp, id, type]
   124  	EvHeapObjectFree  // heap object free [timestamp, id]
   125  
   126  	// Experimental goroutine stack events. Added in Go 1.23.
   127  	EvGoroutineStack      // stack exists [timestamp, id, order]
   128  	EvGoroutineStackAlloc // stack alloc [timestamp, id, order]
   129  	EvGoroutineStackFree  // stack free [timestamp, id]
   130  
   131  	MaxExperimentalEvent
   132  )
   133  
   134  const NumExperimentalEvents = MaxExperimentalEvent - MaxEvent
   135  
   136  // MaxTimedEventArgs is the maximum number of arguments for timed events.
   137  const MaxTimedEventArgs = 5
   138  
   139  func Specs() []EventSpec {
   140  	return specs[:]
   141  }
   142  
   143  var specs = [...]EventSpec{
   144  	// "Structural" Events.
   145  	EvEventBatch: {
   146  		Name: "EventBatch",
   147  		Args: []string{"gen", "m", "time", "size"},
   148  	},
   149  	EvStacks: {
   150  		Name: "Stacks",
   151  	},
   152  	EvStack: {
   153  		Name:    "Stack",
   154  		Args:    []string{"id", "nframes"},
   155  		IsStack: true,
   156  	},
   157  	EvStrings: {
   158  		Name: "Strings",
   159  	},
   160  	EvString: {
   161  		Name:    "String",
   162  		Args:    []string{"id"},
   163  		HasData: true,
   164  	},
   165  	EvCPUSamples: {
   166  		Name: "CPUSamples",
   167  	},
   168  	EvCPUSample: {
   169  		Name: "CPUSample",
   170  		Args: []string{"time", "m", "p", "g", "stack"},
   171  		// N.B. There's clearly a timestamp here, but these Events
   172  		// are special in that they don't appear in the regular
   173  		// M streams.
   174  		StackIDs: []int{4},
   175  	},
   176  	EvFrequency: {
   177  		Name: "Frequency",
   178  		Args: []string{"freq"},
   179  	},
   180  	EvExperimentalBatch: {
   181  		Name:    "ExperimentalBatch",
   182  		Args:    []string{"exp", "gen", "m", "time"},
   183  		HasData: true, // Easier to represent for raw readers.
   184  	},
   185  
   186  	// "Timed" Events.
   187  	EvProcsChange: {
   188  		Name:         "ProcsChange",
   189  		Args:         []string{"dt", "procs_value", "stack"},
   190  		IsTimedEvent: true,
   191  		StackIDs:     []int{2},
   192  	},
   193  	EvProcStart: {
   194  		Name:         "ProcStart",
   195  		Args:         []string{"dt", "p", "p_seq"},
   196  		IsTimedEvent: true,
   197  	},
   198  	EvProcStop: {
   199  		Name:         "ProcStop",
   200  		Args:         []string{"dt"},
   201  		IsTimedEvent: true,
   202  	},
   203  	EvProcSteal: {
   204  		Name:         "ProcSteal",
   205  		Args:         []string{"dt", "p", "p_seq", "m"},
   206  		IsTimedEvent: true,
   207  	},
   208  	EvProcStatus: {
   209  		Name:         "ProcStatus",
   210  		Args:         []string{"dt", "p", "pstatus"},
   211  		IsTimedEvent: true,
   212  	},
   213  	EvGoCreate: {
   214  		Name:         "GoCreate",
   215  		Args:         []string{"dt", "new_g", "new_stack", "stack"},
   216  		IsTimedEvent: true,
   217  		StackIDs:     []int{3, 2},
   218  	},
   219  	EvGoCreateSyscall: {
   220  		Name:         "GoCreateSyscall",
   221  		Args:         []string{"dt", "new_g"},
   222  		IsTimedEvent: true,
   223  	},
   224  	EvGoStart: {
   225  		Name:         "GoStart",
   226  		Args:         []string{"dt", "g", "g_seq"},
   227  		IsTimedEvent: true,
   228  	},
   229  	EvGoDestroy: {
   230  		Name:         "GoDestroy",
   231  		Args:         []string{"dt"},
   232  		IsTimedEvent: true,
   233  	},
   234  	EvGoDestroySyscall: {
   235  		Name:         "GoDestroySyscall",
   236  		Args:         []string{"dt"},
   237  		IsTimedEvent: true,
   238  	},
   239  	EvGoStop: {
   240  		Name:         "GoStop",
   241  		Args:         []string{"dt", "reason_string", "stack"},
   242  		IsTimedEvent: true,
   243  		StackIDs:     []int{2},
   244  		StringIDs:    []int{1},
   245  	},
   246  	EvGoBlock: {
   247  		Name:         "GoBlock",
   248  		Args:         []string{"dt", "reason_string", "stack"},
   249  		IsTimedEvent: true,
   250  		StackIDs:     []int{2},
   251  		StringIDs:    []int{1},
   252  	},
   253  	EvGoUnblock: {
   254  		Name:         "GoUnblock",
   255  		Args:         []string{"dt", "g", "g_seq", "stack"},
   256  		IsTimedEvent: true,
   257  		StackIDs:     []int{3},
   258  	},
   259  	EvGoSyscallBegin: {
   260  		Name:         "GoSyscallBegin",
   261  		Args:         []string{"dt", "p_seq", "stack"},
   262  		IsTimedEvent: true,
   263  		StackIDs:     []int{2},
   264  	},
   265  	EvGoSyscallEnd: {
   266  		Name:         "GoSyscallEnd",
   267  		Args:         []string{"dt"},
   268  		StartEv:      EvGoSyscallBegin,
   269  		IsTimedEvent: true,
   270  	},
   271  	EvGoSyscallEndBlocked: {
   272  		Name:         "GoSyscallEndBlocked",
   273  		Args:         []string{"dt"},
   274  		StartEv:      EvGoSyscallBegin,
   275  		IsTimedEvent: true,
   276  	},
   277  	EvGoStatus: {
   278  		Name:         "GoStatus",
   279  		Args:         []string{"dt", "g", "m", "gstatus"},
   280  		IsTimedEvent: true,
   281  	},
   282  	EvSTWBegin: {
   283  		Name:         "STWBegin",
   284  		Args:         []string{"dt", "kind_string", "stack"},
   285  		IsTimedEvent: true,
   286  		StackIDs:     []int{2},
   287  		StringIDs:    []int{1},
   288  	},
   289  	EvSTWEnd: {
   290  		Name:         "STWEnd",
   291  		Args:         []string{"dt"},
   292  		StartEv:      EvSTWBegin,
   293  		IsTimedEvent: true,
   294  	},
   295  	EvGCActive: {
   296  		Name:         "GCActive",
   297  		Args:         []string{"dt", "gc_seq"},
   298  		IsTimedEvent: true,
   299  		StartEv:      EvGCBegin,
   300  	},
   301  	EvGCBegin: {
   302  		Name:         "GCBegin",
   303  		Args:         []string{"dt", "gc_seq", "stack"},
   304  		IsTimedEvent: true,
   305  		StackIDs:     []int{2},
   306  	},
   307  	EvGCEnd: {
   308  		Name:         "GCEnd",
   309  		Args:         []string{"dt", "gc_seq"},
   310  		StartEv:      EvGCBegin,
   311  		IsTimedEvent: true,
   312  	},
   313  	EvGCSweepActive: {
   314  		Name:         "GCSweepActive",
   315  		Args:         []string{"dt", "p"},
   316  		StartEv:      EvGCSweepBegin,
   317  		IsTimedEvent: true,
   318  	},
   319  	EvGCSweepBegin: {
   320  		Name:         "GCSweepBegin",
   321  		Args:         []string{"dt", "stack"},
   322  		IsTimedEvent: true,
   323  		StackIDs:     []int{1},
   324  	},
   325  	EvGCSweepEnd: {
   326  		Name:         "GCSweepEnd",
   327  		Args:         []string{"dt", "swept_value", "reclaimed_value"},
   328  		StartEv:      EvGCSweepBegin,
   329  		IsTimedEvent: true,
   330  	},
   331  	EvGCMarkAssistActive: {
   332  		Name:         "GCMarkAssistActive",
   333  		Args:         []string{"dt", "g"},
   334  		StartEv:      EvGCMarkAssistBegin,
   335  		IsTimedEvent: true,
   336  	},
   337  	EvGCMarkAssistBegin: {
   338  		Name:         "GCMarkAssistBegin",
   339  		Args:         []string{"dt", "stack"},
   340  		IsTimedEvent: true,
   341  		StackIDs:     []int{1},
   342  	},
   343  	EvGCMarkAssistEnd: {
   344  		Name:         "GCMarkAssistEnd",
   345  		Args:         []string{"dt"},
   346  		StartEv:      EvGCMarkAssistBegin,
   347  		IsTimedEvent: true,
   348  	},
   349  	EvHeapAlloc: {
   350  		Name:         "HeapAlloc",
   351  		Args:         []string{"dt", "heapalloc_value"},
   352  		IsTimedEvent: true,
   353  	},
   354  	EvHeapGoal: {
   355  		Name:         "HeapGoal",
   356  		Args:         []string{"dt", "heapgoal_value"},
   357  		IsTimedEvent: true,
   358  	},
   359  	EvGoLabel: {
   360  		Name:         "GoLabel",
   361  		Args:         []string{"dt", "label_string"},
   362  		IsTimedEvent: true,
   363  		StringIDs:    []int{1},
   364  	},
   365  	EvUserTaskBegin: {
   366  		Name:         "UserTaskBegin",
   367  		Args:         []string{"dt", "task", "parent_task", "name_string", "stack"},
   368  		IsTimedEvent: true,
   369  		StackIDs:     []int{4},
   370  		StringIDs:    []int{3},
   371  	},
   372  	EvUserTaskEnd: {
   373  		Name:         "UserTaskEnd",
   374  		Args:         []string{"dt", "task", "stack"},
   375  		IsTimedEvent: true,
   376  		StackIDs:     []int{2},
   377  	},
   378  	EvUserRegionBegin: {
   379  		Name:         "UserRegionBegin",
   380  		Args:         []string{"dt", "task", "name_string", "stack"},
   381  		IsTimedEvent: true,
   382  		StackIDs:     []int{3},
   383  		StringIDs:    []int{2},
   384  	},
   385  	EvUserRegionEnd: {
   386  		Name:         "UserRegionEnd",
   387  		Args:         []string{"dt", "task", "name_string", "stack"},
   388  		StartEv:      EvUserRegionBegin,
   389  		IsTimedEvent: true,
   390  		StackIDs:     []int{3},
   391  		StringIDs:    []int{2},
   392  	},
   393  	EvUserLog: {
   394  		Name:         "UserLog",
   395  		Args:         []string{"dt", "task", "key_string", "value_string", "stack"},
   396  		IsTimedEvent: true,
   397  		StackIDs:     []int{4},
   398  		StringIDs:    []int{2, 3},
   399  	},
   400  	EvGoSwitch: {
   401  		Name:         "GoSwitch",
   402  		Args:         []string{"dt", "g", "g_seq"},
   403  		IsTimedEvent: true,
   404  	},
   405  	EvGoSwitchDestroy: {
   406  		Name:         "GoSwitchDestroy",
   407  		Args:         []string{"dt", "g", "g_seq"},
   408  		IsTimedEvent: true,
   409  	},
   410  	EvGoCreateBlocked: {
   411  		Name:         "GoCreateBlocked",
   412  		Args:         []string{"dt", "new_g", "new_stack", "stack"},
   413  		IsTimedEvent: true,
   414  		StackIDs:     []int{3, 2},
   415  	},
   416  	EvGoStatusStack: {
   417  		Name:         "GoStatusStack",
   418  		Args:         []string{"dt", "g", "m", "gstatus", "stack"},
   419  		IsTimedEvent: true,
   420  		StackIDs:     []int{4},
   421  	},
   422  
   423  	// Experimental events.
   424  
   425  	EvSpan: {
   426  		Name:         "Span",
   427  		Args:         []string{"dt", "id", "npages_value", "kindclass"},
   428  		IsTimedEvent: true,
   429  		Experiment:   AllocFree,
   430  	},
   431  	EvSpanAlloc: {
   432  		Name:         "SpanAlloc",
   433  		Args:         []string{"dt", "id", "npages_value", "kindclass"},
   434  		IsTimedEvent: true,
   435  		Experiment:   AllocFree,
   436  	},
   437  	EvSpanFree: {
   438  		Name:         "SpanFree",
   439  		Args:         []string{"dt", "id"},
   440  		IsTimedEvent: true,
   441  		Experiment:   AllocFree,
   442  	},
   443  	EvHeapObject: {
   444  		Name:         "HeapObject",
   445  		Args:         []string{"dt", "id", "type"},
   446  		IsTimedEvent: true,
   447  		Experiment:   AllocFree,
   448  	},
   449  	EvHeapObjectAlloc: {
   450  		Name:         "HeapObjectAlloc",
   451  		Args:         []string{"dt", "id", "type"},
   452  		IsTimedEvent: true,
   453  		Experiment:   AllocFree,
   454  	},
   455  	EvHeapObjectFree: {
   456  		Name:         "HeapObjectFree",
   457  		Args:         []string{"dt", "id"},
   458  		IsTimedEvent: true,
   459  		Experiment:   AllocFree,
   460  	},
   461  	EvGoroutineStack: {
   462  		Name:         "GoroutineStack",
   463  		Args:         []string{"dt", "id", "order"},
   464  		IsTimedEvent: true,
   465  		Experiment:   AllocFree,
   466  	},
   467  	EvGoroutineStackAlloc: {
   468  		Name:         "GoroutineStackAlloc",
   469  		Args:         []string{"dt", "id", "order"},
   470  		IsTimedEvent: true,
   471  		Experiment:   AllocFree,
   472  	},
   473  	EvGoroutineStackFree: {
   474  		Name:         "GoroutineStackFree",
   475  		Args:         []string{"dt", "id"},
   476  		IsTimedEvent: true,
   477  		Experiment:   AllocFree,
   478  	},
   479  }
   480  
   481  // GoStatus is the status of a goroutine.
   482  //
   483  // They correspond directly to the various goroutine states.
   484  type GoStatus uint8
   485  
   486  const (
   487  	GoBad GoStatus = iota
   488  	GoRunnable
   489  	GoRunning
   490  	GoSyscall
   491  	GoWaiting
   492  )
   493  
   494  func (s GoStatus) String() string {
   495  	switch s {
   496  	case GoRunnable:
   497  		return "Runnable"
   498  	case GoRunning:
   499  		return "Running"
   500  	case GoSyscall:
   501  		return "Syscall"
   502  	case GoWaiting:
   503  		return "Waiting"
   504  	}
   505  	return "Bad"
   506  }
   507  
   508  // ProcStatus is the status of a P.
   509  //
   510  // They mostly correspond to the various P states.
   511  type ProcStatus uint8
   512  
   513  const (
   514  	ProcBad ProcStatus = iota
   515  	ProcRunning
   516  	ProcIdle
   517  	ProcSyscall
   518  
   519  	// ProcSyscallAbandoned is a special case of
   520  	// ProcSyscall. It's used in the very specific case
   521  	// where the first a P is mentioned in a generation is
   522  	// part of a ProcSteal event. If that's the first time
   523  	// it's mentioned, then there's no GoSyscallBegin to
   524  	// connect the P stealing back to at that point. This
   525  	// special state indicates this to the parser, so it
   526  	// doesn't try to find a GoSyscallEndBlocked that
   527  	// corresponds with the ProcSteal.
   528  	ProcSyscallAbandoned
   529  )
   530  
   531  func (s ProcStatus) String() string {
   532  	switch s {
   533  	case ProcRunning:
   534  		return "Running"
   535  	case ProcIdle:
   536  		return "Idle"
   537  	case ProcSyscall:
   538  		return "Syscall"
   539  	}
   540  	return "Bad"
   541  }
   542  
   543  const (
   544  	// MaxBatchSize sets the maximum size that a batch can be.
   545  	//
   546  	// Directly controls the trace batch size in the runtime.
   547  	//
   548  	// NOTE: If this number decreases, the trace format version must change.
   549  	MaxBatchSize = 64 << 10
   550  
   551  	// Maximum number of PCs in a single stack trace.
   552  	//
   553  	// Since events contain only stack ID rather than whole stack trace,
   554  	// we can allow quite large values here.
   555  	//
   556  	// Directly controls the maximum number of frames per stack
   557  	// in the runtime.
   558  	//
   559  	// NOTE: If this number decreases, the trace format version must change.
   560  	MaxFramesPerStack = 128
   561  
   562  	// MaxEventTrailerDataSize controls the amount of trailer data that
   563  	// an event can have in bytes. Must be smaller than MaxBatchSize.
   564  	// Controls the maximum string size in the trace.
   565  	//
   566  	// Directly controls the maximum such value in the runtime.
   567  	//
   568  	// NOTE: If this number decreases, the trace format version must change.
   569  	MaxEventTrailerDataSize = 1 << 10
   570  )
   571  

View as plain text