Stacktraces and Runtime Metadata
Stacktraces and Runtime Metadata
Overview
A stack trace is not magic: the compiler and linker freeze metadata into the binary; the runtime unwinds live frames using that data. Reflect uses a sibling idea—type descriptors instead of PC→func maps.
Companion read: Internals for Interns — Stacktraces.
Diagram: build time vs run time
regions: build time | run time
flow:
[Unwind]
|
v
[Meta]
[Unwind]
|
v
[Frames]
Who prints stacks
| Trigger | Behavior |
|---|---|
| panic | dump (controlled by GOTRACEBACK) |
runtime.Stack |
buffer of current or all Gs |
pprof goroutine |
stacks of live Gs |
| SIGQUIT (often) | all-G dump |
GOTRACEBACK=all ./appInlining and wrappers
Optimized binaries inline functions; traces may show fewer frames or wrapper names. Disable inlining for forensics:
go build -gcflags='-l' .Relation to profiling
CPU profiles sample stacks with the same unwinding family of mechanisms (222).
Experiment
package main
import (
"fmt"
"runtime"
)
func deep(n int) {
if n == 0 {
buf := make([]byte, 4096)
k := runtime.Stack(buf, false)
fmt.Printf("%s", buf[:k])
return
}
deep(n - 1)
}
func main() { deep(5) }What to notice: Frames list deep repeatedly with decreasing depth.
Try next: Compare stacks with and without -gcflags=-l.