πŸ§ͺ Rover Allocation Tracer

not connected
Host is remembered in this browser. Endpoints are reached at http://<host><base path>… (base path must match the firmware adapter; default /alloctrace). CORS is open on the rover so this page (and the in-page viewer) work straight from file://.

Status

State
β€”
Ring
β€”
Events captured
β€”
Pairs collapsed
β€”
Capture largest
β€”
Collapse pairs
β€”
Stop on full
β€”
Backtrace
β€”

Controls

Stop on Full (no-wrap): when ON, recording freezes once the ring fills, preserving the earliest events (e.g. boot allocations) instead of overwriting them. Default ON. Turn OFF for a rolling "most-recent" window.
Freeze: stops new entries but keeps ring contents β€” use it right after the largest block drops to preserve the fragmentation event.
Capture Largest: records largest-free-block before/after each alloc (~5–10Β΅s/alloc) so the viewer can flag which allocations cut contiguous space.
Backtrace: captures a multi-frame caller chain for allocations passing the walk conditions (depth 1–6, min size, skip frees), so collapsed sites like pvPortMalloc/operator new split into their real callers. These settings persist on the device and apply to the next boot capture.

Heap map load a trace first

Live blocks laid out by address β€” dark gaps are free space; colour = allocating source (legend below each strip; load the ELF for names). Drag the slider or click any table row below to jump to that moment (drag the table's bottom edge to resize it). Scroll out on a strip to zoom to the full physical region; drag to pan; double-click to reset. The free and largest free gap figures are reconstructed at the selected seq over the whole heap frame β€” everything in the frame that isn't a live block is free β€” so they describe exactly what the strip draws, and the red marker always lands on a real gap. The firmware's dump-time heap_caps numbers are shown dimmed alongside for cross-reference (they are whole-region truth at the dump instant, not at a scrubbed seq). Needs the full ring (All events, limit β‰₯ ring count) for an accurate map.

Fragmentation analysis at current seq

Ranks the live blocks walling in the most free space β€” the ones worth relocating or pooling.

View trace

β€”
no ELF loaded Point at firmware.elf to resolve each pc to its function name (parsed locally; nothing uploaded).
Frames whose name starts with one of these is treated as framework; the first frame that doesn't match is shown as the source.
Click a pc cell to copy an addr2line command for it (resolves against firmware.elf to the exact source line). Rows highlighted red cut into the largest contiguous block (needs Capture Largest ON when recorded). Sort by clicking a column header β€” default sort is by largest-block drop (the fragmentation culprits float to the top).
freed(µs) is when each allocation was freed; life(µs) is how long it persisted (freed βˆ’ alloc time). Blank in both = never freed in this trace (still alive β€” the candidates that fragment or leak). Load & View always pulls all event kinds, so the Filter dropdown switches instantly with no re-fetch; pick Still alive to isolate the persistent allocations, or sort by life(µs) to surface the longest-lived ones. Reset Ring clears the device ring to start a fresh capture (required after a stop-on-full ring has filled). Times are µs since the capture was armed (see anchorWallMs in the trace header).
Fragmentation hunt: Capture Largest ON β†’ reproduce β†’ Freeze β†’ Load & View β†’ sort by Ξ”largest. Leak / persistent-alloc hunt: Load & View β†’ Filter Still alive (or sort by life(µs)) β†’ load the ELF β†’ read off the symbols.