def test_nested_remember_forget_2(): p2 = leakfinder.start_tracking_allocations() x = 1234 leakfinder.remember_malloc(x) py.test.raises(leakfinder.MallocMismatch, leakfinder.stop_tracking_allocations, True, prev=p2) leakfinder.stop_tracking_allocations(True)
def test_start_stop_nested(): leakfinder.start_tracking_allocations() p2 = leakfinder.start_tracking_allocations() assert leakfinder.TRACK_ALLOCATIONS leakfinder.stop_tracking_allocations(True, prev=p2) assert leakfinder.TRACK_ALLOCATIONS leakfinder.stop_tracking_allocations(True) assert not leakfinder.TRACK_ALLOCATIONS
def test_nested_remember_forget_1(): leakfinder.start_tracking_allocations() x = 1234 leakfinder.remember_malloc(x) p2 = leakfinder.start_tracking_allocations() leakfinder.stop_tracking_allocations(True, prev=p2) py.test.raises(leakfinder.MallocMismatch, leakfinder.stop_tracking_allocations, True)
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 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 interpret( func, values, view="auto", viewbefore="auto", policy=None, type_system="lltype", backendopt=False, config=None, malloc_check=True, **kwargs ): interp, graph = get_interpreter( func, values, view, viewbefore, policy, type_system=type_system, backendopt=backendopt, config=config, **kwargs ) if not malloc_check: result = interp.eval_graph(graph, values) else: prev = leakfinder.start_tracking_allocations() try: result = interp.eval_graph(graph, values) finally: leaks = leakfinder.stop_tracking_allocations(False, prev) if leaks: raise leakfinder.MallocMismatch(leaks) return result
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 interpret(func, values, view='auto', viewbefore='auto', policy=None, backendopt=False, config=None, malloc_check=True, **kwargs): interp, graph = get_interpreter(func, values, view, viewbefore, policy, backendopt=backendopt, config=config, **kwargs) if not malloc_check: result = interp.eval_graph(graph, values) else: prev = leakfinder.start_tracking_allocations() try: result = interp.eval_graph(graph, values) finally: leaks = leakfinder.stop_tracking_allocations(False, prev) if leaks: raise leakfinder.MallocMismatch(leaks) return result
def test_traceback(): leakfinder.start_tracking_allocations() x = 1234 leakfinder.remember_malloc(x) res = leakfinder.stop_tracking_allocations(check=False) assert res.keys() == [x] print res[x] assert isinstance(res[x], str) assert 'test_traceback' in res[x] assert 'leakfinder.remember_malloc(x)' in res[x]
def pytest_runtest_teardown(self, __multicall__, item): __multicall__.execute() if not isinstance(item, py.test.collect.Function): return if (not getattr(item.obj, 'dont_track_allocations', False) and leakfinder.TRACK_ALLOCATIONS): item._pypytest_leaks = leakfinder.stop_tracking_allocations(False) else: # stop_tracking_allocations() already called item._pypytest_leaks = None # check for leaks, but only if the test passed so far if getattr(item, '_success', False) and item._pypytest_leaks: raise leakfinder.MallocMismatch(item._pypytest_leaks)
def pytest_runtest_teardown(self, item): if not isinstance(item, py.test.collect.Function): return if (not getattr(item.obj, 'dont_track_allocations', False) and leakfinder.TRACK_ALLOCATIONS): kwds = {} try: kwds['do_collection'] = item.track_allocations_collect except AttributeError: pass item._pypytest_leaks = leakfinder.stop_tracking_allocations(False, **kwds) else: # stop_tracking_allocations() already called item._pypytest_leaks = None # check for leaks, but only if the test passed so far if getattr(item, '_success', False) and item._pypytest_leaks: raise leakfinder.MallocMismatch(item._pypytest_leaks)
def pytest_runtest_teardown(self, item): if not isinstance(item, py.test.collect.Function): return if (not getattr(item.obj, 'dont_track_allocations', False) and leakfinder.TRACK_ALLOCATIONS): kwds = {} try: kwds['do_collection'] = item.track_allocations_collect except AttributeError: pass item._pypytest_leaks = leakfinder.stop_tracking_allocations( False, **kwds) else: # stop_tracking_allocations() already called item._pypytest_leaks = None # check for leaks, but only if the test passed so far if getattr(item, '_success', False) and item._pypytest_leaks: raise leakfinder.MallocMismatch(item._pypytest_leaks)
def test_start_stop(): leakfinder.start_tracking_allocations() assert leakfinder.TRACK_ALLOCATIONS leakfinder.stop_tracking_allocations(True) assert not leakfinder.TRACK_ALLOCATIONS
def test_remember_free(): leakfinder.start_tracking_allocations() x = 1234 leakfinder.remember_malloc(x) leakfinder.remember_free(x) leakfinder.stop_tracking_allocations(True)
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()