From 2b7842a39f023e2aa2b401089dfeac0172844574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Trzci=C5=84ski?= Date: Tue, 24 Oct 2017 11:09:23 +0100 Subject: [PATCH] Fix memory leaks in enum.cpp Unfortunately due to optimised build of Python3 libraries and executable I got only partial stack from [http://clang.llvm.org/docs/AddressSanitizer.html], however digging into and reducing my code I tracked it down to be issue with `boost/libs/python/src/object/enum.cpp`. It has to bits that leak (and comment mentioning there is one): PyObject *mod = PyObject_GetAttrString( self_, "__module__"); Leaks reference, as it never decreases it. It also stores a new string object under object's `name` that ref count never gets decremented. That commit fixes both issues. --- src/object/enum.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/object/enum.cpp b/src/object/enum.cpp index 3063320c..4d73ee23 100644 --- a/src/object/enum.cpp +++ b/src/object/enum.cpp @@ -34,11 +34,17 @@ static PyMemberDef enum_members[] = { extern "C" { + static void + enum_dealloc(enum_object* self) + { + Py_XDECREF(self->name); + Py_TYPE(self)->tp_free((PyObject*)self); + } + static PyObject* enum_repr(PyObject* self_) { - // XXX(bhy) Potentional memory leak here since PyObject_GetAttrString returns a new reference - // const char *mod = PyString_AsString(PyObject_GetAttrString( self_, const_cast("__module__"))); PyObject *mod = PyObject_GetAttrString( self_, "__module__"); + object auto_free(handle<>(mod)); enum_object* self = downcast(self_); if (!self->name) { @@ -88,7 +94,7 @@ static PyTypeObject enum_type_object = { const_cast("Boost.Python.enum"), sizeof(enum_object), /* tp_basicsize */ 0, /* tp_itemsize */ - 0, /* tp_dealloc */ + (destructor) enum_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */