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

os, runtime: CTRL_CLOSE_EVENT should generate SIGTERM on Windows #7479

Closed
gopherbot opened this issue Mar 6, 2014 · 33 comments
Closed

os, runtime: CTRL_CLOSE_EVENT should generate SIGTERM on Windows #7479

gopherbot opened this issue Mar 6, 2014 · 33 comments

Comments

@gopherbot
Copy link

by anacrolix@google.com:

On Windows a CTRL_CLOSE_EVENT message is sent prior to unavoidable termination. This
should be represented by notifying the process with a SIGTERM.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms683242(v=vs.85).aspx
@gopherbot
Copy link
Author

Comment 1 by sgellerde:

fyi,
after applying [1] and doing dev tests it looks like CTRL_CLOSE_EVENT can only be
received for a console process in Windows 7 when using some nasty hacks [2]. Pre Win7
the event seems receivable. If desired I would test it under Win8+. Or did I miss
anything obvious in my diff?
[1] https://gist.github.com/sgeller/10196571
[2]
http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/abf09824-4e4c-4f2c-ae1e-5981f06c9c6e/windows-7-console-application-has-no-way-of-trapping-logoffshutdown-event?forum=windowscompatibility

@gopherbot
Copy link
Author

Comment 2 by anacrolix@google.com:

That's strange it works for me and I'm using Windows 7 32bit. From the thread it looks
like the big spanners you can throw in are:
 * Your app is a GUI/full-fledge Win32 app (this requires a flag to the go linker).
 * You're invoking other Win32 APIs such as service-related and event-loop related stuff.
None of the above were true in my testing.
The patch you want is https://codereview.appspot.com/download/issue71900043_40001.diff
Your gist generates SIGINT for CTRL_CLOSE_EVENT which isn't optimal, the patch generates
SIGTERM for reasons given in the source. Either way you must also catch the signal with
os.Notify. There's a test program here:
https://bitbucket.org/anacrolix/dms/src/8d6ab94e3c8032d11b870867609ba9dd618e79fc/play/termsig/?at=default
If you pipe the output to a file from a terminal, and then close the terminal you should
see the termination signal in the file.

@ianlancetaylor
Copy link
Contributor

Comment 3:

Labels changed: added repo-main, release-none, os-windows.

@gopherbot
Copy link
Author

Comment 5 by RetroModular:

FYI // I have just been having a discussion about this with some guys in one of the Go
Google groups because I was looking for a solution to catch the console being closed (on
Windows) while a Go app is running.
This is the discussion:
https://groups.google.com/forum/#!topic/golang-nuts/S_RDVG3lcdI
Java appears to be handling this in a sensible way by listening for CLOSE and SHUTDOWN
events then firing a SIGTERM signal:
http://hg.openjdk.java.net/jdk9/dev/hotspot/file/9b3f5e4f3372/src/os/windows/vm/os_windows.cpp#l1883
It would be really helpful if this could be implemented in Go.

@alexbrainman
Copy link
Member

Comment 6:

I am happy to try and implement this functionality (after go1.4 is released), but I need
some input:
- which extra events we should handle?
- which syscall or os signals these new events should me mapped into?
I have very little experience with these, and I don't want to influence that decision.
Alex

@flowchartsman
Copy link

So is this issue effectively dead? It would be great to be able to handle certain windows-specific signals.

@ianlancetaylor
Copy link
Contributor

The issue is not dead, but I'm not aware of anybody working on it.

@alexbrainman
Copy link
Member

@alaska what are you trying to do?

Alex

@flowchartsman
Copy link

To detect (as best as I can) when the window is closed on a console application. No matter how it's represented internally, CTRL_CLOSE_EVENT is useful to capture so that cleanup actions can be performed, like flushing to disk or gracefully disconnecting from a service in the 5 seconds allotted after the signal is sent.

@alexbrainman
Copy link
Member

Thank you. I will try and implement this once Go source tree opens again. Unless you want to do it yourself.

Alex

@flowchartsman
Copy link

I'd be happy to, though I would like a collaborator or owner to have the final say on what it maps to, though SIGTERM does seem reasonable.

@alexbrainman
Copy link
Member

I really don't know. I suggest we go with SIGTERM. Others will correct us, if they want to.

