Skip to content

Commit ede576f

Browse files
yihong0618dura0ok
andcommitted
fix: strace ./python will forever loop
Signed-off-by: yihong0618 <zouzou0208@gmail.com> Co-authored-by: dura0ok <slpmcf@gmail.com>
1 parent be24ff0 commit ede576f

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

Lib/_pyrepl/unix_console.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,17 @@ def prepare(self):
336336
raw.lflag |= termios.ISIG
337337
raw.cc[termios.VMIN] = 1
338338
raw.cc[termios.VTIME] = 0
339-
tcsetattr(self.input_fd, termios.TCSADRAIN, raw)
339+
try:
340+
tcsetattr(self.input_fd, termios.TCSADRAIN, raw)
341+
except termios.error as e:
342+
if e.args[0] == errno.EIO:
343+
# gh-135329
344+
# When running under external programs (like strace),
345+
# tcsetattr may fail with EIO. We can safely ignore this
346+
# and continue with default terminal settings.
347+
pass
348+
else:
349+
raise
340350

341351
# In macOS terminal we need to deactivate line wrap via ANSI escape code
342352
if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
@@ -368,7 +378,17 @@ def restore(self):
368378
self.__disable_bracketed_paste()
369379
self.__maybe_write_code(self._rmkx)
370380
self.flushoutput()
371-
tcsetattr(self.input_fd, termios.TCSADRAIN, self.__svtermstate)
381+
try:
382+
tcsetattr(self.input_fd, termios.TCSADRAIN, self.__svtermstate)
383+
except termios.error as e:
384+
if e.args[0] == errno.EIO:
385+
# gh-135329
386+
# When running under external programs (like strace),
387+
# tcsetattr may fail with EIO. We can safely ignore this
388+
# as the terminal state will be restored by the external program.
389+
pass
390+
else:
391+
raise
372392

373393
if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
374394
os.write(self.output_fd, b"\033[?7h")
@@ -407,6 +427,13 @@ def get_event(self, block: bool = True) -> Event | None:
407427
return self.event_queue.get()
408428
else:
409429
continue
430+
elif err.errno == errno.EIO:
431+
# gh-135329
432+
# When running under external programs (like strace),
433+
# os.read may fail with EIO. In this case, we should
434+
# exit gracefully to avoid infinite error loops.
435+
import sys
436+
sys.exit(errno.EIO)
410437
else:
411438
raise
412439
else:

0 commit comments

Comments
 (0)