[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