Alex

@mattn
Copy link
Member

mattn commented Jul 17, 2015

+1 to SIGTERM

@alexbrainman
Copy link
Member

I tried implementing this (windows-386 only):

diff --git a/src/runtime/defs_windows_386.go b/src/runtime/defs_windows_386.go
index bac6ce7..04c6d7c 100644
--- a/src/runtime/defs_windows_386.go
+++ b/src/runtime/defs_windows_386.go
@@ -16,8 +16,10 @@ const (
    _THREAD_PRIORITY_HIGHEST = 0x2

    _SIGINT           = 0x2
+   _SIGTERM          = 0xf
    _CTRL_C_EVENT     = 0x0
    _CTRL_BREAK_EVENT = 0x1
+   _CTRL_CLOSE_EVENT = 0x2

    _CONTEXT_CONTROL = 0x10001
    _CONTEXT_FULL    = 0x10007
diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go
index f608b4a..8315375 100644
--- a/src/runtime/os1_windows.go
+++ b/src/runtime/os1_windows.go
@@ -448,19 +448,20 @@ func usleep(us uint32) {
 }

 func ctrlhandler1(_type uint32) uint32 {
-   var s uint32
-
    switch _type {
    case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
-       s = _SIGINT
-   default:
-       return 0
-   }
-
-   if sigsend(s) {
-       return 1
+       if sigsend(_SIGINT) {
+           return 1
+       }
+       exit(2)
+   case _CTRL_CLOSE_EVENT:
+       if sigsend(_SIGTERM) {
+           // should not return from ctrlhandler1,
+           // otherwise windows will terminate us immediately.
+           usleep(100 * 1000000)
+       }
+       exit(2)
    }
-   exit(2) // SIGINT, SIGTERM, etc
    return 0
 }

and the only way I can stop Windows closing my process is by not returning from ctrlhandler1 (see usleep I have inserted there). This way everything works as expected - I get new signal and can act on it as I wish.

Unfortunately my change has one bad side effect. I cannot close console window with my process running in it now (unless I have Go SIGTERM handler doing exiting explicitly). We cannot have this change of default behaviour.

I don't see how we can overcome this.

Alex

@mattn
Copy link
Member

mattn commented Sep 10, 2015

I'm thinking, this issue is how to handle SIGTERM on windows using CTRL_CLOSE_EVENT.So it should be a default behavior if the if the user does not catch SIGTERM.

@alexbrainman
Copy link
Member

But none of my programs handle SIGTERM. Sorry @mattn, but I don't like that suddenly all my Go programs won't allow me to close console window. We have to find a way around this problem.

Alex

@omern1
Copy link

omern1 commented Nov 10, 2015

To handle control events, one can register a Control Handler Function which can be easily done syscalls.

SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);

Is there a reason why nobody has suggested that?

@alexbrainman
Copy link
Member

To handle control events, one can register a Control Handler Function which can be easily done syscalls.
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);
Is there a reason why nobody has suggested that?

Go runtime uses SetConsoleCtrlHandler to handle CTRL_C_EVENT and CTRL_BREAK_EVENT events. (grep runtime package for SetConsoleCtrlHandler). I don't understand why someone has to suggest to use SetConsoleCtrlHandler.

Alex

@rgl
Copy link

rgl commented Apr 2, 2018

Can we please have a way to catch CTRL_SHUTDOWN_EVENT (and not return from the handler)? This is the only signal that is currently (Windows 1803+) sent to a console process that is running inside a Windows Container.

@alexbrainman
Copy link
Member

Can we please have a way to catch CTRL_SHUTDOWN_EVENT (and not return from the handler)?

Did you see #7479 (comment) ? I suspect you will have the same problem with CTRL_SHUTDOWN_EVENT. Feel free to try it yourself.

Alex

@maruel
Copy link
Contributor

maruel commented Apr 6, 2018

@alexbrainman if I understand correctly, the problem lies into making sure that sigsend() is completely synchronous? Maybe call signalWaitUntilIdle()?

Potentially naive pseudo code:

