New submission from Yonatan Zunger <[email protected]>:
Using the following decorator to memoize a function causes the interpreter to
segfault on exit if any exceptions were stored in the cache. Changing the bad
line to instead store copy.copy(e) makes the problem go away.
Almost certainly some kind of problem with the GC of the traceback not
happening at the moment the interpreter expects it, but I haven't had time to
investigate any more deeply yet.
def memoize(keyFunc=lambda x: x, cacheExceptions: bool=True):
def wrapper(func):
return _Memo(func, keyFunc, cacheExceptions)
return wrapper
class _Memo(object):
def __init__(self, func, keyFunc, cacheExceptions: bool) -> None:
self.func = func
self.keyFunc = keyFunc
self.cacheExceptions = cacheExceptions
self.lock = threading.Lock()
self.cache = {}
def __call__(self, *args, **kwargs) -> Any:
key = self.keyFunc(*args, **kwargs)
assert isinstance(key, collections.Hashable)
with self.lock:
if key in self.cache:
value = self.cache[key]
if isinstance(value, BaseException):
raise value
return value
try:
result = self.func(*args, **kwargs)
except BaseException as e:
if self.cacheExceptions:
with self.lock:
self.cache[key] = e # BAD LINE
six.reraise(*sys.exc_info())
else:
with self.lock:
self.cache[key] = result
return result
----------
components: Interpreter Core
messages: 308978
nosy: zunger
priority: normal
severity: normal
status: open
title: Keeping an exception in cache can segfault the interpreter
type: crash
versions: Python 3.6
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue32421>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com