[Python-Dev] Problem with _PyTrash_destroy_chain ?
solipsis at pitrou.net
Thu Aug 30 19:38:00 CEST 2012
On Thu, 30 Aug 2012 14:39:41 +0200
Manu <cupcicm at gmail.com> wrote:
> I am currently hitting http://bugs.python.org/issue13992.
> I have a scenario that reproduces the bug after 1 to 2 hours (intensive
> sqlalchemy and threading). I get the same stack trace as described in the
> The thing is that this deallocator (from what I understood) is also
> bracketed with Py_TRASHCAN macros. It could potentially cause a long
> deallocation chain, that will be added to the _PyTrash_delete_later linked
> list (if it's bigger than the PyTrash_UNWIND_LEVEL). If that happens, it
> seems that the _PyTrash_delete_later list is going to contain twice the
> same object, which could in turn cause the double free ?
I don't see how that can happen. The following piece of logic in
PyObject *op = _PyTrash_delete_later;
destructor dealloc = Py_TYPE(op)->tp_dealloc;
ensures that the object is moved out of the list before it is
potentially re-added to it.
However, there's a potential pitfall producing double dealloc's
described in subtype_dealloc() in typeobject.c, under the following
Q. Why the bizarre (net-zero) manipulation of
_PyTrash_delete_nesting around the trashcan macros?
(I'm not copying the answer since it's quite long-winded, you can find
The bottom line is that subtype_dealloc() mutates
_PyTrash_delete_nesting to avoid being called a second time, but it
seems to miss the fact that another thread can run in-between and also
mutate _PyTrash_delete_nesting in the other direction. The GIL protects
us as long as it is not released, but it can be released inside the
functions called by a non-trivial deallocator such as subtype_dealloc().
This is only a hypothesis, but we see that this traceback involves
subtype_dealloc() and deallocators running from multiple threads:
Software development and contracting: http://pro.pitrou.net
More information about the Python-Dev