func ctrlhandler1(_type uint32) uint32 {
  switch _type {
  case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
    if !sigsend(_SIGINT) {
      exit(2) // Signal processing failed.
    }
    return 1 // Disallow default processing to not terminate the process.
  case CTRL_CLOSE_EVENT:
    if !sigsend(_SIGTERM) {
      exit(2) // Signal processing failed.
    }
    signalWaitUntilIdle()
    return 1 // Windows will terminate the process forcibly.
  default:
    return 0 // Default handler will terminate the process.
  }
}

@rgl
Copy link

rgl commented Apr 6, 2018

@alexbrainman I did see it, but I was looking for an out-of-the-box solution. i.e. I do not want to compile my own version of go.

Maybe we can get around this without re-compiling go? Maybe by calling SetConsoleCtrlHandler from our own program? In theory, Windows, supports multiple handlers. Have you tried it?

@alexbrainman
Copy link
Member

if I understand correctly, the problem lies into making sure that sigsend() is completely synchronous?

@maruel the problem with my change from #7479 (comment) is that it requires every single Go program to handle SIGTERM. For example, if I run this program

package main

import "time"

func main() {
	time.Sleep(time.Hour)
}

in a Windows command window, and then click close button of that window, nothing happens.

Maybe call signalWaitUntilIdle()?

Maybe it will, but I don't see how.

Maybe we can get around this without re-compiling go? Maybe by calling SetConsoleCtrlHandler from our own program? In theory, Windows, supports multiple handlers. Have you tried it?

@rgl I did not try calling SetConsoleCtrlHandler from Go.

Alex

@rgl
Copy link

rgl commented Apr 8, 2018

@alexbrainman I tried with the following snippet, but for some reason, the callback is never called (altough the CTRL+C shortcut stops working). Do you have any idea why its not working?

package main

import (
	"log"
	"time"

	"syscall"

	"golang.org/x/sys/windows"
)

func main() {
	kernel32 := windows.NewLazySystemDLL("kernel32.dll")

	setConsoleCtrlHandler := kernel32.NewProc("SetConsoleCtrlHandler")

	r1, r2, lastErr := setConsoleCtrlHandler.Call(
		syscall.NewCallback(func(controlType uint) uint {
			log.Printf("consoleControlHandler called with %v", controlType)
			panic("ops")
			return 0
		}),
		1)
	log.Printf("call result %v %v %v", r1, r2, lastErr)

	for {
		time.Sleep(1 * time.Second)
	}
}

@yourchanges
Copy link

works on win10 32bit golang program

func registerShutdown()  {
	kernel32 := syscall.NewLazyDLL("kernel32.dll")

	setConsoleCtrlHandler := kernel32.NewProc("SetConsoleCtrlHandler")

	r1, r2, lastErr := setConsoleCtrlHandler.Call(
		syscall.NewCallback(func(controlType uint) uint {
			log.Printf("consoleControlHandler called with %v", controlType)
			return 0
		}),
		1)
	log.Printf("call result %v %v %v\n", r1, r2, lastErr)
}

@alexbrainman
Copy link
Member

@alexbrainman I tried with the following snippet, but for some reason, the callback is never called (altough the CTRL+C shortcut stops working). Do you have any idea why its not working?

@rgl sorry I misplaced your question.

I just checked your example works fine with current version of Go - both 64 and 32 bit. But it was broken at around the time you asked your question (Apr 8, 2018). I bisected the history to this change bb0fae6

Alex

@ncruces
Copy link
Contributor

ncruces commented Jan 25, 2019

A workaround, based on previous comments:

func handleConsoleCtrl(c chan<- os.Signal) error {
	kernel32 := syscall.NewLazyDLL("kernel32.dll")
	setConsoleCtrlHandler := kernel32.NewProc("SetConsoleCtrlHandler")

	n, _, err := setConsoleCtrlHandler.Call(
		syscall.NewCallback(func(controlType uint) uint {
			if controlType >= 2 {
				c <- syscall.Signal(0x1f + controlType)
				select {} // blocks forever
			}
			return 0
		}),
		1)

	if n == 0 {
		return err
	}
	return nil
}

When I want to block waiting for signals:

c := make(chan os.Signal, 1)
if err := handleConsoleCtrl(c); err != nil {
    // handle the error
}
signal.Notify(c) // get notified of all other signals
<-c // handle signals (just blocking here)

