[Python-Dev] RE: Provoking Jim's MRO segfault before shutdown

Tim Peters tim at zope.com
Thu Nov 13 08:04:17 EST 2003


[Tim]
> ...
>> It's trying to resolve self.J in the callback at the time it dies.
>> Unlike Jim's scenario, the failure here is due to that II is an
>> insane state (the class containing the callback code, not some other
>> class) -- but close enough for me.

[Jim Fulton]
> This is exactly like my scenario.  The class containing the callback
> is hosed.

Ah!  I misunderstood.  Great <ehe>, then.

> In my scenario, I wasn't resuurecting anything though.

Right, I was trying to provoke a different (but related) problem.  But it
does't matter what the method is named, or what it's trying to do -- it's
dying before it gets to the part that would have resurrected something ...
for example, this segfaults too:

"""
import gc
import weakref

class J(object):
    pass

class II(object):
    def happy_happy_joy_joy(self, ignore):
        print self.bunny_rabbit


I = II()
I.unused = J
I.wr = weakref.ref(J, I.happy_happy_joy_joy)

del I, J, II
print "the sun shines"
gc.collect()
print "on all the little children"
"""

Comment out the "del" instead, and then all the little children get to enjoy
Mr. Sunshine for the few microseconds it takes to see Mr. Segfault during
shutdown instead.

Random curiousity:  note that this version doesn't set up a cycle *between*
J and I (the "J.I = J" line from the original was cut here).  It's unclear
what "purpose" J serves in this version.  Nevertheless, if "I.unsued = J" is
also removed, the segfault goes away, and it just delivers a bunny_rabbit
AttributeError instead.  As is, the strong reference from I to J nudges gc
into calling tp_clear on II before breaking cycles causes the refcount on J
to fall to 0.




More information about the Python-Dev mailing list