Set 512KiB to thread stack size for static Linux binary#6291
Set 512KiB to thread stack size for static Linux binary#6291SimplyDanny merged 4 commits intorealm:mainfrom
Conversation
251a4e4 to
92a7d25
Compare
SimplyDanny
left a comment
There was a problem hiding this comment.
That's awesome @ainame! Thank you so much for the analysis. That wasn't an easy one.
Would you like to add a changelog entry as well? It's the only form of credit I can offer you. 🙏
| --product swiftlint \ | ||
| --swift-sdk ${{ matrix.swift_sdk }} \ | ||
| -Xswiftc -DSWIFTLINT_DISABLE_SOURCEKIT \ | ||
| -Xlinker -z -Xlinker stack-size=0x80000 # 512KiB |
There was a problem hiding this comment.
Did you try to run this on a Linux machine? It doesn't work on macOS, because the linker expects different arguments to set the stack size.
There was a problem hiding this comment.
Yes I have created this page's binaries with this command on Ubuntu (VM).
https://github.com/ainame/swiftlint-static-test/releases/tag/test3
-z stack-size=VALUE format is supported by ld. Apple's ld64 doesn't support it unfortunately. But that's okay since the binary will be built on ubuntu-24.04/ubuntu-24.04-arm runner, right?
% lld --help
lld is a generic driver.
Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld (WebAssembly) instead
% ld64.lld --help | grep stack
%
stack-size=value
Specify a stack size for an ELF "PT_GNU_STACK" segment. Specifying zero will override any
default non-zero sized "PT_GNU_STACK" segment creation.
There was a problem hiding this comment.
Yes, that's totally fine. I build the binaries on macOS from time to time for testing purposes. So far they worked without the stack size increase. For the release, that's Ubuntu's job. I may trigger a new release right after merging your PR, so that we can verify the binaries again.
There was a problem hiding this comment.
Oh -Xlinker -z -Xlinker stack-size=0x80000 worked with other project indeed.
I assume that the current toolchains might have applied the linker options for SwiftLintCoreMacros target, which is built and run for macOS? and failed. I haven't checked logs or any though.
There was a problem hiding this comment.
Yes, it exactly failed while linking the macro tool. I'm not sure how to configure the flags in more detail in order to determine to which steps they should be applied to with SPM.
|
I updated CHANGELOG.md as well🙏 |
46857ce to
cb50fe2
Compare
| --product swiftlint \ | ||
| --swift-sdk ${{ matrix.swift_sdk }} \ | ||
| -Xswiftc -DSWIFTLINT_DISABLE_SOURCEKIT \ | ||
| -Xlinker -z -Xlinker stack-size=0x80000 # 512KiB |
There was a problem hiding this comment.
Yes, that's totally fine. I build the binaries on macOS from time to time for testing purposes. So far they worked without the stack size increase. For the release, that's Ubuntu's job. I may trigger a new release right after merging your PR, so that we can verify the binaries again.
|
There we go. I noticed that the static binaries lint significantly slower than the dynamic ones. That's also something requiring attention before they can leave their experimental state. |
|
I did casual benchmark and tried a potential fix https://github.com/microsoft/mimalloc. It's promising already. |
That'd be highly appreciated! Please go ahead. 🙏 |
Closes #6287
Background
In #6287, I reported crashes occurred with 0.61.0's new fully static Linux binaries.
Since then I managed to replicate the crashes on GitHub Actions.
In short, it's easy to replicate if you run
swiftlint-staticagainst https://github.com/apple/swift-nio or https://github.com/pointfreeco/isowords repos.https://github.com/ainame/swiftlint-static-test/actions/runs/18432502301
I also did debug
swiftlint-staticwith lldb and identified the root cause, which was stack exhaustion.#6287 (comment)
What
Static Linux SDK comes with musl and musl has limited thread stack size by default - 128KiB, which is smaller than the default size for Darwin's pthread 512KiB.
https://wiki.musl-libc.org/functional-differences-from-glibc.html
https://github.com/apple-oss-distributions/libpthread/blob/1ebf56b3a702df53213c2996e5e128a535d2577e/src/pthread.c#L84-L85
I think SwiftLint running on Linux should have the same default stack size as on macOS,
so it can lint source files of equivalent complexity.
How
Thanks to this we can specify default thread stack size via
swift buildcommand.I updated
release.ymlto use 512KiB, like belowTest
https://github.com/ainame/swiftlint-static-test/actions/runs/18432924761
There are four jobs in matrix
(see details of the compile options and the patch here https://github.com/ainame/swiftlint-static-test/releases/tag/test3)
If
swiftlint-static lintsuccessfully exit (0 or 2), the job succeeds.And thanks to the small patch, you can actually see 512KiB stack size is used for each DispatchQueue.