Skip to content

Free threading: Data race on tool_id in sys.monitoring #154348

Description

@weixlu

Bug report

Bug description:

Thanks devdanzin for his fusil, this issue was reported by #153852 TSAN-0030. It;s a data race about interp->monitoring_tool_names[tool_id]

how to reproduce

run the following on a no-gil tsan build

importsys, threadingassertnotsys._is_gil_enabled(), "run free-threaded: PYTHON_GIL=0"# sys.monitoring.use_tool_id(tool_id, name) does an unsynchronized check-then-act on the# interpreter-global registry interp->monitoring_tool_names[tool_id]:# if (interp->monitoring_tool_names[tool_id] != NULL) { raise; } # :2190 read# interp->monitoring_tool_names[tool_id] = Py_NewRef(name); # :2194 write# Many threads racing to claim the SAME free tool id read the slot while one writes it.mon=sys.monitoringTOOL_ID=3# any 0..5; not reservedNT=8ROUNDS=6000enter=threading.Barrier(NT+1)
leave=threading.Barrier(NT+1)
defworker():
for_inrange(ROUNDS):
enter.wait() # all workers released together onto a freshly-freed slottry:
mon.use_tool_id(TOOL_ID, "t") # read :2190 races the winner's write :2194exceptValueError:
pass# "tool 3 is already in use" -> lost the race, expectedleave.wait()
ts= [threading.Thread(target=worker, name=f"w{i}") foriinrange(NT)]
fortints:
t.start()
forrinrange(ROUNDS):
mon.free_tool_id(TOOL_ID) # NULL the slot so the next round starts from a free identer.wait()
leave.wait()
fortints:
t.join()
print("done, no crash")

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions