[pypy-svn] r27293 - in pypy/dist/pypy/rpython/lltypesystem: . test

pedronis at codespeak.net pedronis at codespeak.net
Tue May 16 19:33:20 CEST 2006


Author: pedronis
Date: Tue May 16 19:33:18 2006
New Revision: 27293

Modified:
   pypy/dist/pypy/rpython/lltypesystem/llmemory.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
Log:
don't crash on repr/str of dead pointer/address

some support for generating exceptions out of accesses to raw_freed stuff



Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py	Tue May 16 19:33:18 2006
@@ -508,7 +508,8 @@
     return size.raw_malloc([])
 
 def raw_free(adr):
-    pass   # for now
+    assert isinstance(adr.ob._obj, lltype._parentable)
+    adr.ob._obj._free()
 
 def raw_malloc_usage(size):
     if isinstance(size, AddressOffset):

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Tue May 16 19:33:18 2006
@@ -875,12 +875,14 @@
         
     def _getobj(self):
         obj = self._obj0
-        if obj is not None and self._weak:
-            obj = obj()
-            if obj is None:
-                raise RuntimeError("accessing already garbage collected %r"
-                                   % (self._T,))                
-            obj._check()
+        if obj is not None:
+            if self._weak:
+                obj = obj()
+                if obj is None:
+                    raise RuntimeError("accessing already garbage collected %r"
+                                   % (self._T,))
+            if not isinstance(obj, int):
+                obj._check()
         return obj
     _obj = property(_getobj)
 
@@ -977,7 +979,10 @@
         return '<%s>' % (self,)
 
     def __str__(self):
-        return '* %s' % (self._obj, )
+        try:
+            return '* %s' % (self._obj, )
+        except RuntimeError:
+            return '* DEAD %s' % self._T
 
     def __call__(self, *args):
         if isinstance(self._T, FuncType):
@@ -1057,11 +1062,16 @@
     __slots__ = ('_TYPE',
                  '_parent_type', '_parent_index', '_keepparent',
                  '_wrparent',
-                 '__weakref__')
+                 '__weakref__',
+                 '_dead')
 
     def __init__(self, TYPE):
         self._wrparent = None
         self._TYPE = TYPE
+        self._dead = False
+
+    def _free(self):
+        self._dead = True
 
     def _setparentstructure(self, parent, parentindex):
         self._wrparent = pickleable_weakref(parent)
@@ -1085,6 +1095,8 @@
         return None
 
     def _check(self):
+        if self._dead:
+            raise RuntimeError("accessing freed %r" % self._TYPE)
         self._parentstructure()
 
     __getstate__ = getstate_with_slots

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py	Tue May 16 19:33:18 2006
@@ -295,6 +295,49 @@
     py.test.raises(IndexError,
                    "(adr + offsetof(S, 'y') + itemoffsetof(A, 10)).signed[0]")
 
+def test_raw_free():
+    A = lltype.GcArray(lltype.Signed)
+    adr = raw_malloc(sizeof(A, 10))
+    p_a = cast_adr_to_ptr(adr, lltype.Ptr(A))
+    p_a[0] = 1
+    raw_free(adr)
+    py.test.raises(RuntimeError, "p_a[0]")
+    py.test.raises(RuntimeError, "p_a[0] = 2")
+    repr(adr)
+    str(p_a)
+
+    S = lltype.GcStruct('S', ('x', lltype.Signed))
+    adr = raw_malloc(sizeof(S))
+    p_s = cast_adr_to_ptr(adr, lltype.Ptr(S))
+    p_s.x = 1
+    raw_free(adr)
+    py.test.raises(RuntimeError, "p_s.x")
+    py.test.raises(RuntimeError, "p_s.x = 2")
+    repr(adr)
+    str(p_s)
+    
+    T = lltype.GcStruct('T', ('s', S))
+    adr = raw_malloc(sizeof(T))
+    p_s = cast_adr_to_ptr(adr, lltype.Ptr(S))
+    p_s.x = 1
+    raw_free(adr)
+    py.test.raises(RuntimeError, "p_s.x")
+    py.test.raises(RuntimeError, "p_s.x = 2")
+    repr(adr)
+    str(p_s)
+    
+    U = lltype.Struct('U', ('y', lltype.Signed))
+    T = lltype.GcStruct('T', ('x', lltype.Signed), ('u', U))
+    adr = raw_malloc(sizeof(T))
+    p_t = cast_adr_to_ptr(adr, lltype.Ptr(T))
+    p_u = p_t.u
+    p_u.y = 1
+    raw_free(adr)
+    py.test.raises(RuntimeError, "p_u.y")
+    py.test.raises(RuntimeError, "p_u.y = 2")
+    repr(adr)
+    str(p_u)
+    
 def test_inlined_substruct():
     T = lltype.Struct('T', ('x', lltype.Signed))
     S1 = lltype.GcStruct('S1', ('t1', T), ('t2', T))

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	Tue May 16 19:33:18 2006
@@ -670,3 +670,13 @@
     assert typeOf(t) == Ptr(T)
     assert cast_ptr_to_int(t) == 21
     assert s == cast_pointer(Ptr(S), t)
+
+def test_str_of_dead_ptr():
+    S = Struct('S', ('x', Signed))
+    T = GcStruct('T', ('s', S))
+    t = malloc(T)
+    s = t.s
+    del t
+    import gc
+    gc.collect()
+    repr(s)



More information about the Pypy-commit mailing list