Skip to content

Data race in repr() of _thread.RLock #153292

Description

@Naserume

Bug report

Bug description:

In the free-threaded build, rlock_repr reads the recursive lock's owner with plain loads to build the repr string, while acquire/release/_acquire_restore write the owner with atomic stores.

static PyObject *
rlock_repr(PyObject *op)
{
rlockobject *self = rlockobject_CAST(op);
PyThread_ident_t owner = self->lock.thread;
int locked = rlock_locked_impl(self);

The reader side is not atomic, so a repr() concurrent with acquire() is a data race on the owner field.

Reproducer:

import _thread
from threading import Thread

r = _thread.RLock()

def thread1():
    for _ in range(20000):
        try:
            repr(r)
        except Exception:
            pass

def thread2():
    for _ in range(20000):
        r.acquire()
        r.release()

threads  = [Thread(target=thread1) for _ in range(6)]
threads += [Thread(target=thread2)   for _ in range(2)]
for t in threads: t.start()
for t in threads: t.join()

TSAN Report:

==================
WARNING: ThreadSanitizer: data race (pid=40273)
  Read of size 8 at 0x7fffb6600f38 by thread T1:
    #0 rlock_repr /cpython/./Modules/_threadmodule.c:1291:41 
    #1 PyObject_Repr /cpython/Objects/object.c:784:11 
    #2 builtin_repr /cpython/Python/bltinmodule.c:2677:12 
    #3 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:2712:35
...

  Previous atomic write of size 8 at 0x7fffb6600f38 by thread T7:
    #0 _Py_atomic_store_ullong_relaxed /cpython/./Include/cpython/pyatomic_gcc.h:518:3 
    #1 _PyRecursiveMutex_LockTimed /cpython/Python/lock.c:439:9 
    #2 _thread_RLock_acquire_impl /cpython/./Modules/_threadmodule.c:1102:22 
    #3 _thread_RLock_acquire /cpython/./Modules/clinic/_threadmodule.c.h:418:20 
    #4 _PyCallMethodDescriptorFastWithKeywords_StackRef /cpython/Python/ceval.c:883:11 
    #5 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:4205:35
...

SUMMARY: ThreadSanitizer: data race /cpython/./Modules/_threadmodule.c:1291:41 in rlock_repr
==================

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions