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

Remove macOS memory leaks when writing to the clipboard #105

Merged
merged 2 commits into from
Jul 26, 2023

Conversation

complexspaces
Copy link
Collaborator

@complexspaces complexspaces commented Jul 24, 2023

This PR removes the long-outstanding memory leaks in the macOS clipboard backend. After some experimentation, I found that these methods had leaky implementations:

  • set_string
  • set_image
  • set_html

None of the reading functions had leaks AFAICT.

The root cause of (most) the issues was that several calls to msg_send! were not passing their arguments correctly. Instead of passing a pointer to the relevant Objective-C object to a class function, they passed the value itself via move. This worked before since the value could still be read by the system, but it became problematic with memory usage. As the system functions only expected a reference to the data, none of them attempted to free it since this would lead to a use-after-free or double-free in user code. So to Rust's eyes, the value was moved across the FFI boundary and never had their destructors called, essentially the same if mem::forget had been used.

To resolve these problems, I corrected the callsites to pass a reference/pointer across like the APIs expected.

The other issue was that when creating an NSImage class allocation, the previous code was accidentally increasing the reference count after allocating instead of taking ownership. This resulted in an unbalanced retain count that meant the resulting class could never be freed. Allocating a class always has at least one reference, otherwise it would be instantly reclaimed by the runtime. Our user code becomes the object's new owner once the runtime has finished preparing it.

Relates to #24

Previously, a number of functions passed some runtime-owned object by
value, in Rust terms. However, the system pasteboard APIs were only
expecting a reference (pointer) to the object instead (like many
Objective-C APIs do). As a result, the object was moved into the FFI
which was, as expected, not attempting to free the object when it was
done.
@complexspaces complexspaces changed the title Remove macOS memory leaks Remove macOS memory leaks due when writing to the clipboard Jul 26, 2023
@complexspaces complexspaces changed the title Remove macOS memory leaks due when writing to the clipboard Remove macOS memory leaks when writing to the clipboard Jul 26, 2023
@complexspaces
Copy link
Collaborator Author

This PR does not fix all of the reported issues like I originally hoped, but these are still valid leaks that should be fixed, so I'm going to merge this in parallel with investigating the getter leaks.

@complexspaces complexspaces merged commit f409d08 into master Jul 26, 2023
@HuakunShen
Copy link

Thank you for your work! @complexspaces

@complexspaces complexspaces deleted the plug-apple-leaks branch September 21, 2023 16:31
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.

2 participants