Improved compatibility of stdout/stderr line buffering across platforms
@@ -37,13 +37,6 @@ import threading
import random
import time
-# If stdout/stderr are not line buffered because they're pipes, make them line
-# buffered now to ensure that prints such as stack traces always appear.
-if not sys.stdout.line_buffering:
- sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
-if not sys.stderr.line_buffering:
- sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 1)
-
import cocotb.handle
from cocotb.scheduler import Scheduler
from cocotb.log import SimLogFormatter, SimBaseLog, SimLog
@@ -76,6 +69,21 @@ if "SPHINX_BUILD" not in os.environ:
# Notify GPI of log level
simulator.log_level(_default_log)
+ # If stdout/stderr are not TTYs, Python may not have opened them with line
+ # buffering. In that case, try to reopen them with line buffering
+ # explicitly enabled. This ensures that prints such as stack traces always
+ # appear. Continue silently if this fails.
+ try:
+ if not sys.stdout.isatty():
+ sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)
+ log.debug("Reopened stdout with line buffering")
+ if not sys.stderr.isatty():
+ sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 1)
+ log.debug("Reopened stderr with line buffering")
+ except Exception as e:
+ log.warning("Failed to ensure that stdout/stderr are line buffered: %s", e)
+ log.warning("Some stack traces may not appear because of this.")
+
scheduler = Scheduler()
regression = None
