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-4249] Result of String.cstring(using:) deallocated prematurely when passed into bridged C function #46832
Comments
Workaround: use |
Comment by Matt Deckard (JIRA) @belkadan, this bug doesn't involve optionals at all so I'm not sure how |
Comment by Matt Deckard (JIRA) Including a snippet from the attached project for illustration public func setStringFieldUnsafely(_ newValue: String) {
// For some reason this will sometimes dealloc before the C function is done with it
// Probably a compiler bug?
Wrapped_setStringField(wrapped, newValue.cString(using: .utf8))
}
public func setStringFieldSafely(_ newValue: String) {
// For some reason this works, while the above method does not
let cstr = newValue.cString(using: .utf8)
Wrapped_setStringField(wrapped, cstr)
} |
|
Comment by Matt Deckard (JIRA) @belkadan, but just extracting the result into a local variable is enough to workaround the issue, even if that variable is still an optional type. The example above already illustrates this but even if you make it the type explicitly optional the bug still does not occur: public func setStringFieldSafely(_ newValue: String) {
// For some reason this works, while the above method does not
let cstr : [CChar]? = newValue.cString(using: .utf8)
Wrapped_setStringField(wrapped, cstr)
} |
I suspect we just don't optimize the destruction of named variables quite as much as we do temporaries. Or maybe it will reoccur with optimizations on, but not when they're off. |
Attachment: Download
Additional Detail from JIRA
md5: 83e016767daba6b9dfe93e338be127af
duplicates:
Issue Description:
Steps to reproduce:
Open the attached project
Run the
test_set_stringField_SUCCEEDS
test and see it passRun the
test_set_stringField_FAILS
test and see that it crashes at thestrnlen()
call inside the wrapped C++ classThe only difference between the two tests is which setter method they call on the Wrapper. One of them saves the result of
cstring(using: )
in a local variable before passing it to the C setter, and the other does it inline. For some reason, in the latter case the result seems to be getting freed up before the function it is being passed into is finished executing, resulting in the crashThe text was updated successfully, but these errors were encountered: