Author: Antonio Cuni <anto.c...@gmail.com>
Branch: 
Changeset: r93039:927cc69f4d52
Date: 2017-11-15 16:06 +0100
http://bitbucket.org/pypy/pypy/changeset/927cc69f4d52/

Log:    merge the fix-vmprof-stacklet-switch: make sure that vmprof does not
        segfault in presence of continuation.switch (and thus with
        greenlets, eventlet, etc.)

diff --git a/pypy/module/_continuation/test/test_translated.py 
b/pypy/module/_continuation/test/test_translated.py
--- a/pypy/module/_continuation/test/test_translated.py
+++ b/pypy/module/_continuation/test/test_translated.py
@@ -5,6 +5,7 @@
     py.test.skip("to run on top of a translated pypy-c")
 
 import sys, random
+from rpython.tool.udir import udir
 
 # ____________________________________________________________
 
@@ -92,6 +93,33 @@
         from pypy.conftest import option
         if not option.runappdirect:
             py.test.skip("meant only for -A run")
+        cls.w_vmprof_file = cls.space.wrap(str(udir.join('profile.vmprof')))
+
+    def test_vmprof(self):
+        """
+        The point of this test is to check that we do NOT segfault.  In
+        particular, we need to ensure that vmprof does not sample the stack in
+        the middle of a switch, else we read nonsense.
+        """
+        try:
+            import _vmprof
+        except ImportError:
+            py.test.skip("no _vmprof")
+        #
+        def switch_forever(c):
+            while True:
+                c.switch()
+        #
+        f = open(self.vmprof_file, 'w+b')
+        _vmprof.enable(f.fileno(), 1/250.0, False, False, False, False)
+        c = _continuation.continulet(switch_forever)
+        for i in range(10**7):
+            if i % 100000 == 0:
+                print i
+            c.switch()
+        _vmprof.disable()
+        f.close()
+
 
 def _setup():
     for _i in range(20):
diff --git a/pypy/module/_vmprof/interp_vmprof.py 
b/pypy/module/_vmprof/interp_vmprof.py
--- a/pypy/module/_vmprof/interp_vmprof.py
+++ b/pypy/module/_vmprof/interp_vmprof.py
@@ -93,8 +93,8 @@
     return space.newtext(path)
 
 def stop_sampling(space):
-    return space.newint(rvmprof.stop_sampling(space))
+    return space.newint(rvmprof.stop_sampling())
 
 def start_sampling(space):
-    rvmprof.start_sampling(space)
+    rvmprof.start_sampling()
     return space.w_None
diff --git a/rpython/rlib/rstacklet.py b/rpython/rlib/rstacklet.py
--- a/rpython/rlib/rstacklet.py
+++ b/rpython/rlib/rstacklet.py
@@ -3,6 +3,7 @@
 from rpython.rlib import jit
 from rpython.rlib.objectmodel import fetch_translated_config
 from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rlib import rvmprof
 from rpython.rlib.rvmprof import cintf
 
 DEBUG = False
@@ -40,11 +41,13 @@
     def switch(self, stacklet):
         if DEBUG:
             debug.remove(stacklet)
+        rvmprof.stop_sampling()
         x = cintf.save_rvmprof_stack()
         try:
             h = self._gcrootfinder.switch(stacklet)
         finally:
             cintf.restore_rvmprof_stack(x)
+            rvmprof.start_sampling()
         if DEBUG:
             debug.add(h)
         return h
diff --git a/rpython/rlib/rvmprof/__init__.py b/rpython/rlib/rvmprof/__init__.py
--- a/rpython/rlib/rvmprof/__init__.py
+++ b/rpython/rlib/rvmprof/__init__.py
@@ -55,9 +55,9 @@
 
     return None
 
-def stop_sampling(space):
+def stop_sampling():
     fd = _get_vmprof().cintf.vmprof_stop_sampling()
     return rffi.cast(lltype.Signed, fd)
 
-def start_sampling(space):
+def start_sampling():
     _get_vmprof().cintf.vmprof_start_sampling()
diff --git a/rpython/rlib/test/test_rstacklet.py 
b/rpython/rlib/test/test_rstacklet.py
--- a/rpython/rlib/test/test_rstacklet.py
+++ b/rpython/rlib/test/test_rstacklet.py
@@ -10,6 +10,8 @@
 from rpython.config.translationoption import DEFL_ROOTFINDER_WITHJIT
 from rpython.rlib import rrandom, rgc
 from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.nonconst import NonConstant
+from rpython.rlib import rvmprof
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.translator.c.test.test_standalone import StandaloneTests
 
@@ -273,7 +275,23 @@
         llmemory.raw_free(raw)
 
 
+# <vmprof-hack>
+# bah, we need to make sure that vmprof_execute_code is annotated, else
+# rvmprof.c does not compile correctly
+class FakeVMProfCode(object):
+    pass
+rvmprof.register_code_object_class(FakeVMProfCode, lambda code: 'name')
+@rvmprof.vmprof_execute_code("xcode1", lambda code, num: code)
+def fake_vmprof_main(code, num):
+    return 42
+# </vmprof-hack>
+
 def entry_point(argv):
+    # <vmprof-hack>
+    if NonConstant(False):
+        fake_vmprof_main(FakeVMProfCode(), 42)
+    # </vmprof-hack>
+    #
     seed = 0
     if len(argv) > 1:
         seed = int(argv[1])
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to