[Python-Dev] Re: More fun with Python shutdown

Jim Fulton jim at zope.com
Tue Nov 11 12:25:19 EST 2003

Tim Peters wrote:
> [Jim Fulton, on <http://www.python.org/sf/839548>]
>>The theory is that it occurs when a cycle involving a class is broken
>>by calling the tp_clear slot on a heap type.  I verified this by
>>setting a gdb break point in Zope 3 and verifying that type_clear was
>>called while a type still had a ref count much higher than 1.
>>From a purely theoretical point of view, the current behavior is
> It is, but a segfault is more than just pure theory <wink>.

I don't know what your point is here.

>>There is clearly an invariant that tp_mro is not None and
>>type_clear violates this.  The fix (setting the mro to () in
>>type_clear, is pretty straightforward.
> The invariant is that tp_mro is not NULL so long as anyone may reference it.
> tp_clear believes that tp_mro will never be referenced again, but it's
> demonstrably wrong in that belief.  The real bug lies there:  why is its
> belief wrong?

I thought that tp_clear was called to break cycles. Surely, if a class is
in a cycle, there are references to it. Why would one assume that none
of these references are instances?

> You patched it so that tp_mro doesn't become NULL, thus avoiding the
> immediate segfault, but until we understand *why* the invariant got
> violated, it's unclear that the patch is "a fix".  Code is still accessing
> the MRO after tp_clear is called, but now instead of a segfault it's going
> to see an empty MRO.  That's also (and clearly so, at least to me)
> incorrect:  code that tries to access a class's MRO should see the MRO the
> programmer intended, and no sane class has an empty tuple for its MRO.  So I
> think the "tp_mro <- ()" patch exchanges gross breakage for subtler
> breakage.

Surely, the original intent is top break something. ;)
I'd much rather get an attribute error than a segfault or an
equally fatal C assertion error.

>>BTW, with a debug build, I get an assertion error rather than a
> Which assertion fails then?  That may be a good clue toward truly
> understanding what's causing this.

The assertion that mro is not NULL. :)

See PyObject_GenericGetAttr.


Jim Fulton           mailto:jim at zope.com       Python Powered!
CTO                  (540) 361-1714            http://www.python.org
Zope Corporation     http://www.zope.com       http://www.zope.org

More information about the Python-Dev mailing list