[pypy-svn] r79899 - in pypy/branch/gc-debug/pypy/rpython/lltypesystem: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Dec 8 16:50:11 CET 2010
Author: arigo
Date: Wed Dec 8 16:50:09 2010
New Revision: 79899
Modified:
pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py
pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py
Log:
Translation of arena_protect().
Modified: pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py
==============================================================================
--- pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py (original)
+++ pypy/branch/gc-debug/pypy/rpython/lltypesystem/llarena.py Wed Dec 8 16:50:09 2010
@@ -130,8 +130,8 @@
def mark_freed(self):
self.freed = True # this method is a hook for tests
- def set_protect(self, accessible):
- if not accessible:
+ def set_protect(self, inaccessible):
+ if inaccessible:
assert self.protect_inaccessible is None
saved = []
for ptr in self.objectptrs.values():
@@ -383,15 +383,15 @@
"""
return Arena(ptr.arena.nbytes, False).getaddr(0)
-def arena_protect(arena_addr, size, accessible):
+def arena_protect(arena_addr, size, inaccessible):
"""For debugging, set or reset memory protection on an arena.
For now, the starting point and size should reference the whole arena.
- The value of 'accessible' is a boolean.
+ The value of 'inaccessible' is a boolean.
"""
arena_addr = getfakearenaaddress(arena_addr)
assert arena_addr.offset == 0
assert size == arena_addr.arena.nbytes
- arena_addr.arena.set_protect(accessible)
+ arena_addr.arena.set_protect(inaccessible)
# ____________________________________________________________
#
@@ -503,6 +503,37 @@
# them immediately.
clear_large_memory_chunk = llmemory.raw_memclear
+if os.name == "posix":
+ from pypy.translator.tool.cbuild import ExternalCompilationInfo
+ _eci = ExternalCompilationInfo(includes=['sys/mman.h'])
+ raw_mprotect = rffi.llexternal('mprotect',
+ [llmemory.Address, rffi.SIZE_T, rffi.INT],
+ rffi.INT,
+ sandboxsafe=True, _nowrapper=True,
+ compilation_info=_eci)
+ def llimpl_arena_protect(addr, size, inaccessible):
+ # do some alignment
+ start = rffi.cast(lltype.Signed, addr)
+ end = start + size
+ start = (start + 4095) & ~ 4095
+ end = end & ~ 4095
+ if end > start:
+ if inaccessible:
+ prot = 0
+ else:
+ from pypy.rlib.rmmap import PROT_READ, PROT_WRITE
+ prot = PROT_READ | PROT_WRITE
+ raw_mprotect(rffi.cast(llmemory.Address, start),
+ rffi.cast(rffi.SIZE_T, end - start),
+ rffi.cast(rffi.INT, prot))
+ # ignore potential errors
+ has_protect = True
+
+else:
+ def llimpl_arena_protect(addr, size, inaccessible):
+ pass
+ has_protect = False
+
llimpl_malloc = rffi.llexternal('malloc', [lltype.Signed], llmemory.Address,
sandboxsafe=True, _nowrapper=True)
@@ -572,6 +603,11 @@
'll_arena.arena_new_view', llimpl=llimpl_arena_new_view,
llfakeimpl=arena_new_view, sandboxsafe=True)
+register_external(arena_protect, [llmemory.Address, lltype.Signed,
+ lltype.Bool], lltype.Void,
+ 'll_arena.arena_protect', llimpl=llimpl_arena_protect,
+ llfakeimpl=arena_protect, sandboxsafe=True)
+
def llimpl_getfakearenaaddress(addr):
return addr
register_external(getfakearenaaddress, [llmemory.Address], llmemory.Address,
Modified: pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py
==============================================================================
--- pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py (original)
+++ pypy/branch/gc-debug/pypy/rpython/lltypesystem/test/test_llarena.py Wed Dec 8 16:50:09 2010
@@ -6,7 +6,8 @@
from pypy.rpython.lltypesystem.llarena import round_up_for_allocation
from pypy.rpython.lltypesystem.llarena import ArenaError, arena_new_view
from pypy.rpython.lltypesystem.llarena import arena_shrink_obj
-from pypy.rpython.lltypesystem.llarena import arena_protect
+from pypy.rpython.lltypesystem.llarena import arena_protect, has_protect
+from pypy.translator.c.test import test_genc, test_standalone
def test_arena():
S = lltype.Struct('S', ('x',lltype.Signed))
@@ -266,8 +267,7 @@
assert res == 42
def test_compiled():
- from pypy.translator.c.test.test_genc import compile
- fn = compile(test_look_inside_object, [])
+ fn = test_genc.compile(test_look_inside_object, [])
res = fn()
assert res == 42
@@ -291,11 +291,43 @@
p = llmemory.cast_adr_to_ptr(a, lltype.Ptr(S))
p.x = 123
assert p.x == 123
- arena_protect(a, 100, accessible=False)
+ arena_protect(a, 100, True)
py.test.raises(ArenaError, arena_reserve, a + 48, llmemory.sizeof(S))
py.test.raises(RuntimeError, "p.x")
py.test.raises(RuntimeError, "p.x = 124")
- arena_protect(a, 100, accessible=True)
+ arena_protect(a, 100, False)
assert p.x == 123
p.x = 125
assert p.x == 125
+
+
+class TestStandalone(test_standalone.StandaloneTests):
+ def test_compiled_arena_protect(self):
+ import os
+ from pypy.translator.c.test.test_genc import compile
+ S = lltype.Struct('S', ('x', lltype.Signed))
+ #
+ def fn(argv):
+ testrun = int(argv[1])
+ a = arena_malloc(65536, False)
+ arena_reserve(a, llmemory.sizeof(S))
+ p = llmemory.cast_adr_to_ptr(a + 23432, lltype.Ptr(S))
+ p.x = 123
+ assert p.x == 123
+ arena_protect(a, 65536, True)
+ result = 0
+ if testrun == 1:
+ print p.x # segfault
+ if testrun == 2:
+ p.x = 124 # segfault
+ arena_protect(a, 65536, False)
+ p.x += 10
+ print p.x
+ return 0
+ #
+ t, cbuilder = self.compile(fn)
+ data = cbuilder.cmdexec('0')
+ assert data == '133\n'
+ if has_protect:
+ cbuilder.cmdexec('1', expect_crash=True)
+ cbuilder.cmdexec('2', expect_crash=True)
More information about the Pypy-commit
mailing list