Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

_io.TextIOWrapper.write: write during flush causespending_bytes length mismatch #119506

Closed
Labels
type-crashA hard crash of the interpreter, possibly with a core dump
@chgnrdv

Description

@chgnrdv

Crash report

What happened?

Bisected to#24592.
Simple repro:

import_ioclassMyIO(_io.BytesIO):def__init__(self):_io.BytesIO.__init__(self)self.writes= []defwrite(self,b):self.writes.append(b)tw.write("c")returnlen(b)buf=MyIO()tw=_io.TextIOWrapper(buf)CHUNK_SIZE=8192tw.write("a"* (CHUNK_SIZE-1))tw.write("b"*2)tw.flush()assertb''.join(tw.buffer.writes)==b"a"* (CHUNK_SIZE-1)+b"b"*2+b"c"

On debug build it causes C assertion failure:

python: ./Modules/_io/textio.c:1582: _textiowrapper_writeflush: Assertion `PyUnicode_GET_LENGTH(pending) == self->pending_bytes_count' failed.Program received signal SIGABRT, Aborted.__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:5050../sysdeps/unix/sysv/linux/raise.c: No such file or directory.(gdb) bt#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50#1  0x00007ffff7c84537 in __GI_abort () at abort.c:79#2  0x00007ffff7c8440f in __assert_fail_base (fmt=0x7ffff7dfb688 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",     assertion=0x555555a24d40 "PyUnicode_GET_LENGTH(pending) == self->pending_bytes_count", file=0x555555a25332 "./Modules/_io/textio.c", line=1582,     function=<optimized out>) at assert.c:92#3  0x00007ffff7c93662 in __GI___assert_fail (assertion=assertion@entry=0x555555a24d40 "PyUnicode_GET_LENGTH(pending) == self->pending_bytes_count",     file=file@entry=0x555555a25332 "./Modules/_io/textio.c", line=line@entry=1582,     function=function@entry=0x555555a256b0 <__PRETTY_FUNCTION__.9> "_textiowrapper_writeflush") at assert.c:101#4  0x00005555559102b9 in _textiowrapper_writeflush (self=self@entry=0x7ffff77896d0) at ./Modules/_io/textio.c:1582#5  0x000055555591065d in _io_TextIOWrapper_flush_impl (self=0x7ffff77896d0) at ./Modules/_io/textio.c:3092#6  0x0000555555910791 in _io_TextIOWrapper_flush (self=<optimized out>, _unused_ignored=<optimized out>) at ./Modules/_io/clinic/textio.c.h:1105#7  0x0000555555693483 in method_vectorcall_NOARGS (func=0x7ffff7731250, args=0x7ffff7fc1070, nargsf=<optimized out>, kwnames=<optimized out>)    at Objects/descrobject.c:447#8  0x0000555555680d7c in _PyObject_VectorcallTstate (tstate=0x555555be4678 <_PyRuntime+294136>, callable=0x7ffff7731250, args=0x7ffff7fc1070,     nargsf=9223372036854775809, kwnames=0x0) at ./Include/internal/pycore_call.h:168#9  0x0000555555680e97 in PyObject_Vectorcall (callable=callable@entry=0x7ffff7731250, args=args@entry=0x7ffff7fc1070, nargsf=<optimized out>,     kwnames=kwnames@entry=0x0) at Objects/call.c:327#10 0x000055555580876d in _PyEval_EvalFrameDefault (tstate=tstate@entry=0x555555be4678 <_PyRuntime+294136>, frame=0x7ffff7fc1020, throwflag=throwflag@entry=0)    at Python/generated_cases.c.h:813...

If_io.TextIOWrapper.write() tries to store more thanself->chunk_size data inself->pending_bytes, it calls_textiowrapper_writeflush():

elseif (self->pending_bytes_count+bytes_len>self->chunk_size) {
// Prevent to concatenate more than chunk_size data.
if (_textiowrapper_writeflush(self)<0) {
Py_DECREF(b);
returnNULL;
}
self->pending_bytes=b;
}

_textiowrapper_writeflush() flushesself->pending_bytes contents to wrapped buffer throughwrite() method call:
self->pending_bytes_count=0;
self->pending_bytes=NULL;
Py_DECREF(pending);
PyObject*ret;
do {
ret=PyObject_CallMethodOneArg(self->buffer,&_Py_ID(write),b);
}while (ret==NULL&&_PyIO_trap_eintr());

The problem is that call towrite() method can cause_io.TextIOWrapper.write() call (directly, as in repro, or from other thread), which re-setsself->pending_bytes andself->pending_bytes_count values.

CPython versions tested on:

3.10, 3.11, 3.12, CPython main branch

Operating systems tested on:

Linux

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

Python 3.14.0a0 (heads/main:e94dbe4ed8, May 24 2024, 00:47:49) [GCC 10.2.1 20210110]

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-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


      [8]ページ先頭

      ©2009-2025 Movatter.jp