Exiting main() (or os.Exit(), etc) terminates the process regardless of the blocked HandlerRoutine.

As to the issue:

I'm not sure I agree with translating these to SIGTERM?
Unlike SIGTERM, you can't cancel these (CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT). They are more like SIGKILL in that respect, except that you get 5-20s to clean up ("synchronously").
That's a difference receivers should be aware of, so I'm sending custom signals instead.

I'm not really sure how to implement these, and not really an expert in any of this. Just my 2¢.

@ncruces
Copy link
Contributor

ncruces commented Feb 8, 2019

the problem with my change from #7479 (comment) is that it requires every single Go program to handle SIGTERM. For example, if I run this program (...) in a Windows command window, and then click close button of that window, nothing happens.

@alexbrainman, when you say nothing happens, does that mean the program is not forcibly closed after the 5s allowed for cleanup? Or just that it takes 5s to close?

Also, is it possible to know whether an handler was installed for a certain signal? If so, and if new signals are created to represent CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT, and if the user registered to handle those, I think it is perfectly fair to block the handler and let the user terminate when he is ready.

I still think SIGTERM should not be used, because these can't be cancelled, and you need to know you have just a few seconds before you should exit.

@alexbrainman
Copy link
Member

@alexbrainman, when you say nothing happens, does that mean the program is not forcibly closed after the 5s allowed for cleanup? Or just that it takes 5s to close?

I am away from my computer for few weeks. But, as far as I remember, I could not close cmd window at all.

Also, is it possible to know whether an handler was installed for a certain signal?

I would not know. Go uses SetConsoleCtrlHandler Windows API. You can google for SetConsoleCtrlHandler documentation to see what is possible and what is not.

Alex

@ncruces
Copy link
Contributor

ncruces commented Feb 9, 2019

Thanks @alexbrainman for taking the time to answer.

I think you misunderstood me on my second point? Let me try again.

I agree with you that it is not good to change behavior (hanging every process is bad, even if only for 5s).

However, if the user registers to receive the signal at the Go level (so signal.Notify, any anything else?), I think it is fair to assume the user will handle the signal and exit the process himself, so giving the user time to do so (hanging) would be fair.

So, is it possible to know, generally, if the user is interested in a particular signal?

This also rests on the assumption that ia new signal (or signals) is used, to indicates to the user that he has only a few seconds to terminate the process (can't be cancelled, and you don't get a second chance to handle them).

Thanks again.

@alexbrainman
Copy link
Member

However, if the user registers to receive the signal at the Go level

