macos: Reset exception ports for shell-spawned processes#44193
Merged
Veykril merged 1 commit intozed-industries:mainfrom Dec 8, 2025
Merged
Conversation
The original fix in zed-industries#40716 only applied to processes spawned via `new_smol_command()`, but shell environment capture uses a different code path: `new_std_command()` → `set_pre_exec_to_start_new_session()` → convert to smol::process::Command. This caused an issue where: 1. Zed spawns a login shell to capture environment variables 2. The shell sources user config (e.g., .zshrc with oh-my-zsh plugins) 3. Plugins may spawn background processes (e.g., `poetry completions zsh &|`) 4. These processes inherit the crash handler's exception ports 5. The inherited exception ports can cause the processes to hang 6. The hanging process keeps the pipe to Zed open 7. Zed's `read_to_end()` blocks waiting for the pipe to close 8. This prevents Zed from spawning any more processes (including LSPs) Fix by also calling `reset_exception_ports()` in `set_pre_exec_to_start_new_session()`, which is used by shell environment capture, terminal spawning, and DAP transport. Fixes zed-industries#36754
a2e1637 to
b40c1b2
Compare
CherryWorm
pushed a commit
to CherryWorm/zed
that referenced
this pull request
Dec 16, 2025
…ies#44193) ## Summary Follow-up to zed-industries#40716. This applies the same `reset_exception_ports()` fix to `set_pre_exec_to_start_new_session()`, which is used by shell environment capture, terminal spawning, and DAP transport. ### Root Cause After more debugging, I finally figured out what was causing the issue on my machine. Here's what was happening: 1. Zed spawns a login shell (zsh) to capture environment variables 2. A pipe is created: reader in Zed, writer mapped to fd 0 in zsh 3. zsh sources `.zshrc` → loads oh-my-zsh → runs poetry plugin 4. Poetry plugin runs `poetry completions zsh &|` in background 5. Poetry inherits fd 0 (the pipe's write end) from zsh 6. zsh finishes `zed --printenv` and exits 7. Poetry still holds fd 0 open 8. Zed's `reader.read_to_end()` blocks waiting for all writers to close 9. Poetry hangs (likely due to inherited crash handler exception ports interfering with its normal operation) 10. Pipe stays open → Zed stuck → no more processes spawn (including LSPs) I confirmed this by killing the hanging `poetry` process, which immediately unblocked Zed and allowed LSPs to start. However, this workaround was needed every time I started Zed. While poetry was the culprit in my case, this can affect any shell configuration that spawns background processes during initialization (oh-my-zsh plugins, direnv, asdf, nvm, etc.). Fixes zed-industries#36754 ## Test plan - [x] Build with `ZED_GENERATE_MINIDUMPS=true` to force crash handler initialization - [x] Verify crash handler logs appear ("spawning crash handler process", "crash handler registered") - [x] Confirm LSPs start correctly with shell plugins that spawn background processes Release Notes: - Fixed an issue on macOS where LSPs could fail to start when shell plugins spawn background processes during environment capture.
someone13574
pushed a commit
to someone13574/zed
that referenced
this pull request
Dec 16, 2025
…ies#44193) ## Summary Follow-up to zed-industries#40716. This applies the same `reset_exception_ports()` fix to `set_pre_exec_to_start_new_session()`, which is used by shell environment capture, terminal spawning, and DAP transport. ### Root Cause After more debugging, I finally figured out what was causing the issue on my machine. Here's what was happening: 1. Zed spawns a login shell (zsh) to capture environment variables 2. A pipe is created: reader in Zed, writer mapped to fd 0 in zsh 3. zsh sources `.zshrc` → loads oh-my-zsh → runs poetry plugin 4. Poetry plugin runs `poetry completions zsh &|` in background 5. Poetry inherits fd 0 (the pipe's write end) from zsh 6. zsh finishes `zed --printenv` and exits 7. Poetry still holds fd 0 open 8. Zed's `reader.read_to_end()` blocks waiting for all writers to close 9. Poetry hangs (likely due to inherited crash handler exception ports interfering with its normal operation) 10. Pipe stays open → Zed stuck → no more processes spawn (including LSPs) I confirmed this by killing the hanging `poetry` process, which immediately unblocked Zed and allowed LSPs to start. However, this workaround was needed every time I started Zed. While poetry was the culprit in my case, this can affect any shell configuration that spawns background processes during initialization (oh-my-zsh plugins, direnv, asdf, nvm, etc.). Fixes zed-industries#36754 ## Test plan - [x] Build with `ZED_GENERATE_MINIDUMPS=true` to force crash handler initialization - [x] Verify crash handler logs appear ("spawning crash handler process", "crash handler registered") - [x] Confirm LSPs start correctly with shell plugins that spawn background processes Release Notes: - Fixed an issue on macOS where LSPs could fail to start when shell plugins spawn background processes during environment capture.
This was referenced Feb 10, 2026
smitbarmase
added a commit
that referenced
this pull request
Feb 10, 2026
Follow-up to #47420 and #44193. #47420 fixed child-exit status handling via upstream alacritty change (alacritty/alacritty#8825). However, stable/preview/nightly builds still reproduced hangs that dev builds did not. The root cause matches #44193: spawned children inherit crash-handler Mach exception ports and hang. We already reset exception ports in `util::command::new_smol_command` and `util::set_pre_exec_to_start_new_session`, but PTY child spawning in `alacritty_terminal` was not covered. This PR updates `alacritty_terminal` to include PTY `pre_exec` exception-port reset: zed-industries/alacritty@9d9640d Upstream: - alacritty/alacritty#8835 Release Notes: - Fixed terminal tasks hanging on macOS when a spawned process is killed by a signal.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #40716. This applies the same
reset_exception_ports()fix toset_pre_exec_to_start_new_session(), which is used by shell environment capture, terminal spawning, and DAP transport.Root Cause
After more debugging, I finally figured out what was causing the issue on my machine. Here's what was happening:
.zshrc→ loads oh-my-zsh → runs poetry pluginpoetry completions zsh &|in backgroundzed --printenvand exitsreader.read_to_end()blocks waiting for all writers to closeI confirmed this by killing the hanging
poetryprocess, which immediately unblocked Zed and allowed LSPs to start. However, this workaround was needed every time I started Zed.While poetry was the culprit in my case, this can affect any shell configuration that spawns background processes during initialization (oh-my-zsh plugins, direnv, asdf, nvm, etc.).
Fixes #36754
Test plan
ZED_GENERATE_MINIDUMPS=trueto force crash handler initializationRelease Notes: