Closed BradLarson closed 1 year ago
Looking at CI this seems to be resolved. Can we close this?
I just tested the above-described reproducer against the latest PostgresNIO commits (tagged version 1.14.0) and the latest nightly Swift toolchain release (2023-04-20) and the segmentation fault and related address sanitizer warnings are still there in the same places. It's possible that CI is not experiencing the same conditions, running an optimized build such that parseCompleteReceived()
and therefore avoidingStateMachineCoW()
are called in the same way. Debug or unoptimized builds will not exhibit this same behavior.
This miscompile should be resolved at the compiler level as of https://github.com/apple/swift/pull/66221
Describe the bug
Starting with nightly Swift snapshots in early January (and with the 5.9 Swift release branch), we've been experiencing segmentation faults in release builds of a project using PostgresNIO. We've been able to minimize this to what appears to be a miscompile of the
avoidingStateMachineCoW()
function onConnectionStateMachine
due to something going wrong in an optimization pass.This seems to be a compiler issue, and we've reported it on apple/swift here. Until fixed within the compiler, people using PostgresNIO in a project built for release may start experiencing random segfaults starting with the 5.9 toolchain. We're examining the compiler-side optimization issue further.
Removing the
avoidingStateMachineCoW()
function and operating directly on the ConnectionStateMachine prevents this miscompile. A question we have is whetheravoidingStateMachineCoW()
provided a significant performance benefit, and if so whether that was still the case under current versions of the compiler. If it does not have a noticeable performance impact today, would it be possible to remove this function to evade the miscompile?To Reproduce
We've provided steps to set up a sample project that exhibits this behavior in our issue on apple/swift. Running a
swift run -c release
should lead to a segfault within PostgresNIO using Swift nightly toolchains from the start of January onward, or toolchains based on the 5.9 release branch.Additionally, you can see the premature release of a context object occurs within the
avoidingStateMachineCoW()
function by changing the@inline(__always)
to@inline(never)
before the definition ofavoidingStateMachineCoW()
and running address sanitizer usingswift run -c release --sanitize=address
. You'll get a report that looks like the following:Expected behavior
The example project should run to completion without a segfault under optimized builds, as it does for debug builds or when
avoidingStateMachineCoW()
is removed in favor of direct access to theConnectionStateMachine
.Environment