Tim Peters added the comment:
OK! This has nothing to do with the trashcan mechanism.
The list object whose gc_next gets stomped on is not itself in a cycle. It's
an empty list, and just happens to be a value in a dict, which in turn is a
value in another dict. Its refcount falls to 0 as an ordinary part of its
containing dict getting deallocated, and that's why the list becomes untracked.
This was confusing me because the memory for the list object was apparently not
deallocated: if it had been, pymalloc would have sprayed 0xdb into most of it,
and gc_next would have appeared to me as 0xdbdbdbdb, not as 0. But after
calling PyObject_GC_UnTrack on it (which sets gc_next to NULL), list_dealloc()
just pushed the list object onto a free list, so no other kind of list
destruction got done.
That pretty much explains everything. Cute: it so happens that the _entire_
`collectable` list gets cleared out as a side effect of a single
finalize(op);
call. The iteration approach in the patch is robust against that, but it's
hard to imagine that anything simpler could be.
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue21435>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com