Skip to content

fix(#344): kernel + bridge fixes for the SIGSEGV that survived #341 (v1.15.6) - #350

Merged
gsdali merged 2 commits into
mainfrom
fix/344-cdf-directory-xcafapp-thread-safety
Jul 21, 2026
Merged

fix(#344): kernel + bridge fixes for the SIGSEGV that survived #341 (v1.15.6)#350
gsdali merged 2 commits into
mainfrom
fix/344-cdf-directory-xcafapp-thread-safety

Conversation

@gsdali

@gsdali gsdali commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Root-causes and fixes #344 (the SIGSEGV that survived #341's theAutoNaming fix), independently of that earlier work — a genuinely different pair of races, both in code the #341 TSan stress never reached (that harness bypasses XCAFApp_Application/CDF_Application entirely; the real bridge path doesn't).

  1. 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).
  2. CDF_Directory::Add/Remove/Contains mutate a shared document list with zero synchronization.

Found during validation: fixing #1 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):

  1. TDocStd_Application::Resources() — identical lazy-init bug.
  2. Resource_Manager's internal maps and CDF_Application::myReaders/myWriters — zero synchronization.

All four fixed in the kernel patch (Scripts/patches/0012). 0/12 further swift test runs of OCCTXCAFTests reproduce any of them.

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()) serializing the three OCAF save/load bridge calls, matching the #298/#341 PR1→PR2 pattern.

Test plan

🤖 Generated with Claude Code

gsdali and others added 2 commits July 22, 2026 08:56
…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.
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.

Uncatchable SIGSEGV in parallel swift test run, right after concurrent OBJ imports — possibly related to #341, unconfirmed

1 participant