def test_mark_deallocating(self): ob = lltype.malloc(PyObjectS, flavor='raw', zero=True) w_marker = W_Root(42) rawrefcount.mark_deallocating(w_marker, ob) assert rawrefcount.to_obj(W_Root, ob) is w_marker rawrefcount._collect() assert rawrefcount.to_obj(W_Root, ob) is w_marker lltype.free(ob, flavor='raw')
def check_and_print_leaks(self): rawrefcount._collect() # check for sane refcnts import gc if 1: #ZZZ not self.enable_leak_checking: leakfinder.stop_tracking_allocations(check=False) return False leaking = False state = self.space.fromcache(RefcountState) gc.collect() lost_objects_w = identity_dict() lost_objects_w.update( (key, None) for key in self.frozen_refcounts.keys()) for w_obj, obj in state.py_objects_w2r.iteritems(): base_refcnt = self.frozen_refcounts.get(w_obj) delta = obj.c_ob_refcnt if base_refcnt is not None: delta -= base_refcnt lost_objects_w.pop(w_obj) if delta != 0: leaking = True print >> sys.stderr, "Leaking %r: %i references" % (w_obj, delta) try: weakref.ref(w_obj) except TypeError: lifeline = None else: lifeline = state.lifeline_dict.get(w_obj) if lifeline is not None: refcnt = lifeline.pyo.c_ob_refcnt if refcnt > 0: print >> sys.stderr, "\tThe object also held by C code." else: referrers_repr = [] for o in gc.get_referrers(w_obj): try: repr_str = repr(o) except TypeError as e: repr_str = "%s (type of o is %s)" % (str(e), type(o)) referrers_repr.append(repr_str) referrers = ", ".join(referrers_repr) print >>sys.stderr, "\tThe object is referenced by these objects:", \ referrers for w_obj in lost_objects_w: print >> sys.stderr, "Lost object %r" % (w_obj, ) leaking = True # the actual low-level leak checking is done by pypy.tool.leakfinder, # enabled automatically by pypy.conftest. return leaking
def test_collect_p_dies(self): p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor='raw', zero=True) rawrefcount.create_link_pypy(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY_LIGHT assert rawrefcount._p_list == [ob] wr_ob = weakref.ref(ob) wr_p = weakref.ref(p) del ob, p rawrefcount._collect() assert rawrefcount._p_list == [] assert wr_ob() is None assert wr_p() is None
def check_and_print_leaks(self): rawrefcount._collect() # check for sane refcnts import gc if 1: #ZZZ not self.enable_leak_checking: leakfinder.stop_tracking_allocations(check=False) return False leaking = False state = self.space.fromcache(RefcountState) gc.collect() lost_objects_w = identity_dict() lost_objects_w.update((key, None) for key in self.frozen_refcounts.keys()) for w_obj, obj in state.py_objects_w2r.iteritems(): base_refcnt = self.frozen_refcounts.get(w_obj) delta = obj.c_ob_refcnt if base_refcnt is not None: delta -= base_refcnt lost_objects_w.pop(w_obj) if delta != 0: leaking = True print >>sys.stderr, "Leaking %r: %i references" % (w_obj, delta) try: weakref.ref(w_obj) except TypeError: lifeline = None else: lifeline = state.lifeline_dict.get(w_obj) if lifeline is not None: refcnt = lifeline.pyo.c_ob_refcnt if refcnt > 0: print >>sys.stderr, "\tThe object also held by C code." else: referrers_repr = [] for o in gc.get_referrers(w_obj): try: repr_str = repr(o) except TypeError as e: repr_str = "%s (type of o is %s)" % (str(e), type(o)) referrers_repr.append(repr_str) referrers = ", ".join(referrers_repr) print >>sys.stderr, "\tThe object is referenced by these objects:", \ referrers for w_obj in lost_objects_w: print >>sys.stderr, "Lost object %r" % (w_obj, ) leaking = True # the actual low-level leak checking is done by pypy.tool.leakfinder, # enabled automatically by pypy.conftest. return leaking
def test_collect_p_keepalive_w_root(self): p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor='raw', zero=True) rawrefcount.create_link_pypy(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY_LIGHT assert rawrefcount._p_list == [ob] wr_ob = weakref.ref(ob) del ob # p remains rawrefcount._collect() ob = wr_ob() assert ob is not None assert rawrefcount._p_list == [ob] assert rawrefcount.to_obj(W_Root, ob) == p assert rawrefcount.from_obj(PyObject, p) == ob lltype.free(ob, flavor='raw')
def test_collect_o_keepalive_w_root(self): p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor="raw", zero=True) p.pyobj = ob rawrefcount.create_link_pyobj(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY assert rawrefcount._o_list == [ob] wr_ob = weakref.ref(ob) del ob # p remains rawrefcount._collect() ob = wr_ob() assert ob is not None assert rawrefcount._o_list == [ob] assert rawrefcount.to_obj(W_Root, ob) == p assert p.pyobj == ob lltype.free(ob, flavor="raw")
def cleanup(self): self.space.getexecutioncontext().cleanup_cpyext_state() rawrefcount._collect() self.space.user_del_action._run_finalizers() try: # set check=True to actually enable leakfinder leakfinder.stop_tracking_allocations(check=False) except leakfinder.MallocMismatch as e: result = e.args[0] filtered_result = {} for obj, value in result.iteritems(): if not is_allowed_to_leak(self.space, obj): filtered_result[obj] = value if filtered_result: raise CpyextLeak(filtered_result, self.space) assert not self.space.finalizer_queue.next_dead()
def test_collect_s_keepalive_pyobject(self): p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor='raw', zero=True) p.pyobj = ob rawrefcount.create_link_pypy(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY assert rawrefcount._p_list == [ob] wr_ob = weakref.ref(ob) wr_p = weakref.ref(p) ob.c_ob_refcnt += 1 # <= del ob, p rawrefcount._collect() ob = wr_ob() p = wr_p() assert ob is not None and p is not None assert rawrefcount._p_list == [ob] assert rawrefcount.to_obj(W_Root, ob) == p lltype.free(ob, flavor='raw')
def test_collect_o_keepalive_pyobject(self): p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor='raw', zero=True) p.pyobj = ob rawrefcount.create_link_pyobj(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY assert rawrefcount._o_list == [ob] wr_ob = weakref.ref(ob) wr_p = weakref.ref(p) ob.c_ob_refcnt += 1 # <= del p rawrefcount._collect() p = wr_p() assert p is None # was unlinked assert ob.c_ob_refcnt == 1 # != REFCNT_FROM_PYPY_OBJECT + 1 assert rawrefcount._o_list == [] assert rawrefcount.to_obj(W_Root, ob) == None lltype.free(ob, flavor='raw')
def test_collect_s_dies(self): trigger = []; rawrefcount.init(lambda: trigger.append(1)) p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor='raw', zero=True) rawrefcount.create_link_pypy(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY assert rawrefcount._p_list == [ob] wr_ob = weakref.ref(ob) wr_p = weakref.ref(p) del ob, p rawrefcount._collect() ob = wr_ob() assert ob is not None assert trigger == [1] assert rawrefcount._d_list == [ob] assert rawrefcount._p_list == [] assert wr_p() is None assert ob.c_ob_refcnt == 1 # from _d_list assert ob.c_ob_pypy_link == 0 lltype.free(ob, flavor='raw')
def test_collect_s_dies(self): trigger = [] rawrefcount.init(lambda: trigger.append(1)) p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor='raw', zero=True) rawrefcount.create_link_pypy(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY assert rawrefcount._p_list == [ob] wr_ob = weakref.ref(ob) wr_p = weakref.ref(p) del ob, p rawrefcount._collect() ob = wr_ob() assert ob is not None assert trigger == [1] assert rawrefcount._d_list == [ob] assert rawrefcount._p_list == [] assert wr_p() is None assert ob.c_ob_refcnt == 1 # from _d_list assert ob.c_ob_pypy_link == 0 lltype.free(ob, flavor='raw')
def test_collect_o_dies(self): trigger = [] rawrefcount.init(lambda: trigger.append(1)) p = W_Root(42) ob = lltype.malloc(PyObjectS, flavor="raw", zero=True) rawrefcount.create_link_pyobj(p, ob) ob.c_ob_refcnt += REFCNT_FROM_PYPY assert rawrefcount._o_list == [ob] wr_ob = weakref.ref(ob) wr_p = weakref.ref(p) del ob, p rawrefcount._collect() ob = wr_ob() assert ob is not None assert trigger == [1] assert rawrefcount.next_dead(PyObject) == ob assert rawrefcount.next_dead(PyObject) == lltype.nullptr(PyObjectS) assert rawrefcount.next_dead(PyObject) == lltype.nullptr(PyObjectS) assert rawrefcount._o_list == [] assert wr_p() is None assert ob.c_ob_refcnt == 0 assert ob.c_ob_pypy_link == 0 lltype.free(ob, flavor="raw")
def debug_collect(space): rawrefcount._collect()
def debug_collect(): rawrefcount._collect()
def cleanup(self): self.space.getexecutioncontext().cleanup_cpyext_state() rawrefcount._collect() self.space.user_del_action._run_finalizers() leakfinder.stop_tracking_allocations(check=False) assert not self.space.finalizer_queue.next_dead()