Skip to content

Simple racing class attribute read-write crashes on free-threaded builds #118362

Description

@Fidget-Spinner

Crash report

What happened?

The following segfaults:

frommultiprocessing.dummyimportPoolNTHREADS=6classA:
attr=1BOTTOM=0TOP=1000ITERS=100defread(id0):
for_inrange(ITERS):
for_inrange(BOTTOM, TOP):
A.attr# print(A.attr)defwrite(id0):
for_inrange(ITERS):
for_inrange(BOTTOM, TOP):
# Make _PyType_Lookup cache hot firstA.attrA.attrx=A.attrx+=1A.attr=x# print(f"WRITTEN {x}\n")defmain(): withPool(NTHREADS) aspool: pool.apply_async(read, (1,))
pool.apply_async(write, (1,))
pool.close()
pool.join()
main()
print("done")

The first issue is that we have assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); in typeobject.c, which may not be true as another thread can modify the attribute in the meantime. We should remove that assertion.

The next issue, which I have not yet been able to solve, is that the attribute evaporates midway in _Py_type_getattro_impl. This is likely caused by a decref of another thread. So far I've tried changing _PyType_Lookup and find_name_in_mro to return strong references, but they don't seem to solve it for some reason.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Output from running 'python -VV' on the command line:

No response

Linked PRs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions