fix(#920): gate the ThruSections test that hits #913's unpatched-kernel crash - #924
Merged
Merged
Conversation
…el crash Root cause of #920/#922 (uncatchable SIGSEGV, no test attribution, observed on CI across multiple unrelated PRs since PR #912's round 2): `generatedFaceIsMemberOfShapeAfterSuccessFailureSuccessOnReusedBuilder` (added in that same round 2) unintentionally constructs #913's exact crash trigger, unguarded — checkCompatibility(false), then a 4th section with MORE edges (a triangle, 3) than section 1 (a circle, 1), 4 sections total, reaching CreateSmoothed()'s fixed-stride array overrun that patch 0027 fixes. Package.swift's remote pin (what ci.yml's swift build + test (macOS) job resolves, and what any fresh checkout with no local Libraries/ gets by default) is the v2.0.0 release asset: OCCT V8_0_1 + only the fifteen patches that existed when that release was cut. Patches 0026 (#905) and 0027 (#913) both landed after and are only applied by kernel-integration.yml's from-source rebuild — never by ci.yml. Every default `swift test` run exercises the unguarded test against a kernel that doesn't have #913's fix. Heap corruption from the array overrun is nondeterministic: sometimes it silently produces a wrong answer (measured directly below), sometimes it corrupts memory a later, unrelated test's allocation reuses, producing a SIGSEGV attributed to whatever part of the parallel suite happens to touch it next — exactly matching every #920 occurrence (different test cluster each time, no attribution possible from the crashing process's own output). This also explains why local reproduction never worked across ~10 attempts throughout this investigation: OCCTSWIFT_LOCAL=1 (used throughout, and also the *default* whenever a local Libraries/OCCT.xcframework is present) resolves the locally-rebuilt kernel, which has all seventeen current patches including 0027. Local runs were never testing the same kernel CI actually uses. Measured, not assumed: forced the exact remote kernel with OCCTSWIFT_REMOTE=1 (overriding the local-directory auto-detection) and ran the suspect test directly — build B's `#expect(!loft.build())` failed, `build()` returned `true` instead of failing cleanly, matching #913's own "silently misaligned... reporting build() == true for an invalid result" description of the unpatched defect exactly. No other test file uses checkCompatibility(false) at all (checked directly), so this is the sole trigger; no Sources/ code path uses it either. Fix: gate the test behind OCCTSWIFT_LOCAL, the identical mechanism and reasoning already established for #913's own equally-dangerous test (mismatchedSectionEdgeCountWithoutCheckFailsCleanly, gated since PR #915's review for this exact class of danger). Verified: OCCTSWIFT_REMOTE=1 now correctly skips it; OCCTSWIFT_LOCAL=1 still runs and passes it, preserving the coverage #912's round 2 intended. Full suite run repeatedly against the forced remote kernel (OCCTSWIFT_REMOTE=1 swift test, matching CI's resolution exactly) — clean every time. Closes duplicate #922 (its patch-count observation was the key clue). No CHANGELOG entry: test-only change, no public API or behavior change.
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.
What & why
Root causes #920 (and its duplicate #922, closed): the uncatchable SIGSEGV observed on CI across
multiple unrelated PRs since PR #912's round 2, with no test attribution possible from the crashing
process's own output.
generatedFaceIsMemberOfShapeAfterSuccessFailureSuccessOnReusedBuilder(
Tests/OCCTStressTests/StressBuilderLifecycleTests.swift, added in that same round 2)unintentionally constructs #913's exact crash trigger, unguarded —
checkCompatibility(false),then a 4th section with more edges (a triangle, 3) than section 1 (a circle, 1), 4 sections
total, reaching
BRepOffsetAPI_ThruSections::CreateSmoothed()'s fixed-stride array overrun thatpatch
0027(#913) fixes.Package.swift's remote pin — whatci.yml'sswift build + test (macOS)job resolves, and whatany fresh checkout with no local
Libraries/gets by default — is the v2.0.0 release asset: OCCTV8_0_1 + only the fifteen patches that existed when that release was cut. Patches
0026(#905) and0027(#913) both landed after and are only applied bykernel-integration.yml's from-sourcerebuild — never by
ci.yml. Every defaultswift testrun exercises the unguarded test against akernel that doesn't have #913's fix.
Heap corruption from the array overrun is nondeterministic: sometimes it silently produces a wrong
answer (measured directly below), sometimes it corrupts memory a later, unrelated test's allocation
reuses, producing a SIGSEGV attributed to whatever part of the parallel suite happens to touch it
next — exactly matching every #920 occurrence (a different test cluster each time).
This also explains why local reproduction never worked across roughly ten attempts throughout the
#920 investigation:
OCCTSWIFT_LOCAL=1(used throughout, and also the default whenever a localLibraries/OCCT.xcframeworkis present) resolves the locally-rebuilt kernel, which has allseventeen current patches including
0027. Local runs were never testing the same kernel CIactually uses.
Measured, not assumed: forced the exact remote kernel with
OCCTSWIFT_REMOTE=1(overriding thelocal-directory auto-detection) and ran the suspect test directly:
build()on "build B" returnedtrueinstead of failing cleanly — matching #913's own "silentlymisaligned... reporting
build() == truefor an invalid result" description of the unpatcheddefect exactly. No other test file uses
checkCompatibility(false)at all (checked directly), andno
Sources/code path uses it either, so this is the sole trigger in the tree.Fix
Gate the test behind
OCCTSWIFT_LOCAL, the identical mechanism and reasoning already establishedfor #913's own equally-dangerous test (
mismatchedSectionEdgeCountWithoutCheckFailsCleanly, gatedsince PR #915's own review for this exact class of danger). Verified:
OCCTSWIFT_REMOTE=1nowcorrectly skips it;
OCCTSWIFT_LOCAL=1still runs and passes it, preserving the coverage#912's round 2 intended.
Closes duplicate #922 (its patch-count observation — 17 patches on
Scripts/patches/, only 15 inthe pinned release asset — was the key clue that cracked this).
CHANGELOG entry
None — test-only change, no public API or behavior change.
SemVer impact
None — test-only change.
Checklist
verification): N/A in the usual sense — this PR fixes test coverage itself rather than
adding source behavior. The fix's own correctness is verified below instead.
--self-testcase was run once with its subject broken, and thefailure is reported here: inverted — the test's own failure against the unpatched kernel is
the evidence the gate is needed (see the
OCCTSWIFT_REMOTE=1transcript above). Verified thegate itself works both directions:
OCCTSWIFT_REMOTE=1→ skipped;OCCTSWIFT_LOCAL=1→ runsand passes.
docs/CHANGELOG.mdis not in this diff.docs/SEMVER.mdis not in this diff.Verification
swift testforced against the exact remote kernel CI uses (OCCTSWIFT_REMOTE=1 swift test) run 6 times — clean every time, 0 crashes (was previously observed to crash acrossmultiple independent CI runs on this exact kernel).
Sources/andTests/) for any othercheckCompatibility(false)usageor any other path that could reach the same defect — none found; this was the sole trigger.
Notes for the reviewer
Filed as a standalone PR rather than bundled into #918 (the code-style PR that also touches
ThruSections-adjacent code) since this blocks CI broadly — every PR, not just one — and is asmall, self-contained, urgent fix that shouldn't wait on a larger PR's review cycle.
The underlying kernel gap (patches
0026/0027not yet in the pinned release asset) is not a newdefect to fix here — it's the normal, already-documented pre-release-vs-release-pin lifecycle
(
CLAUDE.md's own release process re-pointsPackage.swiftat a final asset that includeseverything). This PR fixes the test that shouldn't have run unguarded against the interim state,
matching the precedent already established for #913's own test.