Clean the C members of Error in tp_dealloc instead of tp_clear

tp_clear should only be used to break the reference cycles. tp_clear was
causing a segfault because it was called twice (by the gc and by _dealloc) so
self->codec was freed twice.

Amazingly the double free was only causing a segfault on Python 3.3 (released
in late 2012) talking to Postgres 8.1 (released in 2005) in async mode... no
other combination crashed. Thank you buildbot.
This commit is contained in:
Daniele Varrazzo 2013-03-21 11:51:29 +00:00
parent d5316d7eb2
commit 3b8abf3fc4

View File

@ -93,6 +93,7 @@ error_traverse(errorObject *self, visitproc visit, void *arg)
Py_VISIT(self->pgerror);
Py_VISIT(self->pgcode);
Py_VISIT(self->cursor);
return ((PyTypeObject *)PyExc_StandardError)->tp_traverse(
(PyObject *)self, visit, arg);
}
@ -104,16 +105,17 @@ error_clear(errorObject *self)
Py_CLEAR(self->pgcode);
Py_CLEAR(self->cursor);
PyMem_Free(self->codec);
CLEARPGRES(self->pgres);
return ((PyTypeObject *)PyExc_StandardError)->tp_clear((PyObject *)self);
}
static void
error_dealloc(errorObject *self)
{
PyObject_GC_UnTrack((PyObject *)self);
error_clear(self);
PyMem_Free(self->codec);
CLEARPGRES(self->pgres);
return Py_TYPE(self)->tp_free((PyObject *)self);
}