Swift 5.5 has serious stack corruption bugs!

There is a lot of unhelpful hyperbole here in this thread. Bugs happen, even in compilers, and regardless of how long a feature has been in production you will still eventually be shocked to find that there's a carefully-crafted 5-line program that triggers a problem. I completely understand that when a compiler bug hits your code it's an unwelcome surprise that can be very, very hard to debug and work around. However, the tone of this conversation is actively harmful and reflects very poorly on this community.

We greatly appreciate the bug reports provided here by @taylorswift, which have helped us track down a previously-unknown miscompile with asynchronous calls. We have a fix that addresses all of the bugs reported at the beginning of this thread, and we'll look to roll it out as soon as it is feasible.

For some background, the problem itself is an unsafe coroutine optimization in the formation of asynchronous stack frames. The optimization seeks to reduce the size of asynchronous stack frames by evaluating when the lifetime of a value has ended before a next suspension point, in which case that value can be stored on the synchronous stack only and need not be preserved across the suspension point---which reduces overall heap usage (asynchronous stack frames go on the heap). This optimization failed to account for some kinds of control flow, so it would effectively optimize away live values, resulting in the observed asynchronous stack corruption bugs. The actual bug appears to have been introduced in July 2020 in LLVM's coroutine handling, so it's gone undiagnosed for more than a year despite LLVM coroutines being in use for a number of different features (e.g., C++20 coroutines in Clang, async functions in Swift). In the short term, we're disabling the optimization, at the cost of slightly larger asynchronous stack frames. Longer term, the optimization needs to be made sound because minimizing the size of the asynchronous stack is part of the overall performance storage for asynchronous code.

Doug

101 Likes