Bug report
I saw this in the free threading build when running test_concurrent_futures.test_interpreter_pool. I suspect it affects the default build (with per-interpreter GIL) as well, but I haven't verified that.
The fix looks straightforward to me: only set Py_TPFLAGS_READY if initial is true. Otherwise, the type will already have Py_TPFLAGS_READY set.
WARNING: ThreadSanitizer: data race (pid=1450991)
Write of size 8 at 0x555555d46628 by thread T2:
#0 type_ready /raid/sgross/cpython/Objects/typeobject.c:8662:20 (python+0x302724) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#1 init_static_type /raid/sgross/cpython/Objects/typeobject.c:8732:11 (python+0x302d01) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#2 _PyStaticType_InitBuiltin /raid/sgross/cpython/Objects/typeobject.c:8750:12 (python+0x303013) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#3 _PyTypes_InitTypes /raid/sgross/cpython/Objects/object.c:2430:13 (python+0x2a6afb) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#4 pycore_init_types /raid/sgross/cpython/Python/pylifecycle.c:710:14 (python+0x4b85d9) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#5 pycore_interp_init /raid/sgross/cpython/Python/pylifecycle.c:861:14 (python+0x4b8375) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#6 new_interpreter /raid/sgross/cpython/Python/pylifecycle.c:2317:14 (python+0x4b5063) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#7 Py_NewInterpreterFromConfig /raid/sgross/cpython/Python/pylifecycle.c:2350:12 (python+0x4b4baa) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#8 _PyXI_NewInterpreter /raid/sgross/cpython/Python/crossinterp.c:1936:23 (python+0x44d91e) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#9 interp_create /raid/sgross/cpython/./Modules/_interpretersmodule.c:631:13 (_interpreters.cpython-314t-x86_64-linux-gnu.so+0x3b8e) (BuildId: cbf13907b53ea6706466f16badeadb9cd6f8a096)
...
Previous read of size 8 at 0x555555d46628 by main thread:
#0 lookup_tp_dict /raid/sgross/cpython/Objects/typeobject.c:395:15 (python+0x2f7366) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#1 find_name_in_mro /raid/sgross/cpython/Objects/typeobject.c:5448:26 (python+0x2f7366)
#2 _PyType_LookupRefAndVersion /raid/sgross/cpython/Objects/typeobject.c:5611:11 (python+0x2f6e5f) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#3 _PyType_LookupRef /raid/sgross/cpython/Objects/typeobject.c:5659:12 (python+0x2f3480) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#4 _PyObject_GenericGetAttrWithDict /raid/sgross/cpython/Objects/object.c:1687:13 (python+0x2a2bed) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#5 _Py_module_getattro_impl /raid/sgross/cpython/Objects/moduleobject.c:937:12 (python+0x29931c) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#6 _Py_module_getattro /raid/sgross/cpython/Objects/moduleobject.c:1084:12 (python+0x299800) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
#7 PyObject_GetAttr /raid/sgross/cpython/Objects/object.c:1289:18 (python+0x2a1407) (BuildId: 8b1677c857cece976d8e5c76092eb8d5e05609fe)
...
Write of tp_flags:
|
/* All done -- set the ready flag */ |
|
type->tp_flags |= Py_TPFLAGS_READY; |
|
stop_readying(type); |
Read of tp_flags:
|
static inline PyObject * |
|
lookup_tp_dict(PyTypeObject *self) |
|
{ |
|
if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { |
|
PyInterpreterState *interp = _PyInterpreterState_GET(); |
|
managed_static_type_state *state = _PyStaticType_GetState(interp, self); |
|
assert(state != NULL); |
|
return state->tp_dict; |
|
} |
|
return self->tp_dict; |
|
} |
Linked PRs
Bug report
I saw this in the free threading build when running
test_concurrent_futures.test_interpreter_pool. I suspect it affects the default build (with per-interpreter GIL) as well, but I haven't verified that.The fix looks straightforward to me: only set
Py_TPFLAGS_READYifinitialis true. Otherwise, the type will already havePy_TPFLAGS_READYset.Write of
tp_flags:cpython/Objects/typeobject.c
Lines 8661 to 8663 in fbaa6c8
Read of
tp_flags:cpython/Objects/typeobject.c
Lines 392 to 402 in fbaa6c8
Linked PRs
_PyType_HasFeature()to check tp_flags. #130892