Author: Matti Picus <[email protected]>
Branch: cpyext-debug-type_dealloc
Changeset: r92071:c5b852756f17
Date: 2017-08-04 13:38 +0300
http://bitbucket.org/pypy/pypy/changeset/c5b852756f17/
Log: add debug hacks to find gc referrers in leak test
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -13,6 +13,7 @@
from rpython.tool import leakfinder
from rpython.rlib import rawrefcount
from rpython.tool.udir import udir
+import gc
only_pypy ="config.option.runappdirect and '__pypy__' not in
sys.builtin_module_names"
@@ -113,7 +114,8 @@
return is_interned_string(space, w_obj)
def _get_w_obj(space, c_obj):
- return from_ref(space, cts.cast('PyObject*', c_obj._as_ptr()))
+ py_obj = cts.cast('PyObject*', c_obj._as_ptr())
+ return from_ref(space, py_obj), py_obj
class CpyextLeak(leakfinder.MallocMismatch):
def __str__(self):
@@ -122,9 +124,21 @@
"These objects are attached to the following W_Root objects:")
for c_obj in self.args[0]:
try:
- lines.append(" %s" % (_get_w_obj(self.args[1], c_obj),))
- except:
- pass
+ w_obj, py_obj = _get_w_obj(self.args[1], c_obj)
+ if w_obj and py_obj.c_ob_refcnt ==
rawrefcount.REFCNT_FROM_PYPY:
+ referrers = gc.get_referrers(w_obj)
+ badboys = []
+ for r in referrers:
+ # trap the tuples?
+ if isinstance(r, tuple):
+ badboys.append(r)
+ # look at badboys, why are there tuples of
+ # (type, function) ?
+ import pdb;pdb.set_trace()
+ lines.append(" %s" % (w_obj,))
+ except Exception as e:
+ lines.append(str(e))
+ lines.append(" (no W_Root object)")
return '\n'.join(lines)
diff --git a/pypy/module/cpyext/test/test_typeobject.py
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -586,8 +586,14 @@
class E:
pass
# TODO C passes leak checker, D,E fails
+ # in debugging code in CpyextLeak, badboys has tuple/list
+ # (<W_TypeObject 'instance' at 0x7f45d3d11410>, <FunctionWithFixedCode
__getattribute__>)
+ # (<W_TypeObject 'D' at 0x7f45d31b95d0>, <Function __init__>)
+ # (<W_TypeObject 'instance' at 0x7f45d3d11410>, <FunctionWithFixedCode
__setattr__>)
+ # (<W_TypeObject 'instance' at 0x7f45d3d11410>, <FunctionWithFixedCode
__nonzero__>)
+ # ...
+ assert module.test_leak(D())
assert module.test_leak(C())
- assert module.test_leak(D())
assert module.test_leak(E())
def test_tp_getattro(self):
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -540,7 +540,8 @@
# w_obj is an instance of w_A or one of its subclasses. So climb up the
# inheritance chain until base.c_tp_dealloc is exactly this_func, and then
# continue on up until they differ.
- print 'subtype_dealloc, start from', rffi.charp2str(base.c_tp_name)
+ name = rffi.charp2str(base.c_tp_name)
+ print 'subtype_dealloc, start from', name
while base.c_tp_dealloc != this_func_ptr:
base = base.c_tp_base
assert base
@@ -915,7 +916,6 @@
base = pto.c_tp_base
base_pyo = rffi.cast(PyObject, pto.c_tp_base)
if base and not base.c_tp_flags & Py_TPFLAGS_READY:
- name = rffi.charp2str(cts.cast('char*', base.c_tp_name))
type_realize(space, base_pyo)
if base and not pto.c_ob_type: # will be filled later
pto.c_ob_type = base.c_ob_type
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit