python / python/cpython

data races in decimal module with global context

未關閉
#141,148 16 則留言 2 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

docs extension-modules topic-free-threading type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

Reproducer:

import decimal
from threading import Thread, Barrier

context = decimal.Context()
context.prec = 28

barrier = Barrier(10)

def race():
    barrier.wait()
    decimal.Decimal('1.0', context=context)

if __name__ == "__main__":
    while True:
        threads = [Thread(target=race) for _ in range(10)]
        for thread in threads:
            thread.start()
        for thread in threads:
            thread.join()

Data race:

==================
WARNING: ThreadSanitizer: data race (pid=58514)
  Write of size 4 at 0x00010d315cbc by thread T5808:
    #0 dec_addstatus _decimal.c:612 (_decimal.cpython-315t-darwin.so:arm64+0x9a88)
    #1 PyDecType_FromCStringExact _decimal.c:2323 (_decimal.cpython-315t-darwin.so:arm64+0x1a4a4)
    #2 dec_new _decimal.c.h:572 (_decimal.cpython-315t-darwin.so:arm64+0x506c)
    #3 type_call typeobject.c:2432 (python.exe:arm64+0x10017e768)
    #4 _PyObject_MakeTpCall call.c:242 (python.exe:arm64+0x10007eb64)
    #5 PyObject_Vectorcall call.c:327 (python.exe:arm64+0x10007f750)
    #6 _PyEval_EvalFrameDefault generated_cases.c.h:1620 (python.exe:arm64+0x100277dec)
    #7 _PyEval_Vector ceval.c:1989 (python.exe:arm64+0x10026ad88)
    #8 _PyFunction_Vectorcall call.c (python.exe:arm64+0x10007fcec)
    #9 method_vectorcall classobject.c:65 (python.exe:arm64+0x100084190)
    #10 _PyObject_Call call.c:348 (python.exe:arm64+0x10007f8b0)
    #11 PyObject_Call call.c:373 (python.exe:arm64+0x10007f9d8)
    #12 _PyEval_EvalFrameDefault generated_cases.c.h:2616 (python.exe:arm64+0x10027bf64)
    #13 _PyEval_Vector ceval.c:1989 (python.exe:arm64+0x10026ad88)
    #14 _PyFunction_Vectorcall call.c (python.exe:arm64+0x10007fcec)
    #15 method_vectorcall classobject.c:73 (python.exe:arm64+0x10008422c)
    #16 context_run context.c:728 (python.exe:arm64+0x1002b53dc)
    #17 _PyEval_EvalFrameDefault generated_cases.c.h:3710 (python.exe:arm64+0x10027ffbc)
    #18 _PyEval_Vector ceval.c:1989 (python.exe:arm64+0x10026ad88)
    #19 _PyFunction_Vectorcall call.c (python.exe:arm64+0x10007fcec)
    #20 method_vectorcall classobject.c:73 (python.exe:arm64+0x10008422c)
    #21 _PyObject_Call call.c:348 (python.exe:arm64+0x10007f964)
    #22 PyObject_Call call.c:373 (python.exe:arm64+0x10007f9d8)
    #23 thread_run _threadmodule.c:387 (python.exe:arm64+0x10041b338)
    #24 pythread_wrapper thread_pthread.h:234 (python.exe:arm64+0x100358824)

  Previous write of size 4 at 0x00010d315cbc by thread T5806:
    #0 dec_addstatus _decimal.c:612 (_decimal.cpython-315t-darwin.so:arm64+0x9a88)
    #1 PyDecType_FromCStringExact _decimal.c:2323 (_decimal.cpython-315t-darwin.so:arm64+0x1a4a4)
    #2 dec_new _decimal.c.h:572 (_decimal.cpython-315t-darwin.so:arm64+0x506c)
    #3 type_call typeobject.c:2432 (python.exe:arm64+0x10017e768)
    #4 _PyObject_MakeTpCall call.c:242 (python.exe:arm64+0x10007eb64)
    #5 PyObject_Vectorcall call.c:327 (python.exe:arm64+0x10007f750)
    #6 _PyEval_EvalFrameDefault generated_cases.c.h:1620 (python.exe:arm64+0x100277dec)
    #7 _PyEval_Vector ceval.c:1989 (python.exe:arm64+0x10026ad88)
    #8 _PyFunction_Vectorcall call.c (python.exe:arm64+0x10007fcec)
    #9 method_vectorcall classobject.c:65 (python.exe:arm64+0x100084190)
    #10 _PyObject_Call call.c:348 (python.exe:arm64+0x10007f8b0)
    #11 PyObject_Call call.c:373 (python.exe:arm64+0x10007f9d8)
    #12 _PyEval_EvalFrameDefault generated_cases.c.h:2616 (python.exe:arm64+0x10027bf64)
    #13 _PyEval_Vector ceval.c:1989 (python.exe:arm64+0x10026ad88)
    #14 _PyFunction_Vectorcall call.c (python.exe:arm64+0x10007fcec)
    #15 method_vectorcall classobject.c:73 (python.exe:arm64+0x10008422c)
    #16 context_run context.c:728 (python.exe:arm64+0x1002b53dc)
    #17 _PyEval_EvalFrameDefault generated_cases.c.h:3710 (python.exe:arm64+0x10027ffbc)
    #18 _PyEval_Vector ceval.c:1989 (python.exe:arm64+0x10026ad88)
    #19 _PyFunction_Vectorcall call.c (python.exe:arm64+0x10007fcec)
    #20 method_vectorcall classobject.c:73 (python.exe:arm64+0x10008422c)
    #21 _PyObject_Call call.c:348 (python.exe:arm64+0x10007f964)
    #22 PyObject_Call call.c:373 (python.exe:arm64+0x10007f9d8)
    #23 thread_run _threadmodule.c:387 (python.exe:arm64+0x10041b338)
    #24 pythread_wrapper thread_pthread.h:234 (python.exe:arm64+0x100358824)
SUMMARY: ThreadSanitizer: data race _decimal.c:615 in dec_addstatus
==================

I discovered this while adding thread safety support to msgspec. Running its test suite under pytest-run-parallel leads to similar data races as present above from the minimal reproducer.

See https://gist.github.com/kumaraditya303/3c26f31eaf0beea39d7eeb539b662846 for full tsan report

Linked PRs
  • gh-146482
  • gh-151953

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 _decimal.c、_decimal.c.h 和 context.c 中回報的呼叫路徑開始,然後在 ThreadSanitizer 下執行最小重現程式。將行為與連結的 PR gh-146482 和 gh-151953 進行比較。當重現程式和可比較的平行工作負載不再回報此資料競爭,並在適當位置加入回歸涵蓋時,即表示完成。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
c, python
領域
backend
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。