summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Blecker <matthewb@chromium.org>2018-10-16 12:51:11 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-18 10:55:36 -0700
commit58d06c4e513e035f15710e7f176fa8e39bcda5e6 (patch)
tree54fc9af59769074a9d84ae03ccb92dfacd482b04
parent530a68d904c74a1e509e3b952fa094fab9551dc1 (diff)
downloadchrome-ec-58d06c4e513e035f15710e7f176fa8e39bcda5e6.tar.gz
ec3po console and interpreter: Handle EOFError from the pipes.
EOF is expected sometimes upon shutdown, when one thread (console or interpreter) manages to close its write side of a pipe before the other thread receives the shutdown pipe unblocked notification. EOF is now considered another indication to shutdown. BRANCH=none BUG=b:79684405 TEST=With this change plus CL:1279145 to switch to threading, I am no longer able to reproduce the formerly occasional EOFError tracebacks upon shutdown, with either ctrl+c or SIGTERM. Basic servod functionality continues to work, including dut-control ec_uart_pty, servo_console_pty (both tested with minicom), dut_i2c_mux, enable_ite_dfu, get_ite_chipid. Testing performed with a servo_micro connected to an octopus_ite. I tested both without and with CL:1279145 i.e. both with subprocesses and with threads (though I only ever encountered EOFError with the latter). Change-Id: Iaa1ddc5f05a32ef806fa5f84d0ed0ad4739189ce Signed-off-by: Matthew Blecker <matthewb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1284509 Reviewed-by: Nick Sanders <nsanders@chromium.org> Reviewed-by: Ruben Rodriguez Buchillon <coconutruben@chromium.org>
-rwxr-xr-xutil/ec3po/console.py83
-rw-r--r--util/ec3po/interpreter.py16
2 files changed, 70 insertions, 29 deletions
diff --git a/util/ec3po/console.py b/util/ec3po/console.py
index 61d2315e7c..66ed9ea53b 100755
--- a/util/ec3po/console.py
+++ b/util/ec3po/console.py
@@ -443,6 +443,9 @@ class Console(object):
Returns:
is_enhanced: A boolean indicating whether the EC responded to the
interrogation correctly.
+
+ Raises:
+ EOFError: Allowed to propagate through from self.dbg_pipe.recv().
"""
# Send interrogation byte and wait for the response.
self.logger.debug('Performing interrogation.')
@@ -476,6 +479,10 @@ class Console(object):
Args:
byte: An integer representing the character received from the user.
+
+ Raises:
+ EOFError: Allowed to propagate through from self.CheckForEnhancedECImage()
+ i.e. from self.dbg_pipe.recv().
"""
fd = self.master_pty
@@ -876,8 +883,15 @@ def StartLoop(console, command_active, shutdown_pipe=None):
console.logger.debug('Input from user: %s, locked:%s',
str(line).strip(), command_active.value)
for i in line:
- # Handle each character as it arrives.
- console.HandleChar(i)
+ try:
+ # Handle each character as it arrives.
+ console.HandleChar(i)
+ except EOFError:
+ console.logger.debug(
+ 'ec3po console received EOF from dbg_pipe in HandleChar()'
+ ' while reading console.master_pty')
+ continue_looping = False
+ break
except OSError:
console.logger.debug('Ptm read failed, probably user disconnect.')
@@ -889,34 +903,51 @@ def StartLoop(console, command_active, shutdown_pipe=None):
console.logger.debug('Input from interface: %s, locked:%s',
str(line).strip(), command_active.value)
for i in line:
- # Handle each character as it arrives.
- console.HandleChar(i)
+ try:
+ # Handle each character as it arrives.
+ console.HandleChar(i)
+ except EOFError:
+ console.logger.debug(
+ 'ec3po console received EOF from dbg_pipe in HandleChar()'
+ ' while reading console.interface_pty')
+ continue_looping = False
+ break
elif obj is console.cmd_pipe:
- data = console.cmd_pipe.recv()
- # Write it to the user console.
- console.logger.debug('|CMD|-%s->\'%s\'',
- ('u' if master_connected else '') +
- ('i' if command_active.value else ''), data.strip())
- if master_connected:
- os.write(console.master_pty, data)
- if command_active.value:
- os.write(console.interface_pty, data)
-
- elif obj is console.dbg_pipe:
- data = console.dbg_pipe.recv()
- if console.interrogation_mode == 'auto':
- # Search look buffer for enhanced EC image string.
- console.CheckBufferForEnhancedImage(data)
- # Write it to the user console.
- if len(data) > 1:
- console.logger.debug('|DBG|-%s->\'%s\'',
+ try:
+ data = console.cmd_pipe.recv()
+ except EOFError:
+ console.logger.debug('ec3po console received EOF from cmd_pipe')
+ continue_looping = False
+ else:
+ # Write it to the user console.
+ console.logger.debug('|CMD|-%s->\'%s\'',
('u' if master_connected else '') +
('i' if command_active.value else ''), data.strip())
- if master_connected:
- os.write(console.master_pty, data)
- if command_active.value:
- os.write(console.interface_pty, data)
+ if master_connected:
+ os.write(console.master_pty, data)
+ if command_active.value:
+ os.write(console.interface_pty, data)
+
+ elif obj is console.dbg_pipe:
+ try:
+ data = console.dbg_pipe.recv()
+ except EOFError:
+ console.logger.debug('ec3po console received EOF from dbg_pipe')
+ continue_looping = False
+ else:
+ if console.interrogation_mode == 'auto':
+ # Search look buffer for enhanced EC image string.
+ console.CheckBufferForEnhancedImage(data)
+ # Write it to the user console.
+ if len(data) > 1:
+ console.logger.debug('|DBG|-%s->\'%s\'',
+ ('u' if master_connected else '') +
+ ('i' if command_active.value else ''), data.strip())
+ if master_connected:
+ os.write(console.master_pty, data)
+ if command_active.value:
+ os.write(console.interface_pty, data)
elif obj is shutdown_pipe:
console.logger.debug(
diff --git a/util/ec3po/interpreter.py b/util/ec3po/interpreter.py
index fd811716de..86272f6646 100644
--- a/util/ec3po/interpreter.py
+++ b/util/ec3po/interpreter.py
@@ -347,7 +347,11 @@ class Interpreter(object):
self.dbg_pipe.send(data)
def HandleUserData(self):
- """Handle any incoming commands from the user."""
+ """Handle any incoming commands from the user.
+
+ Raises:
+ EOFError: Allowed to propagate through from self.cmd_pipe.recv().
+ """
self.logger.log(1, 'Command data available. Begin processing.')
data = self.cmd_pipe.recv()
# Process the command.
@@ -418,11 +422,17 @@ def StartLoop(interp, shutdown_pipe=None):
# Handle any commands from the user.
elif obj is interp.cmd_pipe:
- interp.HandleUserData()
+ try:
+ interp.HandleUserData()
+ except EOFError:
+ interp.logger.debug(
+ 'ec3po interpreter received EOF from cmd_pipe in '
+ 'HandleUserData()')
+ continue_looping = False
elif obj is shutdown_pipe:
interp.logger.debug(
- 'ec3po console received shutdown pipe unblocked notification')
+ 'ec3po interpreter received shutdown pipe unblocked notification')
continue_looping = False
for obj in writeable: