Skip to content

LIST_APPEND and SET_ADD opcodes safety in Free Threading #152288

Description

@vstinner

Hi,

While reviewing PR gh-152273, I moved _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so); check to set_add_entry_takeref() to check for bugs. I discovered that SET_ADD opcode calls _PySet_AddTakeRef() without getting the set critical section. That's surprising and IMO it would deserve adding a comment to explain why it's safe to omit locking here.

LIST_APPEND has a similar design (also omit locking).


The following code uses the evil gc.get_objects() function to call set.add() in a different thread while the main thread is building a set:

importdisimportgcimportthreadingGLOBAL_SET=Nonedefworker():
EVENT.wait()
obj=GLOBAL_SETforiinrange(100):
# Call set.add() which uses the critical sectionobj.add(i)
MARKER=b"MARKER".decode()
EVENT=threading.Event()
classEvilHash:
def__init__(self, hash_value):
self.hash_value=hash_valuedef__hash__(self):
globalGLOBAL_SET, EVENTifGLOBAL_SETisNone:
# Invoke the evil gc.get_objects()!forobjingc.get_objects():
ifisinstance(obj, set) andMARKERinobj:
GLOBAL_SET=objEVENT.set()
returnself.hash_valuedef__repr__(self):
returnf"EvilHash({self.hash_value})"deffunc():
build_set= {
# Use *list so following items are added by SET_ADD opcode*[MARKER],
# Added by SET_ADD which calls _PySet_AddTakeRef()# without the critical sectionEvilHash(0), EvilHash(1), EvilHash(2), EvilHash(3), EvilHash(4),
EvilHash(5)}
print(build_set)
print("Length:", len(build_set))
iflen(build_set) !=107:
raiseException("race condition!")
thread=threading.Thread(target=worker)
thread.start()
func()
thread.join()
#dis.dis(func)

I expected the code to fail randomly, but so far I failed to trigger a race condition on Free Threading. Running the code on Python built with --with-thread-sanitizer doesn't show any warning.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions