Skip to content

Possible data race in _io_IncrementalNewlineDecoder_reset_impl in textio.c #144777

@Naserume

Description

@Naserume

Bug report

Bug description:

This code produces TSAN warning on no-gil build, but I'm not sure if this is a real bug since the docs mention TextIOWrapper isn't thread safe.

import codecs
from threading import Thread
from io import IncrementalNewlineDecoder

utf8_decoder = codecs.getincrementaldecoder('utf-8')()
OBJ = IncrementalNewlineDecoder(utf8_decoder, translate=True)

def test1():
    for _ in range(100):
        OBJ.reset()

def main():
    threads = []
    for _ in range(4):
        threads.append(Thread(target=test1))
    for t in threads:
        t.start()
    for t in threads:
        t.join()

if __name__ == "__main__":
    main()

TSAN report:

WARNING: ThreadSanitizer: data race (pid=481349)
  Write of size 1 at 0x7fffb496d230 by thread T4:
    #0 _io_IncrementalNewlineDecoder_reset_impl /cpython/./Modules/_io/textio.c:627:21 (python3.15t+0x5b8b15)
    #1 _io_IncrementalNewlineDecoder_reset /cpython/./Modules/_io/clinic/textio.c.h:492:12 (python3.15t+0x5b8b15)
    #2 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:3943:35 (python3.15t+0x42d408)
    #3 _PyEval_EvalFrame /cpython/./Include/internal/pycore_ceval.h:118:16 (python3.15t+0x422090)
    #4 _PyEval_Vector /cpython/Python/ceval.c:2125:12 (python3.15t+0x422090)
    #5 _PyFunction_Vectorcall /cpython/Objects/call.c (python3.15t+0x20cc0f)
    #6 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:136:11 (python3.15t+0x2112e6)
    #7 method_vectorcall /cpython/Objects/classobject.c:74:20 (python3.15t+0x2112e6)
    #8 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:136:11 (python3.15t+0x476281)
    #9 context_run /cpython/Python/context.c:727:29 (python3.15t+0x476281)
    #10 _PyCallMethodDescriptorFastWithKeywords_StackRefSteal /cpython/Python/ceval.c:913:11 (python3.15t+0x423f4c)
    #11 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:3852:35 (python3.15t+0x42d1e9)
    #12 _PyEval_EvalFrame /cpython/./Include/internal/pycore_ceval.h:118:16 (python3.15t+0x422090)
    #13 _PyEval_Vector /cpython/Python/ceval.c:2125:12 (python3.15t+0x422090)
    #14 _PyFunction_Vectorcall /cpython/Objects/call.c (python3.15t+0x20cc0f)
    #15 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:136:11 (python3.15t+0x2112e6)
    #16 method_vectorcall /cpython/Objects/classobject.c:74:20 (python3.15t+0x2112e6)
    #17 _PyVectorcall_Call /cpython/Objects/call.c:273:16 (python3.15t+0x20c89b)
    #18 _PyObject_Call /cpython/Objects/call.c:348:16 (python3.15t+0x20c89b)
    #19 PyObject_Call /cpython/Objects/call.c:373:12 (python3.15t+0x20c905)
    #20 thread_run /cpython/./Modules/_threadmodule.c:387:21 (python3.15t+0x5f5512)
    #21 pythread_wrapper /cpython/Python/thread_pthread.h:234:5 (python3.15t+0x526127)

  Previous write of size 1 at 0x7fffb496d230 by thread T3:
    #0 _io_IncrementalNewlineDecoder_reset_impl /cpython/./Modules/_io/textio.c:627:21 (python3.15t+0x5b8b15)
    #1 _io_IncrementalNewlineDecoder_reset /cpython/./Modules/_io/clinic/textio.c.h:492:12 (python3.15t+0x5b8b15)
    #2 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:3943:35 (python3.15t+0x42d408)
    #3 _PyEval_EvalFrame /cpython/./Include/internal/pycore_ceval.h:118:16 (python3.15t+0x422090)
    #4 _PyEval_Vector /cpython/Python/ceval.c:2125:12 (python3.15t+0x422090)
    #5 _PyFunction_Vectorcall /cpython/Objects/call.c (python3.15t+0x20cc0f)
    #6 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:136:11 (python3.15t+0x2112e6)
    #7 method_vectorcall /cpython/Objects/classobject.c:74:20 (python3.15t+0x2112e6)
    #8 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:136:11 (python3.15t+0x476281)
    #9 context_run /cpython/Python/context.c:727:29 (python3.15t+0x476281)
    #10 _PyCallMethodDescriptorFastWithKeywords_StackRefSteal /cpython/Python/ceval.c:913:11 (python3.15t+0x423f4c)
    #11 _PyEval_EvalFrameDefault /cpython/Python/generated_cases.c.h:3852:35 (python3.15t+0x42d1e9)
    #12 _PyEval_EvalFrame /cpython/./Include/internal/pycore_ceval.h:118:16 (python3.15t+0x422090)
    #13 _PyEval_Vector /cpython/Python/ceval.c:2125:12 (python3.15t+0x422090)
    #14 _PyFunction_Vectorcall /cpython/Objects/call.c (python3.15t+0x20cc0f)
    #15 _PyObject_VectorcallTstate /cpython/./Include/internal/pycore_call.h:136:11 (python3.15t+0x2112e6)
    #16 method_vectorcall /cpython/Objects/classobject.c:74:20 (python3.15t+0x2112e6)
    #17 _PyVectorcall_Call /cpython/Objects/call.c:273:16 (python3.15t+0x20c89b)
    #18 _PyObject_Call /cpython/Objects/call.c:348:16 (python3.15t+0x20c89b)
    #19 PyObject_Call /cpython/Objects/call.c:373:12 (python3.15t+0x20c905)
    #20 thread_run /cpython/./Modules/_threadmodule.c:387:21 (python3.15t+0x5f5512)
    #21 pythread_wrapper /cpython/Python/thread_pthread.h:234:5 (python3.15t+0x526127)

SUMMARY: ThreadSanitizer: data race /cpython/./Modules/_io/textio.c:627:21 in _io_IncrementalNewlineDecoder_reset_impl

Version: Python 3.15.0a5+ free-threading build (heads/main:d5f96c86653, Feb 11 2026, 04:50:14) [Clang 18.1.3 (1ubuntu1)]

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions