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.


Reply via email to