From df6154445534bf5dcf7b168734695382d9dba390 Mon Sep 17 00:00:00 2001 From: Sean Quah Date: Mon, 22 May 2023 16:20:18 +0100 Subject: WIP: debug --- tests/unittest.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/unittest.py b/tests/unittest.py index c73195b32b..fa2ef51f49 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -227,13 +227,80 @@ class TestCase(unittest.TestCase): @around(self) def tearDown(orig: Callable[[], R]) -> R: + import sys + import time + import tracemalloc + ret = orig() gc.collect(0) # Run a full GC every 50 gen-0 GCs. gen0_stats = gc.get_stats()[0] gen0_collections = gen0_stats["collections"] if gen0_collections % 50 == 0: + if not getattr(tracemalloc, "aaa", None): + tracemalloc.aaa = True + tracemalloc.start() + tracemalloc.s0 = tracemalloc.take_snapshot() + t0 = time.time() gc.collect() + dt = time.time() - t0 + s1 = tracemalloc.take_snapshot() + for line in s1.statistics("lineno")[:20]: + sys.stdout.write(f" {line}\n") + sys.stdout.write(f"full collection took {dt} s\n") + dt = time.time() - t0 + sys.stdout.write(f"snapshot took {dt} s\n") + if dt > 1.5: + + def dump_paths(o: object, max_distance: int) -> None: + import pdb + from collections import deque + + queue: deque[object] = deque() + seen: set[int] = set() + prevs: Dict[int, object] = {} + roots: List[object] = [] + distances: Dict[int, int] = {} + whitelist = {id(queue), id(seen), id(prevs), id(roots)} + i = 0 + seen.add(id(o)) + queue.append(o) + distances[id(o)] = 0 + while len(queue) > 0: + o = queue.popleft() + has_referrers = False + if ( + not isinstance(o, pdb.Pdb) + and distances[id(o)] < max_distance + ): + referrers = gc.get_referrers(o) + for referrer in referrers: + if id(referrer) in whitelist: + continue + has_referrers = True + if id(referrer) in seen: + continue + prevs[id(referrer)] = o + distances[id(referrer)] = distances[id(o)] + 1 + seen.add(id(referrer)) + queue.append(referrer) + + if not has_referrers: + roots.append(o) + + i += 1 + print(f"{len(roots)} roots") + for root in roots: + o = root + while o is not None: + print(str(o)[:200]) + o = prevs.get(id(o)) + print("") + print(f"{len(roots)} roots") + + import pdb + + pdb.set_trace() gc.enable() set_current_context(SENTINEL_CONTEXT) -- cgit 1.4.1