Why's UnicodeDecodeError hidden until after adding time.sleep(1)?
<p><strong>EDITED2:</strong></p>

<p>In the <strong>EDITED</strong> code below, <code>f_out.write(bytearray(out or ""))</code> should be replaced (both times) with:<br>
<code>f_out.write(bytearray((out or ""), 'utf8'))</code>  # BEFORE removing  <code>universal_newlines=True</code><br>
OR<br>
<code>f_out.write(out or "")</code># AFTER removing  <code>universal_newlines=True</code></p>

<hr>

<p><strong>msw, tdelaney, and j-f-sebastian - Thank you so much for all your help!</strong></p>

<p><strong>EDITED - As a result, here's the edited version of my script which NOW CONSISTENTLY TRIGGERS UnicodeDecodeError:</strong></p>

<pre><code>#!python3  # Run this script with Python 3.x (in Windows, assuming pylauncher is installed).
import subprocess
import sys

sys.stderr = sys.stdout = open('std.outerr', 'w')
# Redirected stdout/stderr so that they can be seen even when script is not run from command line.
child = subprocess.Popen([r"Evince\bin\Evince.exe", "fuzzed.pdf"], bufsize=0,
                         stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT, universal_newlines=True)
# `universal_newlines=True` TEMPORARILY left in to show that UnicodeDecodeError is triggered.
# `universal_newlines=True` WILL be removed from FINAL script.
try:
    (out, _) = child.communicate(timeout=5)
# 1 second wasn't long enough for UnicodeDecodeError to consistently be triggered.
# Since subprocess's stderr was redirected to its stdout, 2nd element of tuple will be `None`.
except subprocess.TimeoutExpired:
    child.kill()
    (out, _) = child.communicate()  # Try a 2nd time, without timeout.
    with open('subprocess.out', 'wb') as f_out:
        f_out.write(bytearray(out or ""))  # Treat `None` as an empty string).
else:
    print("\nERROR: A crash occurred before the timeout expired!\n")
    with open('subprocess.out', 'wb') as f_out:
        f_out.write(bytearray(out or ""))
</code></pre>

<p><strong>EDITED - And now (with the script above, minus the <code>universal_newlines=True</code>), the 1.2MB, 18,978 line stderr which Evince generated is correctly captured:</strong></p>

<blockquote>
  <p>Error: PDF file is damaged - attempting to reconstruct xref table...
  Error: Kid object (page 1) is not an indirect reference (integer)</p>
  
  <p>....................................................................<br>
  (Evince.exe:6800): GLib-GObject-CRITICAL **: g_object_unref:
  assertion `G_IS_OBJECT (object)' failed</p>
</blockquote>

<p>For some <a href="https://stackoverflow.com/questions/tagged/fuzzing">fuzzing</a> I'm doing, the <code>subprocess.Popen()</code> call below:</p>

<pre><code>import subprocess
proc = subprocess.Popen([r"Evince\bin\Evince.exe", "fuzzed.pdf"],
                         stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                         universal_newlines=True)
try:
    proc.communicate(timeout=1)  # Works the same with timeout=60 seconds.
except subprocess.TimeoutExpired:  # This exception is new to Python 3.3.
    proc.kill()
    # Other code here.
else:
    print("\nERROR: A crash occurred before the timeout expired!\n")
</code></pre>

<p>gave me a <code>UnicodeDecodeError</code>:</p>

<pre><code>Exception in thread Thread-1: Traceback (most recent call last):  
File "p:\python35-64\lib\threading.py", line 914, in _bootstrap_inner self.run()   
File "p:\python35-64\lib\threading.py", line 862, in run self._target(*self._args, **self._kwargs)   
File "p:\python35-64\lib\subprocess.py", line 1279, in _readerthread buffer.append(fh.read())
File "p:\python35-64\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 291289:  character maps to [undefined]
</code></pre>

<p>That occurred even when I simplified the "Other code" to something as simple as <code>time.sleep(1)</code>. Yet when I removed the "Other code", no exception occured.</p>

<p>I realize now that the exception occurred because of my unnecessarily specifying <code>universal_newlines=True</code> on the <code>Popen()</code> call. [That's <strong>not</strong> compatible with a byte being written to <code>stderr</code> with a value greater than 127 (which was occcuring).]</p>

<p>However, because the exception only occurs when there's some "Other code" after my <code>proc.kill()</code>, it would seem that something else still is likely not quite right with my code. So, I <strong>temporarily</strong> left <code>universal_newlines=True</code> in my code, and omitted my "Other code", in order to be better able to determine what that is. </p>

<p>I tried changing <code>buf_size</code> and tried <code>flush()</code>ing both <code>stdout</code> and <code>stderr, but none of that seems to make any difference.</code> </p>

<p>I saw in the <a href="https://docs.python.org/3.6/library/subprocess.html?highlight=subprocess" rel="nofollow noreferrer">Python docs</a> that:</p>

<blockquote>
  <p>Popen objects are supported as context managers via the with statement: on exit, 
  standard file descriptors are closed, and the process is waited for.</p>
</blockquote>

<p>so I tried replacing my <code>Popen()</code> call with:</p>

<pre><code>with subprocess.Popen(..., universal_newlines=True) as proc:
</code></pre>

<p>and that generated the <code>UnicodeDecodeError</code>, even with no "Other code" present. So, that's 1 way to "fix" my code, but (because of some additional things I need to do), I'd ideally like to use the 3rd-party  <code>PyPI</code><a href="https://pypi.python.org/pypi/psutil/" rel="nofollow noreferrer">psutil</a> module. And, regrettably doesn't currently support context managers. So, if possible, I'd like to code this without <code>with ... as</code>.</p>

<p><strong>What else (other than the value of <code>universal_newlines</code>) could I change in my code, to "fix" it?</strong></p>

<p>Based on what the docs said about  "'Popen' objects are supported as context managers", I tried adding:</p>

<pre><code>if proc.stdout:
    proc.stdout.close()
if proc.stderr:
    proc.stderr.close()
if proc.stdin:
    proc.stdin.close()
</code></pre>

<p>and/or <code>proc.wait()</code> just before my <code>proc.kill()</code>, but then the <code>proc.kill</code> was never reached.</p>

<p>What's <code>with ... as</code>doing that I should be doing?</p>

<p>Thanks in advance.</p>