Skip to content
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

Cleanup lifetime management around NSData.bytes. #2994

Merged
merged 1 commit into from Mar 31, 2021

Conversation

Lukasa
Copy link
Contributor

@Lukasa Lukasa commented Mar 29, 2021

Several blocks of code in Foundation use the .bytes member on NSData to
construct an interior pointer. However, NSData can potentially be freed
very early, and in newer Swift releases is more likely to do so, leading
to this pointer dangling.

This patch attempts a minimal change by forcing the NSData object to
live longer using withExtendedLifetime. This should resolve the misuse
fairly effectively. It does not address cases where the code could
potentially be entirely rewritten to be more efficient or more sensible,
because I wasn't here to engage in a complete refactor.

@spevans
Copy link
Collaborator

spevans commented Mar 29, 2021

@swift-ci test

@spevans
Copy link
Collaborator

spevans commented Mar 29, 2021

Could you apply the patch in https://gist.github.com/spevans/c2c6a15b4cae1c376564ea434bda3eea
It should fix the compile errors.

@Lukasa Lukasa force-pushed the cb-lifetime-management-in-nsstring branch from 9487a49 to 3633901 Compare March 29, 2021 09:40
@Lukasa
Copy link
Contributor Author

Lukasa commented Mar 29, 2021

@swift-ci please test

@Lukasa Lukasa force-pushed the cb-lifetime-management-in-nsstring branch from 1a47cdd to b801a26 Compare March 29, 2021 13:20
@Lukasa
Copy link
Contributor Author

Lukasa commented Mar 29, 2021

@swift-ci please test

@Lukasa
Copy link
Contributor Author

Lukasa commented Mar 30, 2021

@spevans So it looks like we're down to simple pre-existing test failures in XML. I assume we don't have any particular reason to think those XML failures are related to this code. Are you happy to merge as-is or do we need to fix that failure too?

@spevans
Copy link
Collaborator

spevans commented Mar 30, 2021

Correct, the XML code does have long standing underlying memory issues. Could you apply this patch to yours to disable that XML test:

https://gist.github.com/spevans/a7306641613a6531b1e977f321ea7bbb

And then we can retest and merge. I testest your PR with that patch and it passes on Ubuntus16,18 & 20

I think we should also backport your fixes to 5.4 (without the XML test disable)

@Lukasa
Copy link
Contributor Author

Lukasa commented Mar 30, 2021

I don't think this is a memory issue. Memory issues would be more unstable than this. It seems like a logical issue.

@Lukasa
Copy link
Contributor Author

Lukasa commented Mar 30, 2021

Specifically, it seems like the CFXML function _searchNamespace just...does not work.

Several blocks of code in Foundation use the .bytes member on NSData to
construct an interior pointer. However, NSData can potentially be freed
very early, and in newer Swift releases is more likely to do so, leading
to this pointer dangling. Similar problems exist around code that
aggressively passes ARC-ed objects through unmanaged pointers.

This patch attempts a minimal change by forcing the offending objects to
live longer using withExtendedLifetime. This should resolve the misuse
fairly effectively. It does not address cases where the code could
potentially be entirely rewritten to be more efficient or more sensible,
because I wasn't here to engage in a complete refactor.
@Lukasa Lukasa force-pushed the cb-lifetime-management-in-nsstring branch from b801a26 to a8d300d Compare March 30, 2021 09:01
@Lukasa
Copy link
Contributor Author

Lukasa commented Mar 30, 2021

@swift-ci please test

@spevans
Copy link
Collaborator

spevans commented Mar 30, 2021

@swift-ci test

@spevans
Copy link
Collaborator

spevans commented Mar 30, 2021

@swift-ci test linux

element.removeAttribute(forName: "ns1:name")
XCTAssertNil(element.attribute(forLocalName: "name", uri: uriNs1), "ns1:name removed")

withExtendedLifetime(root) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't want to indent a bunch of code, you can do
defer { withExtendedLifetime(root) {} }

@spevans
Copy link
Collaborator

spevans commented Mar 31, 2021

@swift-ci test linux

1 similar comment
@Lukasa
Copy link
Contributor Author

Lukasa commented Mar 31, 2021

@swift-ci test linux

@spevans
Copy link
Collaborator

spevans commented Mar 31, 2021

I believe there are still some further fixes that will be required given the number of uses of unsafeBitCast in sclf to pass objects to CoreFoundation functions, however all of these fixes in this PR are valid so am going to merge this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants