-
-
Notifications
You must be signed in to change notification settings - Fork 168
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
Decref an object because cython increfed it [memory leak] #2665
Decref an object because cython increfed it [memory leak] #2665
Conversation
@@ -1233,6 +1234,7 @@ cdef class Renderer: | |||
raise MemoryError("not enough memory for the surface") | |||
|
|||
surface = <object>pgSurface_New2(surf, 1) | |||
Py_DECREF(surface) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this should be considered a Cython bug and reported? Or is this a known and documented thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I stumbled across similar concerns while searching for an answer, but everyone said that it's intended behavior, perchance, because something like <object>1
would create a Python int
, for example (so, need to increment the reference count).
Anyway, some relevant bits I found:
https://stackoverflow.com/a/32562120/14531062
https://stackoverflow.com/a/56686757/14531062
https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html?highlight=%22except%20%20%22#python-objects-as-parameters-and-return-values
cython/cython#2589
So yeah, seems to be expected and I guess it does make sense if the usual usecase is to directly go from C structs and stuff to Python objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So there must a memory leak, but I don't think it's due to the refcount being wrong. I just passed the return value of the function to sys.getrefcount
, which returns the expected value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were you doing
surf = renderer.to_surface()
print(sys.getrefcount(surf))
or directly? Because that returns two different results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was doing it directly, and I got a 2, which I thought is expected, but actually I was wrong. So yeah, this fix is correct.
Going through one of the links you posted, I see an alternate fix involves changing the declaration itself to avoid the cast, and IMO that is a neater solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no clue how to implement that alternate fix which I assume you meant declaring surface
to be a PyObject pointer and thus it gets passed by reference, but then I'd think you need to incref it if the surface is actually passed since it wouldn't get increfed automatically and I'm not even entirely sure how that mechanic works there, the current fix seems simple enough though, it's only 2 lines after all and quite familiar usage of the C API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I was thinking, is replacing pgSurfaceObject *pgSurface_New2(SDL_Surface *info, int owner)
with object pgSurface_New2(SDL_Surface *info, int owner)
in video.pxd
and then the cast could be removed easily
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, that also appears to have fixed the memory leak, much simpler as well 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slight issue, this is so far failing on emscripten due to incompatible pointer types
https://github.com/pygame-community/pygame-ce/actions/runs/7533032001/job/20504804242?pr=2665#step:7:201
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrmmm, not sure why this is happening, -Werror
is supposed to be ignored on cython files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for the PR 🎉
Left a review for your consideration, but this PR is mergeable in its current state too. Maybe we could squash and merge this PR because the first commit is huge and the second does a lot of reverting
PS: please ignore my alt's reviews, I forgor to switch accounts 💀
5e1e506
to
405ee1a
Compare
Changed cython version to minimize diff Tests for good measure Added a comment to clarify DECREF usage
9b2d8c0
to
61ea93e
Compare
The web build is failing here.
|
Yes, already mentioned that to Ankith in that review comment, not sure what to do though. |
This reverts commit 16ec2dc.
Reverted back to using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay looks like the alternate fix isn't passing WASM CI even after trying some workarounds. Let's go ahead with this PR, thanks! 👍
PS: let's squash and merge this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
* Decref an object because cython increfed it Tests for good measure Added a comment to clarify DECREF usage Skip test on pypy
MRE:
Basically casting to
object
incython
increments the reference count, butpgSurface_New2
already returns an object with an incremented reference count, so have to decrement whatcython
has added on top of that.