Opened 12 years ago
Closed 12 years ago
#10287 closed defect (fixed)
memleak in bitset_realloc()
Reported by: | Minh Van Nguyen | Owned by: | Robert Miller |
---|---|---|---|
Priority: | major | Milestone: | sage-4.6.1 |
Component: | memleak | Keywords: | |
Cc: | Merged in: | sage-4.6.1.alpha3 | |
Authors: | Minh Van Nguyen | Reviewers: | Robert Miller |
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description (last modified by )
This is part of the larger project at #7656. See 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 test.patch:
-
module_list.py
# HG changeset patch # User Minh Van Nguyen <nguyenmi...@gmail.com> # Date 1289991585 28800 # Node ID 0554c5d2f725c4d29a6ca0176249b3febb235be2 # Parent 8c722bce2f917caab751122ef48b6057821142de imported patch test.patch diff --git a/module_list.py b/module_list.py
a b 978 978 Extension('sage.misc.session', 979 979 sources = ['sage/misc/session.pyx']), 980 980 981 Extension('sage.misc.test', 982 sources = ['sage/misc/test.pyx']), 983 981 984 ################################ 982 985 ## 983 986 ## sage.modular -
new file sage/misc/test.pyx
diff --git a/sage/misc/test.pyx b/sage/misc/test.pyx new file mode 100644
- + 1 include "../ext/stdsage.pxi" 2 include "bitset_pxd.pxi" 3 include "bitset.pxi" 4 5 def test(): 6 cdef bitset_t a 7 bitset_init(a, 10) 8 try: 9 bitset_realloc(a, 0) 10 except MemoryError: 11 pass 12 bitset_free(a)
I loaded Sage under valgrind again and performed the following computation:
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:
-
sage/misc/bitset.pxi
# HG changeset patch # User Minh Van Nguyen <nguyenmi...@gmail.com> # 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 b 52 52 cdef unsigned long size_old = bits.size 53 53 if size_old == size: return 0 54 54 bits.limbs = (size - 1)/(8*sizeof(unsigned long)) + 1 55 bits.bits = <unsigned long*>sage_realloc(bits.bits, bits.limbs * sizeof(unsigned long)) 56 if bits.bits == NULL: 55 tmp = <unsigned long*>sage_realloc(bits.bits, bits.limbs * sizeof(unsigned long)) 56 if tmp != NULL: 57 bits.bits = tmp 58 else: 57 59 bits.limbs = limbs_old 58 60 raise MemoryError 59 61 bits.size = size
I loaded Sage under valgrind a third time and performed the following computation, same as above:
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:
Attachments (2)
Change History (6)
Changed 12 years ago by
Attachment: | trac-10287_memleak.patch added |
---|
Changed 12 years ago by
Attachment: | test.patch added |
---|
comment:1 Changed 12 years ago by
Authors: | → Minh Van Nguyen |
---|---|
Description: | modified (diff) |
Status: | new → needs_review |
comment:2 Changed 12 years ago by
Description: | modified (diff) |
---|
comment:3 Changed 12 years ago by
Reviewers: | → Robert Miller |
---|---|
Status: | needs_review → positive_review |
comment:4 Changed 12 years ago by
Merged in: | → sage-4.6.1.alpha3 |
---|---|
Resolution: | → fixed |
Status: | positive_review → closed |