C++ or Cython memory leakage?
I am working on a python extension module written in cython, that wraps a
C++ class I have written.
The crash
I have a simple python code that imports this python module and process
some data with it. Now, about 1 time out of 4, the program segfaults just
before termination, after the calls to the module. This meaning as well
that all the data is correctly processed. It segfaults like this:
/Users/axe/anaconda/bin/python.app: line 2: 73168 Segmentation fault: 11
debugging with gdb, running gdb python and then run code.py, I get
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: 13 at address: 0x0000000000000000
0x00000001000894ae in PyObject_ClearWeakRefs ()
the output of backtrace is
#0 0x00000001000894ae in PyObject_ClearWeakRefs ()
#1 0x00000001010edae4 in array_dealloc ()
#2 0x000000010007503e in tupledealloc ()
#3 0x00000001000559b7 in insertdict_by_entry ()
#4 0x0000000100059177 in PyDict_SetItem ()
#5 0x000000010005d286 in _PyModule_Clear ()
#6 0x00000001000df8cd in PyImport_Cleanup ()
#7 0x00000001000f0027 in Py_Finalize ()
#8 0x0000000100107e1b in Py_Main ()
#9 0x0000000100000f54 in start ()
So the segfault happens outside of my python code. I mention that the
problem persists if I run the code from within ipython, or change
interpreter/ipython to the one from the Enthought distribution, or if I
downgrade Cython from 1.9.1 to 1.6.
Memory leakage in C++ (?)
Since this could look like a memory leak (please let me know if there are
other possible explanations) in the C++ code, I ran Valgrind on some C++
test code of the C++ class, but it didn't find any problems. (I am not
100% sure it is free of problems, because I am on OSX Mountain Lion, and
despite having used the latest trunk version of Valgrind, it is known to
have problems. I am using a OSX10.8 suppression file, with the one
suggested here as a start). Anyway, the C++ class doesn't use
new/delete/malloc/free, so it SHOULD be fine.
Memory leakage in Cython (?)
I tried running valgrind on the python code that crashes. I have added a
python suppression file in addition to the OSX suppression file mentioned
above. Valgrind generates a lot of output and then crashes. In the output
there isn't any reference to my source codes. This is the incriminated
cython code:
def split_props(np.ndarray[fptype, ndim=1, mode="c"] x,
np.ndarray[fptype, ndim=1, mode="c"] y,
np.ndarray[fptype, ndim=1, mode="c"] ylines):
cdef np.ndarray[fptype, ndim = 1, mode = "c"] areas =
np.zeros((ylines.shape[0] + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] static_moments_x =
np.zeros((ylines.shape[0] + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] inertia_moments_xx =
np.zeros((ylines.shape[0] + 1), dtype=np.float64, order="c")
cdef SplitPolygon * SPINSTANCE = new SplitPolygon(100, 100)
SPINSTANCE.split_props(& x[0], # = <fptype *> x.data
& y[0],
x.shape[0],
& ylines[0],
ylines.shape[0],
& areas[0],
& static_moments_x[0],
& inertia_moments_xx[0]
)
del SPINSTANCE
return areas, static_moments_x, inertia_moments_xx
Above, the C++ class is SplitPolygon. In the python code, I import from
the cython module only the function split_props above, so the memory leak
must be in this part of the code or in the C++ code. Moreover, the
functionality of the python code is the same of the C++ test code.
I report below also another part of the module, that is very similar, but
does NOT cause any memory leakage
def SplitCirc(np.ndarray[fptype, ndim=1, mode="c"] ycenters,
np.ndarray[fptype, ndim=1, mode="c"] radii,
np.ndarray[fptype, ndim=1, mode="c"] ylines):
cdef np.ndarray[fptype, ndim = 1, mode = "c"] areas =
np.zeros((len(ylines) + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] static_moments_x =
np.zeros((len(ylines) + 1), dtype=np.float64, order="c")
cdef np.ndarray[fptype, ndim = 1, mode = "c"] inertia_moments_xx =
np.zeros((len(ylines) + 1), dtype=np.float64, order="c")
split_circles(& ycenters[0], & radii[0], len(ycenters),
& ylines[0], len(ylines),
& areas[0], & static_moments_x[0], & inertia_moments_xx[0])
return areas, static_moments_x, inertia_moments_xx
Now, I am really stuck at this point. Does the cython code look good to
you? Is there any test case I can code to check that the C++ class
SplitPolygon is really leak-free? Can the crash happen for some other
reasons?
No comments:
Post a Comment