fix(linux/pipewire): avoid memory leaks#5360
Conversation
|
In theory this PR shouldn't make a difference as C++ should manage memory for those types (std::shared_ptr, std::map, std::vector) by itself correctly for how they are used in kwingrab. @psyke83 maybe you can check if it makes a difference on your end as my tests are a bit inconclusive right now... |
d839b36 to
285f5e1
Compare
|
Doing more testing and also cleaning up pipewire's destructor a bit but so far no luck with the memory leak. It's almost a stable ~16MB increase per full capture re-init for both kwingrab and portalgrab so the culprit is likely somewhere in Almost forgot: If I can't find the source of the leak myself I'll change this PR to do some code maintenance (like rolling 'cleanup_stream()` into the destructor as it's not used anywhere else anymore und updating a few unnecessary things based on CLion/Sonar suggestions). |
Here's another interesting finding: The leak is only ~8MB per full capture re-init for both kwingrab and portalgrab when using VAAPI compared to ~16MB when using Vulkan encoding. |
|
This is part of the puzzle: With your PR branch applied, this resolves leaking with vaapi combined with kwin or portal capture. Vulkan still leaks, and software rendering breaks with the change as-is (haven't looked too deeply yet). Some capture methods employ an img_t override that does extra cleanup. Example: Sunshine/src/platform/linux/wlgrab.cpp Lines 25 to 33 in 3437a0b Sunshine/src/platform/linux/kmsgrab.cpp Lines 807 to 812 in 3437a0b In the case of Pipewire capture, alloc_img() is overridden to use the img_descriptor_t type, but we don't do any special cleanup via a destructor override, and the standard destructor in graphics.h only cleans up the sd fds. |
So we probably have to just add a subclassed img_descriptor_t with the extra cleanup for pipewire and use that in the override? Also is there a specific reason for pipewire using |
|
I'm not sure why that was done, but more investigation actually points this specific leak issue to be isolated to dummy_img: Sunshine/src/platform/linux/pipewire.cpp Lines 1069 to 1077 in 3437a0b Reverting my previous changes and instead short-circuiting dummy_img (inserting Edit: I won't be able to test thoroughly until later, but if it turns out that the destructor really does need to do cleanup, being able to distinguish the ownership between dummy_img()'s vs other img_descriptor_t allocations would probably resolve the double-free crashing. Something like the below snippet. But perhaps there's a more appropriate fix. |
Both kmsgrab and wlgrab implement Sunshine/src/platform/linux/kmsgrab.cpp Lines 1685 to 1692 in 3437a0b Sunshine/src/platform/linux/kmsgrab.cpp Lines 1762 to 1771 in 3437a0b Sunshine/src/platform/linux/wlgrab.cpp Lines 141 to 149 in 3437a0b So I'd say that pipewire.cpp should just do the same thing to keep things similar between linux capture methods. There seems to be no functional disadvantage from doing it this way. |
…ources to ensure nothing is leaking
…er used outside of it
5d88955 to
6a2e3b9
Compare
|
@psyke83 I think you've found the main issues here. To keep things simple and in line with kmsgrab/wlgrab I've just added a subclass for those specific img_descriptor_t's. Also updated There might still be a small leak occurring but that would be somewhere affecting all capture methods including kmsgrab/wlgrab and a separate issue. I also can confirm the memory leak in vulkan encoding as that is still happening albeit at half the previous increase (which was somewhat to be expected due to given behaviour). I'll update the PR and mark this as ready unless you have something to add. |
This is the same implementation as for kmsgrab/wlgrab Co-Authored-By: Psyke83 <psyke83@users.noreply.github.com>
Stop memory from leaking on pipewire's images like wlgrab and kmsgrab do. Co-Authored-By: Psyke83 <psyke83@users.noreply.github.com>
6a2e3b9 to
8d011b5
Compare
|




Description
In #5346 a memory leak in pipewire-based capture methods (portalgrab, kwingrab) was identified.
This PR is a (first) step to fix potential causes in pipewire-based capture by:
dummy_img()to just return 0 without allocating memory as that is enough to mark a dummy image (see also kmsgrab/wlgrab)egl::img_descriptor_tto free allocated memory for the pipewire specificalloc_image()override by using a new subclass (also like kmsgrab/wlgrab do).kwingrabby callingreset()on any created shared_ptr instances in screencast_t andclear()on used lists/maps in screencast_t during destruction.pipewire_tdestruction sequence and rollcleanup_streamin as is is never used outside of it.Screenshot
Issues Fixed or Closed
Roadmap Issues
Type of Change
Checklist
AI Usage