[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
>>wrong.
>
>
> 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
>>segfault.
>
>
> 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
--
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