Expand description
Cooperative all-thread stack capture (#635, S6).
§Cooperative, not external
The probe thread lives inside the target process and walks its own
sibling threads. There is no ptrace, no debugger attach, and no OS
capability grant — those belong to the later --force external tier.
§The suspend window is the whole design
A suspended thread may hold any lock, including the allocator’s. So while
a thread is suspended this code does exactly two things: read its registers
and memcpy a bounded slice of its stack into a preallocated buffer.
Then it resumes immediately.
Nothing else happens in that window — no allocation, no symbolization, no
logging, no lock acquisition. Unwinding and symbolization run afterward,
against the copied bytes, when every thread is running again. Violating
this is how a stack profiler deadlocks the process it is profiling: suspend
a thread inside malloc, then call malloc yourself.
Windows, Linux, and macOS capture x86_64/aarch64 sibling stacks. Each
backend resumes before deferred PE/ELF/Mach-O unwinding. Other platforms
return SnapshotError::Unsupported rather than an empty snapshot.
Modules§
- attribute
- Attributing captured addresses to their loaded module (#725).
- modules
- Loaded-module inventory and in-memory PE section lookup (#635).
- stream
- Bounded sample sink: drop and count, never block (#635).
- unwind
- Turn raw captures into return addresses (#635).
Structs§
- Snapshot
- The result of one capture.
- Snapshot
Config - Knobs for a capture.
- Snapshot
Stats - What a capture cost and covered.
- Thread
Sample - One thread’s captured state.
Enums§
- Capture
Kind - How the capture was obtained, and what remains to be done to it.
- Snapshot
Error - Why a capture could not run at all.
Constants§
- MAX_
STACK_ BYTES - Upper bound on the stack bytes copied per thread.
Functions§
- capture_
all_ threads - Capture every sibling thread of the calling thread.
- capture_
and_ resolve - Capture every sibling thread and resolve each capture to return addresses.