[pypy-svn] r74297 - in pypy/trunk/pypy: module/cpyext/test rpython/lltypesystem rpython/lltypesystem/test
afa at codespeak.net
afa at codespeak.net
Fri Apr 30 19:36:20 CEST 2010
Author: afa
Date: Fri Apr 30 19:36:18 2010
New Revision: 74297
Modified:
pypy/trunk/pypy/module/cpyext/test/test_cpyext.py
pypy/trunk/pypy/rpython/lltypesystem/lltype.py
pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py
Log:
Start a slightly better interface to the leak detection in lltype.
+some unit tests
Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original)
+++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Fri Apr 30 19:36:18 2010
@@ -29,15 +29,6 @@
assert 'PyModule_Check' in api.FUNCTIONS
assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject]
-def set_difference(id_dict1, id_dict2):
- d = id_dict1.copy()
- for key in id_dict2.keys():
- try:
- del d[key]
- except KeyError:
- pass
- return d
-
class AppTestApi:
def setup_class(cls):
cls.space = gettestobjspace(usemodules=['cpyext', 'thread'])
@@ -75,8 +66,7 @@
self.frozen_refcounts[w_obj] = obj.c_ob_refcnt
#state.print_refcounts()
self.frozen_ll2callocations = set(ll2ctypes.ALLOCATED.values())
- self.frozen_lltallocations = lltype.ALLOCATED.copy()
- lltype.TRACK_ALLOCATIONS = True
+ lltype.start_tracking_allocations()
class LeakCheckingTest(object):
def check_and_print_leaks(self):
@@ -121,12 +111,13 @@
leaking = True
print >>sys.stderr, "Did not deallocate %r (ll2ctypes)" % (llvalue, )
print >>sys.stderr, "\t" + "\n\t".join(llvalue._traceback.splitlines())
- for llvalue in set_difference(lltype.ALLOCATED, self.frozen_lltallocations).keys():
+ for llvalue in lltype.ALLOCATED.keys():
leaking = True
print >>sys.stderr, "Did not deallocate %r (llvalue)" % (llvalue, )
print >>sys.stderr, "\t" + "\n\t".join(llvalue._traceback.splitlines())
- return leaking
+ lltype.stop_tracking_allocations()
+ return leaking
class AppTestCpythonExtensionBase(LeakCheckingTest):
def setup_class(cls):
Modified: pypy/trunk/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/trunk/pypy/rpython/lltypesystem/lltype.py Fri Apr 30 19:36:18 2010
@@ -16,7 +16,20 @@
import weakref
TLS = tlsobject()
+
+# Track allocations to detect memory leaks
+# Don't track 'gc' and immortal mallocs
TRACK_ALLOCATIONS = False
+ALLOCATED = identity_dict()
+
+def start_tracking_allocations():
+ global TRACK_ALLOCATIONS
+ TRACK_ALLOCATIONS = True
+ ALLOCATED.clear()
+
+def stop_tracking_allocations():
+ global TRACK_ALLOCATIONS
+ TRACK_ALLOCATIONS = False
class _uninitialized(object):
def __init__(self, TYPE):
@@ -1318,8 +1331,6 @@
def _was_freed(self):
return False
-ALLOCATED = identity_dict()
-
class _parentable(_container):
_kind = "?"
Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py (original)
+++ pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py Fri Apr 30 19:36:18 2010
@@ -1,5 +1,6 @@
import py
from pypy.rpython.lltypesystem.lltype import *
+from pypy.rpython.lltypesystem import lltype, rffi
from pypy.lib.identity_dict import identity_dict
def isweak(p, T):
@@ -777,3 +778,42 @@
assert hash1 == identityhash(a)
p = cast_opaque_ptr(llmemory.GCREF, a)
assert hash1 == identityhash(p)
+
+class TestTrackAllocation:
+ def setup_method(self, func):
+ start_tracking_allocations()
+
+ def teardown_method(self, func):
+ assert not lltype.ALLOCATED, "Memory was not correctly freed"
+ stop_tracking_allocations()
+
+ def test_track_allocation(self):
+ """A malloc'd buffer fills the ALLOCATED dictionary"""
+ assert lltype.TRACK_ALLOCATIONS
+ assert not lltype.ALLOCATED
+ buf = malloc(Array(Signed), 1, flavor="raw")
+ assert len(lltype.ALLOCATED) == 1
+ assert lltype.ALLOCATED.keys() == [buf._obj]
+ free(buf, flavor="raw")
+ assert not lltype.ALLOCATED
+
+ def test_str_from_buffer(self):
+ """gc-managed memory does not need to be freed"""
+ size = 50
+ raw_buf, gc_buf = rffi.alloc_buffer(size)
+ for i in range(size): raw_buf[i] = 'a'
+ rstr = rffi.str_from_buffer(raw_buf, gc_buf, size, size)
+ rffi.keep_buffer_alive_until_here(raw_buf, gc_buf)
+ assert not lltype.ALLOCATED
+
+ def test_leak_traceback(self):
+ """Test info stored for allocated items"""
+ buf = malloc(Array(Signed), 1, flavor="raw")
+ traceback = lltype.ALLOCATED.keys()[0]._traceback
+ lines = traceback.splitlines()
+ assert 'malloc(' in lines[-1] and 'flavor="raw")' in lines[-1]
+
+ # XXX The traceback should not be too long
+ print traceback
+
+ free(buf, flavor="raw")
More information about the Pypy-commit
mailing list