New Xcode, old libswift_Concurrency.dylib

Apps using Structured Concurrency built with Xcode 13.3.1 are still embedded with libswift_Concurrency.dylib 5.5.2. To tests this:

  1. create an iOS app from any Xcode template
  2. add some structured concurrency to it. For example: func echo(value: String) async -> String { value }
  3. lower deployment target to iOS 14 (or 13)
  4. build for simulator iOS 14.x or archive the app
  5. find libswift_Concurrency.dylib in build products and checkout its version

Do I understand correctly that all fixes and improvements of structured concurrency runtime are only available to devices with version iOS 15.4+ (and corresponding macOS, tvOS, watchOS versions)?

If that so, is it possible to update libswift_Concurrency.dylib shipped as a part of Xcode toolchain to 5.6? I hope it would somehow be possible to have fixes and improvements of structured concurrency runtime on iOS versions prior to 15.4.

I'm surprised by this as well. I've confirmed that they're not only the same version but literally the same executable, as the MD5s match. @Douglas_Gregor can you clarify what our expectations should be here? Will the backward deployment library be updated as the runtime evolves, or will be always be equivalent to the 5.5.2 runtime?

Backward-deployment libraries have always been the same (or equivalent) to the oldest version shipped in an OS, so that features (and bugs) follow a strict progression. Otherwise you could get Library v2 on iOS 14, followed by Library v1 on iOS 15, followed by Library v2 on iOS 16. Newer versions of the library might also integrate more deeply with the OS since they don't have to worry about backwards-deployment / multiple distribution methods.

EDIT: and you can't use a backwards-deployment library on an OS that has the library too, or it might be incompatible with uses of the library in other OS frameworks (say, Combine).


Jordan has it right. I would add that we can investigate fixes for bad enough bugs, but it's hard because we also have to figure out a way to patch it in already-shipping OSes and not just in the back-deployment library. We don't want to intentionally create a situation where a bug is unavoidable, but only on some exact release of an OS.


I don't know that I've seen it stated like this before, thanks. It makes sense, from a certain perspective at least. That does seem to imply that concurrency back deployment will not only never see future bug fixes, but will never receive the full set of concurrency features, like custom executors, the time features, or particular algorithms. Perhaps these things could become available with Swift 6 since it could, presumably, ship the full Swift runtime back to some older OS?


The basic ABI support for custom executors for actors is already present in the concurrency library (and used by MainActor), so that actually would naturally back-deploy. Features for customizing the execution of tasks more generally may or may not back-deploy, depending on the feature; in my experience, people mean a lot of different things when they say "custom executors".


in my experience, people mean a lot of different things when they say "custom executors".

It's like all new features that are slightly related to some field one cares about, you start projecting your own needs and wishes on the abstract topic and use your confirmation bias to the best extent possible when listening on explanations :wink: Just human nature!

Confirming that the latest formal description of custom executors still is on point? It'll be a very nice additional tool to the Concurrency toolbox IMHO.

Thank you for clarification. As I anticipated the complexity of back-deplying is quite high. I want to narrow down the conversation to what seems critical to me: back-deploying fixes.

My goal is to push for an adoption of structured concurrency for at my company. I clearly see an overwhelming set of reasons for the adoption even without any features introduced since Swift 5.5. However because we have millions of daily users we just cannot make such an important technological decision lighly.

To assess risks we've made a production test (ran some structured concurrency code on background for 1% of users) and found a blocker (ticket and related post) for the adoption. I had hope that in Swift 5.6 the issue will be fixed and we would be able to resume adoption considerations. There are evidence that the issue was fixed in libswift_Concurrency.dylib 5.6. The bug is not reproducible on iOS 15.4 but still reproducible on prior iOS versions due to libswift_Concurrency.dylib 5.5.2 being embedded.

I assume many Swift engineers are in a similar situation on the adoption of structured concurrency. We cannot adopt structured concurrency for now because our crash rate is going to go over the crash rate budget. So the choice is to either:

  • keep asking for back-deployment of fixes

  • shelf the adoption of structured concurrency until the deployment target is raised to 15.4. Which could take many years.

I want to know if there is a hope to unlock the adoption or will we be limited to GCD+Combine for a while.


I think what we've learned here is that there is no libswift_Concurrency.dylib 5.6, just the updated runtime deployed in the OSes with the 15.4 / 12.3 update.

It seems the only way we'd ever get those fixes would be to ship an updated back deployment library, which seems unlikely. There are other runtime issues it would be nice to have fixed as well. Personally, I'm okay telling users they can only use the latest / last release of a major OS version, so 15.0 - 15.3 wouldn't matter anymore, if the back deployment could maintain compatibility all the way back. Otherwise we're basically in a state where back deployment doesn't really exist at all.

I've found libswift_Concurrency.dylib 5.6 as a part of iOS 15.4 device support at ~/Library/Developer/Xcode/iOS DeviceSupport/15.4.1 (19E258) arm64e/Symbols/usr/lib/swift/ (probably need to instal Xcode command line tools to get this). Maybe is the wrong/incompatible one but it exists. I also looked at a disassembly of a function swift::TaskGroup::offer(swift::AsyncTask*, swift::AsyncContext*) that caused a crash in question it is definitely different from the one in 5.5.2.

Sure, the concurrency feature is still in a separate library shipped as part of the OS, and that's a version of it for development. I think the back deployment library is a separate implementation with the same name, but I really don't know. My point was there's no 5.6 version of the back deployment library as far as we know.

1 Like

We at Apple are looking into back-deploying these bug fixes (specifically, the ones affecting task groups) to the 5.5.x concurrency runtime. It should be possible, but as with back deployment in general we aren’t certain until we’ve tried implementing it. Such a change would address the bugs both on operating system versions containing the Swift 5.5 runtime (e.g., iOS 15.0) as well as operating system versions on which the back-deployed concurrency runtime is used (e.g., iOS 13.0-14.x).



This effort is greatly appreciated.
Is there any chance this could be looked into in the next couple of quarters? My company is intending to ship some products that would greatly benefit from structured concurrency.

Just curious, have there been any findings r/e the feasibility of back-deploying these task group-related fixes? I saw that TaskGroup::offer crash relatively frequently in production, which seems like a blocker for using TaskGroup-related functionality generally since we're targeting < iOS 15.4.

I am wondering too. Back deployment variant of libswift_Concurrency.dylib seems to be the same old 5.5.2 even in the latest Xcode 14 beta 6.
Looks like @Douglas_Gregor has worked on back deployment as part of 5.7 but I do not know if that work will get into Xcode release.

We’re investigating. As always, we can’t make firm commitments right now.


These fixes were included in Xcode 14.1 RC2.