fix: Worker no longer leaves defunct pid on macOS #2857
+3
−1
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.
I noticed a process on macOS that initially consumes
1400%
CPU for a brief moment then becomes a<defunct>
(zombie) pid. I was able to trace it back through theCPU Load
segment in my p10k config. (screenshots from btop)Running any command or even simply hitting return (newline) in iTerm spawns a new 1400% CPU pid that almost immediately goes defunct as the new prompt is rewritten. I confirmed this by quickly opening several new tabs in iTerm, each causing an individual (albeit brief) CPU spike before going defunct.
Initial troubleshooting, I determined that disabling the load segment in my prompt make this issue stop, completely.
Further testing, I was able to track this back to
_p9k_worker_async _p9k_prompt_load_async _p9k_prompt_load_sync
in the _p9k_prompt_load_compute function.This calls
_p9k_worker_async
, whereeval $async
appears to be the culprit, here:sysopen -r -o cloexec -u fd <(() { eval $async; } && print -n '\x1e') || return
I believe the reason is due to how macOS handles process substitution and signals, combined with the
eval
call and the potential for the subshell to get stuck. I've provided this solution, which avoidseval
and provides an explicitwait
call in the parent function after spawning the subshell. This forces the parent to wait for the child to terminate, preventing it from becoming defunct.There may be a cleaner solution, and if so I'm more than happy to update with suggestions.
This change has been tested and confirmed compatible with these systems:
macOS Sequoia: affected
macOS Sonoma: affected
Debian Bookworm: not-affected
Side note, thanks for making such an amazing zsh theme!