[Python-Dev] RE: Evil Trashcan and GC interaction

Tim Peters tim.one@comcast.net
Thu, 28 Mar 2002 13:33:49 -0500


[Neil Schemenauer] [mailto:nas@python.ca]
> ...
> There is insidious bug here.  Andrew helped me walk through it and I
> think we figured it out.  First here's the code to trigger it:
> ...
>             t = () # <-- here
>...
> The line marked with "here" is where things go wrong.  t used to refer
> to a long chain of [t, Ouch()].  The SETLOCAL macro in ceval calls
> Py_XDECREF(GETLOCAL(i)).  That starts the deallocation of the list
> structure.  Ouch.__del__ gets called can creates some more objects,
> triggering a collection.  The f frame's traverse gets called and tries
> to follow the pointer for the t local.  It points to memory that was
> freed by _PyTrash_destroy_chain.

Yup.  Guido & I bumped into that earlier in current CVS.  The debug pymalloc
was a great help in showing instantly that the memory had already been
freed, and Guido immediately thought of ceval.c then.  We each patched
ceval.c locally; e.g., here's mine:

#define SETLOCAL(i, value)	do { PyObject *_t = GETLOCAL(i); 	\
				     GETLOCAL(i) = value;		\
				     Py_XDECREF(_t); } while (0)

> Hmm, now that I think about it the GC is not needed to trigger the bug:

True; this one is a very old bug, but one that simply never had a
consequence before <wink>.

Guido is seeing something stranger than I am now:  on Windows, assorted test
cases all pass now.  On Linux, the list (but not the tuple) test is dying
when releasing a lock(!).  This under current CVS (and may be due to the new
lock implementation on pthreads systems).