daemon/debugtrap_windows.go
f4b08c7f
 package daemon
 
 import (
 	"fmt"
 	"os"
192e6d99
 	"unsafe"
f4b08c7f
 
192e6d99
 	winio "github.com/Microsoft/go-winio"
59d88785
 	"github.com/docker/docker/pkg/signal"
1009e6a4
 	"github.com/sirupsen/logrus"
069fdc8a
 	"golang.org/x/sys/windows"
f4b08c7f
 )
 
4c62b126
 func (d *Daemon) setupDumpStackTrap(root string) {
f4b08c7f
 	// Windows does not support signals like *nix systems. So instead of
 	// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
192e6d99
 	// signaled. ACL'd to builtin administrators and local system
7d0dea10
 	event := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid())
 	ev, _ := windows.UTF16PtrFromString(event)
192e6d99
 	sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
 	if err != nil {
7d0dea10
 		logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", event, err.Error())
192e6d99
 		return
 	}
069fdc8a
 	var sa windows.SecurityAttributes
192e6d99
 	sa.Length = uint32(unsafe.Sizeof(sa))
 	sa.InheritHandle = 1
 	sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
e942513a
 	h, err := windows.CreateEvent(&sa, 0, 0, ev)
192e6d99
 	if h == 0 || err != nil {
7d0dea10
 		logrus.Errorf("failed to create debug stackdump event %s: %s", event, err.Error())
192e6d99
 		return
 	}
f4b08c7f
 	go func() {
7d0dea10
 		logrus.Debugf("Stackdump - waiting signal at %s", event)
192e6d99
 		for {
069fdc8a
 			windows.WaitForSingleObject(h, windows.INFINITE)
e5d36586
 			path, err := signal.DumpStacks(root)
 			if err != nil {
 				logrus.WithError(err).Error("failed to write goroutines dump")
4c62b126
 			} else {
 				logrus.Infof("goroutine stacks written to %s", path)
 			}
f4b08c7f
 		}
 	}()
 }