#10287: memleak in bitset_realloc()
-------------------------------+--------------------------------------------
Reporter: mvngu | Owner: rlm
Type: defect | Status: needs_review
Priority: major | Milestone: sage-4.6.1
Component: memleak | Keywords:
Author: Minh Van Nguyen | Upstream: N/A
Reviewer: | Merged:
Work_issues: |
-------------------------------+--------------------------------------------
Changes (by newvalueoldvalue):
* status: new => needs_review
* author: => Minh Van Nguyen
Old description:
> 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`.
New description:
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, see
[attachment:test.patch]:
{{{
#!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`.
'''Apply:'''
1. [attachment:trac-10287_memleak.patch]
--
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/10287#comment:1>
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.