#13447: Make libsingular multivariate polynomial rings collectable
-------------------------------------------------------+--------------------
Reporter: nbruin | Owner: rlm
Type: defect | Status: new
Priority: major | Milestone:
sage-5.4
Component: memleak | Resolution:
Keywords: | Work issues:
Report Upstream: Reported upstream. No feedback yet. | Reviewers:
Authors: | Merged in:
Dependencies: | Stopgaps:
-------------------------------------------------------+--------------------
Comment (by SimonKing):
I tried to track the problem as follows:
{{{#!diff
diff --git a/sage/libs/singular/ring.pyx b/sage/libs/singular/ring.pyx
--- a/sage/libs/singular/ring.pyx
+++ b/sage/libs/singular/ring.pyx
@@ -16,6 +16,8 @@
include "../../ext/stdsage.pxi"
+import sys
+
from sage.libs.gmp.types cimport __mpz_struct
from sage.libs.gmp.mpz cimport mpz_init_set_ui, mpz_init_set
@@ -495,6 +497,8 @@
cdef object r = wrap_ring(existing_ring)
refcount = ring_refcount_dict.pop(r)
ring_refcount_dict[r] = refcount+1
+ sys.stderr.write("reference %d to %d, wrapper
%d\n"%(refcount+1,<size_t>existing_ring, id(r)))
+ sys.stderr.flush()
return existing_ring
@@ -536,6 +540,8 @@
cdef ring_wrapper_Py r = wrap_ring(doomed)
refcount = ring_refcount_dict.pop(r)
+ sys.stderr.write("dereference level %d of %d, wrapper
%d\n"%(refcount-1,<size_t>doomed, id(r)))
+ sys.stderr.flush()
if refcount > 1:
ring_refcount_dict[r] = refcount-1
return
diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx
b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
--- a/sage/rings/polynomial/multi_polynomial_libsingular.pyx
+++ b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
@@ -151,6 +151,7 @@
sage: b-j*c
b - 1728*c
"""
+import sys
# The Singular API is as follows:
#
@@ -242,7 +243,7 @@
import sage.libs.pari.gen
import polynomial_element
-
+from sage.libs.singular.ring cimport wrap_ring
cdef class MPolynomialRing_libsingular(MPolynomialRing_generic):
def __cinit__(self):
@@ -364,6 +365,8 @@
from sage.rings.polynomial.polynomial_element import
PolynomialBaseringInjection
base_inject = PolynomialBaseringInjection(base_ring, self)
self.register_coercion(base_inject)
+ sys.stderr.write("At %d, creating %s\n"%(<size_t>self._ring,
self))
+ sys.stderr.flush()
def __dealloc__(self):
r"""
@@ -390,6 +393,16 @@
sage: _ = gc.collect()
"""
if self._ring != NULL: # the constructor did not raise an
exception
+ from sage.libs.singular.ring import ring_refcount_dict
+ try:
+ level = ring_refcount_dict[wrap_ring(self._ring)]
+ except KeyError:
+ level = -1
+ if level > 1:
+ sys.stderr.write("WARNING: %d\n"%(<size_t>self._ring))
+ else:
+ sys.stderr.write("__dealloc__:
%s\n"%(<size_t>self._ring))
+ sys.stderr.flush()
singular_ring_delete(self._ring)
def __copy__(self):
}}}
Then, I ran `python -t` on the segfaulting test. Observation: It happens
precisely twice that "WARNING" is printed, i.e., the `__dealloc__` method
is called even though there remain multiple references to the underlying
libsingular ring.
In both cases it is `QQ['a','b','c','d']`. Here is a snipped from the
output:
{{{
reference 2 to 4409548912, wrapper 4302568952
reference 3 to 4409548912, wrapper 4302569000
reference 4 to 4409548912, wrapper 4302568952
At 4409548912, creating Multivariate Polynomial Ring in a, b, c, d over
Rational Field
reference 5 to 4409548912, wrapper 4302569000
reference 6 to 4409548912, wrapper 4302568952
reference 7 to 4409548912, wrapper 4302569000
reference 8 to 4409548912, wrapper 4302568952
reference 9 to 4409548912, wrapper 4302569000
reference 10 to 4409548912, wrapper 4302568952
reference 2 to 4409549416, wrapper 4302568928
reference 3 to 4409549416, wrapper 4302569000
dereference level 9 of 4409548912, wrapper 4302568928
dereference level 8 of 4409548912, wrapper 4302568952
dereference level 7 of 4409548912, wrapper 4302568928
dereference level 6 of 4409548912, wrapper 4302568952
dereference level 5 of 4409548912, wrapper 4302568928
dereference level 4 of 4409548912, wrapper 4302568952
dereference level 3 of 4409548912, wrapper 4302568928
WARNING: 4409548912
dereference level 2 of 4409548912, wrapper 4302568952
dereference level 1 of 4409548912, wrapper 4302568928
dereference level 0 of 4409548912, wrapper 4302568952
}}}
However, I am not totally sure whether this indicates a problem, because
in both cases the remaining references are immediately removed. Also, it
is always the case that 4 references are set to the libsingular ring
before actually creating the polynomial ring in Sage.
One last observation: You may notice a libsingular ring at address
4409549416 that is referenced here as well, aparently in the middle of the
construction of `QQ['a','b','c','d']`. It is later used for
`QQ['x','y','z']`. The last report before the segfault is
{{{
reference 32 to 4409549416, wrapper 4302568952
}}}
Seems like a wild-goose chase to me, though.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/13447#comment:11>
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.