mirror of https://github.com/python/cpython
threading.Thread objects will now print a traceback for an exception raised
during interpreter shutdown instead of masking it with another traceback about accessing a NoneType when trying to print the exception out in the first place. Closes bug #754449 (using patch #954922).
This commit is contained in:
parent
f9bfdd850c
commit
cc4e935ea5
|
@ -367,6 +367,11 @@ _limbo = {}
|
|||
class Thread(_Verbose):
|
||||
|
||||
__initialized = False
|
||||
# Need to store a reference to sys.exc_info for printing
|
||||
# out exceptions when a thread tries to use a global var. during interp.
|
||||
# shutdown and thus raises an exception about trying to perform some
|
||||
# operation on/with a NoneType
|
||||
__exc_info = _sys.exc_info
|
||||
|
||||
def __init__(self, group=None, target=None, name=None,
|
||||
args=(), kwargs={}, verbose=None):
|
||||
|
@ -381,6 +386,9 @@ class Thread(_Verbose):
|
|||
self.__stopped = False
|
||||
self.__block = Condition(Lock())
|
||||
self.__initialized = True
|
||||
# sys.stderr is not stored in the class like
|
||||
# sys.exc_info since it can be changed between instances
|
||||
self.__stderr = _sys.stderr
|
||||
|
||||
def _set_daemon(self):
|
||||
# Overridden in _MainThread and _DummyThread
|
||||
|
@ -438,8 +446,36 @@ class Thread(_Verbose):
|
|||
except:
|
||||
if __debug__:
|
||||
self._note("%s.__bootstrap(): unhandled exception", self)
|
||||
_sys.stderr.write("Exception in thread %s:\n%s\n" %
|
||||
(self.getName(), _format_exc()))
|
||||
# If sys.stderr is no more (most likely from interpreter
|
||||
# shutdown) use self.__stderr. Otherwise still use sys (as in
|
||||
# _sys) in case sys.stderr was redefined since the creation of
|
||||
# self.
|
||||
if _sys:
|
||||
_sys.stderr.write("Exception in thread %s:\n%s\n" %
|
||||
(self.getName(), _format_exc()))
|
||||
else:
|
||||
# Do the best job possible w/o a huge amt. of code to
|
||||
# approximate a traceback (code ideas from
|
||||
# Lib/traceback.py)
|
||||
exc_type, exc_value, exc_tb = self.__exc_info()
|
||||
try:
|
||||
print>>self.__stderr, (
|
||||
"Exception in thread " + self.getName() +
|
||||
" (most likely raised during interpreter shutdown):")
|
||||
print>>self.__stderr, (
|
||||
"Traceback (most recent call last):")
|
||||
while exc_tb:
|
||||
print>>self.__stderr, (
|
||||
' File "%s", line %s, in %s' %
|
||||
(exc_tb.tb_frame.f_code.co_filename,
|
||||
exc_tb.tb_lineno,
|
||||
exc_tb.tb_frame.f_code.co_name))
|
||||
exc_tb = exc_tb.tb_next
|
||||
print>>self.__stderr, ("%s: %s" % (exc_type, exc_value))
|
||||
# Make sure that exc_tb gets deleted since it is a memory
|
||||
# hog; deleting everything else is just for thoroughness
|
||||
finally:
|
||||
del exc_type, exc_value, exc_tb
|
||||
else:
|
||||
if __debug__:
|
||||
self._note("%s.__bootstrap(): normal return", self)
|
||||
|
|
|
@ -360,6 +360,9 @@ Extension modules
|
|||
Library
|
||||
-------
|
||||
|
||||
- Bug #754449: threading.Thread objects will now print out a traceback even
|
||||
when an exception is raised in a thread during interpreter shutdown.
|
||||
|
||||
- Added Decimal.py per PEP 327.
|
||||
|
||||
- Bug #981299: rsync is now a recognized protocol in urlparse that uses a
|
||||
|
|
Loading…
Reference in New Issue