From 1af51757ab103fb18b8d1785bc5df4a0deb3e336 Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Wed, 18 Apr 2018 10:15:05 -0400 Subject: [PATCH] Add a crasher to Lib/test for issue #26153. This crasher doesn't crash Python 3.6, although I've seen the same crash in 3.6 (when involving extension types and more complicated threading setups). --- Lib/test/crashers/warnings_del_crasher.py | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Lib/test/crashers/warnings_del_crasher.py diff --git a/Lib/test/crashers/warnings_del_crasher.py b/Lib/test/crashers/warnings_del_crasher.py new file mode 100644 index 000000000000000..02e680520204147 --- /dev/null +++ b/Lib/test/crashers/warnings_del_crasher.py @@ -0,0 +1,29 @@ +""" +Expose a race in the _warnings module, which is the C backend for the +warnings module. The "_warnings" module tries to access attributes of the +"warnings" module (because of the API it has to support), but doing so +during interpreter shutdown is problematic. Specifically, the call to +PyImport_GetModuleDict() in Python/_warnings.c:get_warnings_attr will +abort() if the modules dict has already been cleaned up. + +This crasher is timing-dependent, and more threads (NUM_THREADS) may be +necessary to expose it reliably on different systems. +""" + +import threading +import warnings + +NUM_THREADS = 10 + +class WarnOnDel(object): + def __del__(self): + warnings.warn("oh no something went wrong", UserWarning) + +def do_work(): + while True: + w = WarnOnDel() + +for i in range(NUM_THREADS): + t = threading.Thread(target=do_work) + t.setDaemon(1) + t.start()