Skip to content

fix(shells): decode background-shell output with errors=replace to avoid pipe deadlock - #19

Open
Yuren0312 wants to merge 1 commit into
openhackai:mainfrom
Yuren0312:fix-issue-13
Open

Yuren0312 wants to merge 1 commit into
openhackai:mainfrom
Yuren0312:fix-issue-13

Conversation

@Yuren0312

Copy link
Copy Markdown

Fixes #13.

Problem

subprocess.Popen is started with text=True but without errors=, so decoding defaults to strict. When a command emits non-UTF-8 bytes, the reader thread raises UnicodeDecodeError, its except Exception: pass swallows it, and the reader stops draining stdout. Once the child fills the 64KB OS pipe buffer, it blocks in write(), and _reader's final proc.wait() hangs forever — freezing background shells and security scanners (strings, fuzzers, compiled-binary tests) indefinitely.

Fix

Decode with errors="replace" so invalid bytes become U+FFFD instead of raising, and the reader keeps consuming the pipe until EOF:

             stderr=subprocess.STDOUT,
             text=True,
+            errors="replace",
             bufsize=1,

Verification

Added test_non_utf8_output_does_not_deadlock in tests/test_shells.py, which spawns python3 -c '... sys.stdout.buffer.write(b"\xff" * 200000)' and asserts the shell exits (no deadlock), returncode == 0, and the invalid bytes are decoded as replacement characters rather than dropped.

Reproduced the hang before the fix (shell stays running forever, child never reaped) and confirmed it exits cleanly after.

…oid pipe deadlock

A command that writes non-UTF-8 bytes to stdout makes the reader thread raise
UnicodeDecodeError (text=True defaults to strict decoding). The reader stops
draining the pipe, the child blocks in write() once the 64KB buffer fills,
and _reader's final proc.wait() hangs forever, freezing background shells and
security scanners.

Decode with errors="replace" so invalid bytes become U+FFFD and the reader
keeps consuming the pipe until EOF.

Fixes openhackai#13
@greptile-apps

greptile-apps Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

Background shells now replace invalid output bytes instead of stopping the reader and leaving the child blocked.

  • Background shells keep reading output with invalid bytes.

Reviews (1) · Last reviewed commit: "fix(shells): decode background-shell out..." · Reviewed by Greptile

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.

Subprocess Pipe Deadlock in shells.py on Non-UTF-8 Output

1 participant