rustup-init leaves user with colored terminal

Created on 1 Dec 2020  路  29Comments  路  Source: rust-lang/rustup

(If this doesn't belong here, please tell me which repo to move it to, thanks!)

Problem


rustup's setup script, rustup-init, leaves the user with a colored terminal when exiting interrupted.

Steps

  1. Execute rustup-init
  2. At the first prompt, interrupt by Ctrl-C
  3. User's shell is now red.

Possible Solution(s)
Check the interrupted-exit code maybe? Make sure that the color is reset before exiting (Since ^C is displayed in red)

Notes

OS: Win 10 (1909)
Output of rustup --version: rustup 1.23.0 (00924c9ba 2020-11-27)
Output of rustup-init --version: rustup-init 1.22.1 (b01adbbc3 2020-07-08)
Output of rustup show:

Default host: x86_64-pc-windows-msvc
rustup home:  C:\Users\kangj\.rustup

installed toolchains
--------------------

stable-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc (default)

active toolchain
----------------

nightly-x86_64-pc-windows-msvc (default)
rustc 1.48.0-nightly (6af1bdda5 2020-09-15)
O-windows bug help wanted

Most helpful comment

If you can reliably reproduce this then we stand a chance of diagnosing it, yes please @chansuke

All 29 comments

Thank you for your report, I shall try and reproduce this tonight. If anyone else reads this and knows what might be going on, please comment on the issue, I'm not a Windows developer by default.

I've run into this before. It happens because conhost doesn't reset the terminal colours after a program is terminated.
I think bash and most other terminals & shells resets the colour automatically.

What's odd is that there's no red in the rustup output at that point. So I wonder what we've done to the terminal that is causing that.

Perhaps the Interrupt is colored (^C)?

Oh and it appears that the bug only reproduces if you wait a few seconds at the first prompt. In that case the interrupt is red.

Waiting up to 4 seconds before interrupting will actually show the beginning of an error, which could be why it's red...

What error is it showing at that point? can you attach a screenshot?

If I interrupt it at exactly 4 seconds, this error shows up, but is blank:
image

Oh interesting, I wonder if the control+C managed to give it some input before it killed it.

but if I interrupt at different time intervals, things happen:

  • Immediately: Regular white ^C, user shell is normal
  • At 4 secs: error, red ^C, user shell is red
  • Between 1-4 secs, and more than 4 secs: no error, red ^C, user shell is red

That is extremely odd.

Could this be a bug with some sort of input-handling loop? Or maybe rustup-init is loading something within the initial 4 secs?

I guess possibly. I'm not entirely sure how the input loop behaves on Windows.

OK... Is there any way that I can see rustup-init's code? (Or is that closed-source?) All I see on this repo is a rustup-init.sh

the src/ tree is rustup and rustup-init - it's all open source. the code in question will be in src/cli/self_update.rs most likely

OK, thanks!

I'm not able to reproduce this, which is also odd. Are you able to investigate at all @Vbbab ?

Hmm, I could try, but I'm not really familiar with Rust, sorry...

Perhaps someone else with Windows and experience with Rust?

I have a WIndows machine and would like to try to reproduce the error tomorrow.

If you can reliably reproduce this then we stand a chance of diagnosing it, yes please @chansuke

I tried to reproduce the error (rustup 1.23.1 (3df2264a9 2020-11-30)) but couldn't succeed...

An update: There's some error message on my end now. _Very_ rare chance of this actually occurring.

The regular way is by hitting ctrl-c as soon as you arrive at the _initial_ prompt, at which point a red ^C would display and leave your shell red.

Oh interesting, I wonder if the control+C managed to give it some input before it killed it.

I do believe so. Take a look:
image

Another screenshot of repro:
image

I think it was easier to reproduce with certain anti-viruses. I can't remember which but I think McAfee was one.

@toothbrush7777777 Ah...thank you for the detailed information!! I will take a look again.

I think you'd typically have to set the reset sequence (explictly print) on die.

https://github.com/rust-lang/rustup/blob/90c840180955f245047b4a7045e6e949d4076884/src/cli/log.rs#L33

Like, at the end of these kinda functions + general execution, good to add a
let _ = t.reset();

I mean, they could always die without reset-ting (and is a common issue with most commands in Unix as well, nothing new). They usually can handle that atexit / signal handler.

BTW, another way to repro:

  • Navigate to the directory of rustup-init.
  • Type rustup-init, but don't hit enter.
  • Now, follow enter key immediately with ctrl - c.
  • Repeat until the bug is produced.

We need to check where all this can happen; What if there's a fault when printing something, or SIGKILL; If this is a signal handler, the at_exit patch I've posted can be easily re-written; Will figure out how to test it.

My question to all is that is at_exit even a standard at this point? beta/stable compilers don't expose it.

I don't think we're going to get to a stable-compatible solution to this problem in the 1.24.0 cycle so I'm going to defer this particular piece of work for 1.25.0 - if we fix it before 1.24.0 is branched then that's great, but I'm not going to hold up the release for it.

I think we're approaching an idea of the fix, but with the need for nightly right now, we're not able to use it yet.

@rustbot label: +O-windows

Was this page helpful?
0 / 5 - 0 ratings

Related issues

davidawad picture davidawad  路  3Comments

fenhl picture fenhl  路  4Comments

matthiaskrgr picture matthiaskrgr  路  3Comments

KasMA1990 picture KasMA1990  路  3Comments

jimmycuadra picture jimmycuadra  路  4Comments