Skip to content

Commit 66947b2

Browse files
author
John Howard
authored
Merge pull request #480 from Microsoft/jjh/debug
Setup stackdump correctly; add debugger event
2 parents 224f462 + 48e0d4a commit 66947b2

3 files changed

Lines changed: 39 additions & 9 deletions

File tree

cmd/containerd-shim-runhcs-v1/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ func main() {
106106
return nil
107107
}
108108

109+
// Setup the event for stack dump
110+
setupDumpStacks()
111+
109112
if err := app.Run(os.Args); err != nil {
110113
fmt.Fprintln(cli.ErrWriter, err)
111114
os.Exit(1)

cmd/containerd-shim-runhcs-v1/serve.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,31 +156,56 @@ var serveCommand = cli.Command{
156156
},
157157
}
158158

159-
func setupDumpStacks() error {
160-
// Windows does not support signals like *nix systems. So instead of
161-
// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
162-
// signaled. ACL'd to builtin administrators and local system
163-
event := "Global\\containerd-shim-runhcs-v1-" + fmt.Sprint(os.Getpid())
159+
// createEvent creates a Windows event ACL'd to builtin administrator
160+
// and local system. Can use docker-signal to signal the event.
161+
func createEvent(event string) (windows.Handle, error) {
164162
ev, _ := windows.UTF16PtrFromString(event)
165163
sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
166164
if err != nil {
167-
return errors.Wrapf(err, "failed to get security descriptor for debug stackdump event '%s'", event)
165+
return 0, errors.Wrapf(err, "failed to get security descriptor for event '%s'", event)
168166
}
169167
var sa windows.SecurityAttributes
170168
sa.Length = uint32(unsafe.Sizeof(sa))
171169
sa.InheritHandle = 1
172170
sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
173171
h, err := windows.CreateEvent(&sa, 0, 0, ev)
174172
if h == 0 || err != nil {
175-
return errors.Wrapf(err, "failed to create debug dump stack event '%s'", event)
173+
return 0, errors.Wrapf(err, "failed to create event '%s'", event)
174+
}
175+
return h, nil
176+
}
177+
178+
// setupDebuggerEvent listens for an event to allow a debugger such as delve
179+
// to attach for advanced debugging. It's called when handling a ContainerCreate
180+
func setupDebuggerEvent() {
181+
if os.Getenv("CONTAINERD_SHIM_RUNHCS_V1_WAIT_DEBUGGER") == "" {
182+
return
183+
}
184+
event := "Global\\debugger-" + fmt.Sprint(os.Getpid())
185+
handle, err := createEvent(event)
186+
if err != nil {
187+
return
188+
}
189+
logrus.Infof("Halting until %s is signalled", event)
190+
windows.WaitForSingleObject(handle, windows.INFINITE)
191+
return
192+
}
193+
194+
// setupDumpStacks listens for an event which when signalled dumps the
195+
// stacks from this process to the log output.
196+
func setupDumpStacks() {
197+
event := "Global\\stackdump-" + fmt.Sprint(os.Getpid())
198+
handle, err := createEvent(event)
199+
if err != nil {
200+
return
176201
}
177202
go func() {
178203
for {
179-
windows.WaitForSingleObject(h, windows.INFINITE)
204+
windows.WaitForSingleObject(handle, windows.INFINITE)
180205
dumpStacks()
181206
}
182207
}()
183-
return nil
208+
return
184209
}
185210

186211
func dumpStacks() {

cmd/containerd-shim-runhcs-v1/service_internal.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ func (s *service) stateInternal(ctx context.Context, req *task.StateRequest) (*t
6969
}
7070

7171
func (s *service) createInternal(ctx context.Context, req *task.CreateTaskRequest) (*task.CreateTaskResponse, error) {
72+
setupDebuggerEvent()
73+
7274
var shimOpts *runhcsopts.Options
7375
if req.Options != nil {
7476
v, err := typeurl.UnmarshalAny(req.Options)

0 commit comments

Comments
 (0)