-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
multithreading traceback KeyError when modifying file #70060
Comments
Modifying a file while getting a stacktrace across multiple threads causes linecache's cache to bust and del to be called on the global cache variable. This is not thread safe and raises a KeyError. Reproducible with, import threading
import traceback
def main():
with open(__file__, 'a') as fp:
fp.write(' ')
traceback.format_stack()
threads = [
threading.Thread(target=main)
for i in range(100)
]
map(lambda t: t.start(), threads)
map(lambda t: t.join(), threads) I see the following error, Exception in thread Thread-56:
Traceback (most recent call last):
File "/Users/me/.pyenv/versions/2.7.10/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/Users/me/.pyenv/versions/2.7.10/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "test.py", line 7, in main
traceback.format_stack()
File "/Users/me/.pyenv/versions/2.7.10/lib/python2.7/traceback.py", line 279, in format_stack
return format_list(extract_stack(f, limit))
File "/Users/me/.pyenv/versions/2.7.10/lib/python2.7/traceback.py", line 305, in extract_stack
linecache.checkcache(filename)
File "/Users/me/.pyenv/versions/2.7.10/lib/python2.7/linecache.py", line 69, in checkcache
del cache[filename]
KeyError: 'test.py' Possible solution is to ignore KeyError on del cache[filename]. |
It seems there was a major refactor in traceback module with 6bc2c1e where this was fixed in Python 3. Ignoring the KeyError seems reasonable to me. Thanks |
As @XTreak said, this looks like it was fixed for Python 3 and was only an issue for 2.7, so I'm closing the issue. |
This issue still exists in Python 3. The repro just needs to be changed so that the threads are actually started. - map(lambda t: t.start(), threads)
- map(lambda t: t.join(), threads)
+ [t.start() for t in threads]
+ [t.join() for t in threads] My fix is linked. |
Thanks Michael, reopening. I was wrong while trying the reproducer since map is lazy in Python 3 and threads were not executed. |
The issue was fixed but a unit test for this still needs to be added. |
I apologize if this is rude, as I am not familiar with this method. I would be happy to receive feedback on the PR. |
@uniocto - thank you for the tests. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: