From ebd205caea0eb58a87dec5c278848fafea3714e0 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 2 May 2011 10:15:14 -0400 Subject: [PATCH 1/5] Fix memory leak in f2py_rout_wrap_call test. --- numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c index 71bee783da6a..73aa408629ad 100644 --- a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c +++ b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c @@ -53,8 +53,10 @@ static PyObject *f2py_rout_wrap_call(PyObject *capi_self, dims[i] = (npy_intp)PyInt_AsLong(PySequence_GetItem(dims_capi,i)); capi_arr_tmp = array_from_pyobj(type_num,dims,rank,intent|F2PY_INTENT_OUT,arr_capi); - if (capi_arr_tmp == NULL) + if (capi_arr_tmp == NULL) { + free(dims); return NULL; + } capi_buildvalue = Py_BuildValue("N",capi_arr_tmp); free(dims); return capi_buildvalue; From bd82d01b544abb16760e24397ee2ad1ad9c94043 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 2 May 2011 10:16:01 -0400 Subject: [PATCH 2/5] Fix memory leak in UMath_Tests_test_signature test --- numpy/core/src/umath/umath_tests.c.src | 1 + 1 file changed, 1 insertion(+) diff --git a/numpy/core/src/umath/umath_tests.c.src b/numpy/core/src/umath/umath_tests.c.src index 8294220903b3..cb1d541f5c16 100644 --- a/numpy/core/src/umath/umath_tests.c.src +++ b/numpy/core/src/umath/umath_tests.c.src @@ -271,6 +271,7 @@ UMath_Tests_test_signature(PyObject *NPY_UNUSED(dummy), PyObject *args) } if (f == NULL) return NULL; core_enabled = ((PyUFuncObject*)f)->core_enabled; + Py_DECREF(f); return Py_BuildValue("i", core_enabled); } From e4934986cc40edbaca25de76ccf25d7a9a4b3e40 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 2 May 2011 10:18:07 -0400 Subject: [PATCH 3/5] Fix reference counting leaks in C-based multiarray_tests --- numpy/core/src/multiarray/multiarray_tests.c.src | 3 --- 1 file changed, 3 deletions(-) diff --git a/numpy/core/src/multiarray/multiarray_tests.c.src b/numpy/core/src/multiarray/multiarray_tests.c.src index f99cb98ad023..d6340025c2fb 100644 --- a/numpy/core/src/multiarray/multiarray_tests.c.src +++ b/numpy/core/src/multiarray/multiarray_tests.c.src @@ -44,7 +44,6 @@ static int copy_@type@(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *ni ptr += 1; } - Py_INCREF(aout); PyList_Append(*out, (PyObject*)aout); Py_DECREF(aout); PyArray_ITER_NEXT(itx); @@ -84,7 +83,6 @@ static int copy_object(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *ni PyArrayNeighborhoodIter_Next(niterx); } - Py_INCREF(aout); PyList_Append(*out, (PyObject*)aout); Py_DECREF(aout); PyArray_ITER_NEXT(itx); @@ -238,7 +236,6 @@ copy_double_double(PyArrayNeighborhoodIterObject *itx, ptr += 1; PyArrayNeighborhoodIter_Next(niterx); } - Py_INCREF(aout); PyList_Append(*out, (PyObject*)aout); Py_DECREF(aout); PyArrayNeighborhoodIter_Next(itx); From e1ae06c82ca089ed89a4711a789127c74363644e Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 2 May 2011 10:27:04 -0400 Subject: [PATCH 4/5] Fix a bug where memory was being read after being freed. On my system (Python 2.7, RHEL5), the call to func.__name__ returns a temporary Python string object with only a single reference. Dereferencing it before copying out its contents results in reading freed memory. --- numpy/core/src/umath/umathmodule.c.src | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/numpy/core/src/umath/umathmodule.c.src b/numpy/core/src/umath/umathmodule.c.src index 7a76c2b3ea30..8d081f85b239 100644 --- a/numpy/core/src/umath/umathmodule.c.src +++ b/numpy/core/src/umath/umathmodule.c.src @@ -94,7 +94,6 @@ ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUS fname_len = 1; PyErr_Clear(); } - Py_XDECREF(pyname); /* * self->ptr holds a pointer for enough memory for @@ -119,6 +118,7 @@ ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUS self->ptr = _pya_malloc(offset[0] + offset[1] + sizeof(void *) + (fname_len + 14)); if (self->ptr == NULL) { + Py_XDECREF(pyname); return PyErr_NoMemory(); } Py_INCREF(function); @@ -139,6 +139,8 @@ ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUS memcpy(str+fname_len, " (vectorized)", 14); self->name = str; + Py_XDECREF(pyname); + /* Do a better job someday */ self->doc = "dynamic ufunc based on a python function"; From 4b80c16f9421983acf3cc3246ab29b3b6ff5a7b5 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 2 May 2011 11:03:13 -0400 Subject: [PATCH 5/5] Cleanup in PyUFunc_FromFuncAndDataAndSignature error case. --- numpy/core/src/umath/ufunc_object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 472c1b55e7da..930c91ca1d03 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -4466,6 +4466,7 @@ PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void **data, self->core_signature = NULL; if (signature != NULL) { if (_parse_signature(self, signature) != 0) { + Py_DECREF(self); return NULL; } }