Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stderr stays mapped to /dev/null #35

Closed
rgouicem opened this issue Oct 4, 2019 · 13 comments
Closed

stderr stays mapped to /dev/null #35

rgouicem opened this issue Oct 4, 2019 · 13 comments

Comments

@rgouicem
Copy link

rgouicem commented Oct 4, 2019

I'm using zsh-async through alien (https://github.com/eendroroy/alien). alien is a prompt theme that uses zsh-async to update the git part of the prompt asynchronously.

Sometimes, I noticed that stderr was no longer printed in my terminal (with echo foo >&2). After some investigation, I realized that stderr was actually mapped to /dev/null (with ls -l /proc/self/fd).

While searching for what caused this, I found this line:

exec 2>/dev/null

Commenting it resolved my problem. I don't know if it is a good way to resolve my issue, this actual errors that should be hidden would be printed.

@mafredri
Copy link
Owner

@rgouicem what version of zsh and operating system did you experience this on? It might be a zsh bug.

The async worker is a clone of your shell but it shouldn't be able to affect its file descriptors. I haven't seen this happen on any of my systems.

@rgouicem
Copy link
Author

I'm currently using zsh 5.7.1 on Arch Linux (might have been updated since my post).

I'm also thinking it might be a zsh bug since it happened again a few times (less frequently than before my fix, but still).

I'm gonna try to investigate a little bit more and maybe open an issue for zsh.

@fd0
Copy link

fd0 commented May 4, 2020

I observe the same issue, zsh 5.7.1 on Debian stable and zsh 5.8 on Arch. I'm using the sorin prompt though, zsh-async is included via the prezto framework. The current commit for zsh-async is 95c2b15.

$ ls -al /proc/$$/fd
total 0
dr-x------ 2 fd0 users  0 Mai  2 11:22 .
dr-xr-xr-x 9 fd0 users  0 Mai  2 11:22 ..
lrwx------ 1 fd0 users 64 Mai  2 11:22 0 -> /dev/pts/2
lrwx------ 1 fd0 users 64 Mai  2 11:22 1 -> /dev/pts/2
l-wx------ 1 fd0 users 64 Mai  2 11:22 2 -> /dev/null

Any ideas on how to debug this further? It is very annoying :)

@mafredri
Copy link
Owner

mafredri commented May 4, 2020

@fd0 oh yeah, that would be super annoying. I'd like to be able to reproduce this somehow, but so far I haven't been able to. I'm wondering if it can be something specific to your .zshrc that is causing it because this really shouldn't happen. We're only redirecting stderr in one place, and that's happening in a forked process. I.e.

exec 2>/dev/null

I have two ideas on what we could try though. The first is to modify this section:

zsh-async/async.zsh

Lines 489 to 492 in 95c2b15

zpty -b $worker _async_worker -p $$ $@ || {
async_stop_worker $worker
return 1
}

With:

	exec {errfd}>&2
	zpty -b $worker _async_worker -p $$ $args 2>&$errfd || {
		async_stop_worker $worker
		return 1
	}
	exec {errfd}>& -

The idea being that we're creating a temporary fd that hopefully is active when the zpty is created, and thus will not reference back to our main stderr fd.

The second is to just add a random sleep N before the exec 2>/dev/null. The idea then being that there might be a race when the zpty is created, and some statements have time to affect the parent process.

@rgouicem
Copy link
Author

Thanks for the fix @mafredri ! I have been trying it for 10 days now, and I don't think I encountered the problem since.
I'm not 100% sure because I still have the reflex to run exec 2>$TTY from time to time so I might have done this unconsciously.

@mafredri
Copy link
Owner

@rgouicem that's great news, thanks for reporting. Which fix were you using btw?

@rgouicem
Copy link
Author

The first one, not the sleep N.

@mafredri
Copy link
Owner

I went ahead and released this now as v1.8.1. Let's hope it works for others too, let me know if any issues pop up!

@jamesoff
Copy link

I have NOCLOBBER set and this change seems to cause a warning with it:

async_start_worker:38: can't clobber parameter errfd containing file descriptor 0

@mafredri
Copy link
Owner

mafredri commented May 20, 2020

@jamesoff I can't reproduce the issue (with noclobber enabled), could you provide reproduction steps?

@jamesoff
Copy link

jamesoff commented May 20, 2020

Definitely doing setopt clobber in my zshrc before anything uses async fixes the issue. It's most notably showing up when my shell starts (I check for active tmux sessions async to remind me they're available to attach to), and that goes away when I change the option. Any hints on how to debug this appreciated, I'm happy to start digging in to my config and the code but I'm not sure where to start. Does this code only execute on the failure of a job (to help me figure out the path which may be leading to it)?

Oddly, it's also causing neovim to segfault as it starts, which I imagine is due to one of my plugins shelling out and being affected in some fashion. Again, setopt clobber fixes that. I'll have a go at building it with debug symbols so I can see where it's failing, but my C debugging skills are worse than my zsh ones ;)

(Edit: not a minimum reproducer, but in case something stands out to you, here's my config, pointing to where I'm using async: https://github.com/jamesoff/zsh/blob/master/.zshrc#L227)

mafredri added a commit that referenced this issue Sep 19, 2020
This commit fixes a clobbering issue of errfd because it was initialized
as an integer (and thus zero value). Instead of always allowing
clobbering, we initialize it as -1 which makes zsh happy and protects us
from accidentally clobbering something in the future.

The error fixed was:

	can't clobber parameter errfd containing file descriptor 0

Possible fix for clobbering issue mentioned in #35.
@mafredri
Copy link
Owner

@jamesoff this kinda fell off my radar, sorry about that. But I believe I might have a fix for your issue in c7f35ec. Would you mind taking a look?

@jamesoff
Copy link

I've updated my install and have re-enabled noclobber in my config. So far so good, I don't see the warning on starting my shell now. I can also start neovim without segfault :)

laggardkernel added a commit to laggardkernel/spacezsh-prompt that referenced this issue Nov 25, 2020
seems fixed the bug of stderr be mapped to /dev/null
mafredri/zsh-async#35
laggardkernel added a commit to laggardkernel/spacezsh-prompt that referenced this issue Nov 25, 2020
seems fixed the bug of stderr be mapped to /dev/null
mafredri/zsh-async#35
laggardkernel added a commit to laggardkernel/spacezsh-prompt that referenced this issue Nov 25, 2020
seems fixed the bug of stderr be mapped to /dev/null
mafredri/zsh-async#35
laggardkernel added a commit to laggardkernel/spacezsh-prompt that referenced this issue Nov 26, 2020
seems fixed the bug of stderr be mapped to /dev/null
mafredri/zsh-async#35
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

No branches or pull requests

4 participants