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

Can't call GenerateConsoleCtrlEvent system call in windows containers #3173

Closed
lox opened this issue Jan 3, 2019 · 12 comments
Closed

Can't call GenerateConsoleCtrlEvent system call in windows containers #3173

lox opened this issue Jan 3, 2019 · 12 comments

Comments

@lox
Copy link

lox commented Jan 3, 2019

Expected behavior

When starting a process in a windows docker container, it's expected that the process should be able to call GenerateConsoleCtrlEvent to send CTRL_C or CTRL_BREAK events to it's own console process group and sub-processes.

This technique is used to signal subprocesses to gracefully terminate, e.g clean up resources before the stop.

Actual behavior

Any call to GenerateConsoleCtrlEvent returns Incorrect function.

Information

Windows version: Windows 10 Pro: Version 10.0.17134.472
Docker for Windows: 2.0.0.0-win81 (29211)

Steps to reproduce the behavior

package main

import (
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var (
	libkernel32                  = syscall.MustLoadDLL("kernel32")
	procGenerateConsoleCtrlEvent = libkernel32.MustFindProc("GenerateConsoleCtrlEvent")
)

func main() {
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs)
	go func() {
		s := <-sigs
		log.Printf("Got signal %v", s)
		os.Exit(0)
	}()

	r, _, err := procGenerateConsoleCtrlEvent.Call(syscall.CTRL_C_EVENT, uintptr(0))
	if r == 0 {
		log.Fatalf("Error sending CTRL_C_EVENT: %v", err)
	}

	time.Sleep(time.Second)
	log.Printf("Exiting normally")
}

Dockerfile:

FROM mcr.microsoft.com/windows/servercore:ltsc2016
COPY ./ctrl-break-test.exe /
CMD ["/ctrl-break-test.exe"]

Tested with golang 1.11.4:

go build -o ctrl-break-test.exe .
docker build --tag ctrl-break-test .
docker run --rm ctrl-break-test

Output is:

2019/01/03 20:47:11 Error sending CTRL_C_EVENT: Incorrect function.

Expected (as when run from outside docker):

2019/01/03 20:52:08 Got signal interrupt
@lox
Copy link
Author

lox commented Jan 6, 2019

@StefanScherer @mattn is this something you have encountered before? @mattn, I was liberally borrowing your idea from https://github.com/mattn/goemon/blob/master/proc_windows.go.

If anyone has a better suggestion on where to post this, I'd welcome it!

@mattn
Copy link

mattn commented Jan 7, 2019

FYI, if you want to terminate process tree forcibly, you can use CreateJobObject/TerminateJobObject.

@lox
Copy link
Author

lox commented Jan 7, 2019

Thanks @mattn, the thing I wanted most was to be able to intercept a signal and do a graceful shutdown with some cleanup. Ctrl-c and Ctrl-break seem like the only practical ways to do that?

@mattn
Copy link

mattn commented Jan 7, 2019

Yes. As far as I know, if you want to do graceful shutdown, GenerateConsoleCtrlEvent is only way to do.

@lox
Copy link
Author

lox commented Jan 7, 2019

Darn, yeah that is the conclusion I've come to after the long journey I've been on too. Thanks for all your trailblazing on this front!

@lox
Copy link
Author

lox commented Jan 7, 2019

Any suggestions on where I might file this bug to get to some windows container folks that would know the answer @mattn?

@StefanScherer
Copy link
Member

@lox have you tried Windows Server 2019? It is fixed in the ltsc2019 image.

I put your example code here and added a Dockerfile

FROM golang:1.11.4

COPY testctrlc.go testctrlc.go
RUN go build testctrlc.go

CMD [ "testctrlc.exe" ]

When I build and run the image on a Windows Server 2016 I can reproduce the error:

$ docker build -t testctrc .
$ docker run testctrlc
2019/01/07 07:29:34 Error sending CTRL_C_EVENT: Incorrect function.

When I build and run the image on a Windows Server 2019 it works:

$ docker build -t testctrc .
$ docker run testctrlc
2019/01/07 07:30:25 Got signal interrupt

Thanks @taylorb-microsoft and team for yet another improvement in Windows Server 2019 :-)
Thanks @tianon and team for adding Windows Server 2019 to the golang multi-arch image 🎉

@lox
Copy link
Author

lox commented Jan 18, 2019

Thanks very much for that @StefanScherer! I'll try that image!

@docker-robott
Copy link
Collaborator

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale comment.
Stale issues will be closed after an additional 30d of inactivity.

Prevent issues from auto-closing with an /lifecycle frozen comment.

If this issue is safe to close now please do so.

Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows.
/lifecycle stale

@mattn
Copy link

mattn commented Apr 18, 2019

ping

@lox
Copy link
Author

lox commented Apr 18, 2019

I can confirm this works in ltsc2019 images, closing!

@lox lox closed this as completed Apr 18, 2019
@docker-robott
Copy link
Collaborator

Closed issues are locked after 30 days of inactivity.
This helps our team focus on active issues.

If you have found a problem that seems similar to this, please open a new issue.

Send feedback to Docker Community Slack channels #docker-for-mac or #docker-for-windows.
/lifecycle locked

@docker docker locked and limited conversation to collaborators Jul 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants