Releases: zz85/profile-bee
Releases · zz85/profile-bee
Release v0.3.2
See CHANGELOG.md for details.
What's Changed
- Replace polling with eBPF-based process exit detection by @claude in #55
- Implement deep stack unwinding via loop-based iteration by @claude in #45
- Add shell-based installer and automated release workflow by @claude in #62
- Fix web interface regression: correct crumbs truncation in collapse_to_json by @claude in #60
- Rewrite flamegraph viewer with viewport-sized canvas and live controlsWeb fixes by @zz85 in #64
- feat(dwarf): increase shard limits to support larger binaries by @zz85 in #67
- Add mouse support for TUI flamegraph navigation by @zz85 in #68
- Implement off-CPU profiling via kprobe on finish_task_switch by @zz85 in #65
- feat(dwarf): replace individual shard maps with ArrayOfMaps by @zz85 in #69
- Prep v0.3.2 by @zz85 in #70
Full Changelog: v0.3.0...v0.3.2
v0.3.0 — Initial Public Release
The first release published to crates.io. Install with cargo install profile-bee — no nightly Rust required.
Highlights
- Interactive TUI flamegraph viewer — live, real-time flamegraphs directly in your terminal with vim-style navigation, search, zoom, and freeze/unfreeze. Forked and adapted from flamelens. Three update modes: reset, accumulate, and decay.
- DWARF-based stack unwinding in eBPF — profiles binaries compiled without frame pointers (
-O2/-O3). Parses.eh_framesections into flat unwind tables loaded into eBPF maps for in-kernel stack walking. Supports PIE, shared libraries, vDSO, PLT stubs, and signal trampolines. - Smart uprobe/uretprobe targeting — GDB-style symbol resolution with auto-discovery across loaded ELF binaries. Supports glob (
pthread_*), regex (/pattern/), demangled C++/Rust names, source file:line (DWARF), explicit library prefixes, and multi-attach. Discovery mode (--list-probes) to inspect matches without attaching. - Raw tracepoint support — bypasses BPF LSM restrictions on
PERF_EVENT_IOC_SET_BPF. Multi-tier fallback: syscall-specific raw_tp → task_pt_regs raw_tp → generic raw_tp → perf tracepoint.
New Features
- TUI mode (
--tui) with real-time flamegraph updates, configurable refresh interval (--tui-refresh-ms), and update modes (--update-mode reset|accumulate|decay) - Combined TUI + web server mode (
--tui --serve) for simultaneous terminal and browser access - DWARF unwinding (
--dwarf) with background thread for detectingdlopen-loaded libraries within ~1 second - Smart uprobes (
--uprobe) with glob, regex, demangled name, and source:line matching - Uprobe discovery mode (
--list-probes) to search symbols without attaching - Raw tracepoint attachment for kprobe, tracepoint, and syscall events
- Frame pointer unwinding in eBPF — custom stack walker using
pt_regsfor deeper stacks thanbpf_get_stackid - Process spawning (
--cmd,-- <command>) — spawn a process and profile it, auto-terminates when it exits - PID exit detection — profiler automatically stops when
--pidtarget process exits - Prebuilt eBPF binary — bundled for
cargo installwithout nightly Rust;build.rsauto-detects fresh builds for development - blazesym integration — symbol resolution via blazesym library with Rust and C++ demangling
- Multi-process DWARF — system-wide profiling with per-process unwind tables and sharded eBPF array maps
Bug Fixes
- Fix TUI/serve modes stopping after 10s due to
--timedefaulting to 10000ms unconditionally - Fix
TracePointContextincorrectly cast topt_regs(tracepoint data struct != registers) - Fix
sys_exittracepoint filtering reading return value instead of syscall NR fromargs[1] - Fix syscall tracepoint fallback using per-syscall names (
sys_enter_write) that don't exist as raw tracepoints - Fix double-counting in headless
process_profiling_data - Fix combined mode missing stopping mechanisms (timer, Ctrl-C, child/PID exit)
- Fix shared library unwinding race condition
- Fix signal trampoline unwinding (
__restore_rt) - Fix PID filtering and empty stacks with
--cmd/-- - Fix spawned processes not terminated on profiler exit
- Fix timing issue: load DWARF tables before setting
TARGET_PID - Fix BPF verifier rejection with DWARF unwinding constants
Breaking Changes
- Binary names changed:
profile-bee→probee(primary) andpbee(short alias) --dwarfnow defaults tofalse(frame pointer unwinding is the default for stability/performance)--timebehavior changed in TUI/serve modes: defaults to 0 (unlimited) instead of 10000ms. CLI mode retains the 10s default.
Performance
- Compact
UnwindEntryfrom 32 → 12 bytes (u32 PC, deduplicated consecutive entries) - Sharded array maps for unwind tables (replaced single HashMap)
- Build-ID based caching for unwind table lookups
- Inode/metadata-based cache keys instead of reading full binaries
- BPF-based stack aggregation to reduce kernel ↔ userspace transfers
Infrastructure
cargo install profile-beeworks on stable Rust (prebuilt eBPF binary bundled)- TUI feature enabled by default (
--no-default-featuresto exclude) - Crate metadata added for crates.io publishing (license, description, repository)
- GitHub Actions CI workflow for Rust packages and E2E tests
- E2E test framework (
tests/run_e2e.sh) with 11 test cases covering FP, DWARF, and edge cases - Test fixtures: C binaries in 6 variants (FP/no-FP × O0/O2), Rust binary, shared library, PIE, signal handler
Platform Support
- Linux x86_64
- DWARF unwinding: x86_64 only (ARM support planned)
- Kernel >= 4.15 for basic profiling, >= 5.15 for raw tracepoint with task_pt_regs
What's Changed
- fix container process addr symbolization by @noneback in #6
- Docs by @zz85 in #7
- Spawn and profile sub process by @zz85 in #9
- More clean up by @zz85 in #10
- Blazesym support by @zz85 in #13
- Experimental support for running frame-pointer based stack unwinding in eBPF by @zz85 in #15
- Initial: Dwarf Stack Unwinding by @zz85 in #20
- Implement end-to-end DWARF stack unwinding with eBPF support by @Copilot in #17
- Auto-terminate profiler when --pid target process exits by @Copilot in #23
- Fix --pid and --cmd target process profiling by @Copilot in #21
- multi-process DWARF unwinding, dlopen support, and PID filtering fixes by @zz85 in #24
- CI: GitHub Actions workflow for Rust packages and e2e tests by @Copilot in #33
- Fix CI: build eBPF before workspace compilation to unblock e2e tests by @Copilot in #36
- Fix timing issue: load DWARF tables before setting TARGET_PID by @claude in #35
- perf: use inode/metadata for unwind table cache lookups instead of reading full binary by @claude in #34
- feat: Add interactive TUI flamegraph viewer with live profiling by @zz85 in #37
- feat: enhance uprobe support with flexible configuration by @zz85 in #39
- feat: add GDB-style smart uprobe resolution with multi-attach support by @zz85 in #40
- Implement combined TUI + serve mode by @zz85 in #38
- Dwarf correctness fixes by @zz85 in #41
- Add real-time flamegraph update modes (Reset, Accumulate, Decay) by @claude in #46
- Add raw tracepoint support by @zz85 in #43
- Changes for initial crates io release by @zz85 in #54
New Contributors
- @noneback made their first contribution in #6
- @zz85 made their first contribution in #7
- @Copilot made their first contribution in #17
- @claude made their first contribution in #35
Full Changelog: v0.1...v0.3.0
v0.1
snapshot of profile-bee I left off in 2022, using older rust and aya toolchain.
release features
- profiling in various mode
- output in stackcollapse, svg, html, or realtime http mode
- embedded http server to view real-time flamegraphs
tagging this before upcoming version 0.2, which would use updated crates and rust toolchain.
example usage
$sudo profile-bee --serve -f 999
Listening on port 8000. Goto http://localhost:8000/
# create some load
seq 1 `nproc` | xargs -P `nproc` -I{} dd if=/dev/zero of=/dev/null
# or
openssl speed -multi $(grep -ci processor /proc/cpuinfo)


