Skip to content

Commit

Permalink
Merge pull request #2837 from jterry75/containerd_dump_stacks
Browse files Browse the repository at this point in the history
Add dumpStacks support for containerd on Windows
  • Loading branch information
estesp committed Nov 28, 2018
2 parents 3ef95e0 + b4a642f commit 1ce733a
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 18 deletions.
16 changes: 16 additions & 0 deletions cmd/containerd/command/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"os"
"os/signal"
"path/filepath"
"runtime"
"time"

"github.com/containerd/containerd/log"
Expand Down Expand Up @@ -232,3 +233,18 @@ func setLevel(context *cli.Context, config *srvconfig.Config) error {
}
return nil
}

func dumpStacks() {
var (
buf []byte
stackSize int
)
bufferLen := 16384
for stackSize == len(buf) {
buf = make([]byte, bufferLen)
stackSize = runtime.Stack(buf, true)
bufferLen *= 2
}
buf = buf[:stackSize]
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
}
17 changes: 0 additions & 17 deletions cmd/containerd/command/main_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ package command
import (
"context"
"os"
"runtime"

"github.com/containerd/containerd/log"
"github.com/containerd/containerd/services/server"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)

Expand Down Expand Up @@ -66,18 +64,3 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
}()
return done
}

func dumpStacks() {
var (
buf []byte
stackSize int
)
bufferLen := 16384
for stackSize == len(buf) {
buf = make([]byte, bufferLen)
stackSize = runtime.Stack(buf, true)
bufferLen *= 2
}
buf = buf[:stackSize]
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
}
35 changes: 34 additions & 1 deletion cmd/containerd/command/main_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ package command

import (
"context"
"fmt"
"os"
"path/filepath"
"unsafe"

winio "github.com/Microsoft/go-winio"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/services/server"

"github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
)

Expand Down Expand Up @@ -54,5 +57,35 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
}
}
}()
setupDumpStacks()
return done
}

func setupDumpStacks() {
// 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
// signaled. ACL'd to builtin administrators and local system
event := "Global\\containerd-daemon-" + fmt.Sprint(os.Getpid())
ev, _ := windows.UTF16PtrFromString(event)
sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
if err != nil {
logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", event, err.Error())
return
}
var sa windows.SecurityAttributes
sa.Length = uint32(unsafe.Sizeof(sa))
sa.InheritHandle = 1
sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
h, err := windows.CreateEvent(&sa, 0, 0, ev)
if h == 0 || err != nil {
logrus.Errorf("failed to create debug stackdump event %s: %s", event, err.Error())
return
}
go func() {
logrus.Debugf("Stackdump - waiting signal at %s", event)
for {
windows.WaitForSingleObject(h, windows.INFINITE)
dumpStacks()
}
}()
}

0 comments on commit 1ce733a

Please sign in to comment.