On Dec 31, 12:58 am, Jean-Pierre Flori <jpfl...@gmail.com> wrote: > But then I had a look at the C code Cython generated and thought it was > the same... > So we should look back at the C code, or ask a Python/Cython guru.
The __delitem__ compiles as an ordinary method lookup and call, whereas the "del A[..]" compiles as a straight call to PyDict_DelItem (or whatever the name of the appropriate routine is). The preparation of the parameter to either call seems to be the same. I agree it's hard to argue that there's a fundamental difference between the two. The "del ..." definitely seems preferable since it saves a method lookup. I have only been successful reproducing this bug on sage-5.6b0 on fedora 16 (x86_64). I have tried advanced debugging tools on 5.6b1 but failed to reproduce the behaviour there. Hence the efforts with plain gdb. So, the scenario we're seeing: - We have an object o that's being deallocated - Its deallocation triggers a weakref callback to an instance of TripleDictEraser - TripleDictEraser removes a key of the form (h1,h2,h3) from a dictionary _refcache, where h1,h2,h3 are IDs of objects k1,k2,k3 (one of which is o) - Somehow this removal triggers another deallocate of o Since h1,h2,h3 are just PyInt, their deletion can't possibly trigger anything else, so the trigger must come from the value stored in the dictionary. This value is (r1,r2,r3), where ri is a weakref (KeyedRef to be precise) to ki (if possible). Python is a sane language, so I trust that deleting a weakref will not trigger deletion of whatever was pointed to. However, when ki is not weakreffable the ri is taken to be ki. Our object o is obviously weakreffable (that's how we got the callback in the first place), However, if one of k1,k2,k3 is not weakreffable (tuples and lists aren't ...) but contains a reference to o then we would get exactly such a trigger. Of course, the existence of a strong reference in _refcache to o would preclude the collection of o ... unless they're all in the same cyclic garbage. Then they could still end up being cleaned. So my conclusion is: TripleDictEraser should NOT decref any ri that is not a weakref, because that could lead to deallocation of objects that are already scheduled for deallocation. Do we need a list, "deathrow", where we can move such references? Should we just try harder to store a weakref to potentially dangerous ki? (we could store them in a container class instance) I am not sure that this is exactly the issue we're running into, but it seems plausible (it certainly needs a very brittle confluence of circumstances to become apparent). Furthermore, I think it is a scenario that does need addressing, because TripleDictEraser doesn't seem to guard against this. -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To post to this group, send email to sage-devel@googlegroups.com. To unsubscribe from this group, send email to sage-devel+unsubscr...@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel?hl=en.