We started migrating our codebase to Swift 6 language mode. In one of our networking interface, we abstract our networking call to use the withCheckedContinuation(isolation:function:_:) while still supporting the Combine-based data task publisher. Recently we got some weird crash after migrating to Xcode 16. This crash is from tvOS 18.0:
Project
+0x92f868
$ss23withCheckedContinuation9isolation8function_xScA_pSgYi_SSyScCyxs5NeverOGXEtYalFTwb (<compiler-generated>)
Called from
libswift_Concurrency
+0x05e9e4
swift::runJobInEstablishedExecutorContext
We’re running into similar crashes in Swift 5 language mode on Xcode 16 and 16.1, but it appears to only be from clients running iOS 18 developer beta 1 through 4. As a result we’re having to roll back our CI system to Xcode 15.4, but lots of our developers are already on Sequoia so they can’t downgrade from Xcode 16.
I feel similarly, but it had a large enough impact on crash free sessions during rollout that it would translate into an unacceptable revenue loss if crash rate were to hold steady as the rollout continued.
If you read the bottom of the thread Jon linked there is a fix for this: copy pasting the broken functions from the stdlib. We’ve been using it in production for weeks now with no problems.
I think it should be, but I don’t know enough about compilers and linkers to tell you how. What follows is going to be pure speculation on my part:
Assuming those libraries are prebuilt (if not, why not just fork them) you can probably find where they reference these symbols and modify those references to point to your own.
Whatever you use needs to only change the references in the code you shipped, and not any references to it in built in libraries that might be running in your process. Which rules out anything that might globally replace the definition, like @_dynamicReplacement or libraries like fishhook.
Yeah. I believe there is a pull request that adds isolation as a parameter to each of these functions, which is the root cause.
If memory serves, withTaskGroup is tricky because it uses a bunch of internal types. We don't call it in production in any of our apps, so we never bothered to fix it. But if you read the file it's defined in there's some stuff there that could maybe help you to call an older version?
As an aside, there are a few functions which don't crash despite having isolation added. We theorized that this is due to the ordering of the parameters being "safe," for example TaskLocal.withValue adds it in a position where presumably it is interpreted as being a String, and is subsequently never read by the body of withValue if I remember correctly. While withContinuation has it listed just before the closure itself, and therefore it's trying to use the isolation you pass in as the closure.