Skip to content

Data race on tp_flags with subinterpreters and static types #129817

Open
@colesbury

Description

@colesbury

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:

cpython/Objects/typeobject.c

Lines 8661 to 8663 in fbaa6c8

/* 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

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions