calls threading.currentThread.
The correction somewhat improves the code, but it was close.
Many thanks to the "with" construct, which turns python code into C calls.
I wonder if it is not better to sys.settrace(None) just after
running the __main__ module and before finalization.
"""])
self.assertEqual(rc, 42)
+ def test_finalize_with_trace(self):
+ # Issue1733757
+ # Avoid a deadlock when sys.settrace steps into threading._shutdown
+ import subprocess
+ rc = subprocess.call([sys.executable, "-c", """if 1:
+ import sys, threading
+
+ # A deadlock-killer, to prevent the
+ # testsuite to hang forever
+ def killer():
+ import os, time
+ time.sleep(2)
+ print 'program blocked; aborting'
+ os._exit(2)
+ t = threading.Thread(target=killer)
+ t.setDaemon(True)
+ t.start()
+
+ # This is the trace function
+ def func(frame, event, arg):
+ threading.currentThread()
+ return func
+
+ sys.settrace(func)
+ """])
+ self.failIf(rc == 2, "interpreted was blocked")
+ self.failUnless(rc == 0, "Unexpected error")
+
+
def test_enumerate_after_join(self):
# Try hard to trigger #1703448: a thread is still returned in
# threading.enumerate() after it has been join()ed.
# since it isn't if dummy_threading is *not* being used then don't
# hide the exception.
- _active_limbo_lock.acquire()
try:
- try:
+ with _active_limbo_lock:
del _active[_get_ident()]
- except KeyError:
- if 'dummy_threading' not in _sys.modules:
- raise
- finally:
- _active_limbo_lock.release()
+ # There must not be any python code between the previous line
+ # and after the lock is released. Otherwise a tracing function
+ # could try to acquire the lock again in the same thread, (in
+ # currentThread()), and would block.
+ except KeyError:
+ if 'dummy_threading' not in _sys.modules:
+ raise
def join(self, timeout=None):
if not self.__initialized:
Core and builtins
-----------------
+- Issue #1733757: The interpreter would hang on shutdown if the tracing
+ function set by sys.settrace is still active and happens to call
+ threading.currentThread().
+
- Patch #1442: properly report exceptions when the PYTHONSTARTUP file
cannot be executed.