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-7734] libxpc and libdispatch objects returned to Swift from C will leak #653
Comments
Comment by Pierre Habouzit (JIRA) Your sample project is bogus as it violates ARC rules. You use ARC conventions through the importer, however you implemented obj-c returning functions in a C file that doesn't understand ARC, so it is your responsibility to make sure the header and implementation match, and they don't. Please read https://clang.llvm.org/docs/AutomaticReferenceCounting.html#retained-return-values you are returning an obj-c type, so the Create naming rule doesn't apply (see it described here: https://clang.llvm.org/docs/AutomaticReferenceCounting.html#c-retainable-pointer-types it only applies to CF types). With this information, there are two ways to fix your project:
|
Comment by Pierre Habouzit (JIRA) F*![](@#*(&)@#(*&@!# stupid markdown I can't type code in that BS |
With respect, this objection misses the mark. The types used by libxpc and libdispatch are not strictly Objective-C types in the sense that they are only available to Objective-C (and indeed, at least in the case of libdispatch, its types originally weren't Objective-C objects, as that compliance was only added in OS X 10.8 and iOS 6.0). Both libraries are available to plain C code, where it's valid to use them, and in which case their types can be manually retained and released via xpc_retain(), xpc_release(), dispatch_retain(), dispatch_release(), etc. In this case, the objects cannot be returned with a +0 retain count, as the plain C interface does not provide any way of which I am aware to do that. Furthermore, it is possible that you do not control the C code you have to interact with, in which case modifying the C file's headers is not a valid option. This code then becomes impossible to use in Swift without leaking memory. |
Furthermore, even if you do control the original C code, this isn't a good solution, because adding __attribute__((ns_returns_retained)) to the MoreLeaks project generates a compiler warning: "'ns_returns_retained' attribute only applies to functions that return an Objective-C object" |
Comment by Pierre Habouzit (JIRA) No it doesn't miss the mark, these types are objective-C objects when used in objective-C exactly so that the importer can reason about them being refcounted. As of the warning, I think it's easy enough to ```C Bridging C backed objective-C objects into Swift does require this kind of jumping through hoops, and if you don't like it, then use pure obj-c please. |
1. Swift's importer works just fine with CFType objects, which are also technically Objective-C objects under the hood thanks to the toll-free bridge, and it does the right thing with them. Also as I said before, sometimes you are working with someone else's code and do not have the ability to change the headers. 2. Is this level of rudeness really necessary? |
Pierre is correct. Dispatch and XPC types aren't "Objective-C types under the hood"; they're Objective-C types in any context where Objective-C is enabled. (You can see the implementation of this in the <os/object.h> header.) It was a decision to let that stand in Swift, and one we're not going to change at this point. From the compiler's point of view, this is the same as declaring a function like this:
and asking for a way to treat that as +1. |
Er, to sum it up:
|
Thank you, Jordan, for your calm and diplomatic response, here and in general. I apologize for getting my feathers ruffled earlier, but it does take a non-trivial amount of time and effort to think up, test, and write reports for corner cases like this, and I appreciate your respectful and non-dismissive tone even in situations where we don't agree on our conclusions. |
Attachment: Download
Environment
Xcode 9.3
Xcode 9.4 beta 2
Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1)
Apple Swift version 4.1.1 (swiftlang-902.0.53 clang-902.0.39.2)
Apple Swift version 4.2-dev (LLVM 072be1cf17, Clang c7422ffe24, Swift 3843d39297)
Additional Detail from JIRA
md5: 706f548fe2f336dd74986ef871d8fddc
Issue Description:
If Swift encounters a C header containing functions which return libxpc or libdispatch objects, like so:
It interprets them thusly:
Unfortunately, in each case, it assumes the returned object has a retain count of +0. However, as the function is in straight C, it cannot return less than +1 without the object being deallocated. This results in Swift generating a retain for the returned objects upon receiving them, which results in them being leaked.
Swift code:
Instruments history for the XPC dictionary:
Instruments history for the dispatch queue:
To solve this, both of these types of objects should probably be imported as Unmanaged, as CFType objects are.
I've attached a sample project which will demonstrate the problem.
The text was updated successfully, but these errors were encountered: