Torsten Landschoff, 22.04.2013 13:07:
> On 04/22/2013 07:31 AM, Stefan Behnel wrote:
>>> But this did not give me the crucial hint: Currently, any references to
>>> Python objects *may* be invalid at the time dealloc is called. This is
>>> because Cython generates a tp_clear function for each extension type
>>> that calls Py_CLEAR for each object reference.
>> Correct, together with your complete analysis (thanks for writing it up).
>> For objects participating in a reference cycle, the cyclic garbage
>> collector will try to break the cycle at an arbitrary object, which may or
>> may not be yours. Thus the unpredictable segfaults.
>
> Perhaps I am misreading the CPython source code but it appears to me
> that each and every object in the reference cycle will get its tp_clear
> called.
> 
> http://hg.python.org/cpython/file/9c0a677dbbc0/Modules/gcmodule.c#l782
> 
> Ah, okay, I get it. The loop will terminate when it reaches an object
> that actually breaks the cycle in tp_clear: The decref will cascade over
> all objects in the cycle.

In any case, there are no guarantees about which objects within a reference
cycle will be cleared or not.


>> I also agree that setting fields to None is probably worse for the innocent
>> user than just setting them to NULL. IIRC, we chose to set everything to
>> None because that's something users can handle in their code. You can test
>> an attribute for None in your __dealloc__ code, but you can't test it for
>> NULL. 
>
> Hmm, okay, that's a good point that I have missed. Wouldn't it be
> possible to allow the special check "foo is NULL" for any Python object?
> Of course Cython usually shields the developer from the possibility that
> foo actually becomes NULL so why bother. :-)

Exactly - an extremely special case.

It's an inherent property of the Cython language that user visible
references are never NULL. (minus evil C code, obviously.)


>> That would be a class decorator. Totally makes sense to me. In fact, a
>> decorator to disable GC for a type would also make sense. 
>
> That would be a great feature. After all, traversing the Python objects
> in my example is of no use as they can not create a cycle.
>
>> Cython could also adopt a policy of automatically excluding attributes
>> referencing types that are known to be safe, e.g. basic builtin types. No
>> big savings, but it may drop the need for a useless tp_clear() entirely in
>> some cases, and that might have an impact on the GC cleanup time, as the GC
>> might succeed in breaking the cycle more quickly. Reconsidering
>
> One could even think about building a graph of possible object
> relationships based on the type declaration for the Python attributes.
> In the example, Slot refers only to Slots and Slots only to Context, so
> these can't build a cycle.

Interesting. Yes, that might work. And it's even easy to control when we
allow users to override this decision explicitly using a class decorator.


> a good idea would be to warn if __dealloc__ actually references a
> Python attribute that tp_clear could have cleared, with a pointer to the
> class decorator that exempts the attribute/instance from tp_clear.

That's a good idea.

Any help with this is appreciated. :)

Stefan

_______________________________________________
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel

Reply via email to