rustup-init leaves user with colored terminal
(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
- Execute
rustup-init - At the first prompt, interrupt by Ctrl-C
- 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)
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:

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:

Another screenshot of repro:

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