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