#13447: Make libsingular multivariate polynomial rings collectable
----------------------------------------------------------------+-----------
Reporter: nbruin |
Owner:
Type: defect |
Status: needs_info
Priority: major |
Milestone: sage-5.4
Component: memleak |
Resolution:
Keywords: | Work
issues: Input from a libsingular expert
Report Upstream: None of the above - read trac for reasoning. |
Reviewers: Simon King
Authors: Nils Bruin, Simon King | Merged
in:
Dependencies: #11521 |
Stopgaps:
----------------------------------------------------------------+-----------
Comment (by nbruin):
Replying to [comment:53 SimonKing]:
> According to the code snipped, the ring is deleted if `r->ref==0`. So,
apparently `r->ref==0` means that there is ''no'' reference.
Indeed, but this is tested ''before'' decrement. So for this to work,
you'd need
{{{
R=create_ring_with_appropriate_refcount
// here R.ref should be 0
//for the following to cause deletion.
intrusive_ptr_release(R)
}}}
We initialize `R.ref=1` in `singular_ring_new`.
> If `ref<=0` then no reference is left, hence, the ring is deleted.
Otherwise, the reference counter is decremented. I really don't understand
the problem.
If `ref<=0` BEFORE the reference count is decreased. The difference is
that `intrusive_ptr_release` happily leaves a ring in memory that AFTER
the call has R.ref==0. Our `singular_ring_delete` will only abstain from
calling `rDelete(doomed)` if after the call we have `doomed.ref > 0`.
{{{
401 doomed.ref = doomed.ref-1
402 if doomed.ref > 0:
403 return
}}}
The two behaviours are off-by-one.
> Singular tests whether `ref<=0`; if it is, then the ring is deleted, but
if it isn't then the counter is decremented.
>
> We first decrement the counter, and then test whether `ref<0`; if it is,
then the ring is deleted, but if it isn't then no further action is taken.
We don't. We test whether `ref<=0` (or rather whether `ref>0` to see if we
should do an early exit).
As our doctests show, apparently we're never calling
`singular_ring_delete` on rings we haven't initialized the `ref` field on
ourselves and that singular expects to to survive after we do, since that
would probably lead to an error (Singular would try to access a
deallocated ring).
A mismatch in the other direction would be milder: Singular takes a
reference on a ring we initialized the ref field on, we lose our last
reference via a `singular_ring_delete` (no rDelete gets called because
Singular correctly increased the refcount). However, Singular will never
delete the ring because we originally initialized the ref field to 1
whereas Singular apparently expects it to be initialized to 0.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/13447#comment:54>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.