Created
July 2, 2014 21:58
-
-
Save xavfernandez/1ea7dc03d5dc793cd082 to your computer and use it in GitHub Desktop.
Python 3.3 hanging analysis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/usr/lib/python3.3/subprocess.py, inside def _communicate_with_poll: | |
while self._fd2file: | |
timeout = self._remaining_time(endtime) | |
if timeout is not None and timeout < 0: | |
raise TimeoutExpired(self.args, orig_timeout) | |
try: | |
ready = poller.poll(timeout) | |
except select.error as e: | |
if e.args[0] == errno.EINTR: | |
continue | |
raise | |
self._check_timeout(endtime, orig_timeout) | |
# XXX Rewrite these to use non-blocking I/O on the | |
# file objects; they are no longer using C stdio! | |
for fd, mode in ready: | |
if mode & select.POLLOUT: | |
chunk = input_view[self._input_offset : | |
self._input_offset + _PIPE_BUF] | |
try: | |
self._input_offset += os.write(fd, chunk) | |
except OSError as e: | |
if e.errno == errno.EPIPE: | |
close_unregister_and_remove(fd) | |
else: | |
raise | |
else: | |
if self._input_offset >= len(self._input): | |
close_unregister_and_remove(fd) | |
elif mode & select_POLLIN_POLLPRI: | |
data = os.read(fd, 32768) | |
if not data: | |
close_unregister_and_remove(fd) | |
self._fd2output[fd].append(data) | |
else: | |
# Ignore hang up or errors. | |
close_unregister_and_remove(fd) | |
return (stdout, stderr) | |
################################################### | |
Entry for both scenario: | |
self.stdout.fileno() => 6 | |
self.stderr.fileno() => 8 | |
self._fd2file => {8: <_io.BufferedReader name=8>, 6: <_io.BufferedReader name=6>} | |
Normal scenario: | |
ready = poller.poll(timeout) => [(8, 16), (6, 17)] | |
close_unregister_and_remove(fd) with fd = 8 | |
select_POLLIN_POLLPRI for fd = 6 | |
data = b'Downloading/unpacking INITools\n ...' | |
self._fd2file => {6: <_io.BufferedReader name=6>} | |
ready = poller.poll(timeout) => [(6, 16)] | |
close_unregister_and_remove(fd) with fd = 6 | |
=> DONE and test pass | |
Stuck scenario: | |
self.stdout.fileno() => 6 | |
self.stderr.fileno() => 8 | |
self._fd2file => {8: <_io.BufferedReader name=8>, 6: <_io.BufferedReader name=6>} | |
ready = poller.poll(timeout) => [(6, 1)] | |
select_POLLIN_POLLPRI for fd = 6 | |
data => b'Downloading/unpacking INITools\n ...' | |
self._fd2file => {8: <_io.BufferedReader name=8>, 6: <_io.BufferedReader name=6>} | |
ready = poller.poll(timeout) => STUCK FOREVER |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment