Skip to content

Race in _PyFreeList_Push #127879

Closed
Closed
@colesbury

Description

@colesbury

Bug report

Seen in https://github.com/python/cpython/actions/runs/12216713951/job/34310688405?pr=126865:

Reported by @markshannon

==================
WARNING: ThreadSanitizer: data race (pid=20210)
  Write of size 8 at 0x7fbb3e0415f0 by thread T31:
    #0 _PyFreeList_Push /home/runner/work/cpython/cpython/./Include/internal/pycore_freelist.h:54:23 (python+0x2cbe10) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #1 _PyFreeList_Free /home/runner/work/cpython/cpython/./Include/internal/pycore_freelist.h:67:10 (python+0x2cbe10)
    #2 long_dealloc /home/runner/work/cpython/cpython/Objects/longobject.c:3667:[13](https://github.com/python/cpython/actions/runs/12216713951/job/34310688405?pr=126865#step:13:14) (python+0x2cbe10)
    #3 _Py_Dealloc /home/runner/work/cpython/cpython/Objects/object.c:2977:5 (python+0x3186c4) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #4 _Py_MergeZeroLocalRefcount /home/runner/work/cpython/cpython/Objects/object.c (python+0x318d15) (BuildId: 7dc38[14](https://github.com/python/cpython/actions/runs/12216713951/job/34310688405?pr=126865#step:13:15)d1a5683dfc5de7e8c3c8846a47a478499)
    #5 Py_DECREF /home/runner/work/cpython/cpython/./Include/refcount.h:323:13 (python+0x5ea28e) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #6 Py_XDECREF /home/runner/work/cpython/cpython/./Include/refcount.h:476:9 (python+0x5ea28e)
    #7 PyMember_SetOne /home/runner/work/cpython/cpython/Python/structmember.c:315:9 
...

Previous atomic read of size 8 at 0x7fbb3e0415f0 by thread T32:
    #0 _Py_atomic_load_uintptr_relaxed /home/runner/work/cpython/cpython/./Include/cpython/pyatomic_gcc.h:375:10 (python+0x5e96b9) (BuildId: 7dc[38](https://github.com/python/cpython/actions/runs/12216713951/job/34310688405?pr=126865#step:13:39)14d1a5683dfc5de7e8c3c8846a47a478499)
    #1 _Py_IsOwnedByCurrentThread /home/runner/work/cpython/cpython/./Include/object.h:242:12 (python+0x5e96b9)
    #2 _Py_TryIncrefFast /home/runner/work/cpython/cpython/./Include/internal/pycore_object.h:547:9 (python+0x5e96b9)
    #3 _Py_TryIncrefCompare /home/runner/work/cpython/cpython/./Include/internal/pycore_object.h:586:9 (python+0x5e96b9)
    #4 PyMember_GetOne /home/runner/work/cpython/cpython/Python/structmember.c:99:18 (python+0x5e93d5) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #5 member_get /home/runner/work/cpython/cpython/Objects/descrobject.c:179:12 (python+0x268c59) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #6 _PyObject_GenericGetAttrWithDict /home/runner/work/cpython/cpython/Objects/object.c:1690:19 (python+0x31d32b) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #7 PyObject_GenericGetAttr /home/runner/work/cpython/cpython/Objects/object.c:1772:12 (python+0x31d1[44](https://github.com/python/cpython/actions/runs/12216713951/job/34310688405?pr=126865#step:13:45)) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #8 PyObject_GetAttr /home/runner/work/cpython/cpython/Objects/object.c:1286:18 (python+0x31c6da) (BuildId: 7dc3814d1a5683dfc5de7e8c3c8846a47a478499)
    #9 _PyEval_EvalFrameDefault /home/runner/work/cpython/cpython/Python/generated_cases.c.h:5254:30 (python+0x4da626) (BuildId: 7dc3814d1a5683dfc5de7e8c3c88

We should be using a relaxed atomic write in pycore_freelist.h.

The background is that we have a few places (dict, list, structmember) that have a fast-path that attempts to avoid a lock. (https://peps.python.org/pep-0703/#optimistically-avoiding-locking). They may access the ob_tid and refcount fields while the object is freed (but the memory is still valid).

The freelist overwrites the first field (ob_tid in the free threading build). That's okay semantically because valid pointers are distinct from the thread ids we use for ob_tid (the GC also relies on this property). However, we still need to use an atomic operation (relaxed is fine here) when we write the field.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions