Repository navigation
slot.__delete__() behaves as non-atomic in free-threading #146270
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Mar 22, 2026 - addedinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
on Mar 22, 2026 I am not able to reproduce the result (
del obj.bdoes not raise any exception) on main. Doesn't the first thread delete bothobj.aandobj.b?The result is reproduced in free-threading. Below is my output on CPython 3.14.3t (via mise):
Traceback (most recent call last): File "/home/user/workspace/example.py", line 42, in <module> main() ~~~~^^ File "/home/user/workspace/example.py", line 38, in main f2.result() # reraise ~~~~~~~~~^^ File "/home/user/.local/share/mise/installs/python/3.14.3t/lib/python3.14t/concurrent/futures/_base.py", line 443, in result return self.__get_result() ~~~~~~~~~~~~~~~~~^^ File "/home/user/.local/share/mise/installs/python/3.14.3t/lib/python3.14t/concurrent/futures/_base.py", line 395, in __get_result raise self._exception File "/home/user/.local/share/mise/installs/python/3.14.3t/lib/python3.14t/concurrent/futures/thread.py", line 86, in run result = ctx.run(self.task) File "/home/user/.local/share/mise/installs/python/3.14.3t/lib/python3.14t/concurrent/futures/thread.py", line 73, in run return fn(*args, **kwargs) File "/home/user/workspace/example.py", line 26, in test del obj.b ^^^^^ AttributeError: b
If you cannot reproduce this, you are likely not running in free-threading mode (the successful deletion of both attributes is the expected behavior that should be achieved). Alternatively, other factors may be at play, but it takes me only a fraction of a second to reproduce the issue.
CPython 3.15.0a7+ free-threading build (heads/main:f0aeabc)
Traceback (most recent call last): File "/home/user/workspace/example.py", line 42, in <module> main() ~~~~^^ File "/home/user/workspace/example.py", line 37, in main f1.result() # reraise ~~~~~~~~~^^ File "/home/user/.local/share/mise/installs/python/3.15t-dev/lib/python3.15t/concurrent/futures/_base.py", line 443, in result return self.__get_result() ~~~~~~~~~~~~~~~~~^^ File "/home/user/.local/share/mise/installs/python/3.15t-dev/lib/python3.15t/concurrent/futures/_base.py", line 395, in __get_result raise self._exception File "/home/user/.local/share/mise/installs/python/3.15t-dev/lib/python3.15t/concurrent/futures/thread.py", line 86, in run result = ctx.run(self.task) File "/home/user/.local/share/mise/installs/python/3.15t-dev/lib/python3.15t/concurrent/futures/thread.py", line 73, in run return fn(*args, **kwargs) File "/home/user/workspace/example.py", line 26, in test del obj.b ^^^^^ AttributeError: b
If you cannot reproduce the issue exactly in free-threading, then it may be due to a difference in the system scheduler. I write my tests specifically based on elapsed time rather than the number of iterations to minimize differences in hardware speed and interpreter implementation (if one machine runs the software twice as fast as another, but both use the same timeslices (e.g., the same 5 milliseconds with GIL), then the first machine’s thread-safety coverage will be twice as bad as the second’s for the same number of iterations; therefore, it seems to me that elapsed time is a much more suitable parameter for reproducibility here, if we ignore the impact of foreign processes). I have a custom scheduler and a laptop from the early 2010s, which may affect reproducibility, since a different scheduler might schedule threads in such a way that two short-term scheduled calls would never actually enter a race condition.
If that is the case, please let me know so I can try to write a test that takes into account the specifics of your scheduler.
I just tested it on modern hardware and the default scheduler. Nope, the issue reproduces there too.
When I run it on main with this config:
./configure --with-pydebug --with-thread-sanitizer --disable-gil,
I do not getting any error. However, when I downloaded 3.14.3t, I did get an error so there is a chance that this issue has already been fixed../configure --with-pydebug --with-thread-sanitizer --disable-gil
When you call
sys._is_gil_enabled(), do you getFalse?I did get an error so there is a chance that this issue has already been fixed.
My comment also includes an output for main, commit f0aeabc, where the issue reproduces. The issue has definitely not been fixed, since I can still see it in the source code and can personally reproduce it on main. (The latter is included here purely for illustrative purposes, since thread-safety issues are not always easy to reproduce.)
Behavior that occurs in free-threading:
- Suppose both threads have entered
PyMember_SetOne(). - Thread A checks
addr == NULL, getsfalse, but sleeps beforeFT_ATOMIC_STORE_PTR_RELEASE(). - Thread B also checks
addr == NULLand also getsfalse(since Thread A did not have time to change the value ofaddr). - The rest of this story is of no interest to us: neither of these threads will raise an
AttributeErroratdel obj.a, and as a result, both threads will attempt to dodel obj.b(and either enter a race condition again, or one of them will raise anAttributeError).
A classic scenario, nothing new. Incorrect sequences such as
if not loop.is_closed(): loop.call_soon_threadsafe(...)also have this nature (unfortunately, I sometimes see this in various projects; here it would be better to use a try-except onRuntimeErrorinstead, since otherwise the event loop may close before the call but after the check), and everything else that for some reason tries to use simple checks in a multithreaded environment.- Suppose both threads have entered
./configure --with-pydebug --with-thread-sanitizer --disable-gil
Okay, I built main with your configuration via Docker (reusing the environment from
python:latest), and I understood why you could not reproduce the issue (apologies for my tone; I have a specific background in working with people). By process of elimination, I concluded that TSan (--with-thread-sanitizer) is to blame, as it affects the test's behavior so significantly that... Let me put it this way: I ran 10 tests with a timeout of 60 (one minute, see the while loop condition), and only 2 of them were able to reproduce the issue (with the same output). Moreover, TSan printed a warning in only one of the remaining 8 runs.output-1&2.txt (reproduced)
WARNING: ThreadSanitizer: data race (pid=10204) Atomic write of size 8 at 0x7ff98015b340 by thread T1: #0 _Py_atomic_store_ptr_release Include/cpython/pyatomic_gcc.h:565 (python+0x45c1b4) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #1 PyMember_SetOne Python/structmember.c:335 (python+0x45c1b4) #2 member_set Objects/descrobject.c:239 (python+0x1afd6b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 _PyObject_GenericSetAttrWithDict Objects/object.c:2047 (python+0x230fc5) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 PyObject_GenericSetAttr Objects/object.c:2118 (python+0x2312e8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 PyObject_SetAttr Objects/object.c:1531 (python+0x22ed96) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 PyObject_DelAttr Objects/object.c:1567 (python+0x22f08a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyEval_EvalFrameDefault Python/generated_cases.c.h:5377 (python+0x3832de) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x3c561b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 context_run Python/context.c:727 (python+0x3c65f1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 method_vectorcall_FASTCALL_KEYWORDS Objects/descrobject.c:421 (python+0x1b071b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:775 (python+0x36f1ca) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 _PyEval_EvalFrameDefault Python/generated_cases.c.h:1841 (python+0x3790ab) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #27 _PyVectorcall_Call Objects/call.c:273 (python+0x19a661) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #28 _PyObject_Call Objects/call.c:348 (python+0x19a9aa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #29 PyObject_Call Objects/call.c:373 (python+0x19aa0a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #30 thread_run Modules/_threadmodule.c:387 (python+0x537b2e) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #31 pythread_wrapper Python/thread_pthread.h:234 (python+0x47255f) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) Previous read of size 8 at 0x7ff98015b340 by thread T2: #0 PyMember_SetOne Python/structmember.c:177 (python+0x45baf8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #1 member_set Objects/descrobject.c:239 (python+0x1afd6b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #2 _PyObject_GenericSetAttrWithDict Objects/object.c:2047 (python+0x230fc5) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 PyObject_GenericSetAttr Objects/object.c:2118 (python+0x2312e8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 PyObject_SetAttr Objects/object.c:1531 (python+0x22ed96) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 PyObject_DelAttr Objects/object.c:1567 (python+0x22f08a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 _PyEval_EvalFrameDefault Python/generated_cases.c.h:5377 (python+0x3832de) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x3c561b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 context_run Python/context.c:727 (python+0x3c65f1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 method_vectorcall_FASTCALL_KEYWORDS Objects/descrobject.c:421 (python+0x1b071b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:775 (python+0x36f1ca) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _PyEval_EvalFrameDefault Python/generated_cases.c.h:1841 (python+0x3790ab) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 _PyVectorcall_Call Objects/call.c:273 (python+0x19a661) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #27 _PyObject_Call Objects/call.c:348 (python+0x19a9aa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #28 PyObject_Call Objects/call.c:373 (python+0x19aa0a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #29 thread_run Modules/_threadmodule.c:387 (python+0x537b2e) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #30 pythread_wrapper Python/thread_pthread.h:234 (python+0x47255f) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) Thread T1 'ThreadPoolExecu' (tid=10206, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1022 (libtsan.so.2+0x568a6) (BuildId: 99ef88596cb10a8ccf307fe1a9070f66a44b1624) #1 do_start_joinable_thread Python/thread_pthread.h:281 (python+0x4729c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #2 PyThread_start_joinable_thread Python/thread_pthread.h:323 (python+0x472b6d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 ThreadHandle_start Modules/_threadmodule.c:474 (python+0x5374fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 do_start_new_thread Modules/_threadmodule.c:1920 (python+0x5376fe) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 thread_PyThread_start_joinable_thread Modules/_threadmodule.c:2043 (python+0x537959) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 cfunction_call Objects/methodobject.c:564 (python+0x223185) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyObject_MakeTpCall Objects/call.c:242 (python+0x198521) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyObject_VectorcallTstate Include/internal/pycore_call.h:142 (python+0x19878a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:775 (python+0x36f1ca) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyEval_EvalFrameDefault Python/generated_cases.c.h:3222 (python+0x37d203) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 PyEval_EvalCode Python/ceval.c:686 (python+0x39a336) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 run_eval_code_obj Python/pythonrun.c:1368 (python+0x44ea97) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 run_mod Python/pythonrun.c:1471 (python+0x44ed78) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 pyrun_file Python/pythonrun.c:1295 (python+0x44f7a1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 _PyRun_SimpleFileObject Python/pythonrun.c:518 (python+0x4515fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _PyRun_AnyFileObject Python/pythonrun.c:81 (python+0x4517fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 pymain_run_file_obj Modules/main.c:410 (python+0x48b858) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 pymain_run_file Modules/main.c:429 (python+0x48b9b4) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 pymain_run_python Modules/main.c:714 (python+0x48c8fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 Py_RunMain Modules/main.c:795 (python+0x48cbd2) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 pymain_main Modules/main.c:825 (python+0x48cc66) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 Py_BytesMain Modules/main.c:849 (python+0x48cd77) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 main Programs/python.c:15 (python+0x9abc7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) Thread T2 'ThreadPoolExecu' (tid=10207, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1022 (libtsan.so.2+0x568a6) (BuildId: 99ef88596cb10a8ccf307fe1a9070f66a44b1624) #1 do_start_joinable_thread Python/thread_pthread.h:281 (python+0x4729c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #2 PyThread_start_joinable_thread Python/thread_pthread.h:323 (python+0x472b6d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 ThreadHandle_start Modules/_threadmodule.c:474 (python+0x5374fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 do_start_new_thread Modules/_threadmodule.c:1920 (python+0x5376fe) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 thread_PyThread_start_joinable_thread Modules/_threadmodule.c:2043 (python+0x537959) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 cfunction_call Objects/methodobject.c:564 (python+0x223185) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyObject_MakeTpCall Objects/call.c:242 (python+0x198521) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyObject_VectorcallTstate Include/internal/pycore_call.h:142 (python+0x19878a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _Py_VectorCall_StackRefSteal Python/ceval.c:733 (python+0x36f06f) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyEval_EvalFrameDefault Python/generated_cases.c.h:3424 (python+0x37ddb3) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 PyEval_EvalCode Python/ceval.c:686 (python+0x39a336) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 run_eval_code_obj Python/pythonrun.c:1368 (python+0x44ea97) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 run_mod Python/pythonrun.c:1471 (python+0x44ed78) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 pyrun_file Python/pythonrun.c:1295 (python+0x44f7a1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 _PyRun_SimpleFileObject Python/pythonrun.c:518 (python+0x4515fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _PyRun_AnyFileObject Python/pythonrun.c:81 (python+0x4517fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 pymain_run_file_obj Modules/main.c:410 (python+0x48b858) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 pymain_run_file Modules/main.c:429 (python+0x48b9b4) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 pymain_run_python Modules/main.c:714 (python+0x48c8fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 Py_RunMain Modules/main.c:795 (python+0x48cbd2) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 pymain_main Modules/main.c:825 (python+0x48cc66) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 Py_BytesMain Modules/main.c:849 (python+0x48cd77) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 main Programs/python.c:15 (python+0x9abc7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) SUMMARY: ThreadSanitizer: data race Include/cpython/pyatomic_gcc.h:565 in _Py_atomic_store_ptr_release ================== Traceback (most recent call last): File "/cpython-main/example.py", line 42, in <module> main() ~~~~^^ File "/cpython-main/example.py", line 38, in main f2.result() # reraise ~~~~~~~~~^^ File "/cpython-main/Lib/concurrent/futures/_base.py", line 443, in result return self.__get_result() ~~~~~~~~~~~~~~~~~^^ File "/cpython-main/Lib/concurrent/futures/_base.py", line 395, in __get_result raise self._exception File "/cpython-main/Lib/concurrent/futures/thread.py", line 86, in run result = ctx.run(self.task) File "/cpython-main/Lib/concurrent/futures/thread.py", line 73, in run return fn(*args, **kwargs) File "/cpython-main/example.py", line 26, in test del obj.b ^^^^^ AttributeError: b ThreadSanitizer: reported 1 warningsoutput-3.txt (not reproduced)
WARNING: ThreadSanitizer: data race (pid=10250) Read of size 8 at 0x7f2d2a15b340 by thread T1: #0 PyMember_SetOne Python/structmember.c:177 (python+0x45baf8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #1 member_set Objects/descrobject.c:239 (python+0x1afd6b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #2 _PyObject_GenericSetAttrWithDict Objects/object.c:2047 (python+0x230fc5) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 PyObject_GenericSetAttr Objects/object.c:2118 (python+0x2312e8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 PyObject_SetAttr Objects/object.c:1531 (python+0x22ed96) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 PyObject_DelAttr Objects/object.c:1567 (python+0x22f08a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 _PyEval_EvalFrameDefault Python/generated_cases.c.h:5377 (python+0x3832de) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x3c561b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 context_run Python/context.c:727 (python+0x3c65f1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 method_vectorcall_FASTCALL_KEYWORDS Objects/descrobject.c:421 (python+0x1b071b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:775 (python+0x36f1ca) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _PyEval_EvalFrameDefault Python/generated_cases.c.h:1841 (python+0x3790ab) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 _PyVectorcall_Call Objects/call.c:273 (python+0x19a661) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #27 _PyObject_Call Objects/call.c:348 (python+0x19a9aa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #28 PyObject_Call Objects/call.c:373 (python+0x19aa0a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #29 thread_run Modules/_threadmodule.c:387 (python+0x537b2e) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #30 pythread_wrapper Python/thread_pthread.h:234 (python+0x47255f) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) Previous atomic write of size 8 at 0x7f2d2a15b340 by thread T2: #0 _Py_atomic_store_ptr_release Include/cpython/pyatomic_gcc.h:565 (python+0x45c1b4) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #1 PyMember_SetOne Python/structmember.c:335 (python+0x45c1b4) #2 member_set Objects/descrobject.c:239 (python+0x1afd6b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 _PyObject_GenericSetAttrWithDict Objects/object.c:2047 (python+0x230fc5) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 PyObject_GenericSetAttr Objects/object.c:2118 (python+0x2312e8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 PyObject_SetAttr Objects/object.c:1531 (python+0x22ed96) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 PyObject_DelAttr Objects/object.c:1567 (python+0x22f08a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyEval_EvalFrameDefault Python/generated_cases.c.h:5377 (python+0x3832de) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x3c561b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 context_run Python/context.c:727 (python+0x3c65f1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 method_vectorcall_FASTCALL_KEYWORDS Objects/descrobject.c:421 (python+0x1b071b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:775 (python+0x36f1ca) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 _PyEval_EvalFrameDefault Python/generated_cases.c.h:1841 (python+0x3790ab) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 _PyFunction_Vectorcall Objects/call.c:413 (python+0x1982c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 _PyObject_VectorcallTstate Include/internal/pycore_call.h:144 (python+0x1986f7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 _PyObject_VectorcallPrepend Objects/call.c:855 (python+0x1996a8) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 method_vectorcall Objects/classobject.c:55 (python+0x19c88b) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #27 _PyVectorcall_Call Objects/call.c:273 (python+0x19a661) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #28 _PyObject_Call Objects/call.c:348 (python+0x19a9aa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #29 PyObject_Call Objects/call.c:373 (python+0x19aa0a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #30 thread_run Modules/_threadmodule.c:387 (python+0x537b2e) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #31 pythread_wrapper Python/thread_pthread.h:234 (python+0x47255f) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) Thread T1 'ThreadPoolExecu' (tid=10252, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1022 (libtsan.so.2+0x568a6) (BuildId: 99ef88596cb10a8ccf307fe1a9070f66a44b1624) #1 do_start_joinable_thread Python/thread_pthread.h:281 (python+0x4729c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #2 PyThread_start_joinable_thread Python/thread_pthread.h:323 (python+0x472b6d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 ThreadHandle_start Modules/_threadmodule.c:474 (python+0x5374fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 do_start_new_thread Modules/_threadmodule.c:1920 (python+0x5376fe) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 thread_PyThread_start_joinable_thread Modules/_threadmodule.c:2043 (python+0x537959) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 cfunction_call Objects/methodobject.c:564 (python+0x223185) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyObject_MakeTpCall Objects/call.c:242 (python+0x198521) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyObject_VectorcallTstate Include/internal/pycore_call.h:142 (python+0x19878a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:775 (python+0x36f1ca) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyEval_EvalFrameDefault Python/generated_cases.c.h:3222 (python+0x37d203) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 PyEval_EvalCode Python/ceval.c:686 (python+0x39a336) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 run_eval_code_obj Python/pythonrun.c:1368 (python+0x44ea97) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 run_mod Python/pythonrun.c:1471 (python+0x44ed78) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 pyrun_file Python/pythonrun.c:1295 (python+0x44f7a1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 _PyRun_SimpleFileObject Python/pythonrun.c:518 (python+0x4515fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _PyRun_AnyFileObject Python/pythonrun.c:81 (python+0x4517fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 pymain_run_file_obj Modules/main.c:410 (python+0x48b858) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 pymain_run_file Modules/main.c:429 (python+0x48b9b4) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 pymain_run_python Modules/main.c:714 (python+0x48c8fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 Py_RunMain Modules/main.c:795 (python+0x48cbd2) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 pymain_main Modules/main.c:825 (python+0x48cc66) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 Py_BytesMain Modules/main.c:849 (python+0x48cd77) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 main Programs/python.c:15 (python+0x9abc7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) Thread T2 'ThreadPoolExecu' (tid=10253, running) created by main thread at: #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1022 (libtsan.so.2+0x568a6) (BuildId: 99ef88596cb10a8ccf307fe1a9070f66a44b1624) #1 do_start_joinable_thread Python/thread_pthread.h:281 (python+0x4729c9) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #2 PyThread_start_joinable_thread Python/thread_pthread.h:323 (python+0x472b6d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #3 ThreadHandle_start Modules/_threadmodule.c:474 (python+0x5374fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #4 do_start_new_thread Modules/_threadmodule.c:1920 (python+0x5376fe) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #5 thread_PyThread_start_joinable_thread Modules/_threadmodule.c:2043 (python+0x537959) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #6 cfunction_call Objects/methodobject.c:564 (python+0x223185) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #7 _PyObject_MakeTpCall Objects/call.c:242 (python+0x198521) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #8 _PyObject_VectorcallTstate Include/internal/pycore_call.h:142 (python+0x19878a) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #9 PyObject_Vectorcall Objects/call.c:327 (python+0x19883d) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #10 _Py_VectorCall_StackRefSteal Python/ceval.c:733 (python+0x36f06f) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #11 _PyEval_EvalFrameDefault Python/generated_cases.c.h:3424 (python+0x37ddb3) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #12 _PyEval_EvalFrame Include/internal/pycore_ceval.h:118 (python+0x399f70) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #13 _PyEval_Vector Python/ceval.c:2166 (python+0x39a1ee) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #14 PyEval_EvalCode Python/ceval.c:686 (python+0x39a336) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #15 run_eval_code_obj Python/pythonrun.c:1368 (python+0x44ea97) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #16 run_mod Python/pythonrun.c:1471 (python+0x44ed78) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #17 pyrun_file Python/pythonrun.c:1295 (python+0x44f7a1) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #18 _PyRun_SimpleFileObject Python/pythonrun.c:518 (python+0x4515fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #19 _PyRun_AnyFileObject Python/pythonrun.c:81 (python+0x4517fc) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #20 pymain_run_file_obj Modules/main.c:410 (python+0x48b858) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #21 pymain_run_file Modules/main.c:429 (python+0x48b9b4) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #22 pymain_run_python Modules/main.c:714 (python+0x48c8fa) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #23 Py_RunMain Modules/main.c:795 (python+0x48cbd2) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #24 pymain_main Modules/main.c:825 (python+0x48cc66) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #25 Py_BytesMain Modules/main.c:849 (python+0x48cd77) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) #26 main Programs/python.c:15 (python+0x9abc7) (BuildId: 2a85fcfbed9bca2cd9af7b0ac67e14b2ce712d4d) SUMMARY: ThreadSanitizer: data race Python/structmember.c:177 in PyMember_SetOne ================== ThreadSanitizer: reported 1 warnings
I also tried running the test for 10 minutes:
root@85d19837c2cd /cpython-main# time ./python example.py ________________________________________________________ Executed in 606.04 secs fish external usr time 18.72 mins 626.00 micros 18.72 mins sys time 0.41 mins 738.00 micros 0.41 mins
No errors, no warnings. All subsequent tries (11) after that were successful: 52.82±37.68 secs. In terms of the number of iterations required for reproduction, TSan increases them by about 20 times (~2K → ~40K).
Yeah, this looks like a bug to me. We should handle
Py_T_OBJECT_EXin the delete code path the same way we handle it further on inPyMember_SetOne.I guess this is something that @dpdani could take
Oops, it seems I forgot looking into that code path back then. It is definitely a bug, thank you for reporting that 👍
Reacted by Ilya EgorovI should note that it would be possible to handle both
__set__()and__delete__()without per-object locks, simply by using something like_Py_atomic_exchange_ptr()frompyatomic.h(and raising anAttributeErrorwhen both the new and old values areNULL). There is no wrapper for it inpycore_pyatomic_ft_wrappers.h, but as I saw in one PR, it can be used with#ifdef Py_GIL_DISABLED.
Oh, wait, I saw the comments about this in the discussion of the first PR mentioned. Never mind.
Hypothetically, it could be used reliably in
PyMember_SetOne()if it were also used inPyMember_GetOne(): the getter would exchange the value with some special value, thereby preventing the setter from performing a decref. It would then attempt a compare-and-exchange back, and perform an incref only if successful. That way, only the getters would have to be synchronized. But this is a dubious benefit, and support for the special value would also have to be handled by C API users (or not? if they always use per-object locks or if some special value is safe, then the new behavior would not make any difference except for the possibility of concurrent writes while holding the lock, but I know too little about C API use cases). So yes, it seems that there is not much that can be done here.On the other hand, the technique I described optimizes my use case (
slot.__delete__()as an atomic Python-level test-and-set). The optimistic path ofPyMember_GetOne()is not going anywhere, so in the best-case scenario (read-only or write-only), all operations will be performed without per-object locks. But there is the problem with the special value...Thanks for the bug report @x42005e1f and @dpdani for fixing this
Reacted by Daniele Parmeggiani and Ilya EgorovReacted by Ilya Egorov
Bug report
Bug description:
In #119368+#123211, member descriptors (related to user-defined slots) were made thread-safe. But not everywhere. The branch related to deletion remained unchanged:
cpython/Python/structmember.c
Lines 174 to 187 in 83360b5
Since threads perform the check (
addr == NULL) in a non-thread-safe manner, the operation may succeed even if it has already been executed by another thread. At the Python level, this means that anAttributeErrormay not be raised during two or more concurrent attempts to delete an attribute, and as a result, code that was supposed to execute only once (after a successful deletion) will be executed more than once.The behavior matches what is expected on CPython with GIL and on PyPy (and possibly other interpreters), but not on CPython without GIL. Without slots (using
__dict__), the behavior also matches what is expected even in free-threading. Meanwhile, user-defined slots already rely on critical sections, so the simplest solution would be to move the check forPy_T_OBJECT_EXunder the critical section (into the case block).Code to reproduce (
del obj.braises anAttributeError):CPython versions tested on:
3.14
Operating systems tested on:
Linux
Linked PRs
PyMember_SetOne(..., NULL)not being atomic #148800PyMember_SetOne(..., NULL)not being atomic (gh-148800) #149460