#10287: memleak in bitset_realloc()
-----------------------+----------------------------------------------------
Reporter: mvngu | Owner: rlm
Type: defect | Status: new
Priority: major | Milestone: sage-4.6.1
Component: memleak | Keywords:
Author: | Upstream: N/A
Reviewer: | Merged:
Work_issues: |
-----------------------+----------------------------------------------------
See [https://groups.google.com/group/sage-
devel/browse_thread/thread/57890c6e134a5d45 this thread] for some
background information.
The relevant module is
{{{
sage/misc/bitset.pxi
}}}
and the function concerned is `bitset_realloc()`. A memleak occurs when we
have a bitset of positive size (or capacity) and then reallocate the size
to be zero. To pick up the memleak, I first loaded Sage 4.6.1.alpha1 under
valgrind and quit Sage without doing any computation. The resulting
memleak summary is:
{{{
==26274== LEAK SUMMARY:
==26274== definitely lost: 80 bytes in 3 blocks.
==26274== indirectly lost: 240 bytes in 10 blocks.
==26274== possibly lost: 562,324 bytes in 1,305 blocks.
==26274== still reachable: 60,547,159 bytes in 41,676 blocks.
==26274== suppressed: 0 bytes in 0 blocks.
==26274== Reachable blocks (those to which a pointer was found) are not
shown.
==26274== To see them, rerun with: --leak-check=full --show-reachable=yes
}}}
I then applied the following patch to the Sage library:
{{{
#!diff
# HG changeset patch
# User Minh Van Nguyen <[email protected]>
# Date 1289991585 28800
# Node ID 0554c5d2f725c4d29a6ca0176249b3febb235be2
# Parent 8c722bce2f917caab751122ef48b6057821142de
imported patch test.patch
diff --git a/module_list.py b/module_list.py
--- a/module_list.py
+++ b/module_list.py
@@ -978,6 +978,9 @@
Extension('sage.misc.session',
sources = ['sage/misc/session.pyx']),
+ Extension('sage.misc.test',
+ sources = ['sage/misc/test.pyx']),
+
################################
##
## sage.modular
diff --git a/sage/misc/test.pyx b/sage/misc/test.pyx
new file mode 100644
--- /dev/null
+++ b/sage/misc/test.pyx
@@ -0,0 +1,12 @@
+include "../ext/stdsage.pxi"
+include "bitset_pxd.pxi"
+include "bitset.pxi"
+
+def test():
+ cdef bitset_t a
+ bitset_init(a, 10)
+ try:
+ bitset_realloc(a, 0)
+ except MemoryError:
+ pass
+ bitset_free(a)
}}}
I loaded Sage under valgrind again and performed the following
computation:
{{{
#!python
sage: from sage.misc.test import test
sage: test()
}}}
which resulted in the following memleak summary:
{{{
==16502== LEAK SUMMARY:
==16502== definitely lost: 88 bytes in 4 blocks.
==16502== indirectly lost: 240 bytes in 10 blocks.
==16502== possibly lost: 563,732 bytes in 1,308 blocks.
==16502== still reachable: 60,550,541 bytes in 41,691 blocks.
==16502== suppressed: 0 bytes in 0 blocks.
==16502== Reachable blocks (those to which a pointer was found) are not
shown.
==16502== To see them, rerun with: --leak-check=full --show-reachable=yes
}}}
Notice that despite the function `test()` explicitly freeing memory,
the report on "definitely lost" shows that we leaked an extra 8 bytes
(compare the 80 and 88 above in the first and second memleak
summaries, respectively). Finally, I applied the following patch to
the Sage library:
{{{
#!diff
# HG changeset patch
# User Minh Van Nguyen <[email protected]>
# Date 1289992646 28800
# Node ID 9b5492b0ccc3a23626435f30433ebc52a673499f
# Parent 0554c5d2f725c4d29a6ca0176249b3febb235be2
imported patch memleak.patch
diff --git a/sage/misc/bitset.pxi b/sage/misc/bitset.pxi
--- a/sage/misc/bitset.pxi
+++ b/sage/misc/bitset.pxi
@@ -52,8 +52,10 @@
cdef unsigned long size_old = bits.size
if size_old == size: return 0
bits.limbs = (size - 1)/(8*sizeof(unsigned long)) + 1
- bits.bits = <unsigned long*>sage_realloc(bits.bits, bits.limbs *
sizeof(unsigned long))
- if bits.bits == NULL:
+ tmp = <unsigned long*>sage_realloc(bits.bits, bits.limbs *
sizeof(unsigned long))
+ if tmp != NULL:
+ bits.bits = tmp
+ else:
bits.limbs = limbs_old
raise MemoryError
bits.size = size
}}}
I loaded Sage under valgrind a third time and performed the following
computation, same as above:
{{{
#!python
sage: from sage.misc.test import test
sage: test()
}}}
The corresponding memleak summary is:
{{{
==22029== LEAK SUMMARY:
==22029== definitely lost: 80 bytes in 3 blocks.
==22029== indirectly lost: 240 bytes in 10 blocks.
==22029== possibly lost: 564,252 bytes in 1,309 blocks.
==22029== still reachable: 60,550,168 bytes in 41,696 blocks.
==22029== suppressed: 0 bytes in 0 blocks.
==22029== Reachable blocks (those to which a pointer was found) are not
shown.
==22029== To see them, rerun with: --leak-check=full --show-reachable=yes
}}}
Notice that the summary for "definitely lost" now shows 80 bytes, the same
as for the first memleak summary above. Thus the patch `memleak.patch`
fixes the memleak in `sage.misc.bitset.bitset_realloc`.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/10287>
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.