aboutsummaryrefslogtreecommitdiffstats
path: root/utils/lit
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-09-22 09:50:38 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-09-22 09:50:38 +0000
commit5a461dd513dddaec6fd30196cb8f8680659a6e0d (patch)
treecb80fde6157f1538b668ee8c93bad375c6913b9d /utils/lit
parentdf3388492bc2bfc73b3e0195693e2f67f10dcf52 (diff)
downloadexternal_llvm-5a461dd513dddaec6fd30196cb8f8680659a6e0d.zip
external_llvm-5a461dd513dddaec6fd30196cb8f8680659a6e0d.tar.gz
external_llvm-5a461dd513dddaec6fd30196cb8f8680659a6e0d.tar.bz2
lit: When executing shell scripts internally, don't allow piped stderr on any
commands except the last one, instead redirect the stderr to a temporary file. This sidesteps a potential deadlocking issue. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82538 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/lit')
-rw-r--r--utils/lit/TestRunner.py24
1 files changed, 21 insertions, 3 deletions
diff --git a/utils/lit/TestRunner.py b/utils/lit/TestRunner.py
index 2995196..7b549ac 100644
--- a/utils/lit/TestRunner.py
+++ b/utils/lit/TestRunner.py
@@ -6,6 +6,7 @@ import Test
import Util
import platform
+import tempfile
class InternalShellError(Exception):
def __init__(self, command, message):
@@ -57,7 +58,11 @@ def executeShCmd(cmd, cfg, cwd, results):
assert isinstance(cmd, ShUtil.Pipeline)
procs = []
input = subprocess.PIPE
- for j in cmd.commands:
+ stderrTempFiles = []
+ # To avoid deadlock, we use a single stderr stream for piped
+ # output. This is null until we have seen some output using
+ # stderr.
+ for i,j in enumerate(cmd.commands):
redirects = [(0,), (1,), (2,)]
for r in j.redirects:
if r[0] == ('>',2):
@@ -104,6 +109,14 @@ def executeShCmd(cmd, cfg, cwd, results):
else:
stderrIsStdout = False
+ # Don't allow stderr on a PIPE except for the last
+ # process, this could deadlock.
+ #
+ # FIXME: This is slow, but so is deadlock.
+ if stderr == subprocess.PIPE and j != cmd.commands[-1]:
+ stderr = tempfile.TemporaryFile(mode='w+b')
+ stderrTempFiles.append((i, stderr))
+
# Resolve the executable path ourselves.
args = list(j.args)
args[0] = Util.which(args[0], cfg.environment['PATH'])
@@ -130,10 +143,10 @@ def executeShCmd(cmd, cfg, cwd, results):
else:
input = subprocess.PIPE
- # FIXME: There is a potential for deadlock here, when we have a pipe and
- # some process other than the last one ends up blocked on stderr.
+ # FIXME: There is probably still deadlock potential here. Yawn.
procData = [None] * len(procs)
procData[-1] = procs[-1].communicate()
+
for i in range(len(procs) - 1):
if procs[i].stdout is not None:
out = procs[i].stdout.read()
@@ -144,6 +157,11 @@ def executeShCmd(cmd, cfg, cwd, results):
else:
err = ''
procData[i] = (out,err)
+
+ # Read stderr out of the temp files.
+ for i,f in stderrTempFiles:
+ f.seek(0, 0)
+ procData[i] = (procData[i][0], f.read())
exitCode = None
for i,(out,err) in enumerate(procData):