Appendix: Glossary and References
Originally published in Japanese at https://zenn.dev/ymotongpoo/books/go-ebpf-primer/viewer/99-glossary_references.
Glossary
This glossary is a quick reference for the terms in this book. The parentheses after each term give the chapter that covers it in the most detail. If you start from a Hurdle chapter and meet a term that you don’t know, this list points back to the chapter that explains it.
Computing basics
- Bits and bytes: The smallest unit of information, which is 0 or 1, and a group of 8 of them. One byte represents 0 through 255 (Chapter 2).
- Memory: A sequence of bytes, each one with a numbered address. You read and write memory by number, not by name (Chapter 2).
- Address: The serial number of one cell of memory. It is a plain number, and most tools print it in hexadecimal (Chapter 2).
- Hexadecimal: The notation for numbers that starts with
0x. Two digits stand for exactly one byte (Chapter 2). - Instructions and machine code: The smallest units of work that a CPU can perform, and the byte sequences that represent them. Instructions also live in memory and have addresses (Chapters 2 and 4).
- PC (program counter): The register that holds the address of the next instruction to execute. Its formal name is RIP (Chapter 2).
- Register: A fast storage location inside the CPU. amd64 has 16 general-purpose registers, each 64 bits wide (Chapter 2).
- SP (stack pointer): The register that points to the top of the stack, which is the last location pushed. Its formal name is RSP. At the first instruction of a function, it points at the return address that the preceding
CALLpushed (Chapters 2 and 5, Hurdle 1). - Pointer: A variable whose value is an address (Chapter 2).
- Field offset: The number of bytes from the start of a struct to a field.
unsafe.Offsetofreturns it (Chapter 2, Hurdle 3). - Padding: The unused bytes that the compiler inserts into a struct to align its fields (Chapter 2).
The OS and the kernel
- Kernel: The core of the OS. It operates the hardware, isolates processes from each other, and schedules them (Chapter 3).
- Process: One running program’s worth of state. The kernel tells processes apart by PID and gives each one its own virtual address space (Chapter 3).
- Virtual addresses and virtual memory: A private sequence of addresses that the kernel prepares for each process. The kernel maps those addresses onto physical memory (Chapter 3).
- Text segment, data segment, heap, stack: The regions of an address space. They hold machine code, global variables, dynamic allocations, and the working area for function calls, in that order (Chapter 3).
- User space and kernel space: The division that follows the CPU’s privilege levels. Applications run on the restricted side, which is user space (Chapter 3).
- System call: A request from user space to the kernel. The call switches the privilege level (Chapter 3).
- Thread: The unit of execution that the kernel manages. Threads in one process share the address space, and each one has its own stack (Chapter 3).
- ASLR: A security mechanism that randomizes the placement of the stack and the heap on each launch (Chapter 3). In a Go binary, the runtime separately picks the base of the heap at random.
- Escape analysis: The analysis that the Go compiler runs to decide whether a value goes on the stack or the heap (Chapter 3).
Executables
- Compiling and linking: The step that turns source code into machine code, and the step that combines the parts into one executable and fixes the addresses (Chapter 4).
- Static linking and dynamic linking: The method that embeds libraries into the executable, and the method that binds to shared libraries at run time (Chapter 4).
- Disassembly: Turning machine-code byte sequences back into instruction notation that a person can read.
go tool objdumpdoes this (Chapter 4). - Symbol table: A table that maps names to addresses. It lives in the ELF
.symtabsection, andgo tool nmprints it (Chapter 4). - ELF and sections: The Linux executable format, and the divisions inside it such as
.textand.rodata(Chapter 4). .gopclntab: A Go-specific table that maps instruction addresses to function names and line numbers. The runtime uses it for stack traces on panic, and even-s -wdoes not remove it (Chapters 4 and 14).- DWARF: Debug information that records types, field offsets, and line numbers. It lives in the
.debug_*sections, and-wremoves it (Chapter 4, Hurdle 3). - Build info: A blob that records the Go version and the list of dependency modules.
go version -mreads it (Chapter 4, Hurdle 3). - Page: The fixed-size unit, usually 4KB, that the mapping table for virtual memory uses. The kernel loads and replaces physical memory one page at a time (Chapter 4).
- Copy-on-write: The kernel mechanism that serves a write to a read-only shared page. The kernel makes a copy private to that process and repoints the mapping table at the copy (Chapters 4 and 7).
Function calls
- Stack frame: The working area that one function call pushes onto the stack (Chapter 5).
- Last in, first out (LIFO): The order in which the last thing pushed comes off first. A function returns in the reverse of the order you called it, so the stack only ever works this way (Chapter 5).
- Return address: The address of the instruction after the call, which
CALLpushes onto the stack.RETpops it and jumps there. At the first instruction of the function,SPpoints at that slot (Chapter 5, Hurdle 1). - Calling convention: The agreement on where arguments and return values go. One form passes arguments on the stack, and the other passes them in registers (Chapter 5, Hurdle 2).
- Inlining: A compiler optimization that replaces a call to a small function with the body of that function. The
CALLinstruction disappears with it (Chapter 5). //go:noinline: A compiler directive that forbids inlining. I use it in this book’s experiments to keep the observation target in place (Chapter 5).
The Go runtime
- Runtime: The execution support machinery that ships inside every Go binary. It performs its own scheduling and memory management (Chapter 6).
- goroutine: The unit of execution that the Go runtime manages. The kernel cannot see it (Chapter 6).
- g, m, p: Runtime-internal structs that represent a goroutine, an OS thread, and the resources needed to run Go code, respectively (Chapter 6).
- Movable stack: The property that a goroutine’s stack relocates to a different region when it grows (Chapter 6, Hurdle 1).
- ABIInternal: The calling convention Go uses internally. The name dates to Go 1.12; on amd64 it passes arguments in registers from Go 1.17 (Hurdle 2).
- ABI0: The stable calling convention for calls out of assembly. It passes arguments on the stack, and a wrapper sits between it and ABIInternal (Hurdle 2).
- R14: The register that, on amd64, always points at the current goroutine’s
gstruct (Hurdle 2).
eBPF and OBI
- eBPF: The Linux mechanism for running small user-written programs safely inside the kernel (Chapter 7).
- Verifier: The mechanism that statically analyzes an eBPF program before the kernel loads it, and guarantees termination and memory safety (Chapter 7).
- Map: A key-value store that the kernel manages and that eBPF programs and user space share (Chapter 7).
- uprobe and uretprobe: A probe that the kernel places at an instruction address, and a mechanism that catches the return of a function. The kernel places a uprobe by replacing one byte with a breakpoint instruction. It places a uretprobe by rewriting the return address on the stack at function entry (Chapter 7, Hurdle 1).
- Trampoline: The kernel-side code that a uretprobe writes onto the stack in place of the return address (Hurdle 1).
- cilium/ebpf: The de facto Go library for loading and attaching eBPF programs (Chapter 7).
- Ring buffer: A shared buffer that passes events from the kernel to user space (Chapter 8).
- OBI: OpenTelemetry eBPF Instrumentation. An eBPF auto-instrumentation tool that descends from Beyla (Chapter 8).
- Zero-code instrumentation: Adding observation points from the outside, without changing the application’s code (Chapter 1).
- Protocol instrumentation: A language-independent instrumentation path that interprets the byte sequence flowing through a socket as a protocol (Chapter 8).
offsets.json: OBI’s table of field offsets for each version of Go and of the libraries (Hurdle 3).bpf_probe_write_user: The eBPF helper that rewrites user-space memory in the target process (Hurdle 4).
Distributed tracing
- Instrumentation: Adding observation points that record processing times and call relationships (Chapter 1).
- Distributed trace, trace ID, span: The record of one operation that spans several services, the identifier of that record, and one segment of it (Chapter 1).
- traceparent: The W3C standard header that carries the trace ID and the span ID over HTTP (Chapter 1, Hurdle 4).
- Backend: The server that collects telemetry records and displays them (Chapter 1).
- Context propagation: Carrying a trace’s identifying information across process and service boundaries (Hurdle 4).
- OTLP: OpenTelemetry’s standard protocol for transporting telemetry (Chapter 8).
References
OBI
- OpenTelemetry eBPF Instrumentation (OBI): https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation
- Official OBI documentation: https://opentelemetry.io/docs/zero-code/obi/
- OBI distributed traces documentation: https://opentelemetry.io/docs/zero-code/obi/distributed-traces/
- Support status overview (
SUPPORT_MATRIX.md): https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/blob/main/SUPPORT_MATRIX.md - Context propagation design notes (
devdocs/context-propagation.md): https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/blob/main/devdocs/context-propagation.md
This book cites the following locations in the OBI source.
| Topic | File |
|---|---|
Searching for RET instructions | pkg/internal/goexec/instructions_amd64.go |
| ELF parsing and locating moduledata | pkg/internal/goexec/instructions.go |
| Attaching uprobes | pkg/ebpf/instrumenter.go |
Macros for argument registers and the g pointer | bpf/bpfcore/utils.h |
| goroutine identifiers | bpf/common/go_addr_key.h |
| Parent-child tracking of goroutines | bpf/gotracer/go_runtime.c, bpf/gotracer/go_common.h |
| Header injection | bpf/gotracer/go_nethttp.c |
| Offset resolution and reading build info | pkg/internal/goexec/structmembers.go, pkg/internal/goexec/gofile.go |
| Offset table | pkg/internal/goexec/offsets.json |
| List of instrumented symbols | pkg/internal/ebpf/gotracer/gotracer.go |
Upstream Go
- golang/go#22008 (runtime: ebpf uretprobe support): https://github.com/golang/go/issues/22008
- golang/go#27077 (report of
fatal error: unknown caller pcwhen attaching a uprobe, closed): https://github.com/golang/go/issues/27077 - golang/go#73798 (proposal for a goroutine start hook, not planned): https://github.com/golang/go/issues/73798
- golang/go#63185 (runtime/trace flight recorder, Go 1.25): https://github.com/golang/go/issues/63185
- Go 1.17 Release Notes (register-based calling convention): https://go.dev/doc/go1.17
- Go internal ABI specification: https://github.com/golang/go/blob/master/src/cmd/compile/abi-internal.md
- open-telemetry/opentelemetry-go-compile-instrumentation (the Compile-Time Instrumentation SIG,
otelc): https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation - Announcing v1 of OpenTelemetry Go Compile-Time Instrumentation: https://opentelemetry.io/blog/2026/go-compile-time-instrumentation-v1/
eBPF
- cilium/ebpf (the Go loader library): https://github.com/cilium/ebpf
Talk
- Go Conference 2026, “Behind the Scenes of OpenTelemetry eBPF Instrumentation” (in Japanese): https://gocon.jp/2026/timetable/1263399/
The program output in this book includes values, such as addresses, that change from run to run. The start of Chapter 1 lists the versions of Go, OBI, and the kernel that I used to check the results.