bubblepprof

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 11, 2026 License: BSD-3-Clause Imports: 5 Imported by: 0

Documentation

Index

Constants

View Source
const MemUsageBundlePath = "/debug/memusage/bundle"

MemUsageBundlePath is the canonical path under which BundleHandler is expected to be mounted.

View Source
const MemUsagePath = "/debug/memusage"

MemUsagePath is the canonical path under which MemUsageHandler is expected to be mounted.

Variables

This section is empty.

Functions

func BundleHandler added in v0.2.0

func BundleHandler() http.Handler

BundleHandler returns an http.Handler that serves GET /debug/memusage/bundle with default options. The response is a tar stream ("bundle") containing a heap dump of the current process, a snapshot of its read-only memory segments, and metadata — the input for the external analyser (the bubblepprof CLI), which runs the same analysis as the in-process /debug/memusage endpoint without spending the target's CPU and memory on it.

Security: a bundle contains the full heap dump and read-only program memory of the process — strictly more sensitive than the /debug/memusage JSON response and equivalent to /debug/pprof heap and goroutine dumps. Protect this endpoint with the same authentication and network controls you apply to /debug/pprof. It must never be exposed to untrusted callers.

Performance: each request triggers a stop-the-world heap dump, but no parsing or graph analysis happens in-process; the target only streams files. The handler enforces single in-flight execution — concurrent callers receive 429.

func BundleHandlerWithOptions added in v0.2.0

func BundleHandlerWithOptions(opts BundleOptions) http.Handler

BundleHandlerWithOptions returns an http.Handler with the supplied BundleOptions. The zero value mirrors BundleHandler(). See BundleHandler for security and performance notes.

func MemUsageHandler

func MemUsageHandler() http.Handler

MemUsageHandler returns an http.Handler that serves POST /debug/memusage with the default configuration: GC runs before the heap dump and system/background goroutines are excluded from label matching.

On each request the handler stops all goroutines, captures a full heap dump, parses it lazily without retaining object contents, recovers pprof labels directly from heap-dump runtime state, builds a process-wide reachability graph, and returns the heap memory reachable from goroutines whose recovered labels contain every requested key/value pair.

Security: this endpoint is equivalent in sensitivity to /debug/pprof. A single call can expose pprof label values (which may include tenant IDs, job identifiers, or other runtime metadata) and heap size breakdowns. Protect it with the same authentication and network controls you apply to /debug/pprof. It should never be exposed to untrusted callers.

Performance: each request triggers a stop-the-world heap dump. Latency for the caller is proportional to live heap size. The handler enforces single in-flight execution — concurrent callers receive 429.

Label compatibility: profiled code should use the standard runtime/pprof API directly. No bubblepprof wrapper is required:

pprof.Do(ctx, pprof.Labels("job", "42"), func(ctx context.Context) {
    runJob(ctx)
})

Known limitations: heap-native label recovery is verified for go1.24.*–go1.26.* on Linux, macOS, Windows, and FreeBSD for little-endian 64-bit (amd64, arm64) and 32-bit (arm, 386) families; go1.27-devel (tip) is experimental. On unsupported runtime versions the endpoint returns HTTP 422 with code "unsupported_runtime". When pprof label strings reside outside heap object contents (common for string literals), the in-process reader is consulted on Linux, macOS, FreeBSD, and Windows; on FreeBSD the reader requires procfs mounted at /proc OR a non-PIE binary (the ELF fallback assumes static PT_LOAD Vaddrs). On other platforms — or on a FreeBSD host where neither FreeBSD condition holds, or when DisableProcessMemoryReader is set — the endpoint may return 422 with code "string_missing". Other structural label recovery failures return 422 with code "label_recovery_failed".

func MemUsageHandlerWithOptions

func MemUsageHandlerWithOptions(opts MemUsageOptions) http.Handler

MemUsageHandlerWithOptions returns an http.Handler with the supplied MemUsageOptions. The zero value of MemUsageOptions mirrors MemUsageHandler(). See MemUsageHandler for security and performance notes.

func Register added in v0.2.0

func Register(mux *http.ServeMux)

Register mounts both debugging endpoints on mux with default options:

POST /debug/memusage        — in-process analysis (MemUsageHandler)
GET  /debug/memusage/bundle — capture artifact for the external
                              analyser CLI (BundleHandler)

The two handlers share one single-flight gate: each triggers a stop-the-world heap dump, so while either request is running the other endpoint responds 429 busy.

func RegisterBundle added in v0.2.0

func RegisterBundle(mux *http.ServeMux)

RegisterBundle mounts BundleHandler at /debug/memusage/bundle on mux. Callers must opt in explicitly; see BundleHandler for the security contract. To serve both the in-process endpoint and the bundle endpoint, prefer Register, which makes the two share one single-flight gate.

func RegisterBundleWithOptions added in v0.2.0

func RegisterBundleWithOptions(mux *http.ServeMux, opts BundleOptions)

RegisterBundleWithOptions mounts BundleHandlerWithOptions at /debug/memusage/bundle on mux.

func RegisterMemUsage

func RegisterMemUsage(mux *http.ServeMux)

RegisterMemUsage mounts MemUsageHandler at /debug/memusage on mux. It is intentionally separate from any default handler registration: callers must opt in explicitly because the endpoint is expensive, stop-the-world, and should be protected from untrusted callers. See MemUsageHandler for the full security and performance contract.

func RegisterMemUsageWithOptions

func RegisterMemUsageWithOptions(mux *http.ServeMux, opts MemUsageOptions)

RegisterMemUsageWithOptions mounts MemUsageHandlerWithOptions at /debug/memusage on mux. Use this when the zero-value MemUsageOptions defaults are not sufficient.

func RegisterWithOptions added in v0.2.0

func RegisterWithOptions(mux *http.ServeMux, mo MemUsageOptions, bo BundleOptions)

RegisterWithOptions is Register with explicit options for each endpoint.

Types

type BundleOptions added in v0.2.0

type BundleOptions struct {
	// DisableGCBeforeHeapDump turns off the runtime.GC() that runs
	// immediately before debug.WriteHeapDump. The default (false) keeps
	// the GC enabled. A request may override per call with ?gc=0|1.
	DisableGCBeforeHeapDump bool

	// DisableRodataCapture skips the read-only memory segment snapshot.
	// Without it, an external analyser cannot recover ordinary
	// runtime/pprof string literals (e.g. pprof.Labels("job", "42"))
	// and such labels surface as string_missing during analysis.
	DisableRodataCapture bool

	// MaxRodataBytes caps the total read-only segment bytes embedded in
	// a bundle. Zero falls back to the internal default (256 MiB).
	// Segments that do not fit are dropped and the bundle's rodata
	// status is recorded as "truncated".
	MaxRodataBytes int64
}

BundleOptions controls the behavior of BundleHandler.

All bool fields use negative defaults (Disable*) so the zero value matches BundleHandler()'s defaults: GC before the heap dump, rodata snapshot enabled.

type MemUsageOptions

type MemUsageOptions struct {
	// DisableGCBeforeHeapDump turns off the runtime.GC() that
	// MemUsageHandler runs immediately before debug.WriteHeapDump. The
	// default (false) keeps the GC enabled.
	DisableGCBeforeHeapDump bool

	// IncludeSystemGoroutines lets system/background goroutines
	// participate in label matching. Default false.
	IncludeSystemGoroutines bool

	// DisableProcessMemoryReader turns off the in-process
	// address-space reader the handler opens on Linux, macOS,
	// FreeBSD, and Windows so the heap-label decoder can recover
	// ordinary runtime/pprof string literals that live outside heap
	// object contents. When true, label decoding sees heap object
	// contents only, and ordinary pprof.Labels("job","42") may fail
	// with string_missing. Default false (reader enabled).
	//
	// FreeBSD caveat: the reader prefers procfs (/proc/self/mem) and
	// falls back to the on-disk ELF. The ELF fallback is only correct
	// for non-PIE binaries. On a FreeBSD host with procfs unmounted
	// AND a PIE binary, the reader will still open successfully but
	// literal-string labels surface as string_missing.
	DisableProcessMemoryReader bool

	// MaxRequestBodyBytes caps the request body. Zero falls back to the
	// internal default (1 MiB).
	MaxRequestBodyBytes int64

	// Resource limits applied during validation. Zero falls back to the
	// internal defaults.
	MaxLabels          int
	MaxLabelKeyBytes   int
	MaxLabelValueBytes int
}

MemUsageOptions controls the behavior of MemUsageHandler.

MemUsageHandler is an expensive, stop-the-world debugging endpoint. Protect it the same way you protect /debug/pprof in production: it triggers a full heap dump on each call and can expose sensitive memory information.

All bool fields use negative defaults (Disable*, Include*) so the zero-value MemUsageOptions{} matches MemUsageHandler()'s defaults: GC before the heap dump, exclude system goroutines.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL