diff options
author | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2013-03-21 11:51:29 +0000 |
---|---|---|
committer | Daniele Varrazzo <daniele.varrazzo@gmail.com> | 2013-03-21 12:34:53 +0000 |
commit | 3b8abf3fc4d0ccccb36a226be03387d02e817cea (patch) | |
tree | daf1c1ea08ff352381265cc5600fff12fce8cd49 | |
parent | d5316d7eb2e3cb75bbfdbd9b7a10f10240c4f462 (diff) | |
download | psycopg2-3b8abf3fc4d0ccccb36a226be03387d02e817cea.tar.gz |
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.
-rw-r--r-- | psycopg/error_type.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/psycopg/error_type.c b/psycopg/error_type.c index fd0947b..95ce071 100644 --- a/psycopg/error_type.c +++ b/psycopg/error_type.c @@ -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); } |