Free-threading race betwen two Py_SETREF
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 22/100
Hướng nghiên cứu
The race is in the Py_SETREF and Py_XSETREF macros, which copy the old pointer, store the new one, and then decref in separate non-atomic steps. Run the reproducer with a free-threaded debug build and read the assertion at Include/refcount.h:617 to confirm the negative refcount on a tuple. Done would mean the reproducer runs clean under free-threading, which needs a design decision about atomic swap semantics first.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Bug report
This can be triggered with existing Python objects that use Py_SETREF or Py_XSETREF such as Exceptions (although slightly contrived):
import threading
e = Exception()
def worker():
for _ in range(1_000_000):
e.__init__(1)
threads = [threading.Thread(target=worker) for _ in range(2)]
for t in threads:
t.start()
for t in threads:
t.join()
Gives on a 3.16 free-threaded debug build:
../cpython/Include/refcount.h:617: _Py_NegativeRefcount: Assertion failed: object has negative ref count
Enable tracemalloc to get the memory block allocation traceback
object address : 0x2000204c3b0
object refcount : 0
object type : 0x5623737ad5c8
object type name: tuple
object repr : <refcnt 0 at 0x2000204c3b0>
Fatal Python error: _PyObject_AssertFailed: _PyObject_AssertFailed
Python runtime state: initialized
Stack (most recent call first):
File "/<home>/projects/python/setref_bug.py", line 8 in worker
File "/<home>/projects/python/cpython/Lib/threading.py", line 1161 in run
File "/<home>/projects/python/cpython/Lib/threading.py", line 1219 in _bootstrap_inner
File "/<home>/projects/python/cpython/Lib/threading.py", line 1181 in _bootstrap
[1] 397225 abort (core dumped) ./build/python setref_bug.py
This arrives because Py_SETREF copies the ref and stores a new new one as two separate non-atomic steps. So two threads can do:
T1: old = *slot
T2: old = *slot // same object as T1
T1: *slot = a
T2: *slot = b // a's reference is lost, so a leaks
T1: Py_XDECREF(old)
T2: Py_XDECREF(old) // the slot's one reference to old is dropped twice
I ran into this trying to build a cache which swapped an old value for a new value with Py_SETREF and finding it sometimes resulted in a double free when two threads swapped the value simultaneously (And ended up thinking they had the last reference).
CPython versions tested on:
3.16, CPython main branch
Operating systems tested on:
Linux
- Ngôn ngữ chính
- Python
- Star
- 78.2k
- Fork
- 36.6k
- Merge trung bình
- 19 giờ 57 phút
- Pull request đã merge (30 ngày)
- 630
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của python/cpython
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
stdlib type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
extension-modules stdlib topic-XML type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
python/cpython#161807 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
stdlib type-feature
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
python/cpython#161788 · 7 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
extension-modules topic-IO type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của python/cpython
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
cpp-best-practices/project_validator#267 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Project-N-E-K-O/N.E.K.O#3725 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] Sending a Telegram message chain twice duplicates mentionsCó thể đã có người làm @123XieC đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
AstrBotDevs/AstrBot#11125 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
backend bug priority: high
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
nooriegarg/ContribIQ#73 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug p3 security
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày