python / python/cpython

Free threading: Data race on `tool_id` in `sys.monitoring`

オープン
#154,348 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

interpreter-core topic-free-threading type-bug
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

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

import sys, threading
assert not sys._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.monitoring
TOOL_ID = 3                 # any 0..5; not reserved
NT = 8
ROUNDS = 6000

enter = threading.Barrier(NT + 1)
leave = threading.Barrier(NT + 1)

def worker():
    for _ in range(ROUNDS):
        enter.wait()            # all workers released together onto a freshly-freed slot
        try:
            mon.use_tool_id(TOOL_ID, "t")   # read :2190 races the winner's write :2194
        except ValueError:
            pass                # "tool 3 is already in use" -> lost the race, expected
        leave.wait()

ts = [threading.Thread(target=worker, name=f"w{i}") for i in range(NT)]
for t in ts:
    t.start()
for r in range(ROUNDS):
    mon.free_tool_id(TOOL_ID)   # NULL the slot so the next round starts from a free id
    enter.wait()
    leave.wait()
for t in ts:
    t.join()
print("done, no crash")
CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs
  • gh-154459

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、2190行目と2194行目付近で参照されているエントリポイント sys.monitoring.use_tool_id() と free_tool_id() から始め、次に提供された reproducer を no-GIL TSAN ビルドで実行してください。繰り返し実行する並行 claim/free テストで data race が報告されなくなり、期待される tool-id の動作が維持されていれば完了です。リンクされた PR gh-154459 は、すでに作業が進行中であることを示しています。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。