Skip to content

Crash when calling textiowrapper_iternext and writing to a text file simultaneously in ft build #134908

Description

@duaneg

Running this script under free-threading build:

importosimporttempfileimportthreadingN=2COUNT=100defwriter(file, barrier):
barrier.wait()
for_inrange(COUNT):
f.write("x")
defreader(file, stopping):
whilenotstopping.is_set():
forlineinfile:
assertline==""stopping=threading.Event()
withtempfile.NamedTemporaryFile("w+") asf:
reader=threading.Thread(target=reader, args=(f, stopping))
reader.start()
barrier=threading.Barrier(N)
writers= [threading.Thread(target=writer, args=(f, barrier))
for_inrange(N)]
fortinwriters:
t.start()
fortinwriters:
t.join()
stopping.set()
reader.join()
f.flush()
assert(os.stat(f.name).st_size==COUNT*N)

...results in a crash:

python: ./Modules/_io/textio.c:1751: _io_TextIOWrapper_write_impl: Assertion `self->pending_bytes_count == 0' failed.
Aborted (core dumped)

The textiowrapper_iternext method is not protected by a critical section and calls _textiowrapper_readline, which calls _textiowrapper_writeflush, which relies on the GIL or critical section to synchronise access to its internal data. In a free-threading build this means iterating over lines in a text file is not thread-safe and can crash if it races with writes or other operations.

It looks like all other entry points that could call _textiowrapper_writeflush are protected by the critical section, so the easiest fix is probably to just likewise protect textiowrapper_iternext.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions