Skip to content

fix: keep sysmon responsive and harden runtime backtrace refresh - #295

Merged
swananan merged 5 commits into
mainfrom
fix/runtime-backtrace-refresh-followups
Sep 5, 2026
Merged

fix: keep sysmon responsive and harden runtime backtrace refresh#295
swananan merged 5 commits into
mainfrom
fix/runtime-backtrace-refresh-followups

Conversation

@swananan

@swananan swananan commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Summary

Follow up on #292, based on the current main (1420f7f). The already-merged
runtime-loading commits are excluded from this PR; only the additional fixes
and sysmon improvements remain.

  • Keep sysmon collectors draining under sustained map churn by separating
    event collection from /proc scanning and offset refresh work.
  • Render trace batches against immutable, generation-tagged module snapshots
    without waiting for the process coordinator lock.
  • Preserve precompile discovery of late PID modules, bound zero-sized symbols,
    and keep normalized non-PIE frames resolvable.
  • Retain validated file mappings through parsing; enforce discovery deadlines,
    terminal-observation retry bounds, and the runtime-module limit.
  • Publish completed CFI to current actors, seed newly attached traces, and
    serialize all writers to shared pinned CFI maps.
  • Keep target-only offset refreshes from replacing complete process ranges,
    and publish runtime symbols at the renderer-cache invalidation boundary.
  • Anchor module reads to validated descriptors, preserving /proc/PID/root
    mount-namespace access without reopening a same-named host library.

Validation

  • Formatting and diff whitespace checks pass on the amended tree.
  • Clean-worktree full-workspace Clippy passes with -D warnings and
    -D clippy::undocumented_unsafe_blocks.
  • Both previously failing dlopen backtrace cases pass under
    host -> docker-private in runner job 5bde05be7838. Coverage now checks
    fully symbolized blocks and the last ten shared-library backtraces.
  • Clean-worktree cargo test --all-features passes (946 tests), with Rust
    compatibility toolchains required and dwarf-tool built first.
  • The amended runtime-discovery and sysmon-worker commits independently pass
    affected-crate strict Clippy and unit tests (174 and 73 tests respectively).
  • Full host-to-host runner job fd30db271c75 and full host-to-private runner
    job d83803938a23 both pass all 32 backtrace tests, concurrent CFI
    publication, and all late-start globals cases. Both then stop at
    rust_script_execution: 33 passed and 16 failed. The failing test names
    and assertion locations match pre-fix job 04d5a1bc8db7 exactly. Later
    local test binaries are not reached; CI runs the complete suite.

Earlier local full jobs e7b4ca35a884 and 04d5a1bc8db7 shared 16 Rust
value-rendering failures. Those are tracked separately from the dlopen
backtrace CI failures fixed here.

All five commit messages are wrapped at 80 columns or fewer (maximum: 77).
Original author and committer timestamps are preserved.

CI outcome

All ten checks pass on 1e39eb3:

  • CI:
    Rustfmt, strict Clippy, Test Suite, Build, and Standard E2E all pass.
    Standard E2E reports 342 passed and zero failed.
  • Container matrix:
    all three full topologies pass (342 tests each), along with host-PID smoke.
  • DWARF Perf Regression
    passes.

Both dlopen backtrace cases pass in Standard E2E and all three full container
topologies. The Rust value-rendering group also passes all 49 tests in each
CI topology, unlike the local runner environment noted above.

The first CI attempt exposed three concrete causes: symbol visibility
preceded renderer cache invalidation, periodic target-only updates discarded
other process ranges, and canonicalizing a proc-root path selected the host
libc. The amended commits fix those causes while preserving identity
validation, without increasing test timeouts or reducing event rates.

Refresh PID analyzers before compiling scripts for newly mapped libraries.
Bound zero-sized symbols at the next address and preserve normalized
zero-bias executable frames when coordinator lookup is unavailable.
Retain validated descriptors through parsing, including proc-root paths
across mount namespaces, and isolate discovery so timeouts cannot block
event handling or runtime shutdown. Bound retries for terminal observations
and stop scheduling when the module limit is reached.

Publish CFI to current trace actors, retain completed rows for later traces,
and serialize initial and incremental writes to shared pinned maps. Publish
runtime symbols with cache invalidation after CFI publication.
Bound ring-buffer draining so periodic reconciliation runs under sustained
map-change load. Coalesce per-process map notifications and cache namespace
PID scans for the noisy path while keeping lifecycle resolution fresh.

Add a regression stressor that reproduces missing target offsets on the old
implementation.
Move /proc scanning and offset refreshes to a dedicated worker so ring and
perf collectors continue draining under load.

Keep lifecycle work separate from coalesced map changes, and retain the first
pending refresh deadline under continuous mmap traffic. Keep target-only
offset updates from replacing complete process module ranges.
Publish immutable process-module snapshots for event rendering.
Keep rendering off the coordinator lock and key caches by mapping generation.
Require complete late-loaded-module symbolization in e2e coverage.
@swananan
swananan force-pushed the fix/runtime-backtrace-refresh-followups branch from 06ed101 to 1e39eb3 Compare September 5, 2026 15:47
@swananan
swananan merged commit 83413da into main Sep 5, 2026
10 checks passed
@swananan
swananan deleted the fix/runtime-backtrace-refresh-followups branch September 5, 2026 18:55
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