python / python/cpython

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

Đang mở
#154,348 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

interpreter-core topic-free-threading type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với các entry point sys.monitoring.use_tool_id() và free_tool_id() được tham chiếu quanh các dòng 2190 và 2194, sau đó chạy reproducer được cung cấp trên bản build TSAN no-GIL. Được xem là hoàn tất khi bài kiểm tra claim/free đồng thời lặp lại không còn báo cáo data race, đồng thời vẫn giữ nguyên hành vi tool-id như mong đợi; PR được liên kết gh-154459 cho biết công việc đã được tiến hành.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
backend
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.