New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-6848] Protocol conformance registration on Linux leaks in Swift 4.1 #49397
Comments
At the request of @alblue I tried a couple of tests to narrow things down. Adding an extra call to |
In fact I have a simpler repro. The following Swift file also leaks in the same way: import Foundation
let data = Data(base64Encoded: "UE9TVCAvIEhUVFAvMS4wDQpDb250ZW50LUxlbmd0aDoNCg0K")!
print(data.count) |
Some bisects on the Swift 4.1 nightlies reveal that |
Ok, let's remove protocol P { }
let x: Any = 1
let y = x as? P I think at this point we can call this either a compiler or standard library bug. |
@swift-ci create |
The runtime does need to allocate memory in _registerProtocolProtocols to track the sections in which it can find protocol conformances. That'll happen the first time one dynamically queries conformances (e.g., triggered here by the "as? P"), as well as any time one dlopen's another shared library. We hold on to the memory forever because we may need to rescan these sections later on. The actual allocations here should be very few, so if we're seeing a lot of growth here that would be a bug. However, it looks like something where we need to whitelist these allocations as intentionally never freed. |
@DougGregor Are you sure that's what's happening here? Both valgrind and ASAN are adamant that the allocations are entirely lost: that is, they're heap-allocated and there are no pointers remaining to them. That's not quite the same as "allocating but never freeing": it's "allocating and then losing". |
Put another way: older versions of the runtime on Linux do not trip this issue, and the Darwin runtime does not either. |
Oh, they're entirely lost. That is indeed bad! |
And now I see the "definitely lost"; sorry for jumping the gun here. |
No problem, it took me a while to convince myself this was a real problem too. FWIW, I should stress that this isn't a particularly high-urgency leak, unlike SR-6849. The size of the leak in this case is small: in all my tests I've never seen it leak more than 64 bytes. This doesn't pose a threat to any running programs, obviously![]( It mostly just makes ASAN tricky to use on Linux, which is a bit sad. The Swift team has done some great work to bring sanitizers to the Linux platform, I'd really like people to be able to use them effectively) |
This bit of code over at https://github.com/apple/swift/blob/master/stdlib/public/runtime/ProtocolConformance.cpp#L291-L293 is potential suspicious: // Conformance cache should always be sufficiently initialized by this point.
_registerProtocolConformances(Conformances.unsafeGetAlreadyInitialized(),
recordsBegin, recordsEnd); It's plausible that, with ELF, we're getting into this code (addImageProtocolConformanceBlockCallback) before the Conformances table gets initialized. I'm not set up to easily test this at the moment, but I'd want to try changing this to: // Conformance cache should always be sufficiently initialized by this point.
_registerProtocolConformances(Conformances.get(), recordsBegin, recordsEnd); |
Environment
Linux Ubuntu 16.04
Swift 4.1 Nightly from the 25th of January
Additional Detail from JIRA
md5: 3e2f791cf990fa92581d802dccce573e
Issue Description:
Spotted while attempting to fuzz test some Swift projects.
It seems that something in protocol conformance is leaking on the Swift nightly builds. At the very least a trivial program is capable of leaking the protocol conformances. Compiling the following program with ASAN on Linux immediately shows a leak:
Compiling with ASAN (
swiftc -sanitize=address test.swift
) from one of the recent 4.1 nightlies and then running gives this output:Removing ASAN and using Valgrind gives us a more useful stack trace:
This is not the only leak here, I have found others, I just don't yet have small reproducers for them.
The text was updated successfully, but these errors were encountered: