Skip to content

feat: add persistent DWARF analysis cache#247

Draft
swananan wants to merge 1 commit into
mainfrom
feature/prepared-analysis-cache
Draft

feat: add persistent DWARF analysis cache#247
swananan wants to merge 1 commit into
mainfrom
feature/prepared-analysis-cache

Conversation

@swananan

@swananan swananan commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • add a rootless --prepare --target mode for parsed DWARF analysis
  • reuse versioned, identity-bound analysis entries in CLI and TUI startup
  • report per-module cache hits, misses, and rejected-entry fallback reasons
  • keep PID filters, module mappings, CFI publication, and eBPF state runtime-only
  • cover malformed caches and cached/uncached cross-module backtraces in e2e

Design

The cache stores only target-independent symbol, source-line, file, and
compilation-unit indices. Trace sessions open it read-only and continue to
resolve runtime modules, dlopen changes, CFI rows, symbolization, kernel
capabilities, and attachment state through the existing runtime paths.

Entries use a versioned fixed header and binary/debug-file identities. Decoding
validates size limits and identity before deserializing the payload. Missing or
unusable entries fall back to raw DWARF without turning a successful module
load into an error.

This intentionally does not serialize eBPF bytecode or runtime backtrace state.

Testing

  • cargo fmt --all -- --check
  • cargo clippy --all-targets --all-features -- -D warnings
  • focused DWARF cache, CLI reporter, and TUI summary tests
  • rootless prepare/reuse/corrupt-cache e2e
  • cached-main plus uncached-shared-library backtrace e2e
  • full host e2e through runner job 05441fe22415

Container-topology e2e was not run because this change does not alter container
or PID-namespace behavior.

Related to #240

@swananan

Copy link
Copy Markdown
Owner Author

Nginx benchmark note

I tested the PR against the existing OpenResty nginx worker:

  • PID: 2762799
  • ELF: /usr/local/openresty/nginx/sbin/nginx
  • ELF size: 28 MiB, embedded DWARF, 12,590 symbols
  • command shape: -p <pid> -t <nginx> --script-file <bt-script> --dry-run
  • GhostScope: release build from this PR
  • runtime modules: 7; only the nginx executable had a prepared entry

Results:

  • full raw dry-run: 1.575 s
  • full cached dry-run: 1.743 s
  • nginx raw module parse/index: 775 ms / 16 ms
  • nginx cached decode/index: 1,020 ms / 14 ms
  • cache payload: 125,455,004 bytes for a 28 MiB ELF

The cache hit was confirmed in the runtime log, but this target was about 10%
slower on the warm release path. The raw run executed first, so page-cache
warming should have favored the cached run rather than the raw run.

The current payload repeats file-path and compilation-unit strings across about
600,000 line entries, which likely explains the 120 MiB artifact and sequential
decode cost. The format should be compacted or interned, and the benchmark
should be repeated before treating this as a startup-performance win.

@swananan swananan marked this pull request as draft July 11, 2026 13:21
Add a rootless prepare mode that serializes target-independent DWARF
analysis and reuses it during later CLI and TUI startup.

Validate cache identity and bounds, fall back to raw DWARF for unusable
entries, and report hit, miss, and rejection states.
@swananan swananan force-pushed the feature/prepared-analysis-cache branch from ceb8a56 to 36201d2 Compare July 12, 2026 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant