Author: Armin Rigo <[email protected]>
Branch: py3k-faulthandler
Changeset: r87373:7ac3dadd629a
Date: 2016-09-25 19:30 +0200
http://bitbucket.org/pypy/pypy/changeset/7ac3dadd629a/
Log: Change the API in rvmprof to support more directly what we need, in
a way that is also more testable
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
@@ -37,8 +37,3 @@
def disable():
_get_vmprof().disable()
-
[email protected](0)
-def enum_all_code_objs(CodeClass, callback, arg):
- assert _was_registered(CodeClass)
- CodeClass._vmprof_enum_all_code_objs(callback, arg)
diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py
--- a/rpython/rlib/rvmprof/cintf.py
+++ b/rpython/rlib/rvmprof/cintf.py
@@ -156,7 +156,7 @@
vmprof_tl_stack.setraw(x)
#
-# faulthandler support
+# rvmprof.traceback support
def get_rvmprof_stack():
return vmprof_tl_stack.get_or_make_raw()
diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py
--- a/rpython/rlib/rvmprof/rvmprof.py
+++ b/rpython/rlib/rvmprof/rvmprof.py
@@ -116,25 +116,6 @@
# the types of code objects
prev = self._gather_all_code_objs
self._gather_all_code_objs = gather_all_code_objs
- #
- # For special usages: the faulthandler pypy module uses this.
- # It must not allocate anything.
- @staticmethod
- @rgc.no_collect
- def enum_all_code_objs(callback, arg):
- all_code_wrefs = CodeClass._vmprof_weak_list.get_all_handles()
- i = len(all_code_wrefs) - 1
- while i >= 0:
- code = all_code_wrefs[i]()
- i -= 1
- if code is not None:
- uid = code._vmprof_unique_id
- if uid != 0:
- res = callback(code, uid, arg)
- if res != 0:
- return res
- return 0
- CodeClass._vmprof_enum_all_code_objs = enum_all_code_objs
@jit.dont_look_inside
def enable(self, fileno, interval):
diff --git a/rpython/rlib/rvmprof/test/test_traceback.py
b/rpython/rlib/rvmprof/test/test_traceback.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rvmprof/test/test_traceback.py
@@ -0,0 +1,31 @@
+from rpython.rlib import rvmprof
+from rpython.rlib.rvmprof.traceback import traceback
+
+
+def test_direct():
+ class MyCode:
+ pass
+ def get_name(mycode):
+ raise NotImplementedError
+ rvmprof.register_code_object_class(MyCode, get_name)
+ #
+ @rvmprof.vmprof_execute_code("mycode", lambda code, level: code,
+ _hack_update_stack_untranslated=True)
+ def mainloop(code, level):
+ if level > 0:
+ mainloop(code, level - 1)
+ else:
+ traceback(MyCode, my_callback, 42)
+ #
+ seen = []
+ def my_callback(depth, code, arg):
+ seen.append((depth, code, arg))
+ return 0
+ #
+ code1 = MyCode()
+ rvmprof.register_code(code1, "foo")
+ mainloop(code1, 2)
+ #
+ assert seen == [(0, code1, 42),
+ (1, code1, 42),
+ (2, code1, 42)]
diff --git a/rpython/rlib/rvmprof/traceback.py
b/rpython/rlib/rvmprof/traceback.py
new file mode 100644
--- /dev/null
+++ b/rpython/rlib/rvmprof/traceback.py
@@ -0,0 +1,38 @@
+"""
+Semi-public interface to gather and print a raw traceback, e.g.
+from the faulthandler module.
+"""
+
+from rpython.rlib.rvmprof import cintf
+from rpython.rlib.objectmodel import specialize
+
+
[email protected](0, 1)
+def traceback(CodeClass, callback, arg):
+ """For each frame, invoke 'callback(depth, code_obj, arg)'.
+ 'code_obj' is either a CodeClass, or None if we fail to determine
+ what it should be (shouldn't occur, but you never know). If it
+ returns a non-null integer, stop and return that. Otherwise,
+ continue. If all callbacks return 0, this returns 0.
+ """
+ s = cintf.get_rvmprof_stack()
+ depth = 0
+ while s:
+ if s.c_kind == cintf.VMPROF_CODE_TAG:
+ code_id = s.c_value
+ found_code = None
+ if code_id != 0:
+ all_code_wrefs = CodeClass._vmprof_weak_list.get_all_handles()
+ i = len(all_code_wrefs) - 1
+ while i >= 0:
+ code = all_code_wrefs[i]()
+ if code is not None and code._vmprof_unique_id == code_id:
+ found_code = code
+ break
+ i -= 1
+ result = callback(depth, found_code, arg)
+ if result != 0:
+ return result
+ depth += 1
+ s = s.c_next
+ return 0
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit