python / python/cpython

Data race: `sys.addaudithook()` lazily creates `interp->audit_hooks` with no lock

Open
#154,431 1 comment 0 reactions 1 assignee View on GitHub

@sobolevn is already working on this.

Since Jul 22, 2026.

extension-modules topic-free-threading type-bug
Dominant language
Python
Stars
77.2k
Forks
36k
PR merge metrics
PR metrics pending

Description

Bug report

Full report: https://gist.github.com/devdanzin/0b13838fd6089e73a3f063ed8f68e733

Repro:

import sys, threading
assert not sys._is_gil_enabled(), "run free-threaded: PYTHON_GIL=0"

NADD = 24      # threads slamming the first-time lazy-init store (write @540) at once
NAUD = 8       # threads spinning audit events (should_audit read @239)
barrier = threading.Barrier(NADD + NAUD)

def _hook(*a):
    return None

def adder():
    barrier.wait()
    for _ in range(200):
        sys.addaudithook(_hook)          # write interp->audit_hooks (first time) @540

def auditor():
    barrier.wait()
    for _ in range(200000):
        sys.audit("fusil.tsan.test")     # should_audit read of interp->audit_hooks @239

ts = [threading.Thread(target=adder) for _ in range(NADD)]
ts += [threading.Thread(target=auditor) for _ in range(NAUD)]
for t in ts: t.start()
for t in ts: t.join()
print("done, no crash")

The fix is incoming.

Linked PRs
  • gh-154462
  • gh-154477
  • gh-154478
  • gh-154494
  • gh-154554
  • gh-154769
  • gh-154774

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.