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

None being leaked in slicing (or memoryview creation) #3023

Closed
seberg opened this issue Jun 28, 2019 · 1 comment
Closed

None being leaked in slicing (or memoryview creation) #3023

seberg opened this issue Jun 28, 2019 · 1 comment

Comments

@seberg
Copy link
Contributor

seberg commented Jun 28, 2019

compiling the following code (within numpy, but I do not think that matters):

import array

def test_buffer():
    cdef uint32_t[:] randoms
    randoms = array.array("I", [10])
    memoryview(randoms)

will leak a reference to None on every call. The culprit is the memoryview(randoms) line, although it split into two parts on the C-level (so I do not think the call to the python memoryview itself is actually involved).

I can "fix" this by applying this patch:

diff --git a/Cython/Utility/MemoryView.pyx b/Cython/Utility/MemoryView.pyx
index 9cb897761..56d85a008 100644
--- a/Cython/Utility/MemoryView.pyx
+++ b/Cython/Utility/MemoryView.pyx
@@ -1018,7 +1018,7 @@ cdef memoryview_fromslice({{memviewslice_name}} memviewslice,
     result.view.buf = <void *> memviewslice.data
     result.view.ndim = ndim
     (<__pyx_buffer *> &result.view).obj = Py_None
-    Py_INCREF(Py_None)
+    #Py_INCREF(Py_None)
 
     if (<memoryview>memviewslice.memview).flags & PyBUF_WRITABLE:
         result.flags = PyBUF_RECORDS

but it seems unlikely on first sight that it is correct (I have difficulties following the code though). Obviously that reduces the refcount of None by one so patches over the issue since it gets called...

A reference count issue on None is harmless of course, but I am debugging numpy with pytest-leaks so its nice to keep even the harmless stuff clean.

@seberg
Copy link
Contributor Author

seberg commented Jun 30, 2019

OK, tracking things down a bit: The memoryviewslice is created with obj=None (I guess a fast path thing). As such inside the __dealloc__ (all the memoryview superclass), Py_ReleaseBuffer is skipped.

My best guess is that the cleanest fix would be to call Py_ XDECREF(obj) (or maybe no X) when skipping the Py_BufferRelease.

EDIT: Hmm, no, that doesn't seem right, obj can be None otherwise too it seems to me. Maybe some special handling with a comment is actually right. But I am a bit unsure about the whole obj=None dynamics.

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

Successfully merging a pull request may close this issue.

2 participants