summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2013-03-21 11:51:29 +0000
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2013-03-21 12:34:53 +0000
commit3b8abf3fc4d0ccccb36a226be03387d02e817cea (patch)
treedaf1c1ea08ff352381265cc5600fff12fce8cd49
parentd5316d7eb2e3cb75bbfdbd9b7a10f10240c4f462 (diff)
downloadpsycopg2-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.c8
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);
}