summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_weakref.py
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2003-11-12 20:43:28 (GMT)
committerTim Peters <tim.peters@gmail.com>2003-11-12 20:43:28 (GMT)
commitadd09b4149b17afa30aa042dbb718b9d9ec741c3 (patch)
treee3d9f2501d6143ff2d27a50a7d93674c99dde7cd /Lib/test/test_weakref.py
parent045f1de57ed524d5dbaab92fea8eabc59b33d6f2 (diff)
downloadcpython-add09b4149b17afa30aa042dbb718b9d9ec741c3.zip
cpython-add09b4149b17afa30aa042dbb718b9d9ec741c3.tar.gz
cpython-add09b4149b17afa30aa042dbb718b9d9ec741c3.tar.bz2
SF bug 840829: weakref callbacks and gc corrupt memory.
subtype_dealloc(): This left the dying object exposed to gc, so that if cyclic gc triggered during the weakref callback, gc tried to delete the dying object a second time. That's a disaster. subtype_dealloc() had a (I hope!) unique problem here, as every normal dealloc routine untracks the object (from gc) before fiddling with weakrefs etc. But subtype_dealloc has obscure technical reasons for re-registering the dying object with gc (already explained in a large comment block at the bottom of the function). The fix amounts to simply refraining from reregistering the dying object with gc until after the weakref callback (if any) has been called. This is a critical bug (hard to predict, and causes seemingly random memory corruption when it occurs). I'll backport it to 2.3 later.
Diffstat (limited to 'Lib/test/test_weakref.py')
-rw-r--r--Lib/test/test_weakref.py20
1 files changed, 20 insertions, 0 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 35ab77f..9149318 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -298,6 +298,26 @@ class ReferencesTestCase(TestBase):
else:
self.fail("exception not properly restored")
+ def test_sf_bug_840829(self):
+ # "weakref callbacks and gc corrupt memory"
+ # subtype_dealloc erroneously exposed a new-style instance
+ # already in the process of getting deallocated to gc,
+ # causing double-deallocation if the instance had a weakref
+ # callback that triggered gc.
+ # If the bug exists, there probably won't be an obvious symptom
+ # in a release build. In a debug build, a segfault will occur
+ # when the second attempt to remove the instance from the "list
+ # of all objects" occurs.
+
+ import gc
+
+ class C(object):
+ pass
+
+ c = C()
+ wr = weakref.ref(c, lambda ignore: gc.collect())
+ del c
+
class Object:
def __init__(self, arg):