A standalone Go library for working with User Statically-Defined Tracepoints (USDTs). Parse USDT probes from ELF binaries, extract argument specifications, and attach eBPF programs to probes at runtime.
- ELF probe parsing: Read
.note.stapsdtsections, apply prelink adjustments, convert virtual addresses to file offsets for uprobe attachment - Argument spec parsing: Decode USDT argument specifications (registers, memory dereferences, constants) for x86_64 and ARM64
- eBPF headers: BPF-side helpers for extracting USDT arguments at runtime (
BPF_USDT()macro,bpf_usdt_arg()) - bpf2go integration: Pre-compiled eBPF objects with generated Go bindings via
go generate - Pluggable ELF reader: Interface-based design lets you use
debug/elf(included) or bring your own optimized reader
go get github.com/parca-dev/usdtprobes, err := usdt.ParseProbesFromFile("/usr/lib/libc.so.6")
if err != nil {
log.Fatal(err)
}
for _, p := range probes {
fmt.Printf("%s:%s at offset 0x%x args=%q\n",
p.Provider, p.Name, p.Location, p.Arguments)
}// Parse a USDT argument string like "-4@%esi 8@%rdi"
spec, err := usdt.ParseUSDTArguments("-4@%esi 8@%rdi")
if err != nil {
log.Fatal(err)
}
fmt.Printf("%d arguments\n", spec.Arg_cnt)Implement the ELFReader interface to use your own ELF parser:
type ELFReader interface {
Sections() ([]usdt.ELFSection, error)
LoadSegments() []usdt.ELFProg
}
probes, err := usdt.ParseProbes(myCustomReader)Include in your BPF programs for USDT argument extraction:
#include "usdt_args.h"
SEC("usdt/myprovider/myprobe")
int BPF_USDT(myprobe, s64 arg0, u64 arg1)
{
// arg0 and arg1 are automatically extracted
return 0;
}# Generate eBPF objects and run tests
make
# Regenerate after modifying BPF sources
make generate
# Run tests only
make test- Go 1.25+
- clang (for
go generate/ bpf2go BPF compilation) systemtap-sdt-dev(for test probes, providessys/sdt.h)- Requires Linux 5.15+ for bpf_get_attach_cookie
Apache License 2.0. See LICENSE for details.