Skip to content

Fix QEMU hanging when boot.sh --test output is piped#378

Merged
jserv merged 1 commit into
sysprog21:masterfrom
linesight:fix/qemu-stdin-sigttou
May 19, 2026
Merged

Fix QEMU hanging when boot.sh --test output is piped#378
jserv merged 1 commit into
sysprog21:masterfrom
linesight:fix/qemu-stdin-sigttou

Conversation

@linesight

@linesight linesight commented May 18, 2026

Copy link
Copy Markdown
Contributor

When I ran devtools/test-modules.sh from my terminal, it printed "Booting QEMU for testing" and then produced no further output. In ps aux, QEMU was stuck in state Tl (stopped).

Root cause: -nographic makes QEMU call tcsetattr() to put the terminal in raw mode for serial input. That's fine when QEMU runs in the foreground, but test-modules.sh pipes stdout through tee, and timeout(1) moves the child into its own process group (so it can kill the whole group on timeout). Since that group isn't the terminal's foreground group, tcsetattr() receives SIGTTOU and the kernel stops QEMU before it prints anything.

The fix: redirect stdin from /dev/null in boot.sh --test mode. The guest never needs keyboard input during automated testing, so this is always safe, and it prevents QEMU from ever touching a real terminal.

CI never hit this because GitHub Actions runners don't have a TTY — tcsetattr() fails silently with ENOTTY inside a container.

Tested both test-modules.sh (33 passed, 0 failed) and interactive boot.sh to confirm the fix doesn't break anything.


Summary by cubic

Prevents QEMU from hanging in test mode when output is piped by redirecting stdin from /dev/null. This avoids SIGTTOU from tcsetattr() under -nographic so tests print output and complete.

  • Bug Fixes
    • In boot.sh --test, exec QEMU with < /dev/null to avoid touching the real TTY.
    • Works with tee and timeout(1); devtools/test-modules.sh passes, and interactive boot.sh is unchanged.

Written for commit 37cf3aa. Summary will update on new commits. Review in cubic

boot.sh --test now redirects stdin from /dev/null before exec'ing QEMU,
so QEMU's -nographic serial setup never calls tcsetattr() on a real
terminal.  When the caller pipes stdout (e.g., through tee) or wraps
boot.sh with timeout(1), QEMU runs in a process group that is not the
terminal's foreground group; a tcsetattr() call then receives SIGTTOU
and stops the process (state Tl), producing no output.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

@jserv jserv merged commit ddca0e0 into sysprog21:master May 19, 2026
8 checks passed
@jserv

jserv commented May 19, 2026

Copy link
Copy Markdown
Contributor

Thank @linesight for contributing!

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