Index: Lib/threading.py =================================================================== --- Lib/threading.py (revision 51000) +++ Lib/threading.py (working copy) @@ -537,6 +537,16 @@ _active_limbo_lock.acquire() try: try: + # We need to turn off any tracing/profiling functions for + # this thread, now. If we don't then when we delete + # _active[_get_ident()], if either of the functions call + # currentThread(), a _DummyThread object will be created, + # which will try to acquire _active_limbo_lock which we're + # currently holding. + if _trace_hook: + _sys.settrace(None) + if _profile_hook: + _sys.setprofile(None) del _active[_get_ident()] except KeyError: if 'dummy_threading' not in _sys.modules: Index: Lib/test/test_threading.py =================================================================== --- Lib/test/test_threading.py (revision 51000) +++ Lib/test/test_threading.py (working copy) @@ -121,6 +121,28 @@ threading._DummyThread)) del threading._active[tid] + def test_trace_and_profile_func(self): + # Make sure that a thread can successfully delete itself from + # the _active dictionary even if tracing/profiling functions are + # being used. + def trace(frame, event, arg): + id = threading.currentThread().getName() + return trace + + def target(): + for i in range(100): + pass + + threading.settrace(trace) + t1 = threading.Thread(target=target) + t1.start() + t1.join() + + threading.setprofile(trace) + t2 = threading.Thread(target=target) + t2.start() + t2.join() + def test_main(): test.test_support.run_unittest(ThreadTests)