But my example from before ( #7479 (comment) ) does not have any user registers to receive the signal code. Do we punish users that do not have such code too?

So, is it possible to know, generally, if the user is interested in a particular signal?

I would not know. Go uses SetConsoleCtrlHandler Windows API. You can google for SetConsoleCtrlHandler documentation to see what is possible and what is not.

Alex

tianon added a commit to tianon/golang-x-sys that referenced this issue Jul 25, 2019
…VENT

This is part of the changes necessary to allow simulated `SIGTERM` on Windows (these are the relevant events for `SetConsoleCtrlHandler` that would correspond to `SIGTERM` on Unix).

Updates golang/go#7479
tianon added a commit to tianon/golang-x-sys that referenced this issue Jul 25, 2019
…VENT

This is part of the changes necessary to allow simulated `SIGTERM` on Windows (these are the relevant events for `SetConsoleCtrlHandler` that would correspond to `SIGTERM` on Unix).

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

Updates golang/go#7479
@gopherbot
Copy link
Author

Change https://golang.org/cl/187578 mentions this issue: windows: add CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT

gopherbot pushed a commit to golang/sys that referenced this issue Jul 26, 2019
…VENT

This is part of the changes necessary to allow simulated `SIGTERM` on Windows (these are the relevant events for `SetConsoleCtrlHandler` that would correspond to `SIGTERM` on Unix).

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

Updates golang/go#7479

(This exists under `src/cmd/vendor/golang.org/x/sys/windows/types_windows.go` in https://github.com/golang/go, so I figured I would start here and follow up with a https://github.com/golang/go PR/CL if reviewers here were amenable to this half.)

Change-Id: If3d0175bb889e4eddca838ef765faf5e379285ea
GitHub-Last-Rev: 7db84d6
GitHub-Pull-Request: #37
Reviewed-on: https://go-review.googlesource.com/c/sys/+/187578
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
tianon added a commit to tianon/go that referenced this issue Jul 26, 2019
…NT as SIGTERM on Windows

This matches the existing behavior of treating CTRL_C_EVENT, CTRL_BREAK_EVENT as a synthesized SIGINT event.

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

As for the usage of these events, the "Timeouts" section of that upstream documentation is important to note, especially the limited window in which to do any cleanup before the program will be forcibly killed (defaults typically 5s, but as low as 500ms, and in many cases configurable system-wide).

These events are especially relevant for Windows containers, where these events (particularly `CTRL_SHUTDOWN_EVENT`) are one of the only ways containers can "gracefully" shut down (moby/moby#25982 (comment)).

This also updates the vendoring of "golang.org/x/sys" under "cmd" to include CL 187578 (adding these same symbols).

Fixes golang#7479
@gopherbot
Copy link
Author

Change https://golang.org/cl/187739 mentions this issue: runtime: treat CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT as SIGTERM on Windows

tianon added a commit to tianon/go that referenced this issue Jul 29, 2019
…NT as SIGTERM on Windows

This matches the existing behavior of treating CTRL_C_EVENT, CTRL_BREAK_EVENT as a synthesized SIGINT event.

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

As for the usage of these events, the "Timeouts" section of that upstream documentation is important to note, especially the limited window in which to do any cleanup before the program will be forcibly killed (defaults typically 5s, but as low as 500ms, and in many cases configurable system-wide).

These events are especially relevant for Windows containers, where these events (particularly `CTRL_SHUTDOWN_EVENT`) are one of the only ways containers can "gracefully" shut down (moby/moby#25982 (comment)).

This was verified by making a simple `main()` which implements the same code as in `ExampleNotify_allSignals` but in a `for` loop, building a `main.exe`, running that in a container, then doing `docker kill -sTERM` on said container.  The program prints `Got signal: SIGTERM`, then exits after the aforementioned timeout, as expected.  Behavior before this patch is that the program gets no notification (and thus no output) but still exits after the timeout.

Fixes golang#7479
tianon added a commit to tianon/go that referenced this issue Jul 29, 2019
…NT as SIGTERM on Windows

This matches the existing behavior of treating CTRL_C_EVENT, CTRL_BREAK_EVENT as a synthesized SIGINT event.

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

As for the usage of these events, the "Timeouts" section of that upstream documentation is important to note, especially the limited window in which to do any cleanup before the program will be forcibly killed (defaults typically 5s, but as low as 500ms, and in many cases configurable system-wide).

These events are especially relevant for Windows containers, where these events (particularly `CTRL_SHUTDOWN_EVENT`) are one of the only ways containers can "gracefully" shut down (moby/moby#25982 (comment)).

This was verified by making a simple `main()` which implements the same code as in `ExampleNotify_allSignals` but in a `for` loop, building a `main.exe`, running that in a container, then doing `docker kill -sTERM` on said container.  The program prints `Got signal: SIGTERM`, then exits after the aforementioned timeout, as expected.  Behavior before this patch is that the program gets no notification (and thus no output) but still exits after the timeout.

Fixes golang#7479
tianon added a commit to tianon/go that referenced this issue Aug 5, 2019
…NT as SIGTERM on Windows

This matches the existing behavior of treating CTRL_C_EVENT, CTRL_BREAK_EVENT as a synthesized SIGINT event.

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

As for the usage of these events, the "Timeouts" section of that upstream documentation is important to note, especially the limited window in which to do any cleanup before the program will be forcibly killed (defaults typically 5s, but as low as 500ms, and in many cases configurable system-wide).

These events are especially relevant for Windows containers, where these events (particularly `CTRL_SHUTDOWN_EVENT`) are one of the only ways containers can "gracefully" shut down (moby/moby#25982 (comment)).

This was verified by making a simple `main()` which implements the same code as in `ExampleNotify_allSignals` but in a `for` loop, building a `main.exe`, running that in a container, then doing `docker kill -sTERM` on said container.  The program prints `Got signal: SIGTERM`, then exits after the aforementioned timeout, as expected.  Behavior before this patch is that the program gets no notification (and thus no output) but still exits after the timeout.

Fixes golang#7479
tianon added a commit to tianon/go that referenced this issue Aug 14, 2019
…NT as SIGTERM on Windows

This matches the existing behavior of treating CTRL_C_EVENT, CTRL_BREAK_EVENT as a synthesized SIGINT event.

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

As for the usage of these events, the "Timeouts" section of that upstream documentation is important to note, especially the limited window in which to do any cleanup before the program will be forcibly killed (defaults typically 5s, but as low as 500ms, and in many cases configurable system-wide).

These events are especially relevant for Windows containers, where these events (particularly `CTRL_SHUTDOWN_EVENT`) are one of the only ways containers can "gracefully" shut down (moby/moby#25982 (comment)).

This was verified by making a simple `main()` which implements the same code as in `ExampleNotify_allSignals` but in a `for` loop, building a `main.exe`, running that in a container, then doing `docker kill -sTERM` on said container.  The program prints `Got signal: SIGTERM`, then exits after the aforementioned timeout, as expected.  Behavior before this patch is that the program gets no notification (and thus no output) but still exits after the timeout.

Fixes golang#7479
tomocy pushed a commit to tomocy/go that referenced this issue Sep 1, 2019
…NT as SIGTERM on Windows

This matches the existing behavior of treating CTRL_C_EVENT, CTRL_BREAK_EVENT as a synthesized SIGINT event.

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

As for the usage of these events, the "Timeouts" section of that upstream documentation is important to note, especially the limited window in which to do any cleanup before the program will be forcibly killed (defaults typically 5s, but as low as 500ms, and in many cases configurable system-wide).

These events are especially relevant for Windows containers, where these events (particularly `CTRL_SHUTDOWN_EVENT`) are one of the only ways containers can "gracefully" shut down (moby/moby#25982 (comment)).

This was verified by making a simple `main()` which implements the same code as in `ExampleNotify_allSignals` but in a `for` loop, building a `main.exe`, running that in a container, then doing `docker kill -sTERM` on said container.  The program prints `Got signal: SIGTERM`, then exits after the aforementioned timeout, as expected.  Behavior before this patch is that the program gets no notification (and thus no output) but still exits after the timeout.

Fixes golang#7479

Change-Id: I2af79421cd484a0fbb9467bb7ddb5f0e8bc3610e
GitHub-Last-Rev: 9e05d63
GitHub-Pull-Request: golang#33311
Reviewed-on: https://go-review.googlesource.com/c/go/+/187739
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
t4n6a1ka pushed a commit to t4n6a1ka/go that referenced this issue Sep 5, 2019
…NT as SIGTERM on Windows

This matches the existing behavior of treating CTRL_C_EVENT, CTRL_BREAK_EVENT as a synthesized SIGINT event.

See https://docs.microsoft.com/en-us/windows/console/handlerroutine for a good documentation source upstream to confirm these values.

As for the usage of these events, the "Timeouts" section of that upstream documentation is important to note, especially the limited window in which to do any cleanup before the program will be forcibly killed (defaults typically 5s, but as low as 500ms, and in many cases configurable system-wide).

These events are especially relevant for Windows containers, where these events (particularly `CTRL_SHUTDOWN_EVENT`) are one of the only ways containers can "gracefully" shut down (moby/moby#25982 (comment)).

This was verified by making a simple `main()` which implements the same code as in `ExampleNotify_allSignals` but in a `for` loop, building a `main.exe`, running that in a container, then doing `docker kill -sTERM` on said container.  The program prints `Got signal: SIGTERM`, then exits after the aforementioned timeout, as expected.  Behavior before this patch is that the program gets no notification (and thus no output) but still exits after the timeout.

Fixes golang#7479

Change-Id: I2af79421cd484a0fbb9467bb7ddb5f0e8bc3610e
GitHub-Last-Rev: 9e05d63
GitHub-Pull-Request: golang#33311
Reviewed-on: https://go-review.googlesource.com/c/go/+/187739
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
@golang golang locked and limited conversation to collaborators Aug 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet