fix(#344): kernel + bridge fixes for the SIGSEGV that survived #341 (v1.15.6) - #350
Merged
Merged
Conversation
…v1.15.6) Root-caused independently of #341's theAutoNaming fix: XCAFApp_Application:: GetApplication()'s lazy singleton init races two threads' first concurrent call (both construct an instance, race to assign the shared handle) -- confirmed via a debug build + custom SIGSEGV handler (~50% crash rate at 10 threads x 3000 barrier-synchronized rounds against stock p1) and via TSan (234 race reports at 8 threads x 200 iterations, the large majority a destructor cascade from concurrently-constructed duplicate instances). CDF_Directory::Add/Remove/Contains mutate a shared document list with zero synchronization, independently confirmed by TSan. Found during validation: fixing GetApplication() means every caller genuinely shares ONE TDocStd_Application instance for the first time, surfacing two more races on that instance's other state, previously masked by threads sometimes getting different (uncontended) instances -- TDocStd_Application::Resources() (identical lazy-init bug), Resource_ Manager's internal maps, and CDF_Application::myReaders/myWriters. All fixed in the same kernel patch (Scripts/patches/0012). 0/12 further `swift test` runs of OCCTXCAFTests reproduce any of these four races. A fifth, architecturally different crash also surfaced (BinLDrivers_ DocumentStorageDriver::Write corrupting a shared, cached, non-reentrant storage-driver instance under concurrent Save/SaveAs of the same format, ~60% crash rate once the races above stopped masking it) -- filed separately as #349 since it needs its own kernel investigation (a shared worker object, not a container needing a lock). Ships with an interim bridge-side mutex (ocafStoreMutex(), OCCTBridge_Document.mm) serializing the three OCAF save/load bridge calls, matching the #298/#341 PR1->PR2 pattern -- 0/12 further runs crash with it in place. New regression test: parallelDocumentCreate (OCCTStressTests). Filed upstream as Open-Cascade-SAS/OCCT#1389 (repro) / OCCT#1390 (fix, CI green). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…er's copy ctor
Fixes GCC -Wextra ("base class should be explicitly initialized in the
copy constructor") caught by the upstream OCCT PR's CI matrix. No
behavior change (the base was already default-constructed implicitly);
doesn't require an xcframework rebuild.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Root-causes and fixes #344 (the SIGSEGV that survived #341's
theAutoNamingfix), independently of that earlier work — a genuinely different pair of races, both in code the #341 TSan stress never reached (that harness bypassesXCAFApp_Application/CDF_Applicationentirely; the real bridge path doesn't).XCAFApp_Application::GetApplication()'s lazy singleton init races two threads' first concurrent call. Confirmed via a debug build + custom SIGSEGV handler (~50% crash rate at 10 threads × 3000 barrier-synchronized rounds) and via TSan (234 race reports, the majority a destructor cascade from concurrently-constructed duplicate instances).CDF_Directory::Add/Remove/Containsmutate a shared document list with zero synchronization.Found during validation: fixing #1 means every caller genuinely shares ONE
TDocStd_Applicationinstance for the first time, surfacing two more races on that instance's other state (previously masked by threads sometimes getting different, uncontended instances):TDocStd_Application::Resources()— identical lazy-init bug.Resource_Manager's internal maps andCDF_Application::myReaders/myWriters— zero synchronization.All four fixed in the kernel patch (
Scripts/patches/0012). 0/12 furtherswift testruns ofOCCTXCAFTestsreproduce any of them.A fifth, architecturally different crash also surfaced (
BinLDrivers_DocumentStorageDriver::Writecorrupting a shared, cached, non-reentrant storage-driver instance under concurrentSave/SaveAsof the same format — ~60% crash rate once the races above stopped masking it). Filed separately as #349 since it needs its own kernel investigation (a shared worker object, not a container needing a lock). Ships with an interim bridge-side mutex (ocafStoreMutex()) serializing the three OCAF save/load bridge calls, matching the #298/#341 PR1→PR2 pattern.Test plan
swift build— zero errorsswift test --filter OCCTStressTests— 354/354 pass, including newparallelDocumentCreateregression testswift test --filter OBJDocumentIOTests— 4/4 passswift test --filter OCCTXCAFTests— 0/12 crashes with the full fix + bridge mitigation in place (was crashing in the original Uncatchable SIGSEGV in parallel swift test run, right after concurrent OBJ imports — possibly related to #341, unconfirmed #344 report, and again mid-validation before the bridge mitigation)SIGSEGV/SIGBUShandler, and via ThreadSanitizer (minimal-module protocol matching SheetMetal.Builder.build silently returns an empty solid under parallel test execution (8/10 runs) — contradicts the documented "independent shapes are thread-safe" guarantee #298/isSelfIntersecting: hard-bounded (worker-thread) variant + upstream OCCT checkpoint/quadratic report (follow-up to #293) #319/NCollection race under parallel execution: documented downstream as 'run --no-parallel', never filed or characterised upstream — needs the #298 TSan protocol #341)CLAUDE.md,docs/CHANGELOG.md,docs/thread-safety.md,Scripts/patches/README.md,okf/references/carried-occt-patches.mdOCCT.xcframework+OCCTBridge.xcframeworkrebuilt (all 3 core slices),Package.swiftversion/checksums bumped to v1.15.6🤖 Generated with Claude Code