Skip to content

fix: stdout/stderr interleaving in build output (issue #2511) - #2630

Open
wolfv wants to merge 3 commits into
mainfrom
claude/rattler-build-2511-owmedn
Open

fix: stdout/stderr interleaving in build output (issue #2511)#2630
wolfv wants to merge 3 commits into
mainfrom
claude/rattler-build-2511-owmedn

Conversation

@wolfv

@wolfv wolfv commented Jul 3, 2026

Copy link
Copy Markdown
Member

Summary

This PR fixes a critical issue where stdout and stderr from build processes were appearing in random order in the output logs. The problem was caused by reading stdout and stderr as separate streams and racing them with tokio::select!, which couldn't recover the true ordering due to independent buffering.

Key Changes

  • Merged stdout and stderr into a single OS pipe: Both streams now write to the same pipe, preserving the kernel's ordering of writes
  • Simplified output handling: Removed the dual-stream reading logic with tokio::select! in favor of reading from a single merged pipe
  • Cross-platform pipe handling: Added platform-specific code to convert OS pipe handles to std::fs::File for both Unix and Windows
  • Updated output structure: Changed from separate stdout_log and stderr_log to a single output_log, with stderr now empty (all output merged into stdout)
  • Added regression test: Implemented test_stdout_stderr_interleaved_in_write_order() that runs 20 iterations to verify consistent ordering

Implementation Details

  • Uses the os_pipe crate to create OS-level pipes that preserve write ordering
  • Drops the parent's write end of the pipe before reading to ensure EOF is properly detected
  • Wraps the pipe's read end as a tokio::fs::File to perform async reads on the blocking thread pool
  • The merged pipe approach is equivalent to the documented exec 2>&1 workaround but applied uniformly regardless of the shell interpreter
  • All output filtering and log file writing logic remains unchanged, just operating on the merged stream

https://claude.ai/code/session_01TTZZd4NWFdMcEnGyWwyefx

Build script output could appear in a random order because stdout and
stderr were read from two separate pipes and merged with `tokio::select!`,
which picks whichever stream has a line ready. The relative ordering of the
two independently buffered streams cannot be recovered that way.

Point both the child's stdout and stderr at a single OS pipe so the kernel
interleaves them in the exact order they were written, then read that one
stream. This is the same effect as the documented `exec 2>&1` workaround,
applied uniformly regardless of the interpreter running inside the wrapper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTZZd4NWFdMcEnGyWwyefx
@wolfv wolfv changed the title Fix stdout/stderr interleaving in build output (issue #2511) fix: stdout/stderr interleaving in build output (issue #2511) Jul 6, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…2511-owmedn

# Conflicts:
#	Cargo.lock
#	py-rattler-build/rust/Cargo.lock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants