Skip to content

Fix git hang caused by accidental inheritance of stdin FD#57572

Merged
maxbrunsfeld merged 2 commits into
mainfrom
prevent-inheritance-of-pipes-on-exec
May 25, 2026
Merged

Fix git hang caused by accidental inheritance of stdin FD#57572
maxbrunsfeld merged 2 commits into
mainfrom
prevent-inheritance-of-pipes-on-exec

Conversation

@maxbrunsfeld

Copy link
Copy Markdown
Collaborator

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 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.

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`.
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label May 23, 2026
@zed-community-bot zed-community-bot Bot added the staff Pull requests authored by a current member of Zed staff label May 23, 2026

@kubkon kubkon left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice!

@maxbrunsfeld maxbrunsfeld enabled auto-merge May 25, 2026 16:14
@maxbrunsfeld maxbrunsfeld added this pull request to the merge queue May 25, 2026
Merged via the queue into main with commit 2e20860 May 25, 2026
32 checks passed
@maxbrunsfeld maxbrunsfeld deleted the prevent-inheritance-of-pipes-on-exec branch May 25, 2026 16:23
@maxbrunsfeld

Copy link
Copy Markdown
Collaborator Author

/cherry-pick preview
/cherry-pick stable

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>
@spreiter

Copy link
Copy Markdown

Thank you. I think this fixed #49799 for me finally!! <3

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants