-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
TypeError: descriptor 'some_method' for 'A' objects doesn't apply to a 'B' object #121368
Comments
By the way I hit this last week with 3.13.0b2 so this is likely a problem on the 3.13 branch as well and not something new in 3.14. |
Another interesting failure from running the
Look at the failing |
I have tried to reproduce the above issue with pywt, and I'm routinely seeing errors like:
Has the NumPy argument parsing been made thread-safe yet? |
No, that PR is still in-flight: numpy/numpy#26780 |
I should probably mention, I'm testing all this with |
Minimal repro so farThis is somewhat frustrating to reproduce without any larger dependencies or codebases. The smallest thing I managed to get to crash is this:
Run it with
with the The hash seed is a red herring but, believe me, if I remove that bit, I can't repro no more. The result of running this for a longer while is a similar unexpected code execution, one example being:
where the jump from calling |
Thanks, I'm able to reproduce it intermittently now. So far only on my macOS arm64 laptop, not on x86-64 Linux. Reducing |
The bug is in our seq lock implementation: Lines 550 to 560 in cb688ba
Lines 5390 to 5402 in cb688ba
The memory ordering on the The bug occurs on arm64, but not x86-64, because x86-64 enforces ordering of loads relative to each other. |
The `_PySeqLock_EndRead` function needs an acquire fence to ensure that the load of the sequence happens after any loads within the read side critical section. The acquire on the final sequence load isn't sufficent (or necessary).
The `_PySeqLock_EndRead` function needs an acquire fence to ensure that the load of the sequence happens after any loads within the read side critical section. The missing fence can trigger bugs on macOS arm64. Additionally, we need a release fence in `_PySeqLock_LockWrite` to ensure that the sequence update is visible before any modifications to the cache entry.
…onGH-121388) The `_PySeqLock_EndRead` function needs an acquire fence to ensure that the load of the sequence happens after any loads within the read side critical section. The missing fence can trigger bugs on macOS arm64. Additionally, we need a release fence in `_PySeqLock_LockWrite` to ensure that the sequence update is visible before any modifications to the cache entry. (cherry picked from commit 1d3cf79) Co-authored-by: Sam Gross <[email protected]>
…121388) (#121505) The `_PySeqLock_EndRead` function needs an acquire fence to ensure that the load of the sequence happens after any loads within the read side critical section. The missing fence can trigger bugs on macOS arm64. Additionally, we need a release fence in `_PySeqLock_LockWrite` to ensure that the sequence update is visible before any modifications to the cache entry. (cherry picked from commit 1d3cf79) Co-authored-by: Sam Gross <[email protected]>
With the PRs merged, is there anything left to do here? |
I close the issue. |
…on#121388) The `_PySeqLock_EndRead` function needs an acquire fence to ensure that the load of the sequence happens after any loads within the read side critical section. The missing fence can trigger bugs on macOS arm64. Additionally, we need a release fence in `_PySeqLock_LockWrite` to ensure that the sequence update is visible before any modifications to the cache entry.
…on#121388) The `_PySeqLock_EndRead` function needs an acquire fence to ensure that the load of the sequence happens after any loads within the read side critical section. The missing fence can trigger bugs on macOS arm64. Additionally, we need a release fence in `_PySeqLock_LockWrite` to ensure that the sequence update is visible before any modifications to the cache entry.
Bug report
I found a bug that seems to be code corruption.
While working on an example project with ~70 threads, I occasionally (once every hour or so) get the following exception from various locks:
or
This looks like it's a bug related to locks but it isn't. It's not even related to descriptors, only descriptors nicely refuse running invalid code.
This issue is also externally reported in PyWavelets/pywt#758 with the same Lock descriptor error message I've seen, and I can reproduce the failure locally, albeit with a different exception:
To reproduce this with cpython
main
, do the following:pip install -e .
pip install . --no-build-isolation
(important: no-e
in this case)pip install -e . --no-build-isolation
(important: you DO need-e
in this case)PYTHON_GIL=0 pytest pywt/tests/test_concurrent.py
You will need to run this for a longer while to get to a failure.
By doing this, I managed to find this particular failure case:
Observe how Python wants to call
self._adjust_thread_count()
(with no arguments) but ends up callingf.set_result()
, which causes an exception due to no arguments being passed.Tested on macOS Sonoma on M1 Max with Python 3.14.0a0 experimental free-threading build (heads/main:7a807c3efaa, Jul 2 2024, 11:58:38).
AFAICT the problem only occurs with the GIL actually disabled.
Linked PRs
The text was updated successfully, but these errors were encountered: