Skip to content

fix(tui): add signal handlers to prevent orphaned processes on terminal close#13848

Open
Arasple wants to merge 1 commit intoanomalyco:devfrom
Arasple:fix/orphan-process-signal-handlers
Open

fix(tui): add signal handlers to prevent orphaned processes on terminal close#13848
Arasple wants to merge 1 commit intoanomalyco:devfrom
Arasple:fix/orphan-process-signal-handlers

Conversation

@Arasple
Copy link
Contributor

@Arasple Arasple commented Feb 16, 2026

What does this PR do?

Fixes #12767, relates to #11527, #10563

When a terminal tab is closed, @opentui/core's exitHandler catches SIGTERM/SIGINT/SIGQUIT/SIGABRT but only calls destroy() without calling process.exit() or re-raising the signal -- silently swallowing them. SIGHUP has no handler at all. The Worker thread keeps the event loop alive, so the bun binary survives as an orphan (PPID=1) with revoked file descriptors, leaking memory indefinitely.

On my machine this accumulated 152 orphaned processes over 10 days.

b1affa4d177d89e62b7fbfcccc0248ca 52c4ac4bf5515ac18ef0b3781a2a5c65

The fix adds signal handlers in thread.ts that gracefully shut down the worker (disposes instances, stops servers) before calling process.exit() with the correct exit code (128 + signum). A 5s timeout ensures exit even if shutdown hangs. A reentrancy guard prevents double-shutdown from multiple signals.

How did you verify your code works?

  • tsc --noEmit passes (0 errors in opencode package)
  • Verified SIGHUP/SIGTERM kill orphaned processes: kill -HUP <pid> and kill -TERM <pid> both cause clean exit
  • Confirmed normal Ctrl+C / Ctrl+D exit path is unaffected (raw mode means SIGINT is not generated by the terminal driver; the app handles ^C as a keypress)

…al close

When a terminal tab/window is closed, the OS sends SIGHUP to the process
group. @opentui/core registers handlers for SIGTERM/SIGINT/SIGQUIT/SIGABRT
that call destroy() but never call process.exit() or re-raise the signal,
silently swallowing them. SIGHUP has no handler at all. Combined with the
Worker thread keeping the event loop alive, the bun binary survives as an
orphan (PPID=1) with revoked file descriptors, leaking memory indefinitely.

On a real machine this accumulated 150+ orphaned processes consuming ~13GB
of RAM over 10 days.

The fix registers signal handlers in thread.ts that gracefully shut down
the worker (disposing instances, stopping servers) before calling
process.exit() with the correct signal-based exit code (128 + signum).
A 5-second timeout ensures exit even if shutdown hangs.

Fixes anomalyco#12767, relates to anomalyco#11527, anomalyco#10563
@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential Duplicate PRs Found

Based on the search results, here are related PRs addressing similar issues:

  1. PR fix(cli): handle SIGHUP to prevent orphaned processes on terminal close #12718 - fix(cli): handle SIGHUP to prevent orphaned processes on terminal close

    • Directly related: handles SIGHUP signal to prevent orphaned processes when terminal closes, similar scope to this PR
  2. PR fix: resolve memory leaks and zombie processes from missing cleanup handlers #13186 - fix: resolve memory leaks and zombie processes from missing cleanup handlers

    • Related: addresses zombie processes and cleanup handlers, may overlap with the signal handling improvements
  3. PR fix: prevent orphaned worker process when killed #11603 - fix: prevent orphaned worker process when killed

    • Related: specifically addresses orphaned worker processes, which is the core issue this PR fixes
  4. PR fix: force kill MCP server processes on dispose to prevent orphan processes #7424 - fix: force kill MCP server processes on dispose to prevent orphan processes

    • Related: addresses orphaned process cleanup via dispose functions

These PRs appear to be addressing the same root problem (orphaned processes) but in different contexts. PR #12718 seems most directly related as it handles SIGHUP signals similarly. You may want to verify whether these are complementary fixes or if any have already been merged/superseded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Opencode process survives terminal close — missing SIGHUP handler causes orphaned process accumulation

1 participant