Skip to content

Entity-lifecycle stress tests; fix a discovery/teardown UAF - #77

Merged
sqt merged 4 commits into
mainfrom
test/entity-lifecycle-stress
Aug 30, 2026
Merged

Entity-lifecycle stress tests; fix a discovery/teardown UAF#77
sqt merged 4 commits into
mainfrom
test/entity-lifecycle-stress

Conversation

@sqt

@sqt sqt commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Motivation

zzdds has no concurrency- or lifecycle-under-load tests — the roadmap and DCPS coverage audit both call for an OpenDDS-EntityLifecycleStress-shaped stress tier. Standing up the first scenario immediately exposed a real use-after-free: rapid concurrent create/delete of DataWriters and Publishers on one participant crashes the SEDP receive thread mid-on_publication_matched dispatch.

Description of changes

  • New stress-tests/ (mirrors examples/ layout). The README carries a survey of OpenDDS's EntityLifecycleStress and the port design. Python run_all.py orchestrator + two Zig apps under zig/:
    • entity_lifecycle_stress — faithful multi-process port: N pub + M sub processes, interleaved, on a per-run-unique domain, keyed Messenger type, teardown-duration monitor, deterministic --cleanup {explicit,cascade}, structured SUMMARY: line, optional --churn.
    • lifecycle_churn — in-process N-thread churn under DebugAllocator, --scenario {entities,reentrant} (frame ready for waitset/listener/instance/cft).
  • New ci.yml stress job (needs: test-linux): builds native + -Ddebug-allocator, runs run_all.py --strict, plus a ThreadSanitizer reentrant lane and a heavier schedule-only matrix.
  • UAF fix (src/dcps/{participant,writer,reader,publisher,subscriber}.zig), two parts:
    a. onReaderDiscovered / onWriterDiscovered / the two announceMatched* paths released participant.mu before firing matched_notify while pinning only the RTPS proto, not the target DataWriterImpl/DataReaderImpl. MatchedNotify now carries is_reader + quiesce hooks, acquired while mu is held and held across the notify.
    b. PublisherImpl / SubscriberImpl gained an EntityQuiesce; each child DataWriter/DataReader holds a lifetime reference on its parent, so the DDS §2.2.4.1.5 listener-fallback chain (writer → publisher → participant) can never read a freed enclosing entity. Owned-child teardown moved from reallyDeinit into deinit to break the resulting ref cycle; a parent_pinned flag keeps hand-built test impls (which skip init()) balanced.
  • New test/dcps/lifecycle_churn_test.zig — regression (UDP loopback, stable reader + writer-churn thread), wired into dcps_test_files.

@greptile-apps

greptile-apps Bot commented Aug 30, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds lifecycle stress coverage and strengthens entity ownership during concurrent discovery callbacks and teardown.

  • Pins mlugg/setup-zig to an immutable commit across CI and release workflows, resolving the prior supply-chain finding.
  • Holds quiescence references across match notifications and pins writers/readers to their enclosing publisher/subscriber.
  • Adds multi-process and in-process lifecycle stress applications, orchestration, DebugAllocator coverage, and a TSan lane.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported mutable third-party action reference is now pinned to a full commit SHA throughout the changed workflows.

Important Files Changed

Filename Overview
.github/workflows/ci.yml Adds the gated stress and sanitizer lanes and replaces mutable third-party Zig setup tags with an immutable commit.
.github/workflows/release.yml Pins the third-party Zig setup action to the same immutable commit used by CI.
src/dcps/participant.zig Extends matched-notification handling so endpoint quiescence remains pinned while callbacks run outside the participant lock.
src/dcps/publisher.zig Adds publisher quiescence and moves owned-writer teardown earlier to support child-to-parent lifetime references.
src/dcps/subscriber.zig Adds the corresponding subscriber quiescence and owned-reader teardown ordering.
src/dcps/writer.zig Pins initialized writers to their parent publisher and releases that reference during final destruction.
src/dcps/reader.zig Pins initialized readers to their parent subscriber and releases that reference during final destruction.
stress-tests/run_all.py Orchestrates the new lifecycle stress scenarios with strict result handling.
stress-tests/zig/entity_lifecycle_stress/main.zig Implements multi-process publisher/subscriber lifecycle stress with explicit and cascading cleanup modes.
stress-tests/zig/lifecycle_churn/main.zig Implements threaded in-process entity churn and reentrant lifecycle scenarios.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    D[Discovery callback] --> L[Lock participant state]
    L --> Q[Acquire endpoint quiesce reference]
    Q --> U[Release participant lock]
    U --> N[Dispatch matched notification]
    N --> R[Release quiesce reference]
    T[Writer or reader teardown] --> B[Block new quiesce entries]
    B --> W[Wait for active references]
    W --> F[Destroy endpoint and release parent reference]
Loading

Reviews (4): Last reviewed commit: "resolving CI issues" | Re-trigger Greptile

Comment thread .github/workflows/ci.yml Outdated
sqt and others added 2 commits August 30, 2026 08:21
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjSMCfwAYbhV2soLT9vSic
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjSMCfwAYbhV2soLT9vSic
@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.66667% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/dcps/participant.zig 82.35% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjSMCfwAYbhV2soLT9vSic
@sqt
sqt merged commit 7e72280 into main Aug 30, 2026
39 checks passed
@sqt
sqt deleted the test/entity-lifecycle-stress branch August 30, 2026 13:31
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