Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nondeterministic compiler crash in debug builds #18

Merged
merged 1 commit into from
Apr 10, 2021

Conversation

lorentey
Copy link
Member

@lorentey lorentey commented Apr 10, 2021

So as it turns out, the Swift compiler’s MergeModules phase (which SwiftPM uses in Debug builds) has a known issue with dependency cycles between separate source files — it rarely triggers, but when it does, swiftc hits an assertion complaining about a deserialization failure.

The v0.0.1 of Swift Collections happens to include such a cycle, but it only triggers the assertion on a small fraction of machines. I don’t yet know what exactly makes it nondeterministic, but it is reproducible by randomly reshuffling the source filenames of the OrderedSet implementation — a couple dozen randomizations will eventually lead to a state where it happens in every build.

The workaround is to put OrderedSet’s Sequence and RandomAccessCollection conformances in the same file. (OrderedSet uses the standard IndexingIterator, which requires a Collection conformance, while Collection itself refines Sequence — I believe this is the dependency cycle that is causing all this problem.)

Unfortunately, until we figure out what triggers the nondeterminism (or until the MergeModules action is fixed or replaced with something that actually, you know, works, this issue may keep randomly reoccurring. None of this makes much sense, but here we are. 😝

Resolves #7. (Verified by rebuilding the package with a couple thousand different file orderings.)

Checklist

  • I've read the Contribution Guidelines
  • My contributions are licensed under the Swift license.
  • I've followed the coding style of the rest of the project.
  • I've added tests covering all new code paths my change adds to the project (if appropriate).
  • I've added benchmarks covering new functionality (if appropriate).
  • I've verified that my change does not break any existing tests or introduce unexplained benchmark regressions.
  • I've updated the documentation if necessary.

So as it turns out, the Swift compiler’s MergeModules phase (which SwiftPM uses of in Debug builds) has a known issue with dependency cycles between separate source files — it rarely triggers, but when it does, swiftc hits an assertion complaining about a deserialization failure.

The v0.0.1 of Swift Collections happens to include such a cycle, but it only triggers the assertion on a small fraction of machines. I don’t yet know what exactly makes it nondeterministic, but it is reproducible by randomly reshuffling the source filenames of the OrderedSet implementation — a couple dozen randomizations will eventually lead to a state where it happens in every build.

The workaround is to put OrderedSet’s Sequence and RandomAccessCollection conformances in the same file. (OrderedSet uses the standard IndexingIterator, which requires a Collection conformance, while Collection itself refines Sequence — I believe this is the dependency cycle that is causing all this problem.)

Unfortunately, until we figure out what triggers the nondeterminism (or until the MergeModules action is replaced with something that actually, you know, works, this issue may keep randomly reoccurring. None of this makes much sense, but here we are. 😝
@lorentey
Copy link
Member Author

@swift-ci test

1 similar comment
@lorentey
Copy link
Member Author

@swift-ci test

@lorentey lorentey merged commit 2d719d7 into apple:main Apr 10, 2021
@lorentey lorentey deleted the fix-heisencrash branch April 10, 2021 07:17
@lorentey lorentey added this to the 0.0.2 milestone Apr 10, 2021
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.

Fails to compile (Abort trap: 6)
1 participant