Terminal: Unexpected behavior of closeOnExit

Created on 6 Dec 2019  Â·  18Comments  Â·  Source: microsoft/terminal

Environment

Windows 10 version 10.0.18362.0
Windows Terminal 0.7.3291.0
PowerShell Core version 6.2.3

Steps to reproduce

Created a manual profile for PowerShell Core (as an automatic profile won't get added when it's installed as a dotnet global tool), like this:

    {
      "guid": "{1ba0ecbe-ee5f-4f20-80fc-c7f3376445ca}",
      "name": "PowerShell Core",
      "commandline": "%USERPROFILE%\\.dotnet\\tools\\pwsh.exe",
      "startingDirectory": "%USERPROFILE%",
      "hidden": false,
      "fontFace": "Cascadia Mono PL",
      "fontSize": 13,
      "colorScheme": "Gruvbox Dark"
    }

Create a new PowerShell Core window, then run a native command (.exe) that takes a bit of time to run and then immediately hit Ctrl+C.

In my case, I've tested this running both java applications as well as kubectl get pods --all-namespaces for my kubernetes cluster.

Expected behavior

I'd expect the native application to handle the Ctrl+C, terminate, and get back to the PowerShell Core prompt.

Actual behavior

The entire Windows Terminal tab is getting killed, as if the shell had been terminated.

What appears to be going on here is related to the closeOnExit setting. My original profile used the default value for this, and apparently, Windows Terminal is mistaking the child process terminating due to Ctrl+C as the PowerShell Core shell terminating, so it's killing the tab window.

Setting closeOnExit: false seems to work around this, and lets the tab open, but the default behavior is very surprising, and seems like a bug tracking which process terminated.

Area-TerminalConnection Issue-Bug Product-Powershell Tracking-External

Most helpful comment

Scoop already has an issue, and are working towards a solution:
https://github.com/lukesampson/scoop/issues/3634

All 18 comments

This looks like it is a bug in the dotnet global tool launcher. It isn't suppressing the _terminate_ event for Ctrl+C. You see this often in process launchers -- they don't cede full lifetime control to the spawned process.

I'd recommend filing this bug on dotnet upstream, because it will impact all dotnet global consumers.

FWIW: Windows Terminal tracks the console host (in versions <= 0.7) and the root process (in versions >= 8.0) -- if this mechanism fails, Windows' CreateProcess has gone terribly, horribly wrong and nothing on the system will work correctly. :smile:

I'm somewhat confused.... If the dotnet launcher is the problem, wouldn't I just end up with a dead shell when closeOnExit: false, then?

Or are you saying that the top-level process is the dotnet launcher, that is dying, but leaving the underlying powershell core process running attached to the same console?

Er, sorry about that. The top-level process is the dotnet launcher, and that's the one that's exiting. With closeOnExit: false, is the shell actually _usable_ after you ^C it?

Yep, perfectly usable. That's why I said it was the workaround I was currently using.

_Fascinating._

With our changes to closeOnExit in the upcoming 0.8 release, this'll actually get _worse._ Hmm. I'm going to reopen this for right now.

I've filed an issue upstream on PowerShell here: https://github.com/PowerShell/PowerShell/issues/11314. It looks like they're ceding ownership of the console to whatever processes happen to be running, and because they are the actual root process, Terminal decides they've exited.

Thanks!

In the 0.8 release, instead of the tab closing, it now writes that the process exited and becomes unresponsive. Is this what you meant by worse @DHowett-MSFT ?

Yep.

Can confirm it's definitely worse now.

Now it's broken with both closeOnExit enabled or disabled. ¯_(ツ)_/¯

Alas. If you're having an issue with the dotnet global version of PowerShell, pile on to https://github.com/PowerShell/PowerShell/issues/11314. If you're having an issue with Scoop, somebody will need to file the same exact issue on them. I don't use scoop, so I do not know anything about their issue process.

Scoop already has an issue, and are working towards a solution:
https://github.com/lukesampson/scoop/issues/3634

I'm not sure how related this is, but I'm seeing the same exit behaviour with CMD and a batch script (v0.8.10091.0 - closeOnExit enabled). It seems like terminating the script with ^C causes the console to get confused about what state things are in.

Minimal repro using simple infinite-loop batch script:

Microsoft Windows [Version 10.0.19041.21]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Users\Kirlac>more test.bat
@echo off

:Test
    echo test
    timeout 5 > NUL
    GOTO :Test

C:\Users\Kirlac>test.bat
test
test
test
^CTerminate batch job (Y/N)? y

C:\Users\Kirlac>exit

[process exited with code 3221225786]

The strange thing is if I do something other than exit immediately after killing the batch script this seems to resolve itself and the exit command starts working again.

eg. Using the same script as above but calling cd between ^C and exit:

C:\Users\Kirlac>test.bat
test
test
^CTerminate batch job (Y/N)? y

C:\Users\Kirlac>cd
C:\Users\Kirlac

C:\Users\Kirlac>exit

At this point the terminal window closed as expected without the "process exited with code 3221225786" message.

Using Terminal 0.11.1191.0. I cleared my settings and reinstalled Terminal.

I have the same issue with PowerShell (dotnet global) 6.2.3:

PowerShell 6.2.3
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/pscore6-docs
Type 'help' to get help.

PS C:\Users\kolbe> ping 127.0.0.1

Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Ping statistics for 127.0.0.1:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
Control-C

[process exited with code 3221225786]

But not with PowerShell 7.0.0:

PowerShell 7.0.0
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/powershell
Type 'help' to get help.

PS C:\Users\kolbe> ping 127.0.0.1

Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Ping statistics for 127.0.0.1:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
Control-C

This is a bug in the dotnet global wrapper that came with powershell 6. The wrapper is exiting when you press ^C, which takes the powershell process down at the same time.

This is the same issue I linked upthread, https://github.com/PowerShell/PowerShell/issues/11314

It is not just powershell, i was running cmd.
image
Same thing happened to me when i tried to exit.

edit:
what i figured out is that if I type a mistake, for example 'exita' instead of 'exit', then type 'exit' it crashes.
this was correct for cmd, ubuntu, ubuntu 20.04, ubuntu 18.04, git bash.
but for powershell, it closed correctly.
for cmd the error code is 9009, and for all the others it was 127.

It is not just powershell, i was running cmd.

I can confirm this happening. Also happens when, for example, using ping but aborting directly via CTRL-C, then using exit. Result is [process exited with code 3221225786].

Was this page helpful?
0 / 5 - 0 ratings