github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/daemon/debugtrap_windows.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"unsafe"
     7  
     8  	winio "github.com/Microsoft/go-winio"
     9  	"github.com/docker/docker/pkg/signal"
    10  	"github.com/sirupsen/logrus"
    11  	"golang.org/x/sys/windows"
    12  )
    13  
    14  func (d *Daemon) setupDumpStackTrap(root string) {
    15  	// Windows does not support signals like *nix systems. So instead of
    16  	// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
    17  	// signaled. ACL'd to builtin administrators and local system
    18  	event := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid())
    19  	ev, _ := windows.UTF16PtrFromString(event)
    20  	sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
    21  	if err != nil {
    22  		logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", event, err.Error())
    23  		return
    24  	}
    25  	var sa windows.SecurityAttributes
    26  	sa.Length = uint32(unsafe.Sizeof(sa))
    27  	sa.InheritHandle = 1
    28  	sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
    29  	h, err := windows.CreateEvent(&sa, 0, 0, ev)
    30  	if h == 0 || err != nil {
    31  		logrus.Errorf("failed to create debug stackdump event %s: %s", event, err.Error())
    32  		return
    33  	}
    34  	go func() {
    35  		logrus.Debugf("Stackdump - waiting signal at %s", event)
    36  		for {
    37  			windows.WaitForSingleObject(h, windows.INFINITE)
    38  			path, err := signal.DumpStacks(root)
    39  			if err != nil {
    40  				logrus.WithError(err).Error("failed to write goroutines dump")
    41  			} else {
    42  				logrus.Infof("goroutine stacks written to %s", path)
    43  			}
    44  		}
    45  	}()
    46  }