[Python-Dev] Re: [PythonLabs] Re: [Python-checkins] python/dist/src/Modules gcmodule.c,2.33.6.5,2.33.6.6

Jeremy Hylton jeremy@zope.com
04 Apr 2003 11:46:32 -0500


On Thu, 2003-04-03 at 23:37, Tim Peters wrote:
> > ! 		next = gc->gc.gc_next;
> >   		if (has_finalizer(op)) {
> >   			gc_list_remove(gc);
> >   			gc_list_append(gc, finalizers);
> >   			gc->gc.gc_refs = GC_MOVED;
> >   		}
> >   	}
> >   }
> > --- 277,290 ----
> >   	for (; gc != unreachable; gc=next) {
> >   		PyObject *op = FROM_GC(gc);
> > ! 		/* has_finalizer() may result in arbitrary Python
> > ! 		   code being run. */
> >   		if (has_finalizer(op)) {
> > + 			next = gc->gc.gc_next;
> >   			gc_list_remove(gc);
> >   			gc_list_append(gc, finalizers);
> >   			gc->gc.gc_refs = GC_MOVED;
> >   		}
> > + 		else
> > + 			next = gc->gc.gc_next;
> >   	}
> >   }
> 
> Are we certain that has_finalizer() can't unlink gc itself from the
> unreachable list?  If it can, then
> 
> > + 		else
> > + 			next = gc->gc.gc_next;
> 
> will set next to the content of free()ed memory.  In fact, I believe the
> Boom program will suffer this fate ... yup, it does.  "The problem" isn't
> yet really fixed in any version of Python, although I agree it's a lot
> better with the change above.

It looks like it's hard to find a place to stand.  Since arbitrary
Python code can run, then an arbitrary set of objects in the unreachable
list can suddenly become unlinked.  The previous, current, and next
objects are all suspect.

I think a safe approach would be to move everything out of unreachable
and into either "collectable" or "finalizers".  That way, we can do a 
while (!gc_list_is_empty(unreachable)) loop and always deal with the
head of the unreachable list.  Each time through the loop, the head of
the list can be moved to collectable or finalizers or become unlinked,
so we always make progress.

Sound plausible?

Jeremy