Crash in thread on program termination

Alec Wysoker alecw at pobox.com
Wed Feb 9 17:24:59 EST 2005


I have several programs that have two or more threads.  The threads that are not the main thread are daemon threads, i.e. the fact that they are running should not stop the program from terminating if the main thread (the only non-daemon thread) terminates.  I do not join to these threads, but just run off the end of the main module to terminate the program.  I'm using Python 2.3.4.  I occasionally get the following error:

Traceback (most recent call last):
  File "C:\Python23\lib\threading.py", line 451, in __bootstrap
    self.__stop()
  File "C:\Python23\lib\threading.py", line 460, in __stop
    self.__block.notifyAll()
  File "C:\Python23\lib\threading.py", line 256, in notifyAll
    self.notify(len(self.__waiters))
  File "C:\Python23\lib\threading.py", line 238, in notify
    currentThread() # for side-effect
TypeError: 'NoneType' object is not callable


What seems to be happening is that at the time the thread is stopped, the threading module object is no longer in an unhealthy state.  I.e. threading.currentThread is None.  I hacked around this problem by substituting my own code for _Condition.notifyAll() that would not call notify() if there were no waiters to be notified.  However, that merely allowed the code to get a little further, before crashing with a similar problem, i.e. threading._StringIO is None instead of being a class object.

Traceback (most recent call last):
  File "C:\Python23\lib\threading.py", line 443, in __bootstrap
    s = _StringIO()
TypeError: 'NoneType' object is not callable


I turned on threading.__debug__ and threading._VERBOSE to get some debug output, and one thing that is strange is that I don't get the debugging output I expect.

# From threading.Thread.__bootstrap():
            try:
                self.run()
            except SystemExit:
                if __debug__:
                    self._note("%s.__bootstrap(): raised SystemExit", self)
            except:
                if __debug__:
                    self._note("%s.__bootstrap(): unhandled exception", self)
                s = _StringIO()
                _print_exc(file=s)
                _sys.stderr.write("Exception in thread %s:\n%s\n" %
                                 (self.getName(), s.getvalue()))
            else:
                if __debug__:
                    self._note("%s.__bootstrap(): normal return", self)
        finally:
            self.__stop()   # Line 451


I.e. I would expect to get one of the messages ('raised SystemExit', 'unhandled exception', or 'normal return') before self.__stop() is called at line 451.  However, I do not see any of those messages.

Any ideas or suggestions?  I am baffled.

Thanks,

Alec Wysoker





More information about the Python-list mailing list