xonsh / xontrib-coreutils

Additional cross-platform core utilities that are implemented in xonsh.
2 stars 1 forks source link

Sufficiently slow external PROMPT command can cause errors if coreutils is loaded #1

Open chipbuster opened 2 years ago

chipbuster commented 2 years ago

xonfig

``` xontrib load coreutils # Comment out to fix issue $XONSH_SHOW_TRACEBACK = True def prompt(): return $(sleep 0.5 | echo """Prompt>""" | cat) $PROMPT = prompt ```

Expected Behavior

The shell doesn't crash.

Current Behavior

When running a sufficiently slow external command as PROMPT in xonsh, one of two things can happen:

In the output below, I was mashing ENTER at a blank prompt, and the exception occurred after 3 attempts.

The issue completely disappears if xontrib load coreutils is commented.

Traceback (if applicable)

``` /home/chipbuster/.config/xonsh/rc.xsh:1:8 - xontrib load coreutils # Comment out to fix issue /home/chipbuster/.config/xonsh/rc.xsh:1:8 + ![xontrib load coreutils] # Comment out to fix issue Prompt> Failed to format prompt ``-> :'NoneType' object cannot be interpreted as an integer Prompt> Failed to format prompt ``-> :'NoneType' object cannot be interpreted as an integer Prompt> Failed to format prompt ``-> :'NoneType' object cannot be interpreted as an integer xonsh: To log full traceback to a file set: $XONSH_TRACEBACK_LOGFILE = Traceback (most recent call last): File "/usr/lib/python3.10/site-packages/xonsh/prompt/__amalgam__.py", line 880, in __call__ toks = self._format_prompt(template=template, **kwargs) File "/usr/lib/python3.10/site-packages/xonsh/ptk_shell/formatter.py", line 46, in _format_prompt toks = super()._format_prompt( File "/usr/lib/python3.10/site-packages/xonsh/prompt/__amalgam__.py", line 892, in _format_prompt tmpl = template() if callable(template) else template File "/home/chipbuster/.config/xonsh/rc.xsh", line 6, in prompt return $(sleep 0.5 | echo """Prompt>""" | cat) File "/usr/lib/python3.10/site-packages/xonsh/built_ins.py", line 166, in subproc_captured_stdout return xonsh.procs.specs.run_subproc(cmds, captured="stdout", envs=envs) File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 3582, in run_subproc command.end() File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 928, in end self._end(tee_output=tee_output) File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 936, in _end for _ in self.tee_stdout(): File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 838, in tee_stdout for line in self.iterraw(): File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 723, in iterraw task = xj.wait_for_active_job() File "/usr/lib/python3.10/site-packages/xonsh/__amalgam__.py", line 11043, in wait_for_active_job _, wcode = os.waitpid(obj.pid, os.WUNTRACED) TypeError: 'NoneType' object cannot be interpreted as an integer During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.10/site-packages/xonsh/prompt/__amalgam__.py", line 987, in _failover_template_format return template() File "/home/chipbuster/.config/xonsh/rc.xsh", line 6, in prompt return $(sleep 0.5 | echo """Prompt>""" | cat) File "/usr/lib/python3.10/site-packages/xonsh/built_ins.py", line 166, in subproc_captured_stdout return xonsh.procs.specs.run_subproc(cmds, captured="stdout", envs=envs) File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 3582, in run_subproc command.end() File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 928, in end self._end(tee_output=tee_output) File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 936, in _end for _ in self.tee_stdout(): File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 838, in tee_stdout for line in self.iterraw(): File "/usr/lib/python3.10/site-packages/xonsh/procs/__amalgam__.py", line 723, in iterraw task = xj.wait_for_active_job() File "/usr/lib/python3.10/site-packages/xonsh/__amalgam__.py", line 11043, in wait_for_active_job _, wcode = os.waitpid(obj.pid, os.WUNTRACED) TypeError: 'NoneType' object cannot be interpreted as an integer Traceback (most recent call last): File "/usr/lib/python3.10/site-packages/xonsh/__amalgam__.py", line 21797, in main sys.exit(main_xonsh(args)) File "/usr/lib/python3.10/site-packages/xonsh/__amalgam__.py", line 21835, in main_xonsh shell.shell.cmdloop() File "/usr/lib/python3.10/site-packages/xonsh/ptk_shell/shell.py", line 402, in cmdloop line = self.singleline(auto_suggest=auto_suggest) File "/usr/lib/python3.10/site-packages/xonsh/ptk_shell/shell.py", line 371, in singleline line = self.prompter.prompt(**prompt_args) File "/usr/lib/python3.10/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1033, in prompt return self.app.run( File "/usr/lib/python3.10/site-packages/prompt_toolkit/application/application.py", line 937, in run return loop.run_until_complete( File "/usr/lib/python3.10/asyncio/base_events.py", line 641, in run_until_complete return future.result() File "/usr/lib/python3.10/site-packages/prompt_toolkit/application/application.py", line 856, in run_async return await _run_async2() File "/usr/lib/python3.10/site-packages/prompt_toolkit/application/application.py", line 826, in _run_async2 result = await _run_async() File "/usr/lib/python3.10/site-packages/prompt_toolkit/application/application.py", line 741, in _run_async with self.input.raw_mode(), self.input.attach( File "/usr/lib/python3.10/site-packages/prompt_toolkit/input/vt100.py", line 266, in __enter__ termios.tcsetattr(self.fileno, termios.TCSANOW, newattr) termios.error: (5, 'Input/output error') Xonsh encountered an issue during launch Failback to /bin/sh sh: initialize_job_control: no job control in background: Bad file descriptor sh-5.1$ ```

Steps to Reproduce

I believe that simply using the config above, launching xonsh, and mashing ENTER at a blank prompt should trigger the bug. However, both systems tested with this bug seem to be using Python 3.10. I attempted to test this with Python 3.8 and I think I got a reproduction, but I'm not 100% certain I did it correctly (I'm not terribly familiar with python environments), so let me know if this fails to reproduce.

For community

⬇️ Please click the 👍 reaction instead of leaving a +1 or 👍 comment

gforsyth commented 2 years ago

Hey @chipbuster -- thanks for reporting! I have to dig in a bit more, but the root cause of this is that the coreutils implementation of cat is doing something a bit fishy with our process runner.

There are two workarounds:

  1. Don't load coreutils (especially since it seems like you're on linux or OSX and should have those utils available already)
  2. Specifically, don't use cat if you do load coreutils -- that is, ignore the cat alias that gets created by coreutils and directly call the cat binary, e.g. in your example:
def prompt():
    return $(sleep 0.5 | echo  """Prompt>""" | /usr/bin/cat)
TeddyHuang-00 commented 2 years ago
  1. Don't load coreutils

I tried this workaround and it works well on all of my *nix machine, including native Debian, Debian on WSL2 and OSX. Thanks a lot for that! 😄

eugenesvk commented 1 year ago

Had a similar issue trying to pin down why execx($(starship init xonsh)) would crash the shell on OSX!

Another issue I had was that the fallback /bin/bash process would take a lot of CPU% even after I close the terminal. Any idea how to remove this fallback behavior?

As a workaround, this seems to work (add it after loading coreutils)

del aliases['cat'] # workaround for this bug https://github.com/xonsh/xontrib-coreutils/issues/1