Skip to content

Conversation

@scottrbaxter
Copy link

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 the CPU Load segment in my p10k config. (screenshots from btop)

Screenshot 2025-04-21 at 10 33 23 PM

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.

Screenshot 2025-04-21 at 10 33 55 PM

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, where eval $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 avoids eval and provides an explicit wait 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!


# usage: _p9k_worker_async <work> <callback>
function _p9k_worker_async() {
local fd async=$1
Copy link

@ryder-gillen-ltk ryder-gillen-ltk Sep 28, 2025

Choose a reason for hiding this comment

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

when you wait outside of cloexec you have turned the asynchronous worker into an synchronous one.

Copy link
Owner

Choose a reason for hiding this comment

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

Indeed. The fix is wrong but the issue is legit--or at least I don't see why it wouldn't be just from the description. Do you also experience it?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants