bpo-35615: Fix crashes when copying a Weak{Key,Value}Dictionary.#11384
Conversation
Protect dict iterations by wrapping them with _IterationGuard in the following methods: - WeakValueDictionary.copy() - WeakValueDictionary.__deepcopy__() - WeakKeyDictionary.copy() - WeakKeyDictionary.__deepcopy__()
|
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA (this might be simply due to a missing "GitHub Name" entry in your b.p.o account settings). This is necessary for legal reasons before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. You can check yourself to see if the CLA has been received. Thanks again for your contribution, we look forward to reviewing it! |
pitrou
left a comment
There was a problem hiding this comment.
LGTM. We might want to add a test (see check_weak_destroy_and_mutate_while_iterating in test_weakref.py).
vstinner
left a comment
There was a problem hiding this comment.
Is it possible to write a test reproducing the bug? (to then make sure that the fix works as expected)
As much as I want, I couldn't write a reliable test case in a standalone Python file to trigger this bug. I could, however, reliably trigger it when debugging my multithreaded PySide2 application. We also happened to trigger it once on our CI after hundreds of runs. I'm open to ideas of how to write a reliable test case to trigger this bug! |
|
I explained above where to look for and how to add a test. Please take a look. Edit: ok, the challenge here is to execute arbitrary code during the |
|
@pitrou I took a look at |
|
@ltfish You're right, I was too optimistic. I think we're left to using two threads: one that heavily copies a very large weakdict, another that loses references to the weakdict keys' or values', one at a time, in more or less random order. |
|
@pitrou Thanks. Lemme give it a try! |
a8af3a7 to
bfaeb71
Compare
bfaeb71 to
e2b9d24
Compare
|
On master branch: With this PR: |
|
Hi there, is there any update on this PR? |
|
Sorry @ltfish. I'm gonna review soon. |
Please see my previous reply. Without the fix, my newly added test case fails reliably on my machine. I can also open a PR without my fix if needed (to make sure the test case works as expected on the CI). |
|
Thanks @ltfish ! |
…honGH-11384) Protect dict iterations by wrapping them with _IterationGuard in the following methods: - WeakValueDictionary.copy() - WeakValueDictionary.__deepcopy__() - WeakKeyDictionary.copy() - WeakKeyDictionary.__deepcopy__() (cherry picked from commit 96d37db) Co-authored-by: Fish <ltfish@users.noreply.github.com>
|
GH-11785 is a backport of this pull request to the 3.7 branch. |
…11384) (GH-11785) Protect dict iterations by wrapping them with _IterationGuard in the following methods: - WeakValueDictionary.copy() - WeakValueDictionary.__deepcopy__() - WeakKeyDictionary.copy() - WeakKeyDictionary.__deepcopy__() (cherry picked from commit 96d37db) Co-authored-by: Fish <ltfish@users.noreply.github.com>
Protect dict iterations by wrapping them with _IterationGuard in the
following methods:
https://bugs.python.org/issue35615