Documentation
¶
Overview ¶
Package bundle implements the external-analyser capture artifact: a tar stream containing a heap dump, a snapshot of the target's read-only memory segments (so literal pprof label strings can be recovered out of process), and metadata. The target process produces a bundle cheaply (no parsing); the analyser CLI feeds it into the same memusage.AnalyzeDump pipeline used by the in-process endpoint.
Index ¶
- Constants
- func CaptureSelf(ctx context.Context, w io.Writer, opts CaptureOptions) error
- func Handler(hopts HandlerOptions) http.Handler
- func Write(w io.Writer, in WriteInput) error
- type Bundle
- type CaptureOptions
- type HandlerOptions
- type HexUint64
- type Meta
- type RodataMeta
- type Segment
- type SegmentInfo
- type SegmentsReader
- type WriteInput
Constants ¶
const ( MetaMember = "meta.json" SegmentsMember = "rodata/segments.json" HeapDumpMember = "heap.dump" )
Tar member names. heap.dump is emitted last (largest member); meta.json first so consumers can inspect a bundle cheaply. Readers must not rely on member order.
const ( RodataOK = "ok" RodataDisabled = "disabled" RodataTruncated = "truncated" )
Rodata status values recorded in Meta.Rodata.Status.
const DefaultMaxRodataBytes = 256 << 20
DefaultMaxRodataBytes caps the total read-only segment bytes embedded in a bundle when CaptureOptions.MaxRodataBytes is zero.
const FormatVersion = 1
FormatVersion is the bundle format produced by this package. Readers reject bundles with a greater version; unknown extra tar members are ignored for forward compatibility within a version.
Variables ¶
This section is empty.
Functions ¶
func CaptureSelf ¶
CaptureSelf dumps the calling process's heap, snapshots its eligible read-only memory ranges, and streams a format-version-1 bundle tar to w. The heap dump is written to a temp file first (debug.WriteHeapDump needs a file descriptor and the tar header needs the size up front) and removed before returning.
The dump is captured before the rodata ranges are read; the ranges are read-only program data, so the two views are consistent without stopping the world twice.
func Handler ¶
func Handler(hopts HandlerOptions) http.Handler
Handler returns an http.Handler that serves GET /debug/memusage/bundle by streaming a capture bundle of the current process.
HTTP semantics:
GET -> application/x-tar bundle stream GET?gc=0|1 -> overrides Capture.GCBeforeHeapDump for this request other methods -> 405 with Allow: GET
Errors before the first body byte produce a JSON ErrorResponse (capture_failed, 500). Once streaming has started the only honest failure mode is aborting the connection, so the client sees a truncated tar instead of a falsely complete one.
Types ¶
type Bundle ¶
type Bundle struct {
Meta Meta
// HeapDumpPath is the heap dump extracted to a temp file (removed
// by Close).
HeapDumpPath string
// Segments serves the saved read-only segments as an
// addrspace.Reader; nil when the bundle carries no rodata snapshot.
Segments *SegmentsReader
// Warnings to append to analysis diagnostics: the bundle's own
// warnings plus the standard literal-label phrasing when the rodata
// snapshot is absent or partial.
Warnings []string
}
Bundle is an opened capture artifact ready for analysis.
type CaptureOptions ¶
type CaptureOptions struct {
// GCBeforeHeapDump triggers runtime.GC() before the dump so the
// bundle reflects live memory rather than floating garbage.
GCBeforeHeapDump bool
// DisableRodata skips the read-only segment snapshot; literal pprof
// label strings then surface as string_missing during analysis.
DisableRodata bool
// MaxRodataBytes caps total embedded segment bytes; 0 means
// DefaultMaxRodataBytes. Segments that do not fit are dropped and
// the rodata status becomes "truncated".
MaxRodataBytes int64
// Producer is recorded in meta.json (e.g. "bubblepprof/v0.2.0").
Producer string
}
CaptureOptions configures CaptureSelf.
type HandlerOptions ¶
type HandlerOptions struct {
Capture CaptureOptions
// Semaphore is the single-flight gate (capacity-1 channel). When nil
// the handler creates a private one. Supplying the same channel used
// by the /debug/memusage handler serializes the two endpoints, since
// each triggers a stop-the-world WriteHeapDump.
Semaphore chan struct{}
}
HandlerOptions configures Handler.
type HexUint64 ¶
type HexUint64 uint64
HexUint64 marshals as a "0x..."-prefixed JSON string: virtual addresses routinely exceed JSON's exact float53 integer range.
func (HexUint64) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (*HexUint64) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
type Meta ¶
type Meta struct {
FormatVersion int `json:"format_version"`
CreatedAt string `json:"created_at"` // RFC 3339, UTC
Producer string `json:"producer"`
GoVersion string `json:"go_version"`
GOARCH string `json:"goarch"`
PtrSize int `json:"ptr_size"`
BigEndian bool `json:"big_endian"`
Rodata RodataMeta `json:"rodata"`
Warnings []string `json:"warnings"`
}
Meta is the meta.json member. The go_version/goarch/ptr_size/ big_endian fields are convenience copies for humans inspecting a bundle; the heap dump's own Params record remains the authoritative source for runtime layout lookup during analysis.
type RodataMeta ¶
type RodataMeta struct {
// Status is one of the Rodata* constants.
Status string `json:"status"`
// Reason is human-readable context when Status is not "ok".
Reason string `json:"reason,omitempty"`
// Segments is the number of rodata/NNNNN.bin members.
Segments int `json:"segments"`
// TotalBytes is the sum of segment sizes.
TotalBytes uint64 `json:"total_bytes"`
}
RodataMeta describes the read-only segment snapshot carried by the bundle.
type Segment ¶
Segment is one read-only memory segment to embed in a bundle. R must yield exactly Size bytes.
type SegmentInfo ¶
type SegmentInfo struct {
// Member is the tar member holding the segment bytes.
Member string `json:"member"`
// Addr is the runtime virtual address of the first byte.
Addr HexUint64 `json:"addr"`
// Size is the segment length in bytes (always < 2^53, safe as a
// plain JSON number).
Size uint64 `json:"size"`
// Perms is the mapping permission string, e.g. "r--" or "r-x".
Perms string `json:"perms"`
// Path is the backing file of the mapping, when known.
Path string `json:"path,omitempty"`
}
SegmentInfo is one entry of the rodata/segments.json member, index-aligned with the rodata/NNNNN.bin members.
type SegmentsReader ¶
type SegmentsReader struct {
// contains filtered or unexported fields
}
SegmentsReader implements addrspace.Reader over the read-only segments saved in a bundle, keyed by their original runtime virtual addresses. It mirrors the ProcessReader contract: a read must lie entirely within a single segment; size==0 succeeds; addr==0 and overflowing ranges fail.
func NewSegmentsReader ¶
func NewSegmentsReader(infos []SegmentInfo, data [][]byte) (*SegmentsReader, error)
NewSegmentsReader builds a SegmentsReader. Each data slice i covers [infos[i].Addr, infos[i].Addr+len(data[i])); infos and data must be index-aligned with len(data[i]) == infos[i].Size.
func (*SegmentsReader) Name ¶
func (r *SegmentsReader) Name() string
Name implements addrspace.NamedReader.
func (*SegmentsReader) ReadAtAddr ¶
func (r *SegmentsReader) ReadAtAddr(addr uint64, size uint64) ([]byte, bool)
ReadAtAddr implements addrspace.Reader.