From 4dd3dfe8e3266459d855008af78d611071ff99e2 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 16 Jun 2020 11:02:00 -0700 Subject: [PATCH] [lldb/Python] Fix the infinitely looping Python prompt bug Executing commands below will get you bombarded by a wall of Python command prompts (>>> ). $ echo 'foo' | ./bin/lldb -o script $ cat /tmp/script script print("foo") $ lldb --source /tmp/script The issue is that our custom input reader doesn't handle EOF. According to the Python documentation, file.readline always includes a trailing newline character unless the file ends with an incomplete line. An empty string signals EOF. This patch raises an EOFError when that happens. [1] https://docs.python.org/2/library/stdtypes.html#file.readline Differential revision: https://reviews.llvm.org/D81898 --- lldb/source/Interpreter/embedded_interpreter.py | 7 ++++++- lldb/test/Shell/ScriptInterpreter/Python/eof.test | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 lldb/test/Shell/ScriptInterpreter/Python/eof.test diff --git a/lldb/source/Interpreter/embedded_interpreter.py b/lldb/source/Interpreter/embedded_interpreter.py index 8a1195d83c6f..9312dbfaca4e 100644 --- a/lldb/source/Interpreter/embedded_interpreter.py +++ b/lldb/source/Interpreter/embedded_interpreter.py @@ -73,7 +73,12 @@ def get_terminal_size(fd): def readfunc_stdio(prompt): sys.stdout.write(prompt) sys.stdout.flush() - return sys.stdin.readline().rstrip() + line = sys.stdin.readline() + # Readline always includes a trailing newline character unless the file + # ends with an incomplete line. An empty line indicates EOF. + if not line: + raise EOFError + return line.rstrip() def run_python_interpreter(local_dict): diff --git a/lldb/test/Shell/ScriptInterpreter/Python/eof.test b/lldb/test/Shell/ScriptInterpreter/Python/eof.test new file mode 100644 index 000000000000..d777f24591ea --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Python/eof.test @@ -0,0 +1,6 @@ +RUN: echo 'foo' | %lldb -o script | FileCheck %s + +# Check that the python interpreter detects the OF and the prompt is printed +# exactly once. +CHECK: >>> +CHECK-NOT: >>>