summaryrefslogtreecommitdiff
path: root/Lib/test/test_gc.py
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-03-28 21:08:30 +0000
committerTim Peters <tim.peters@gmail.com>2002-03-28 21:08:30 +0000
commitd222559cdb51b0149462f927c6aa0889915e684f (patch)
tree4168b0a9bf587edfc1a709c42d4b07a8be7e1c19 /Lib/test/test_gc.py
parent8d62e94761b0b11655f3ba0215eefa3278594883 (diff)
downloadcpython-git-d222559cdb51b0149462f927c6aa0889915e684f.tar.gz
New test_traschcan() test in test_gc, which reliably provokes segfaults
under 2.0, 2.1 and 2.2. Bugfix candidate.
Diffstat (limited to 'Lib/test/test_gc.py')
-rw-r--r--Lib/test/test_gc.py29
1 files changed, 29 insertions, 0 deletions
diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
index d4fcf7b223..33c57caf8e 100644
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -171,6 +171,34 @@ def test_del():
gc.disable()
apply(gc.set_threshold, thresholds)
+class Ouch:
+ n = 0
+ def __del__(self):
+ Ouch.n = Ouch.n + 1
+ if Ouch.n % 7 == 0:
+ gc.collect()
+
+def test_trashcan():
+ # "trashcan" is a hack to prevent stack overflow when deallocating
+ # very deeply nested tuples etc. It works in part by abusing the
+ # type pointer and refcount fields, and that can yield horrible
+ # problems when gc tries to traverse the structures.
+ # If this test fails (as it does in 2.0, 2.1 and 2.2), it will
+ # most likely die via segfault.
+
+ gc.enable()
+ N = 200
+ for i in range(3):
+ t = []
+ for i in range(N):
+ t = [t, Ouch()]
+ u = []
+ for i in range(N):
+ u = [u, Ouch()]
+ v = {}
+ for i in range(N):
+ v = {1: v, 2: Ouch()}
+ gc.disable()
def test_all():
gc.collect() # Delete 2nd generation garbage
@@ -187,6 +215,7 @@ def test_all():
run_test("finalizers", test_finalizer)
run_test("__del__", test_del)
run_test("saveall", test_saveall)
+ run_test("trashcan", test_trashcan)
def test():
if verbose: