Skip to content

Possible data race in _io_IncrementalNewlineDecoder_reset_impl in textio.c #144777

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

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions