[issue38006] Crash in remove() weak reference callback of weakref.WeakValueDictionary at Python exit
STINNER Victor
report at bugs.python.org
Tue Sep 3 08:45:01 EDT 2019
STINNER Victor <vstinner at python.org> added the comment:
Second step: when func_clear() is called, the closure is cleared. Clearing the closure should call the function which is being cleared (or is already cleared).
---
import gc
class CallFunc:
def __del__(self):
func = self.func
if func is None:
return
print("CallFunc", func)
func("call func from CallFunc.__del__")
def create_remove():
call_func = CallFunc()
def remove(msg):
x = call_func
print(msg)
remove.__name__ = "evil_func"
call_func.func = remove
return call_func, remove
call_func, remove = create_remove()
print("== clear ==")
call_func = None
remove = None
print()
print("== collect ==")
gc.collect()
print()
print("== exit ==")
---
Output (with my hacked CPython):
------------------
== clear ==
== collect ==
CallFunc <function create_remove.<locals>.remove at 0x7fab8a189eb0>
call func from CallFunc.__del__
func_clear remove() -- in delete_garbage? 1
== exit ==
------------------
call_func and remove are part of a reference cycle. A forced garbage collection breaks the cycle and removes the two objects, but they are not removed in the expected order:
* first: call_func
* then: remove
The crash requires to destroy the objects in the reverse order
----------
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue38006>
_______________________________________
More information about the Python-bugs-list
mailing list