mitogen: first_stage: Break the while loop in case of EOF

The current implementation can cause an infinite loop, leading to a process that
hangs and consumes 100% CPU. This occurs because the EOF condition is not
handled properly, resulting in repeated select(...) and read(...) calls.

The fix is to properly handle the EOF condition and break out of the loop when
it occurs.

-SSH command size: 822
+SSH command size: 838
 Preamble (mitogen.core + econtext) size: 18226 (17.80KiB)

-mitogen.parent        99062  96.7KiB  51235 50.0KiB 51.7%  12936 12.6KiB 13.1%
+mitogen.parent        99240  96.9KiB  51244 50.0KiB 51.6%  12956 12.7KiB 13.1%

Fixes: https://github.com/mitogen-hq/mitogen/issues/1348
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
pull/1389/head
Marc Hartmayer 2 weeks ago
parent f5195edf08
commit 8807cd53be

@ -27,6 +27,7 @@ In progress (unreleased)
* :gh:issue:`1354` docs: Document Ansible 13 (ansible-core 2.20) support
* :gh:issue:`1354` :mod:`mitogen`: Clarify error message when a module
request would be refused by allow or deny listing
* :gh:issue:`1348` :mod:`mitogen`: Fix hanging process with 100% CPU usage
v0.3.35 (2025-12-01)

@ -1436,11 +1436,16 @@ class Connection(object):
os.environ['ARGV0']=sys.executable
os.execl(sys.executable,sys.executable+'(mitogen:%s)'%sys.argv[2])
os.write(1,'MITO000\n'.encode())
# Size of the compressed core source to be read
n=int(sys.argv[3])
# Read `len(compressed preamble)` bytes sent by our Mitogen parent.
# `select()` handles non-blocking stdin (e.g. sudo + log_output).
# `C` accumulates compressed bytes.
C=''.encode()
while int(sys.argv[3])-len(C)and select.select([0],[],[]):C+=os.read(0,int(sys.argv[3])-len(C))
# data chunk
V='V'
# Stop looping if no more data is needed or EOF is detected (empty bytes).
while n-len(C) and V:select.select([0],[],[]);V=os.read(0,n-len(C));C+=V
# Raises `zlib.error` if compressed preamble is truncated or invalid
C=zlib.decompress(C)
f=os.fdopen(W,'wb',0)

Loading…
Cancel
Save