Fix git hang caused by accidental inheritance of stdin FD#57572
Merged
Conversation
Set the close-on-exec flag for the pipe file descriptors, so that they are not inherited by child processes spawned using code paths that don't set `POSIX_SPAWN_CLOEXEC_DEFAULT`.
cole-miller
approved these changes
May 23, 2026
Collaborator
Author
|
/cherry-pick preview |
maxbrunsfeld
added a commit
that referenced
this pull request
May 25, 2026
…herry-pick to stable) (#57662) Cherry-pick of #57572 to stable ---- When restarting Zed, I hit a bug where all Git operations were hung. I realized that there was a hanging git process running `git cat-file --batch-check=%(objectname)`. The process was waiting on stdin. This was surprising, because [the code](https://github.com/zed-industries/zed/blob/e2bbdb19b6da2ee157ca1d36100acde2134a1663/crates/git/src/repository.rs#L1665-L1709) that spawns this process explicitly closes the pipe that is attached to the process's stdin after writing a list of ref names. Using Claude, I found that this could be caused by that pipe file descriptor being cloned due to file descriptor inheritance when another child process is `exec`'d while that stdin pipe is open. The fix is to enhance our Darwin process spawning layer to set the close-on-exec flag for the pipe file descriptors, so that they are not inherited by child processes spawned using code paths that don't set `POSIX_SPAWN_CLOEXEC_DEFAULT`. Release Notes: - Fixed a bug on macOS where Git operations could be blocked depending on the timing of spawning child processes. Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
maxbrunsfeld
added a commit
that referenced
this pull request
May 25, 2026
…herry-pick to preview) (#57661) Cherry-pick of #57572 to preview ---- When restarting Zed, I hit a bug where all Git operations were hung. I realized that there was a hanging git process running `git cat-file --batch-check=%(objectname)`. The process was waiting on stdin. This was surprising, because [the code](https://github.com/zed-industries/zed/blob/e2bbdb19b6da2ee157ca1d36100acde2134a1663/crates/git/src/repository.rs#L1665-L1709) that spawns this process explicitly closes the pipe that is attached to the process's stdin after writing a list of ref names. Using Claude, I found that this could be caused by that pipe file descriptor being cloned due to file descriptor inheritance when another child process is `exec`'d while that stdin pipe is open. The fix is to enhance our Darwin process spawning layer to set the close-on-exec flag for the pipe file descriptors, so that they are not inherited by child processes spawned using code paths that don't set `POSIX_SPAWN_CLOEXEC_DEFAULT`. Release Notes: - Fixed a bug on macOS where Git operations could be blocked depending on the timing of spawning child processes. Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
|
Thank you. I think this fixed #49799 for me finally!! <3 |
1 task
This was referenced May 26, 2026
TomPlanche
pushed a commit
to TomPlanche/zed
that referenced
this pull request
Jun 2, 2026
…ries#57572) When restarting Zed, I hit a bug where all Git operations were hung. I realized that there was a hanging git process running `git cat-file --batch-check=%(objectname)`. The process was waiting on stdin. This was surprising, because [the code](https://github.com/zed-industries/zed/blob/e2bbdb19b6da2ee157ca1d36100acde2134a1663/crates/git/src/repository.rs#L1665-L1709) that spawns this process explicitly closes the pipe that is attached to the process's stdin after writing a list of ref names. Using Claude, I found that this could be caused by that pipe file descriptor being cloned due to file descriptor inheritance when another child process is `exec`'d while that stdin pipe is open. The fix is to enhance our Darwin process spawning layer to set the close-on-exec flag for the pipe file descriptors, so that they are not inherited by child processes spawned using code paths that don't set `POSIX_SPAWN_CLOEXEC_DEFAULT`. Release Notes: - Fixed a bug on macOS where Git operations could be blocked depending on the timing of spawning child processes.
This was referenced Jun 3, 2026
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.
When restarting Zed, I hit a bug where all Git operations were hung. I realized that there was a hanging git process running
git cat-file --batch-check=%(objectname). The process was waiting on stdin. This was surprising, because the code that spawns this process explicitly closes the pipe that is attached to the process's stdin after writing a list of ref names.Using Claude, I found that this could be caused by that pipe file descriptor being cloned due to file descriptor inheritance when another child process is
exec'd while that stdin pipe is open. The fix is to enhance our Darwin process spawning layer to set the close-on-exec flag for the pipe file descriptors, so that they are not inherited by child processes spawned using code paths that don't setPOSIX_SPAWN_CLOEXEC_DEFAULT.Release Notes: