Sampling profiler — kit prof (planned work)
Forward-looking design for kit prof, a host-native statistical CPU profiler.
It reuses the interactive JIT debugger's host signal infrastructure
(../DBG.md, DEBUG.md): SIGPROF fires on the debugger's
worker thread, the handler walks the frame-pointer chain into a pre-allocated
ring buffer and returns without parking — the one property that keeps
sampling cheap and guest timing undisturbed — and PCs are symbolicated after the
guest exits.
Nothing exists yet: no prof subcommand in driver/main.c, no
src/dbg/prof.c, no on_sample field on KitDbgSignalOps. This document is the
worklist for building it.
Scope — this is the sampling profiler, deliberately on the host-native substrate. It is one of two complementary profilers, and it is not being rebased onto the emulator. This one measures real wall/CPU time by statistically sampling natively-run kit code; the deterministic instruction-counting profiler (callgrind-style — exact, reproducible, any guest arch) lives on the emulator substrate (INSTRUMENT.md §9, §12.1). The two share a back-end (symbolication + folded / flat output), not a collector. See INSTRUMENT.md §9 for the perf-vs-callgrind split and the one-core-two-collectors factoring.
1. Public API (include/kit.h)
- Add
on_sample(void* session, void* ucontext)toKitDbgSignalOps(NULL = ignore SIGPROF); it receives the rawucontext_t*, not a marshalled frame, because it extracts only PC and FP on the hot path. - Declare
KitProfBuf(fixed-capacity sample ring:pcs[PROF_MAX_DEPTH]per sample,count/cap/dropped) andKitProfWriter(post-run symbolication callback vtable), pluskit_dbg_session_prof_attach(session, buf)(beforesession_call) andkit_dbg_session_prof_collect(session, buf, writer).
2. Library (src/dbg/prof.c, freestanding C11)
dbg_fp_walk(ucontext, sample): frame-pointer walk viadbg_os->guarded_copyfor every dereference; terminate on NULL / misaligned / non-advancing FP orPROF_MAX_DEPTH. The three frame layouts are identical ([FP]= saved FP,[FP+8]= saved LR/return addr); FP is x29 / rbp / s0(x8). WHY: no DWARF or symbol lookup on the signal path — raw PCs only.on_samplebody: capacity check, walk, append or bumpdropped(non-atomic; the single worker makes that safe).prof_attach/prof_collectbodies;prof_collectsymbolicates each PC viakit_jit_addr_to_sym+kit_dwarf_addr_to_line, dispatching to the writer (may allocate freely).
3. Host adapter (driver/env/posix_dbg.c and windows.c)
- Add SIGPROF to the POSIX handler's signal set with an early-return path:
if (signo == SIGPROF && on_sample) { on_sample(...); return; }— no park/unpark. SIGPROF joins the blocked cohort so it does not recurse. Timer arming (setitimer(ITIMER_PROF)) and thread targeting stay driver-side and do not belong behindKitDbgOs. - Decide the Windows sampling mechanism (no SIGPROF): a periodic
SuspendThread+GetThreadContextsampler thread is the natural analog of the VEH interrupt path. WHY: the SIGPROF design has no direct Windows equivalent, so this is a genuine open design question, not a port.
4. Driver (driver/cmd/prof.c)
Wired into the multi-call dispatch in driver/main.c:
- Flags
--rate(default 1ms),--depth(64),--cap(1M),--output(prof.folded),--no-folded,--no-flat. Input handling mirrorskit run, with-gforced on so symbolication always has DWARF. - Arm the timer before
session_call, disarm after, thenprof_collect. Emit folded stacks (sorted + RLE forflamegraph.pl) plus a flat self%/cumul% report to stdout and a dropped-sample warning.
5. Tests
test/smoke/prof_hello: assertprof.foldedis non-empty andmainappears.test/dbg/fp_walk_*: canned frame chains per arch, assert the PC sequence and termination.test/dbg/prof_buf_overflow: fill to capacity, assertdroppedincrements andcountcaps.
6. Follow-ons (deferred)
- Per-thread timers via
timer_create(CLOCK_THREAD_CPUTIME_ID)+SIGEV_THREAD_IDfor multi-thread guests. This depends on wideningKitDbgOsfor multi-threaded guests (DEBUG.md §7). - An
ITIMER_REALwall-clock mode for I/O-bound programs. - Allocation profiling via a conditional breakpoint on the allocator.
- SpeedScope / pprof output.